diff --git a/test/626-const-class-linking/src/Main.java b/test/626-const-class-linking/src/Main.java
new file mode 100644
index 0000000..0029428
--- /dev/null
+++ b/test/626-const-class-linking/src/Main.java
@@ -0,0 +1,354 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+import java.lang.ref.WeakReference;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+
+public class Main {
+    public static void main(String[] args) throws Exception {
+        try {
+            System.loadLibrary(args[0]);
+        } catch (UnsatisfiedLinkError ule) {
+            usingRI = true;
+            // Add expected JNI_OnLoad log line to match expected.txt.
+            System.out.println("JNI_OnLoad called");
+        }
+
+        testClearDexCache();
+        testMultiDex();
+        testRacyLoader();
+        testRacyLoader2();
+        testMisbehavingLoader();
+        testRacyMisbehavingLoader();
+        testRacyMisbehavingLoader2();
+    }
+
+    private static void testClearDexCache() throws Exception {
+        DelegatingLoader delegating_loader = createDelegatingLoader();
+        Class<?> helper = delegating_loader.loadClass("Helper1");
+
+        WeakReference<Class<?>> weak_test1 = wrapHelperGet(helper);
+        changeInner(delegating_loader);
+        clearResolvedTypes(helper);
+        Runtime.getRuntime().gc();
+        WeakReference<Class<?>> weak_test2 = wrapHelperGet(helper);
+        Runtime.getRuntime().gc();
+
+        Class<?> test1 = weak_test1.get();
+        if (test1 == null) {
+            System.out.println("test1 disappeared");
+        }
+        Class<?> test2 = weak_test2.get();
+        if (test2 == null) {
+            System.out.println("test2 disappeared");
+        }
+        if (test1 != test2) {
+            System.out.println("test1 != test2");
+        }
+
+        System.out.println("testClearDexCache done");
+    }
+
+    private static void testMultiDex() throws Exception {
+        DelegatingLoader delegating_loader = createDelegatingLoader();
+
+        Class<?> helper1 = delegating_loader.loadClass("Helper1");
+        WeakReference<Class<?>> weak_test1 = wrapHelperGet(helper1);
+
+        changeInner(delegating_loader);
+
+        Class<?> helper2 = delegating_loader.loadClass("Helper2");
+        WeakReference<Class<?>> weak_test2 = wrapHelperGet(helper2);
+
+        Runtime.getRuntime().gc();
+
+        Class<?> test1 = weak_test1.get();
+        if (test1 == null) {
+            System.out.println("test1 disappeared");
+        }
+        Class<?> test2 = weak_test2.get();
+        if (test2 == null) {
+            System.out.println("test2 disappeared");
+        }
+        if (test1 != test2) {
+            System.out.println("test1 != test2");
+        }
+
+        System.out.println("testMultiDex done");
+    }
+
+    private static void testMisbehavingLoader() throws Exception {
+        ClassLoader system_loader = ClassLoader.getSystemClassLoader();
+        DefiningLoader defining_loader = new DefiningLoader(system_loader);
+        MisbehavingLoader misbehaving_loader =
+            new MisbehavingLoader(system_loader, defining_loader);
+        Class<?> helper = misbehaving_loader.loadClass("Helper1");
+
+        try {
+            WeakReference<Class<?>> weak_test = wrapHelperGet(helper);
+        } catch (InvocationTargetException ite) {
+            String message = ite.getCause().getMessage();
+            if (usingRI && "Test".equals(message)) {
+              // Replace RI message with dalvik message to match expected.txt.
+              message = "Initiating class loader of type " +
+                  misbehaving_loader.getClass().getName() +
+                  " returned class Helper2 instead of Test.";
+            }
+            System.out.println(ite.getCause().getClass().getName() + ": " + message);
+        }
+        System.out.println("testMisbehavingLoader done");
+    }
+
+    private static void testRacyLoader() throws Exception {
+        final ClassLoader system_loader = ClassLoader.getSystemClassLoader();
+
+        final Thread[] threads = new Thread[4];
+        final Object[] results = new Object[threads.length];
+
+        final RacyLoader racy_loader = new RacyLoader(system_loader, threads.length);
+        final Class<?> helper1 = racy_loader.loadClass("Helper1");
+        skipVerification(helper1);  // Avoid class loading during verification.
+
+        for (int i = 0; i != threads.length; ++i) {
+            final int my_index = i;
+            Thread t = new Thread() {
+                public void run() {
+                    try {
+                        Method get = helper1.getDeclaredMethod("get");
+                        results[my_index] = get.invoke(null);
+                    } catch (InvocationTargetException ite) {
+                        results[my_index] = ite.getCause();
+                    } catch (Throwable t) {
+                        results[my_index] = t;
+                    }
+                }
+            };
+            t.start();
+            threads[i] = t;
+        }
+        for (Thread t : threads) {
+            t.join();
+        }
+        dumpResultStats(results, 1);
+        System.out.println("testRacyLoader done");
+    }
+
+    private static void testRacyLoader2() throws Exception {
+        final ClassLoader system_loader = ClassLoader.getSystemClassLoader();
+
+        final Thread[] threads = new Thread[4];
+        final Object[] results = new Object[threads.length];
+
+        final RacyLoader racy_loader = new RacyLoader(system_loader, threads.length);
+        final Class<?> helper1 = racy_loader.loadClass("Helper1");
+        skipVerification(helper1);  // Avoid class loading during verification.
+        final Class<?> helper3 = racy_loader.loadClass("Helper3");
+        skipVerification(helper3);  // Avoid class loading during verification.
+
+        for (int i = 0; i != threads.length; ++i) {
+            final int my_index = i;
+            Thread t = new Thread() {
+                public void run() {
+                    try {
+                        Class<?> helper = (my_index < threads.length / 2) ? helper1 : helper3;
+                        Method get = helper.getDeclaredMethod("get");
+                        results[my_index] = get.invoke(null);
+                    } catch (InvocationTargetException ite) {
+                        results[my_index] = ite.getCause();
+                    } catch (Throwable t) {
+                        results[my_index] = t;
+                    }
+                }
+            };
+            t.start();
+            threads[i] = t;
+        }
+        for (Thread t : threads) {
+            t.join();
+        }
+        dumpResultStats(results, 2);
+        System.out.println("testRacyLoader2 done");
+    }
+
+    private static void testRacyMisbehavingLoader() throws Exception {
+        final ClassLoader system_loader = ClassLoader.getSystemClassLoader();
+
+        final Thread[] threads = new Thread[4];
+        final Object[] results = new Object[threads.length];
+
+        final RacyMisbehavingLoader racy_loader =
+            new RacyMisbehavingLoader(system_loader, threads.length, false);
+        final Class<?> helper1 = racy_loader.loadClass("RacyMisbehavingHelper");
+        skipVerification(helper1);  // Avoid class loading during verification.
+
+        for (int i = 0; i != threads.length; ++i) {
+            final int my_index = i;
+            Thread t = new Thread() {
+                public void run() {
+                    try {
+                        Method get = helper1.getDeclaredMethod("get");
+                        results[my_index] = get.invoke(null);
+                    } catch (InvocationTargetException ite) {
+                        results[my_index] = ite.getCause();
+                    } catch (Throwable t) {
+                        results[my_index] = t;
+                    }
+                }
+            };
+            t.start();
+            threads[i] = t;
+        }
+        for (Thread t : threads) {
+            t.join();
+        }
+        dumpResultStats(results, 1);
+        System.out.println("testRacyMisbehavingLoader done");
+    }
+
+    private static void testRacyMisbehavingLoader2() throws Exception {
+        final ClassLoader system_loader = ClassLoader.getSystemClassLoader();
+
+        final Thread[] threads = new Thread[4];
+        final Object[] results = new Object[threads.length];
+
+        final RacyMisbehavingLoader racy_loader =
+            new RacyMisbehavingLoader(system_loader, threads.length, true);
+        final Class<?> helper1 = racy_loader.loadClass("RacyMisbehavingHelper");
+        skipVerification(helper1);  // Avoid class loading during verification.
+
+        for (int i = 0; i != threads.length; ++i) {
+            final int my_index = i;
+            Thread t = new Thread() {
+                public void run() {
+                    try {
+                        Method get = helper1.getDeclaredMethod("get");
+                        results[my_index] = get.invoke(null);
+                    } catch (InvocationTargetException ite) {
+                        results[my_index] = ite.getCause();
+                    } catch (Throwable t) {
+                        results[my_index] = t;
+                    }
+                }
+            };
+            t.start();
+            threads[i] = t;
+        }
+        for (Thread t : threads) {
+            t.join();
+        }
+        dumpResultStats(results, 1);
+        System.out.println("testRacyMisbehavingLoader2 done");
+    }
+
+    private static void dumpResultStats(Object[] results, int expected_unique) throws Exception {
+        int throwables = 0;
+        int classes = 0;
+        int unique_classes = 0;
+        for (int i = 0; i != results.length; ++i) {
+            Object r = results[i];
+            if (r instanceof Throwable) {
+                ++throwables;
+                System.out.println(((Throwable) r).getMessage());
+            } else if (isClassPair(r)) {
+                printPair(r);
+                Object ref = getSecond(r);
+                ++classes;
+                ++unique_classes;
+                for (int j = 0; j != i; ++j) {
+                    Object rj = results[j];
+                    if (isClassPair(results[j]) && getSecond(results[j]) == ref) {
+                        --unique_classes;
+                        break;
+                    }
+                }
+            }
+        }
+        System.out.println("total: " + results.length);
+        System.out.println("  throwables: " + throwables);
+        System.out.println("  classes: " + classes
+            + " (" + unique_classes + " unique)");
+        if (expected_unique != unique_classes) {
+            System.out.println("MISMATCH with expected_unique: " + expected_unique);
+            ArrayList<Class<?>> list = new ArrayList<Class<?>>();
+            for (int i = 0; i != results.length; ++i) {
+                Object r = results[i];
+                if (isClassPair(r)) {
+                    list.add(getSecond(r));
+                }
+            }
+            nativeDumpClasses(list.toArray());
+        }
+    }
+
+    private static DelegatingLoader createDelegatingLoader() {
+        ClassLoader system_loader = ClassLoader.getSystemClassLoader();
+        DefiningLoader defining_loader = new DefiningLoader(system_loader);
+        return new DelegatingLoader(system_loader, defining_loader);
+    }
+
+    private static void changeInner(DelegatingLoader delegating_loader) {
+        ClassLoader system_loader = ClassLoader.getSystemClassLoader();
+        DefiningLoader defining_loader = new DefiningLoader(system_loader);
+        delegating_loader.resetDefiningLoader(defining_loader);
+    }
+
+    private static WeakReference<Class<?>> wrapHelperGet(Class<?> helper) throws Exception {
+        Method get = helper.getDeclaredMethod("get");
+        Object pair = get.invoke(null);
+        printPair(pair);
+        return new WeakReference<Class<?>>(getSecond(pair));
+    }
+
+    private static void printPair(Object pair) throws Exception {
+        Method print = pair.getClass().getDeclaredMethod("print");
+        print.invoke(pair);
+    }
+
+    private static Class<?> getSecond(Object pair) throws Exception {
+        Field second = pair.getClass().getDeclaredField("second");
+        return (Class<?>) second.get(pair);
+    }
+
+    private static boolean isClassPair(Object r) {
+        return r != null && r.getClass().getName().equals("ClassPair");
+    }
+
+    public static void clearResolvedTypes(Class<?> c) {
+        if (!usingRI) {
+            nativeClearResolvedTypes(c);
+        }
+    }
+
+    // Skip verification of a class on ART. Verification can cause classes to be loaded
+    // while holding a lock on the class being verified and holding that lock can interfere
+    // with the intent of the "racy" tests. In these tests we're waiting in the loadClass()
+    // for all the tested threads to synchronize and they cannot reach that point if they
+    // are waiting for the class lock on ClassLinker::InitializeClass(Helper1/Helper3).
+    public static void skipVerification(Class<?> c) {
+        if (!usingRI) {
+            nativeSkipVerification(c);
+        }
+    }
+
+    public static native void nativeClearResolvedTypes(Class<?> c);
+    public static native void nativeSkipVerification(Class<?> c);
+    public static native void nativeDumpClasses(Object[] array);
+
+    static boolean usingRI = false;
+}
