diff --git a/src/test/examplesAndroidO/multidex004/fakelibrary/MultiDex.java b/src/test/examplesAndroidO/multidex004/fakelibrary/MultiDex.java
new file mode 100644
index 0000000..3b15c11
--- /dev/null
+++ b/src/test/examplesAndroidO/multidex004/fakelibrary/MultiDex.java
@@ -0,0 +1,265 @@
+// Copyright (c) 2017, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package multidex004.fakelibrary;
+
+
+import multidex004.fakeframeworks.Application;
+import multidex004.fakeframeworks.Context;
+
+import java.io.File;
+import java.io.IOException;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Random;
+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} must contain the classes necessary for calling this
+ * class methods. Secondary dex files named classes2.dex, classes3.dex... found
+ * in the application apk will be added to the classloader after first call to
+ * {@link #install(Context)}.
+ *
+ * <p/>
+ * This library provides compatibility for platforms with API level 4 through 20. 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 MAX_SUPPORTED_SDK_VERSION = 20;
+
+    private static final int MIN_SDK_VERSION = 4;
+
+    private static final int VM_WITH_MULTIDEX_VERSION_MAJOR = 2;
+
+    private static final int VM_WITH_MULTIDEX_VERSION_MINOR = 1;
+
+    private static final Set<String> installedApk = null;
+
+    private static final boolean IS_VM_MULTIDEX_CAPABLE =
+            isVMMultidexCapable(System.getProperty("java.vm.version"));
+
+    private MultiDex() {}
+
+    /**
+     * Patches the application context class loader by appending extra dex files
+     * loaded from the application apk. This method should be called in the
+     * attachBaseContext of your {@link Application}, see
+     * {@link MultiDexApplication} for more explanation and an example.
+     *
+     * @param context application context.
+     * @throws RuntimeException if an error occurred preventing the classloader
+     *         extension.
+     */
+    public static void install(Context context) {
+        if (IS_VM_MULTIDEX_CAPABLE) {
+            try {
+                clearOldDexDir(context);
+            } catch (Throwable t) {
+            }
+            return;
+        }
+     }
+
+    /**
+     * Identifies if the current VM has a native support for multidex, meaning there is no need for
+     * additional installation by this library.
+     * @return true if the VM handles multidex
+     */
+    /* package visible for test */
+    static boolean isVMMultidexCapable(String versionString) {
+        boolean isMultidexCapable = false;
+        if (versionString != null) {
+        }
+        return isMultidexCapable;
+    }
+
+    private static void installSecondaryDexes(ClassLoader loader, File dexDir, List<File> files)
+            throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException,
+            InvocationTargetException, NoSuchMethodException, IOException {
+      int version = new Random().nextInt(23);
+        if (!files.isEmpty()) {
+            if (version >= 19) {
+                V19.install(loader, files, dexDir);
+            } else if (version >= 14) {
+                V14.install(loader, files, dexDir);
+            } else {
+                V4.install(loader, files);
+            }
+        }
+    }
+
+    /**
+     * Returns whether all files in the list are valid zip files.  If {@code files} is empty, then
+     * returns true.
+     */
+    private static boolean checkValidZipFiles(List<File> files) {
+        for (File file : files) {
+        }
+        return true;
+    }
+
+    /**
+     * 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 " +
+                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[]) null;
+        System.arraycopy(original, 0, combined, 0, original.length);
+        System.arraycopy(extraElements, 0, combined, original.length, extraElements.length);
+        jlrField.set(instance, combined);
+    }
+
+    private static void clearOldDexDir(Context context) throws Exception {
+
+     }
+
+    /**
+     * 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);
+        }
+
+    }
+    /**
+     * 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);
+        }
+
+     }
+
+    /**
+     * Installer for platform versions 4 to 13.
+     */
+    private static final class V4 {
+        private static void install(ClassLoader loader, List<File> additionalClassPathEntries)
+                        throws IllegalArgumentException, IllegalAccessException,
+                        NoSuchFieldException, IOException {
+            /* The patched class loader is expected to be a descendant of
+             * dalvik.system.DexClassLoader. We modify its
+             * fields mPaths, mFiles, mZips and mDexs 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];
+            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;
+            }
+
+            pathField.set(loader, path.toString());
+            expandFieldArray(loader, "mPaths", extraPaths);
+            expandFieldArray(loader, "mFiles", extraFiles);
+        }
+    }
+
+}
