diff --git a/instrumentation/Android.mk b/instrumentation/Android.mk
new file mode 100644
index 0000000..22ee642
--- /dev/null
+++ b/instrumentation/Android.mk
@@ -0,0 +1,22 @@
+# Copyright (C) 2013 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := android-support-multidex-instrumentation
+LOCAL_JAVA_LIBRARIES := android-support-multidex android-test-lib
+LOCAL_SDK_VERSION := 4
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+include $(BUILD_STATIC_JAVA_LIBRARY)
diff --git a/instrumentation/README.txt b/instrumentation/README.txt
new file mode 100644
index 0000000..322676b
--- /dev/null
+++ b/instrumentation/README.txt
@@ -0,0 +1,6 @@
+Library Project including compatibility IntrumentationTestRunner
+for multiple dex applications.
+
+This can be used by an Android test project to set up the classloader
+of applications with multiple dexes.
+
diff --git a/instrumentation/src/com/android/test/runner/MultiDexAndroidJUnitRunner.java b/instrumentation/src/com/android/test/runner/MultiDexAndroidJUnitRunner.java
new file mode 100644
index 0000000..afb6e08
--- /dev/null
+++ b/instrumentation/src/com/android/test/runner/MultiDexAndroidJUnitRunner.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.test.runner;
+
+import com.android.test.runner.AndroidJUnitRunner;
+
+import android.os.Bundle;
+import android.support.multidex.MultiDex;
+
+/**
+ * Extends AndroidJUnitRunner to patch up things for GMS Core multi-dex support.
+ */
+public class MultiDexAndroidJUnitRunner extends AndroidJUnitRunner {
+    @Override
+    public void onCreate(Bundle arguments) {
+        MultiDex.install(getTargetContext());
+        super.onCreate(arguments);
+    }
+}
diff --git a/instrumentation/src/com/android/test/runner/MultiDexTestRunner.java b/instrumentation/src/com/android/test/runner/MultiDexTestRunner.java
new file mode 100644
index 0000000..a93a740
--- /dev/null
+++ b/instrumentation/src/com/android/test/runner/MultiDexTestRunner.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.test.runner;
+
+import android.os.Bundle;
+import android.support.multidex.MultiDex;
+import android.test.InstrumentationTestRunner;
+
+public class MultiDexTestRunner extends InstrumentationTestRunner {
+
+    @Override
+    public void onCreate(Bundle arguments) {
+        MultiDex.install(getTargetContext());
+        super.onCreate(arguments);
+    }
+
+}
diff --git a/library/Android.mk b/library/Android.mk
new file mode 100644
index 0000000..7e14a45
--- /dev/null
+++ b/library/Android.mk
@@ -0,0 +1,21 @@
+# Copyright (C) 2013 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := android-support-multidex
+LOCAL_SDK_VERSION := 4
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+include $(BUILD_STATIC_JAVA_LIBRARY)
diff --git a/library/README.txt b/library/README.txt
new file mode 100644
index 0000000..2fde7e2
--- /dev/null
+++ b/library/README.txt
@@ -0,0 +1,6 @@
+Library Project including compatibility multi dex loader.
+
+This can be used by an Android project to install classloader
+with multiple dex of applications running on API 4+.
+
+
diff --git a/library/src/android/support/multidex/MultiDex.java b/library/src/android/support/multidex/MultiDex.java
new file mode 100644
index 0000000..1fffe3d
--- /dev/null
+++ b/library/src/android/support/multidex/MultiDex.java
@@ -0,0 +1,383 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.support.multidex;
+
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.os.Build;
+import android.util.Log;
+
+import dalvik.system.DexFile;
+
+import java.io.File;
+import java.io.IOException;
+import java.lang.reflect.Array;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Set;
+
+/**
+ * Monkey patches {@link Context#getClassLoader() the application context class
+ * loader} in order to load classes from more than one dex file. The primary
+ * {@code classes.dex} file necessary for calling this class methods. secondary
+ * dex files named classes2.dex, classes".dex... found in the application apk
+ * will be added to the classloader after first call to
+ * {@link #install(Context)}.
+ *
+ * <p/>
+ * <strong>IMPORTANT:</strong>This library provides compatibility for platforms
+ * with API level 4 through 19. This library does nothing on newer versions of
+ * the platform which provide built-in support for secondary dex files.
+ */
+public final class MultiDex {
+
+    static final String TAG = "MultiDex";
+
+    private static final String SECONDARY_FOLDER_NAME = "secondary-dexes";
+
+    private static final int SUPPORTED_MULTIDEX_SDK_VERSION = 20;
+
+    private static final int MIN_SDK_VERSION = 4;
+
+    private static final Set<String> installedApk = new HashSet<String>();
+
+    private MultiDex() {}
+
+    /**
+     * Patches the application context class loader by appending extra dex files
+     * loaded from the application apk. Call this method first thing in your
+     * {@code Application#OnCreate}, {@code Instrumentation#OnCreate},
+     * {@code BackupAgent#OnCreate}, {@code Service#OnCreate},
+     * {@code BroadcastReceiver#onReceive}, {@code Activity#OnCreate} and
+     * {@code ContentProvider#OnCreate} .
+     *
+     * @param context application context.
+     * @throws RuntimeException if an error occurred preventing the classloader
+     *         extension.
+     */
+    public static void install(Context context) {
+
+        if (Build.VERSION.SDK_INT < MIN_SDK_VERSION) {
+            throw new RuntimeException("Multi dex installation failed. SDK " + Build.VERSION.SDK_INT
+                    + " is unsupported. Min SDK version is " + MIN_SDK_VERSION + ".");
+        }
+
+
+        try {
+            PackageManager pm;
+            String packageName;
+            try {
+                pm = context.getPackageManager();
+                packageName = context.getPackageName();
+            } catch (RuntimeException e) {
+                /* Ignore those exceptions so that we don't break tests relying on Context like
+                 * a android.test.mock.MockContext or a android.content.ContextWrapper with a null
+                 * base Context.
+                 */
+                Log.w(TAG, "Failure while trying to obtain ApplicationInfo from Context. " +
+                        "Must be running in test mode. Skip patching.", e);
+                return;
+            }
+            if (pm == null || packageName == null) {
+                // This is most likely a mock context, so just return without patching.
+                return;
+            }
+            ApplicationInfo applicationInfo =
+                    pm.getApplicationInfo(packageName, PackageManager.GET_META_DATA);
+            if (applicationInfo == null) {
+                // This is from a mock context, so just return without patching.
+                return;
+            }
+
+            synchronized (installedApk) {
+                String apkPath = applicationInfo.sourceDir;
+                if (installedApk.contains(apkPath)) {
+                    return;
+                }
+                installedApk.add(apkPath);
+
+                if (Build.VERSION.SDK_INT >= SUPPORTED_MULTIDEX_SDK_VERSION) {
+                    // STOPSHIP: Any app that uses this class needs approval before being released
+                    // as well as figuring out what the right behavior should be here.
+                    throw new RuntimeException("Platform support of multidex for SDK " +
+                            Build.VERSION.SDK_INT + " has not been confirmed yet.");
+                }
+
+                /* The patched class loader is expected to be a descendant of
+                 * dalvik.system.BaseDexClassLoader. We modify its
+                 * dalvik.system.DexPathList pathList field to append additional DEX
+                 * file entries.
+                 */
+                ClassLoader loader;
+                try {
+                    loader = context.getClassLoader();
+                } catch (RuntimeException e) {
+                    /* Ignore those exceptions so that we don't break tests relying on Context like
+                     * a android.test.mock.MockContext or a android.content.ContextWrapper with a
+                     * null base Context.
+                     */
+                    Log.w(TAG, "Failure while trying to obtain Context class loader. " +
+                            "Must be running in test mode. Skip patching.", e);
+                    return;
+                }
+                if (loader == null) {
+                    // Note, the context class loader is null when running Robolectric tests.
+                    Log.e(TAG,
+                            "Context class loader is null. Must be running in test mode. "
+                            + "Skip patching.");
+                    return;
+                }
+
+                File dexDir = new File(context.getFilesDir(), SECONDARY_FOLDER_NAME);
+                List<File> files = MultiDexExtractor.load(context, applicationInfo, dexDir);
+                if (!files.isEmpty()) {
+                    if (Build.VERSION.SDK_INT >= 19) {
+                        V19.install(loader, files, dexDir);
+                    } else if (Build.VERSION.SDK_INT >= 14) {
+                        V14.install(loader, files, dexDir);
+                    } else {
+                        V4.install(loader, files, dexDir);
+                    }
+                }
+            }
+
+        } catch (Exception e) {
+            Log.e(TAG, "Multidex installation failure", e);
+            throw new RuntimeException("Multi dex installation failed (" + e.getMessage() + ").");
+        }
+    }
+
+    /**
+     * Locates a given field anywhere in the class inheritance hierarchy.
+     *
+     * @param instance an object to search the field into.
+     * @param name field name
+     * @return a field object
+     * @throws NoSuchFieldException if the field cannot be located
+     */
+    private static Field findField(Object instance, String name) throws NoSuchFieldException {
+        for (Class<?> clazz = instance.getClass(); clazz != null; clazz = clazz.getSuperclass()) {
+            try {
+                Field field = clazz.getDeclaredField(name);
+
+
+                if (!field.isAccessible()) {
+                    field.setAccessible(true);
+                }
+
+                return field;
+            } catch (NoSuchFieldException e) {
+                // ignore and search next
+            }
+        }
+
+        throw new NoSuchFieldException("Field " + name + " not found in " + instance.getClass());
+    }
+
+    /**
+     * Locates a given method anywhere in the class inheritance hierarchy.
+     *
+     * @param instance an object to search the method into.
+     * @param name method name
+     * @param parameterTypes method parameter types
+     * @return a method object
+     * @throws NoSuchMethodException if the method cannot be located
+     */
+    private static Method findMethod(Object instance, String name, Class<?>... parameterTypes)
+            throws NoSuchMethodException {
+        for (Class<?> clazz = instance.getClass(); clazz != null; clazz = clazz.getSuperclass()) {
+            try {
+                Method method = clazz.getDeclaredMethod(name, parameterTypes);
+
+
+                if (!method.isAccessible()) {
+                    method.setAccessible(true);
+                }
+
+                return method;
+            } catch (NoSuchMethodException e) {
+                // ignore and search next
+            }
+        }
+
+        throw new NoSuchMethodException("Method " + name + " with parameters " +
+                Arrays.asList(parameterTypes) + " not found in " + instance.getClass());
+    }
+
+    /**
+     * Replace the value of a field containing a non null array, by a new array containing the
+     * elements of the original array plus the elements of extraElements.
+     * @param instance the instance whose field is to be modified.
+     * @param fieldName the field to modify.
+     * @param extraElements elements to append at the end of the array.
+     */
+    private static void expandFieldArray(Object instance, String fieldName,
+            Object[] extraElements) throws NoSuchFieldException, IllegalArgumentException,
+            IllegalAccessException {
+        Field jlrField = findField(instance, fieldName);
+        Object[] original = (Object[]) jlrField.get(instance);
+        Object[] combined = (Object[]) Array.newInstance(
+                original.getClass().getComponentType(), original.length + extraElements.length);
+        System.arraycopy(original, 0, combined, 0, original.length);
+        System.arraycopy(extraElements, 0, combined, original.length, extraElements.length);
+        jlrField.set(instance, combined);
+    }
+
+    /**
+     * Installer for platform versions 19.
+     */
+    private static final class V19 {
+
+        private static void install(ClassLoader loader, List<File> additionalClassPathEntries,
+                File optimizedDirectory)
+                        throws IllegalArgumentException, IllegalAccessException,
+                        NoSuchFieldException, InvocationTargetException, NoSuchMethodException {
+            /* The patched class loader is expected to be a descendant of
+             * dalvik.system.BaseDexClassLoader. We modify its
+             * dalvik.system.DexPathList pathList field to append additional DEX
+             * file entries.
+             */
+            Field pathListField = findField(loader, "pathList");
+            Object dexPathList = pathListField.get(loader);
+            ArrayList<IOException> suppressedExceptions = new ArrayList<IOException>();
+            expandFieldArray(dexPathList, "dexElements", makeDexElements(dexPathList,
+                    new ArrayList<File>(additionalClassPathEntries), optimizedDirectory,
+                    suppressedExceptions));
+            if (suppressedExceptions.size() > 0) {
+                Field suppressedExceptionsField =
+                        findField(loader, "dexElementsSuppressedExceptions");
+                IOException[] dexElementsSuppressedExceptions =
+                        (IOException[]) suppressedExceptionsField.get(loader);
+
+                if (dexElementsSuppressedExceptions == null) {
+                    dexElementsSuppressedExceptions =
+                            suppressedExceptions.toArray(
+                                    new IOException[suppressedExceptions.size()]);
+                } else {
+                    IOException[] combined =
+                            new IOException[suppressedExceptions.size() +
+                                            dexElementsSuppressedExceptions.length];
+                    suppressedExceptions.toArray(combined);
+                    System.arraycopy(dexElementsSuppressedExceptions, 0, combined,
+                            suppressedExceptions.size(), dexElementsSuppressedExceptions.length);
+                    dexElementsSuppressedExceptions = combined;
+                }
+
+                suppressedExceptionsField.set(loader, dexElementsSuppressedExceptions);
+            }
+        }
+
+        /**
+         * A wrapper around
+         * {@code private static final dalvik.system.DexPathList#makeDexElements}.
+         */
+        private static Object[] makeDexElements(
+                Object dexPathList, ArrayList<File> files, File optimizedDirectory,
+                ArrayList<IOException> suppressedExceptions)
+                        throws IllegalAccessException, InvocationTargetException,
+                        NoSuchMethodException {
+            Method makeDexElements =
+                    findMethod(dexPathList, "makeDexElements", ArrayList.class, File.class,
+                            ArrayList.class);
+
+            return (Object[]) makeDexElements.invoke(dexPathList, files, optimizedDirectory,
+                    suppressedExceptions);
+        }
+    }
+
+    /**
+     * Installer for platform versions 14, 15, 16, 17 and 18.
+     */
+    private static final class V14 {
+
+        private static void install(ClassLoader loader, List<File> additionalClassPathEntries,
+                File optimizedDirectory)
+                        throws IllegalArgumentException, IllegalAccessException,
+                        NoSuchFieldException, InvocationTargetException, NoSuchMethodException {
+            /* The patched class loader is expected to be a descendant of
+             * dalvik.system.BaseDexClassLoader. We modify its
+             * dalvik.system.DexPathList pathList field to append additional DEX
+             * file entries.
+             */
+            Field pathListField = findField(loader, "pathList");
+            Object dexPathList = pathListField.get(loader);
+            expandFieldArray(dexPathList, "dexElements", makeDexElements(dexPathList,
+                    new ArrayList<File>(additionalClassPathEntries), optimizedDirectory));
+        }
+
+        /**
+         * A wrapper around
+         * {@code private static final dalvik.system.DexPathList#makeDexElements}.
+         */
+        private static Object[] makeDexElements(
+                Object dexPathList, ArrayList<File> files, File optimizedDirectory)
+                        throws IllegalAccessException, InvocationTargetException,
+                        NoSuchMethodException {
+            Method makeDexElements =
+                    findMethod(dexPathList, "makeDexElements", ArrayList.class, File.class);
+
+            return (Object[]) makeDexElements.invoke(dexPathList, files, optimizedDirectory);
+        }
+    }
+
+    /**
+     * Installer for platform versions 4 to 13.
+     */
+    private static final class V4 {
+        private static void install(ClassLoader loader, List<File> additionalClassPathEntries,
+                File optimizedDirectory)
+                        throws IllegalArgumentException, IllegalAccessException,
+                        NoSuchFieldException, IOException {
+            /* The patched class loader is expected to be a descendant of
+             * dalvik.system.DexClassLoader. We modify its
+             * dalvik.system.DexPathList pathList field to append additional DEX
+             * file entries.
+             */
+            int extraSize = additionalClassPathEntries.size();
+
+            Field pathField = findField(loader, "path");
+
+            StringBuilder path = new StringBuilder((String) pathField.get(loader));
+            String[] extraPaths = new String[extraSize];
+            File[] extraFiles = new File[extraSize];
+            DexFile[] extraDexs = new DexFile[extraSize];
+            for (ListIterator<File> iterator = additionalClassPathEntries.listIterator();
+                    iterator.hasNext();) {
+                File additionalEntry = iterator.next();
+                String entryPath = additionalEntry.getAbsolutePath();
+                path.append(':').append(entryPath);
+                int index = iterator.previousIndex();
+                extraPaths[index] = entryPath;
+                extraFiles[index] = additionalEntry;
+                extraDexs[index] = DexFile.loadDex(entryPath, entryPath + ".dex", 0);
+            }
+
+            pathField.set(loader, path.toString());
+            expandFieldArray(loader, "mPaths", extraPaths);
+            expandFieldArray(loader, "mFiles", extraFiles);
+            expandFieldArray(loader, "mDexs", extraDexs);
+        }
+    }
+
+}
diff --git a/library/src/android/support/multidex/MultiDexExtractor.java b/library/src/android/support/multidex/MultiDexExtractor.java
new file mode 100644
index 0000000..220f2aa
--- /dev/null
+++ b/library/src/android/support/multidex/MultiDexExtractor.java
@@ -0,0 +1,175 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.support.multidex;
+
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.util.Log;
+
+import java.io.Closeable;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+import java.util.zip.ZipOutputStream;
+
+/**
+ * Exposes application secondary dex files as files in the application data
+ * directory.
+ */
+final class MultiDexExtractor {
+
+    private static final String TAG = MultiDex.TAG;
+
+    /**
+     * We look for additional dex files named {@code classes2.dex},
+     * {@code classes3.dex}, etc.
+     */
+    private static final String DEX_PREFIX = "classes";
+    private static final String DEX_SUFFIX = ".dex";
+
+    private static final String EXTRACTED_NAME_EXT = ".classes";
+    private static final String EXTRACTED_SUFFIX = ".zip";
+
+    private static final int BUFFER_SIZE = 0x4000;
+
+    /**
+     * Extracts application secondary dexes into files in the application data
+     * directory.
+     *
+     * @param dexDir
+     *
+     * @return a list of files that were created. The list may be empty if there
+     *         are no secondary dex files.
+     * @throws IOException if encounters a problem while reading or writing
+     *         secondary dex files
+     */
+    static List<File> load(Context context, ApplicationInfo applicationInfo, File dexDir)
+            throws IOException {
+
+        String extractedFilePrefix = new File(applicationInfo.sourceDir).getName()
+                + EXTRACTED_NAME_EXT;
+
+        prepareDexDir(dexDir, extractedFilePrefix);
+
+        final List<File> files = new ArrayList<File>();
+        ZipFile apk = new ZipFile(applicationInfo.sourceDir);
+        try {
+
+            int secondaryNumber = 2;
+
+            ZipEntry dexFile = apk.getEntry(DEX_PREFIX + secondaryNumber + DEX_SUFFIX);
+            while (dexFile != null) {
+                String fileName = extractedFilePrefix + secondaryNumber + EXTRACTED_SUFFIX;
+                File extractedFile = new File(dexDir, fileName);
+                files.add(extractedFile);
+
+                if (!extractedFile.isFile()) {
+                    extract(context, apk, dexFile, extractedFile, extractedFilePrefix);
+                }
+                secondaryNumber++;
+                dexFile = apk.getEntry(DEX_PREFIX + secondaryNumber + DEX_SUFFIX);
+            }
+        } finally {
+            try {
+                apk.close();
+            } catch (IOException e) {
+                Log.w(TAG, "Failed to close resource", e);
+            }
+        }
+
+        return files;
+    }
+
+    private static void prepareDexDir(File dexDir, final String extractedFilePrefix)
+            throws IOException {
+        dexDir.mkdir();
+        if (!dexDir.isDirectory()) {
+            throw new IOException("Failed to create dex directory " + dexDir.getPath());
+        }
+
+        // Clean possible old files
+        FilenameFilter filter = new FilenameFilter() {
+            @Override
+            public boolean accept(File dir, String name) {
+                return !name.startsWith(extractedFilePrefix);
+            }
+        };
+        File[] files = dexDir.listFiles(filter);
+        if (files == null) {
+            Log.w(TAG, "Failed to list secondary dex dir content (" + dexDir.getPath() + ").");
+            return;
+        }
+        for (File oldFile : files) {
+            if (!oldFile.delete()) {
+                Log.w(TAG, "Failed to delete old file " + oldFile.getPath());
+            }
+        }
+    }
+
+    private static void extract(
+            Context context, ZipFile apk, ZipEntry dexFile, File extractTo,
+            String extractedFilePrefix) throws IOException, FileNotFoundException {
+
+        InputStream in = apk.getInputStream(dexFile);
+        ZipOutputStream out = null;
+        File tmp = File.createTempFile(extractedFilePrefix, EXTRACTED_SUFFIX,
+                extractTo.getParentFile());
+        Log.i(TAG, "Extracting " + tmp.getPath());
+        try {
+            out = new ZipOutputStream(new FileOutputStream(tmp));
+            try {
+                ZipEntry classesDex = new ZipEntry("classes.dex");
+                out.putNextEntry(classesDex);
+
+                byte[] buffer = new byte[BUFFER_SIZE];
+                int length = in.read(buffer);
+                while (length > 0) {
+                    out.write(buffer, 0, length);
+                    length = in.read(buffer);
+                }
+            } finally {
+                closeQuietly(out);
+            }
+            Log.i(TAG, "Renaming to " + extractTo.getPath());
+            if (!tmp.renameTo(extractTo)) {
+                throw new IOException("Failed to rename \"" + tmp.getAbsolutePath() + "\" to \"" +
+                        extractTo.getAbsolutePath() + "\"");
+            }
+        } finally {
+            closeQuietly(in);
+            tmp.delete(); // return status ignored
+        }
+    }
+
+    /**
+     * Closes the given {@code Closeable}. Suppresses any IO exceptions.
+     */
+    private static void closeQuietly(Closeable closeable) {
+        try {
+            closeable.close();
+        } catch (IOException e) {
+            Log.w(TAG, "Failed to close resource", e);
+        }
+    }
+}
