diff --git a/tests/CoreTests/android/core/HeapTest.java b/tests/CoreTests/android/core/HeapTest.java
deleted file mode 100644
index 400d041..0000000
--- a/tests/CoreTests/android/core/HeapTest.java
+++ /dev/null
@@ -1,476 +0,0 @@
-/*
- * Copyright (C) 2007 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.core;
-
-import android.test.suitebuilder.annotation.LargeTest;
-import android.test.suitebuilder.annotation.MediumTest;
-import android.test.suitebuilder.annotation.SmallTest;
-import android.util.Log;
-import android.test.suitebuilder.annotation.Suppress;
-import dalvik.system.VMRuntime;
-import junit.framework.TestCase;
-
-import java.lang.ref.PhantomReference;
-import java.lang.ref.ReferenceQueue;
-import java.lang.ref.SoftReference;
-import java.lang.ref.WeakReference;
-import java.util.LinkedList;
-import java.util.Random;
-
-
-public class HeapTest extends TestCase {
-
-    private static final String TAG = "HeapTest";
-
-    /**
-     * Returns a WeakReference to an object that has no
-     * other references.  This is done in a separate method
-     * to ensure that the Object's address isn't sitting in
-     * a stale local register.
-     */
-    private WeakReference<Object> newRef() {
-        return new WeakReference<Object>(new Object());
-    }
-
-    private static void makeRefs(Object objects[], SoftReference<Object> refs[]) {
-        for (int i = 0; i < objects.length; i++) {
-            objects[i] = (Object) new byte[8 * 1024];
-            refs[i] = new SoftReference<Object>(objects[i]);
-        }
-    }
-
-    private static <T> int checkRefs(SoftReference<T> refs[], int last) {
-        int i;
-        int numCleared = 0;
-        for (i = 0; i < refs.length; i++) {
-            Object o = refs[i].get();
-            if (o == null) {
-                numCleared++;
-            }
-        }
-        if (numCleared != last) {
-            Log.i(TAG, "****** " + numCleared + "/" + i + " cleared ******");
-        }
-        return numCleared;
-    }
-
-    private static void clearRefs(Object objects[], int skip) {
-        for (int i = 0; i < objects.length; i += skip) {
-            objects[i] = null;
-        }
-    }
-
-    private static void clearRefs(Object objects[]) {
-        clearRefs(objects, 1);
-    }
-
-    private static <T> void checkRefs(T objects[], SoftReference<T> refs[]) {
-        boolean ok = true;
-
-        for (int i = 0; i < objects.length; i++) {
-            if (refs[i].get() != objects[i]) {
-                ok = false;
-            }
-        }
-        if (!ok) {
-            throw new RuntimeException("Test failed: soft refs not cleared");
-        }
-    }
-
-    @MediumTest
-    public void testGcSoftRefs() throws Exception {
-        final int NUM_REFS = 128;
-
-        Object objects[] = new Object[NUM_REFS];
-        SoftReference<Object> refs[] = new SoftReference[objects.length];
-
-        /* Create a bunch of objects and a parallel array
-         * of SoftReferences.
-         */
-        makeRefs(objects, refs);
-        Runtime.getRuntime().gc();
-
-        /* Let go of some of the hard references to the objects so that
-         * the references can be cleared.
-         */
-        clearRefs(objects, 3);
-
-        /* Collect all softly-reachable objects.
-         */
-        VMRuntime.getRuntime().gcSoftReferences();
-        Runtime.getRuntime().runFinalization();
-
-        /* Make sure that the objects were collected.
-         */
-        checkRefs(objects, refs);
-
-        /* Remove more hard references and re-check.
-         */
-        clearRefs(objects, 2);
-        VMRuntime.getRuntime().gcSoftReferences();
-        Runtime.getRuntime().runFinalization();
-        checkRefs(objects, refs);
-
-        /* Remove the rest of the references and re-check.
-         */
-        /* Remove more hard references and re-check.
-         */
-        clearRefs(objects);
-        VMRuntime.getRuntime().gcSoftReferences();
-        Runtime.getRuntime().runFinalization();
-        checkRefs(objects, refs);
-    }
-
-    public void xxtestSoftRefPartialClean() throws Exception {
-        final int NUM_REFS = 128;
-
-        Object objects[] = new Object[NUM_REFS];
-        SoftReference<Object> refs[] = new SoftReference[objects.length];
-
-        /* Create a bunch of objects and a parallel array
-        * of SoftReferences.
-        */
-        makeRefs(objects, refs);
-        Runtime.getRuntime().gc();
-
-        /* Let go of the hard references to the objects so that
-        * the references can be cleared.
-        */
-        clearRefs(objects);
-
-        /* Start creating a bunch of temporary and permanent objects
-        * to drive GC.
-        */
-        final int NUM_OBJECTS = 64 * 1024;
-        Object junk[] = new Object[NUM_OBJECTS];
-        Random random = new Random();
-
-        int i = 0;
-        int mod = 0;
-        int totalSize = 0;
-        int cleared = -1;
-        while (i < junk.length && totalSize < 8 * 1024 * 1024) {
-            int r = random.nextInt(64 * 1024) + 128;
-            Object o = (Object) new byte[r];
-            if (++mod % 16 == 0) {
-                junk[i++] = o;
-                totalSize += r * 4;
-            }
-            cleared = checkRefs(refs, cleared);
-        }
-    }
-
-    private static void makeRefs(Object objects[], WeakReference<Object> refs[]) {
-        for (int i = 0; i < objects.length; i++) {
-            objects[i] = new Object();
-            refs[i] = new WeakReference<Object>(objects[i]);
-        }
-    }
-
-    private static <T> void checkRefs(T objects[], WeakReference<T> refs[]) {
-        boolean ok = true;
-
-        for (int i = 0; i < objects.length; i++) {
-            if (refs[i].get() != objects[i]) {
-                ok = false;
-            }
-        }
-        if (!ok) {
-            throw new RuntimeException("Test failed: " +
-                    "weak refs not cleared");
-        }
-    }
-
-    @MediumTest
-    public void testWeakRefs() throws Exception {
-        final int NUM_REFS = 16;
-
-        Object objects[] = new Object[NUM_REFS];
-        WeakReference<Object> refs[] = new WeakReference[objects.length];
-
-        /* Create a bunch of objects and a parallel array
-        * of WeakReferences.
-        */
-        makeRefs(objects, refs);
-        Runtime.getRuntime().gc();
-        checkRefs(objects, refs);
-
-        /* Clear out every other strong reference.
-        */
-        for (int i = 0; i < objects.length; i += 2) {
-            objects[i] = null;
-        }
-        Runtime.getRuntime().gc();
-        checkRefs(objects, refs);
-
-        /* Clear out the rest of them.
-        */
-        for (int i = 0; i < objects.length; i++) {
-            objects[i] = null;
-        }
-        Runtime.getRuntime().gc();
-        checkRefs(objects, refs);
-    }
-
-    private static void makeRefs(Object objects[], PhantomReference<Object> refs[],
-            ReferenceQueue<Object> queue) {
-        for (int i = 0; i < objects.length; i++) {
-            objects[i] = new Object();
-            refs[i] = new PhantomReference<Object>(objects[i], queue);
-        }
-    }
-
-    static <T> void checkRefs(T objects[], PhantomReference<T> refs[],
-            ReferenceQueue<T> queue) {
-        boolean ok = true;
-
-        /* Make sure that the reference that should be on
-        * the queue are marked as enqueued.  Once we
-        * pull them off the queue, they will no longer
-        * be marked as enqueued.
-        */
-        for (int i = 0; i < objects.length; i++) {
-            if (objects[i] == null && refs[i] != null) {
-                if (!refs[i].isEnqueued()) {
-                    ok = false;
-                }
-            }
-        }
-        if (!ok) {
-            throw new RuntimeException("Test failed: " +
-                    "phantom refs not marked as enqueued");
-        }
-
-        /* Make sure that all of the references on the queue
-        * are supposed to be there.
-        */
-        PhantomReference<T> ref;
-        while ((ref = (PhantomReference<T>) queue.poll()) != null) {
-            /* Find the list index that corresponds to this reference.
-            */
-            int i;
-            for (i = 0; i < objects.length; i++) {
-                if (refs[i] == ref) {
-                    break;
-                }
-            }
-            if (i == objects.length) {
-                throw new RuntimeException("Test failed: " +
-                        "unexpected ref on queue");
-            }
-            if (objects[i] != null) {
-                throw new RuntimeException("Test failed: " +
-                        "reference enqueued for strongly-reachable " +
-                        "object");
-            }
-            refs[i] = null;
-
-            /* TODO: clear doesn't do much, since we're losing the
-            * strong ref to the ref object anyway.  move the ref
-            * into another list.
-            */
-            ref.clear();
-        }
-
-        /* We've visited all of the enqueued references.
-        * Make sure that there aren't any other references
-        * that should have been enqueued.
-        *
-        * NOTE: there is a race condition here;  this assumes
-        * that the VM has serviced all outstanding reference
-        * enqueue() calls.
-        */
-        for (int i = 0; i < objects.length; i++) {
-            if (objects[i] == null && refs[i] != null) {
-//                System.out.println("HeapTest/PhantomRefs: refs[" + i +
-//                        "] should be enqueued");
-                ok = false;
-            }
-        }
-        if (!ok) {
-            throw new RuntimeException("Test failed: " +
-                    "phantom refs not enqueued");
-        }
-    }
-
-    @MediumTest
-    public void testPhantomRefs() throws Exception {
-        final int NUM_REFS = 16;
-
-        Object objects[] = new Object[NUM_REFS];
-        PhantomReference<Object> refs[] = new PhantomReference[objects.length];
-        ReferenceQueue<Object> queue = new ReferenceQueue<Object>();
-
-        /* Create a bunch of objects and a parallel array
-        * of PhantomReferences.
-        */
-        makeRefs(objects, refs, queue);
-        Runtime.getRuntime().gc();
-        checkRefs(objects, refs, queue);
-
-        /* Clear out every other strong reference.
-        */
-        for (int i = 0; i < objects.length; i += 2) {
-            objects[i] = null;
-        }
-        // System.out.println("HeapTest/PhantomRefs: cleared evens");
-        Runtime.getRuntime().gc();
-        Runtime.getRuntime().runFinalization();
-        checkRefs(objects, refs, queue);
-
-        /* Clear out the rest of them.
-        */
-        for (int i = 0; i < objects.length; i++) {
-            objects[i] = null;
-        }
-        // System.out.println("HeapTest/PhantomRefs: cleared all");
-        Runtime.getRuntime().gc();
-        Runtime.getRuntime().runFinalization();
-        checkRefs(objects, refs, queue);
-    }
-
-    private static int sNumFinalized = 0;
-    private static final Object sLock = new Object();
-
-    private static class FinalizableObject {
-        protected void finalize() {
-            // System.out.println("gc from finalize()");
-            Runtime.getRuntime().gc();
-            synchronized (sLock) {
-                sNumFinalized++;
-            }
-        }
-    }
-
-    private static void makeRefs(FinalizableObject objects[],
-            WeakReference<FinalizableObject> refs[]) {
-        for (int i = 0; i < objects.length; i++) {
-            objects[i] = new FinalizableObject();
-            refs[i] = new WeakReference<FinalizableObject>(objects[i]);
-        }
-    }
-
-    @LargeTest
-    public void testWeakRefsAndFinalizers() throws Exception {
-        final int NUM_REFS = 16;
-
-        FinalizableObject objects[] = new FinalizableObject[NUM_REFS];
-        WeakReference<FinalizableObject> refs[] = new WeakReference[objects.length];
-        int numCleared;
-
-        /* Create a bunch of objects and a parallel array
-        * of WeakReferences.
-        */
-        makeRefs(objects, refs);
-        Runtime.getRuntime().gc();
-        checkRefs(objects, refs);
-
-        /* Clear out every other strong reference.
-        */
-        sNumFinalized = 0;
-        numCleared = 0;
-        for (int i = 0; i < objects.length; i += 2) {
-            objects[i] = null;
-            numCleared++;
-        }
-        // System.out.println("HeapTest/WeakRefsAndFinalizers: cleared evens");
-        Runtime.getRuntime().gc();
-        Runtime.getRuntime().runFinalization();
-        checkRefs(objects, refs);
-        if (sNumFinalized != numCleared) {
-            throw new RuntimeException("Test failed: " +
-                    "expected " + numCleared + " finalizations, saw " +
-                    sNumFinalized);
-        }
-
-        /* Clear out the rest of them.
-        */
-        sNumFinalized = 0;
-        numCleared = 0;
-        for (int i = 0; i < objects.length; i++) {
-            if (objects[i] != null) {
-                objects[i] = null;
-                numCleared++;
-            }
-        }
-        // System.out.println("HeapTest/WeakRefsAndFinalizers: cleared all");
-        Runtime.getRuntime().gc();
-        Runtime.getRuntime().runFinalization();
-        checkRefs(objects, refs);
-        if (sNumFinalized != numCleared) {
-            throw new RuntimeException("Test failed: " +
-                    "expected " + numCleared + " finalizations, saw " +
-                    sNumFinalized);
-        }
-    }
-
-    // TODO: flaky test
-    //@MediumTest
-    public void testOomeLarge() throws Exception {
-        /* Just shy of the typical max heap size so that it will actually
-         * try to allocate it instead of short-circuiting.
-         */
-        final int SIXTEEN_MB = (16 * 1024 * 1024 - 32);
-
-        Boolean sawEx = false;
-        byte a[];
-
-        try {
-            a = new byte[SIXTEEN_MB];
-        } catch (OutOfMemoryError oom) {
-            //Log.i(TAG, "HeapTest/OomeLarge caught " + oom);
-            sawEx = true;
-        }
-
-        if (!sawEx) {
-            throw new RuntimeException("Test failed: " +
-                    "OutOfMemoryError not thrown");
-        }
-    }
-
-    //See bug 1308253 for reasons.
-    @Suppress
-    public void disableTestOomeSmall() throws Exception {
-        final int SIXTEEN_MB = (16 * 1024 * 1024);
-        final int LINK_SIZE = 6 * 4; // estimated size of a LinkedList's node
-
-        Boolean sawEx = false;
-
-        LinkedList<Object> list = new LinkedList<Object>();
-
-        /* Allocate progressively smaller objects to fill up the entire heap.
-         */
-        int objSize = 1 * 1024 * 1024;
-        while (objSize >= LINK_SIZE) {
-            try {
-                for (int i = 0; i < SIXTEEN_MB / objSize; i++) {
-                    list.add((Object)new byte[objSize]);
-                }
-            } catch (OutOfMemoryError oom) {
-                sawEx = true;
-            }
-
-            if (!sawEx) {
-                throw new RuntimeException("Test failed: " +
-                        "OutOfMemoryError not thrown while filling heap");
-            }
-            sawEx = false;
-
-            objSize = (objSize * 4) / 5;
-        }
-    }
-}
