diff --git a/android/test/ActivityInstrumentationTestCase.java b/android/test/ActivityInstrumentationTestCase.java
new file mode 100644
index 0000000..aca1c16
--- /dev/null
+++ b/android/test/ActivityInstrumentationTestCase.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2008 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.test;
+
+import android.app.Activity;
+
+/**
+ * This class provides functional testing of a single activity.  The activity under test will
+ * be created using the system infrastructure (by calling InstrumentationTestCase.launchActivity())
+ * and you will then be able to manipulate your Activity directly.  Most of the work is handled
+ * automatically here by {@link #setUp} and {@link #tearDown}.
+ *
+ * <p>If you prefer an isolated unit test, see {@link android.test.ActivityUnitTestCase}.
+ *
+ * @deprecated new tests should be written using
+ * {@link android.test.ActivityInstrumentationTestCase2}, which provides more options for
+ * configuring the Activity under test
+ */
+@Deprecated
+public abstract class ActivityInstrumentationTestCase<T extends Activity>
+        extends ActivityTestCase {
+    String mPackage;
+    Class<T> mActivityClass;
+    boolean mInitialTouchMode = false;
+
+    /**
+     * Creates an {@link ActivityInstrumentationTestCase} in non-touch mode.
+     *
+     * @param pkg ignored - no longer in use.
+     * @param activityClass The activity to test. This must be a class in the instrumentation
+     * targetPackage specified in the AndroidManifest.xml
+     */
+    public ActivityInstrumentationTestCase(String pkg, Class<T> activityClass) {
+        this(pkg, activityClass, false);
+    }
+
+    /**
+     * Creates an {@link ActivityInstrumentationTestCase}.
+     *
+     * @param pkg ignored - no longer in use.
+     * @param activityClass The activity to test. This must be a class in the instrumentation
+     * targetPackage specified in the AndroidManifest.xml
+     * @param initialTouchMode true = in touch mode
+     */
+    public ActivityInstrumentationTestCase(String pkg, Class<T> activityClass,
+            boolean initialTouchMode) {
+        mActivityClass = activityClass;
+        mInitialTouchMode = initialTouchMode;
+    }
+
+    @Override
+    public T getActivity() {
+        return (T) super.getActivity();
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        // set initial touch mode
+        getInstrumentation().setInTouchMode(mInitialTouchMode);
+        final String targetPackageName = getInstrumentation().getTargetContext().getPackageName();
+        setActivity(launchActivity(targetPackageName, mActivityClass, null));
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        getActivity().finish();
+        setActivity(null);
+
+        // Scrub out members - protects against memory leaks in the case where someone
+        // creates a non-static inner class (thus referencing the test case) and gives it to
+        // someone else to hold onto
+        scrubClass(ActivityInstrumentationTestCase.class);
+
+        super.tearDown();
+    }
+
+    public void testActivityTestCaseSetUpProperly() throws Exception {
+        assertNotNull("activity should be launched successfully", getActivity());
+    }
+}
diff --git a/android/test/ActivityInstrumentationTestCase2.java b/android/test/ActivityInstrumentationTestCase2.java
new file mode 100644
index 0000000..0e61ce7
--- /dev/null
+++ b/android/test/ActivityInstrumentationTestCase2.java
@@ -0,0 +1,195 @@
+/*
+ * Copyright (C) 2008 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.test;
+
+import android.app.Activity;
+import android.content.Intent;
+
+import java.lang.reflect.Method;
+
+/**
+ * This class provides functional testing of a single activity.  The activity under test will
+ * be created using the system infrastructure (by calling InstrumentationTestCase.launchActivity())
+ * and you will then be able to manipulate your Activity directly.
+ *
+ * <p>Other options supported by this test case include:
+ * <ul>
+ * <li>You can run any test method on the UI thread (see {@link android.test.UiThreadTest}).</li>
+ * <li>You can inject custom Intents into your Activity (see
+ * {@link #setActivityIntent(Intent)}).</li>
+ * </ul>
+ *
+ * <p>This class replaces {@link android.test.ActivityInstrumentationTestCase}, which is deprecated.
+ * New tests should be written using this base class.
+ *
+ * <p>If you prefer an isolated unit test, see {@link android.test.ActivityUnitTestCase}.
+ *
+ * @deprecated Use
+ * <a href="{@docRoot}reference/android/support/test/rule/ActivityTestRule.html">
+ * ActivityTestRule</a> instead. New tests should be written using the
+ * <a href="{@docRoot}tools/testing-support-library/index.html">Android Testing Support Library</a>.
+ */
+@Deprecated
+public abstract class ActivityInstrumentationTestCase2<T extends Activity>
+        extends ActivityTestCase {
+    Class<T> mActivityClass;
+    boolean mInitialTouchMode = false;
+    Intent mActivityIntent = null;
+
+    /**
+     * Creates an {@link ActivityInstrumentationTestCase2}.
+     *
+     * @param pkg ignored - no longer in use.
+     * @param activityClass The activity to test. This must be a class in the instrumentation
+     * targetPackage specified in the AndroidManifest.xml
+     *
+     * @deprecated use {@link #ActivityInstrumentationTestCase2(Class)} instead
+     */
+    @Deprecated
+    public ActivityInstrumentationTestCase2(String pkg, Class<T> activityClass) {
+        this(activityClass);
+    }
+
+    /**
+     * Creates an {@link ActivityInstrumentationTestCase2}.
+     *
+     * @param activityClass The activity to test. This must be a class in the instrumentation
+     * targetPackage specified in the AndroidManifest.xml
+     */
+    public ActivityInstrumentationTestCase2(Class<T> activityClass) {
+        mActivityClass = activityClass;
+    }
+
+    /**
+     * Get the Activity under test, starting it if necessary.
+     *
+     * For each test method invocation, the Activity will not actually be created until the first
+     * time this method is called.
+     *
+     * <p>If you wish to provide custom setup values to your Activity, you may call
+     * {@link #setActivityIntent(Intent)} and/or {@link #setActivityInitialTouchMode(boolean)}
+     * before your first call to getActivity().  Calling them after your Activity has
+     * started will have no effect.
+     *
+     * <p><b>NOTE:</b> Activities under test may not be started from within the UI thread.
+     * If your test method is annotated with {@link android.test.UiThreadTest}, then your Activity
+     * will be started automatically just before your test method is run.  You still call this
+     * method in order to get the Activity under test.
+     *
+     * @return the Activity under test
+     */
+    @Override
+    public T getActivity() {
+        Activity a = super.getActivity();
+        if (a == null) {
+            // set initial touch mode
+            getInstrumentation().setInTouchMode(mInitialTouchMode);
+            final String targetPackage = getInstrumentation().getTargetContext().getPackageName();
+            // inject custom intent, if provided
+            if (mActivityIntent == null) {
+                a = launchActivity(targetPackage, mActivityClass, null);
+            } else {
+                a = launchActivityWithIntent(targetPackage, mActivityClass, mActivityIntent);
+            }
+            setActivity(a);
+        }
+        return (T) a;
+    }
+
+    /**
+     * Call this method before the first call to {@link #getActivity} to inject a customized Intent
+     * into the Activity under test.
+     *
+     * <p>If you do not call this, the default intent will be provided.  If you call this after
+     * your Activity has been started, it will have no effect.
+     *
+     * <p><b>NOTE:</b> Activities under test may not be started from within the UI thread.
+     * If your test method is annotated with {@link android.test.UiThreadTest}, then you must call
+     * {@link #setActivityIntent(Intent)} from {@link #setUp()}.
+     *
+     * <p>The default Intent (if this method is not called) is:
+     *  action = {@link Intent#ACTION_MAIN}
+     *  flags = {@link Intent#FLAG_ACTIVITY_NEW_TASK}
+     * All other fields are null or empty.
+     *
+     * @param i The Intent to start the Activity with, or null to reset to the default Intent.
+     */
+    public void setActivityIntent(Intent i) {
+        mActivityIntent = i;
+    }
+
+    /**
+     * Call this method before the first call to {@link #getActivity} to set the initial touch
+     * mode for the Activity under test.
+     *
+     * <p>If you do not call this, the touch mode will be false.  If you call this after
+     * your Activity has been started, it will have no effect.
+     *
+     * <p><b>NOTE:</b> Activities under test may not be started from within the UI thread.
+     * If your test method is annotated with {@link android.test.UiThreadTest}, then you must call
+     * {@link #setActivityInitialTouchMode(boolean)} from {@link #setUp()}.
+     *
+     * @param initialTouchMode true if the Activity should be placed into "touch mode" when started
+     */
+    public void setActivityInitialTouchMode(boolean initialTouchMode) {
+        mInitialTouchMode = initialTouchMode;
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        mInitialTouchMode = false;
+        mActivityIntent = null;
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        // Finish the Activity off (unless was never launched anyway)
+        Activity a = super.getActivity();
+        if (a != null) {
+            a.finish();
+            setActivity(null);
+        }
+
+        // Scrub out members - protects against memory leaks in the case where someone
+        // creates a non-static inner class (thus referencing the test case) and gives it to
+        // someone else to hold onto
+        scrubClass(ActivityInstrumentationTestCase2.class);
+
+        super.tearDown();
+    }
+
+    /**
+     * Runs the current unit test. If the unit test is annotated with
+     * {@link android.test.UiThreadTest}, force the Activity to be created before switching to
+     * the UI thread.
+     */
+    @Override
+    protected void runTest() throws Throwable {
+        try {
+            Method method = getClass().getMethod(getName(), (Class[]) null);
+            if (method.isAnnotationPresent(UiThreadTest.class)) {
+                getActivity();
+            }
+        } catch (Exception e) {
+            // eat the exception here; super.runTest() will catch it again and handle it properly
+        }
+        super.runTest();
+    }
+
+}
diff --git a/android/test/ActivityTestCase.java b/android/test/ActivityTestCase.java
new file mode 100644
index 0000000..51dd3ef
--- /dev/null
+++ b/android/test/ActivityTestCase.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2008 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.test;
+
+import android.app.Activity;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+
+/**
+ * This is common code used to support Activity test cases.  For more useful classes, please see
+ * {@link android.test.ActivityUnitTestCase} and
+ * {@link android.test.ActivityInstrumentationTestCase}.
+ *
+ * @deprecated New tests should be written using the
+ * <a href="{@docRoot}tools/testing-support-library/index.html">Android Testing Support Library</a>.
+ */
+@Deprecated
+public abstract class ActivityTestCase extends InstrumentationTestCase {
+
+    /**
+     * The activity that will be set up for use in each test method.
+     */
+    private Activity mActivity;
+
+    /**
+     * @return Returns the activity under test.
+     */
+    protected Activity getActivity() {
+        return mActivity;
+    }
+
+    /**
+     * Set the activity under test.
+     * @param testActivity The activity under test
+     */
+    protected void setActivity(Activity testActivity) {
+        mActivity = testActivity;
+    }
+
+    /**
+     * This function is called by various TestCase implementations, at tearDown() time, in order
+     * to scrub out any class variables.  This protects against memory leaks in the case where a
+     * test case creates a non-static inner class (thus referencing the test case) and gives it to
+     * someone else to hold onto.
+     *
+     * @param testCaseClass The class of the derived TestCase implementation.
+     *
+     * @throws IllegalAccessException
+     */
+    protected void scrubClass(final Class<?> testCaseClass)
+    throws IllegalAccessException {
+        final Field[] fields = getClass().getDeclaredFields();
+        for (Field field : fields) {
+            final Class<?> fieldClass = field.getDeclaringClass();
+            if (testCaseClass.isAssignableFrom(fieldClass) && !field.getType().isPrimitive()
+                    && (field.getModifiers() & Modifier.FINAL) == 0) {
+                try {
+                    field.setAccessible(true);
+                    field.set(this, null);
+                } catch (Exception e) {
+                    android.util.Log.d("TestCase", "Error: Could not nullify field!");
+                }
+
+                if (field.get(this) != null) {
+                    android.util.Log.d("TestCase", "Error: Could not nullify field!");
+                }
+            }
+        }
+    }
+
+
+
+}
diff --git a/android/test/ActivityUnitTestCase.java b/android/test/ActivityUnitTestCase.java
new file mode 100644
index 0000000..a191445
--- /dev/null
+++ b/android/test/ActivityUnitTestCase.java
@@ -0,0 +1,348 @@
+/*
+ * Copyright (C) 2008 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.test;
+
+import android.app.Activity;
+import android.app.Application;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.test.mock.MockApplication;
+import android.view.Window;
+import android.util.Log;
+
+
+
+/**
+ * This class provides isolated testing of a single activity.  The activity under test will
+ * be created with minimal connection to the system infrastructure, and you can inject mocked or
+ * wrappered versions of many of Activity's dependencies.  Most of the work is handled
+ * automatically here by {@link #setUp} and {@link #tearDown}.
+ *
+ * <p>If you prefer a functional test, see {@link android.test.ActivityInstrumentationTestCase}.
+ *
+ * <p>It must be noted that, as a true unit test, your Activity will not be running in the
+ * normal system and will not participate in the normal interactions with other Activities.
+ * The following methods should not be called in this configuration - most of them will throw
+ * exceptions:
+ * <ul>
+ * <li>{@link android.app.Activity#createPendingResult(int, Intent, int)}</li>
+ * <li>{@link android.app.Activity#startActivityIfNeeded(Intent, int)}</li>
+ * <li>{@link android.app.Activity#startActivityFromChild(Activity, Intent, int)}</li>
+ * <li>{@link android.app.Activity#startNextMatchingActivity(Intent)}</li>
+ * <li>{@link android.app.Activity#getCallingActivity()}</li>
+ * <li>{@link android.app.Activity#getCallingPackage()}</li>
+ * <li>{@link android.app.Activity#createPendingResult(int, Intent, int)}</li>
+ * <li>{@link android.app.Activity#getTaskId()}</li>
+ * <li>{@link android.app.Activity#isTaskRoot()}</li>
+ * <li>{@link android.app.Activity#moveTaskToBack(boolean)}</li>
+ * </ul>
+ *
+ * <p>The following methods may be called but will not do anything.  For test purposes, you can use
+ * the methods {@link #getStartedActivityIntent()} and {@link #getStartedActivityRequest()} to
+ * inspect the parameters that they were called with.
+ * <ul>
+ * <li>{@link android.app.Activity#startActivity(Intent)}</li>
+ * <li>{@link android.app.Activity#startActivityForResult(Intent, int)}</li>
+ * </ul>
+ *
+ * <p>The following methods may be called but will not do anything.  For test purposes, you can use
+ * the methods {@link #isFinishCalled()} and {@link #getFinishedActivityRequest()} to inspect the
+ * parameters that they were called with.
+ * <ul>
+ * <li>{@link android.app.Activity#finish()}</li>
+ * <li>{@link android.app.Activity#finishFromChild(Activity child)}</li>
+ * <li>{@link android.app.Activity#finishActivity(int requestCode)}</li>
+ * </ul>
+ *
+ * @deprecated Write
+ * <a href="{@docRoot}training/testing/unit-testing/local-unit-tests.html">Local Unit Tests</a>
+ * instead.
+ */
+@Deprecated
+public abstract class ActivityUnitTestCase<T extends Activity>
+        extends ActivityTestCase {
+
+    private static final String TAG = "ActivityUnitTestCase";
+    private Class<T> mActivityClass;
+
+    private Context mActivityContext;
+    private Application mApplication;
+    private MockParent mMockParent;
+
+    private boolean mAttached = false;
+    private boolean mCreated = false;
+
+    public ActivityUnitTestCase(Class<T> activityClass) {
+        mActivityClass = activityClass;
+    }
+
+    @Override
+    public T getActivity() {
+        return (T) super.getActivity();
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        // default value for target context, as a default
+      mActivityContext = getInstrumentation().getTargetContext();
+    }
+
+    /**
+     * Start the activity under test, in the same way as if it was started by
+     * {@link android.content.Context#startActivity Context.startActivity()}, providing the
+     * arguments it supplied.  When you use this method to start the activity, it will automatically
+     * be stopped by {@link #tearDown}.
+     *
+     * <p>This method will call onCreate(), but if you wish to further exercise Activity life
+     * cycle methods, you must call them yourself from your test case.
+     *
+     * <p><i>Do not call from your setUp() method.  You must call this method from each of your
+     * test methods.</i>
+     *
+     * @param intent The Intent as if supplied to {@link android.content.Context#startActivity}.
+     * @param savedInstanceState The instance state, if you are simulating this part of the life
+     * cycle.  Typically null.
+     * @param lastNonConfigurationInstance This Object will be available to the
+     * Activity if it calls {@link android.app.Activity#getLastNonConfigurationInstance()}.
+     * Typically null.
+     * @return Returns the Activity that was created
+     */
+    protected T startActivity(Intent intent, Bundle savedInstanceState,
+            Object lastNonConfigurationInstance) {
+        assertFalse("Activity already created", mCreated);
+
+        if (!mAttached) {
+            assertNotNull(mActivityClass);
+            setActivity(null);
+            T newActivity = null;
+            try {
+                IBinder token = null;
+                if (mApplication == null) {
+                    setApplication(new MockApplication());
+                }
+                ComponentName cn = new ComponentName(mActivityClass.getPackage().getName(),
+                        mActivityClass.getName());
+                intent.setComponent(cn);
+                ActivityInfo info = new ActivityInfo();
+                CharSequence title = mActivityClass.getName();
+                mMockParent = new MockParent();
+                String id = null;
+
+                newActivity = (T) getInstrumentation().newActivity(mActivityClass, mActivityContext,
+                        token, mApplication, intent, info, title, mMockParent, id,
+                        lastNonConfigurationInstance);
+            } catch (Exception e) {
+                Log.w(TAG, "Catching exception", e);
+                assertNotNull(newActivity);
+            }
+
+            assertNotNull(newActivity);
+            setActivity(newActivity);
+
+            mAttached = true;
+        }
+
+        T result = getActivity();
+        if (result != null) {
+            getInstrumentation().callActivityOnCreate(getActivity(), savedInstanceState);
+            mCreated = true;
+        }
+        return result;
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+
+        setActivity(null);
+
+        // Scrub out members - protects against memory leaks in the case where someone
+        // creates a non-static inner class (thus referencing the test case) and gives it to
+        // someone else to hold onto
+        scrubClass(ActivityInstrumentationTestCase.class);
+
+        super.tearDown();
+    }
+
+    /**
+     * Set the application for use during the test.  You must call this function before calling
+     * {@link #startActivity}.  If your test does not call this method,
+     * @param application The Application object that will be injected into the Activity under test.
+     */
+    public void setApplication(Application application) {
+        mApplication = application;
+    }
+
+    /**
+     * If you wish to inject a Mock, Isolated, or otherwise altered context, you can do so
+     * here.  You must call this function before calling {@link #startActivity}.  If you wish to
+     * obtain a real Context, as a building block, use getInstrumentation().getTargetContext().
+     */
+    public void setActivityContext(Context activityContext) {
+        mActivityContext = activityContext;
+    }
+
+    /**
+     * This method will return the value if your Activity under test calls
+     * {@link android.app.Activity#setRequestedOrientation}.
+     */
+    public int getRequestedOrientation() {
+        if (mMockParent != null) {
+            return mMockParent.mRequestedOrientation;
+        }
+        return 0;
+    }
+
+    /**
+     * This method will return the launch intent if your Activity under test calls
+     * {@link android.app.Activity#startActivity(Intent)} or
+     * {@link android.app.Activity#startActivityForResult(Intent, int)}.
+     * @return The Intent provided in the start call, or null if no start call was made.
+     */
+    public Intent getStartedActivityIntent() {
+        if (mMockParent != null) {
+            return mMockParent.mStartedActivityIntent;
+        }
+        return null;
+    }
+
+    /**
+     * This method will return the launch request code if your Activity under test calls
+     * {@link android.app.Activity#startActivityForResult(Intent, int)}.
+     * @return The request code provided in the start call, or -1 if no start call was made.
+     */
+    public int getStartedActivityRequest() {
+        if (mMockParent != null) {
+            return mMockParent.mStartedActivityRequest;
+        }
+        return 0;
+    }
+
+    /**
+     * This method will notify you if the Activity under test called
+     * {@link android.app.Activity#finish()},
+     * {@link android.app.Activity#finishFromChild(Activity)}, or
+     * {@link android.app.Activity#finishActivity(int)}.
+     * @return Returns true if one of the listed finish methods was called.
+     */
+    public boolean isFinishCalled() {
+        if (mMockParent != null) {
+            return mMockParent.mFinished;
+        }
+        return false;
+    }
+
+    /**
+     * This method will return the request code if the Activity under test called
+     * {@link android.app.Activity#finishActivity(int)}.
+     * @return The request code provided in the start call, or -1 if no finish call was made.
+     */
+    public int getFinishedActivityRequest() {
+        if (mMockParent != null) {
+            return mMockParent.mFinishedActivityRequest;
+        }
+        return 0;
+    }
+
+    /**
+     * This mock Activity represents the "parent" activity.  By injecting this, we allow the user
+     * to call a few more Activity methods, including:
+     * <ul>
+     * <li>{@link android.app.Activity#getRequestedOrientation()}</li>
+     * <li>{@link android.app.Activity#setRequestedOrientation(int)}</li>
+     * <li>{@link android.app.Activity#finish()}</li>
+     * <li>{@link android.app.Activity#finishActivity(int requestCode)}</li>
+     * <li>{@link android.app.Activity#finishFromChild(Activity child)}</li>
+     * </ul>
+     *
+     * TODO: Make this overrideable, and the unit test can look for calls to other methods
+     */
+    private static class MockParent extends Activity {
+
+        public int mRequestedOrientation = 0;
+        public Intent mStartedActivityIntent = null;
+        public int mStartedActivityRequest = -1;
+        public boolean mFinished = false;
+        public int mFinishedActivityRequest = -1;
+
+        /**
+         * Implementing in the parent allows the user to call this function on the tested activity.
+         */
+        @Override
+        public void setRequestedOrientation(int requestedOrientation) {
+            mRequestedOrientation = requestedOrientation;
+        }
+
+        /**
+         * Implementing in the parent allows the user to call this function on the tested activity.
+         */
+        @Override
+        public int getRequestedOrientation() {
+            return mRequestedOrientation;
+        }
+
+        /**
+         * By returning null here, we inhibit the creation of any "container" for the window.
+         */
+        @Override
+        public Window getWindow() {
+            return null;
+        }
+
+        /**
+         * By defining this in the parent, we allow the tested activity to call
+         * <ul>
+         * <li>{@link android.app.Activity#startActivity(Intent)}</li>
+         * <li>{@link android.app.Activity#startActivityForResult(Intent, int)}</li>
+         * </ul>
+         */
+        @Override
+        public void startActivityFromChild(Activity child, Intent intent, int requestCode) {
+            mStartedActivityIntent = intent;
+            mStartedActivityRequest = requestCode;
+        }
+
+        /**
+         * By defining this in the parent, we allow the tested activity to call
+         * <ul>
+         * <li>{@link android.app.Activity#finish()}</li>
+         * <li>{@link android.app.Activity#finishFromChild(Activity child)}</li>
+         * </ul>
+         */
+        @Override
+        public void finishFromChild(Activity child) {
+            mFinished = true;
+        }
+
+        /**
+         * By defining this in the parent, we allow the tested activity to call
+         * <ul>
+         * <li>{@link android.app.Activity#finishActivity(int requestCode)}</li>
+         * </ul>
+         */
+        @Override
+        public void finishActivityFromChild(Activity child, int requestCode) {
+            mFinished = true;
+            mFinishedActivityRequest = requestCode;
+        }
+    }
+}
diff --git a/android/test/AndroidTestCase.java b/android/test/AndroidTestCase.java
new file mode 100644
index 0000000..fcb8d43
--- /dev/null
+++ b/android/test/AndroidTestCase.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2019 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.test;
+
+import android.compat.annotation.UnsupportedAppUsage;
+import android.content.Context;
+
+import junit.framework.TestCase;
+
+/**
+ * @deprecated Stub only
+ */
+@SuppressWarnings({ "unchecked", "deprecation", "all" })
+@Deprecated
+public class AndroidTestCase extends TestCase {
+
+    /**
+     * Stub only
+     */
+    @UnsupportedAppUsage
+    public void setTestContext(Context context) {
+        throw new RuntimeException("Stub!");
+    }
+
+    /**
+     * Stub only
+     */
+    @UnsupportedAppUsage
+    public Context getTestContext() {
+        throw new RuntimeException("Stub!");
+    }
+}
diff --git a/android/test/AndroidTestRunner.java b/android/test/AndroidTestRunner.java
new file mode 100644
index 0000000..f898516
--- /dev/null
+++ b/android/test/AndroidTestRunner.java
@@ -0,0 +1,247 @@
+/*
+ * 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.test;
+
+import android.app.Instrumentation;
+import android.content.Context;
+
+import java.util.ArrayList;
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestListener;
+import junit.framework.TestResult;
+import junit.framework.TestSuite;
+import junit.runner.BaseTestRunner;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.util.List;
+
+/**
+ * @deprecated Use
+ * <a href="{@docRoot}reference/android/support/test/runner/AndroidJUnitRunner.html">
+ * AndroidJUnitRunner</a> instead. New tests should be written using the
+ * <a href="{@docRoot}tools/testing-support-library/index.html">Android Testing Support Library</a>.
+ */
+@Deprecated
+public class AndroidTestRunner extends BaseTestRunner {
+
+    private TestResult mTestResult;
+    private String mTestClassName;
+    private List<TestCase> mTestCases;
+    private Context mContext;
+    private boolean mSkipExecution = false;
+
+    private List<TestListener> mTestListeners = new ArrayList<>();
+    private Instrumentation mInstrumentation;
+
+    @SuppressWarnings("unchecked")
+    public void setTestClassName(String testClassName, String testMethodName) {
+        Class testClass = loadTestClass(testClassName);
+
+        if (shouldRunSingleTestMethod(testMethodName, testClass)) {
+            TestCase testCase = buildSingleTestMethod(testClass, testMethodName);
+            mTestCases = new ArrayList<>();
+            mTestCases.add(testCase);
+            mTestClassName = testClass.getSimpleName();
+        } else {
+            setTest(getTest(testClass), testClass);
+        }
+    }
+
+    public void setTest(Test test) {
+        setTest(test, test.getClass());
+    }
+
+    private void setTest(Test test, Class<? extends Test> testClass) {
+        mTestCases = (List<TestCase>) TestCaseUtil.getTests(test, true);
+        if (TestSuite.class.isAssignableFrom(testClass)) {
+            mTestClassName = TestCaseUtil.getTestName(test);
+        } else {
+            mTestClassName = testClass.getSimpleName();
+        }
+    }
+
+    public void clearTestListeners() {
+        mTestListeners.clear();
+    }
+
+    public void addTestListener(TestListener testListener) {
+        if (testListener != null) {
+            mTestListeners.add(testListener);
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    private Class<? extends Test> loadTestClass(String testClassName) {
+        try {
+            return (Class<? extends Test>) mContext.getClassLoader().loadClass(testClassName);
+        } catch (ClassNotFoundException e) {
+            runFailed("Could not find test class. Class: " + testClassName);
+        }
+        return null;
+    }
+
+    private TestCase buildSingleTestMethod(Class testClass, String testMethodName) {
+        try {
+            Constructor c = testClass.getConstructor();
+            return newSingleTestMethod(testClass, testMethodName, c);
+        } catch (NoSuchMethodException e) {
+        }
+
+        try {
+            Constructor c = testClass.getConstructor(String.class);
+            return newSingleTestMethod(testClass, testMethodName, c, testMethodName);
+        } catch (NoSuchMethodException e) {
+        }
+
+        return null;
+    }
+
+    private TestCase newSingleTestMethod(Class testClass, String testMethodName,
+            Constructor constructor, Object... args) {
+        try {
+            TestCase testCase = (TestCase) constructor.newInstance(args);
+            testCase.setName(testMethodName);
+            return testCase;
+        } catch (IllegalAccessException e) {
+            runFailed("Could not access test class. Class: " + testClass.getName());
+        } catch (InstantiationException e) {
+            runFailed("Could not instantiate test class. Class: " + testClass.getName());
+        } catch (IllegalArgumentException e) {
+            runFailed("Illegal argument passed to constructor. Class: " + testClass.getName());
+        } catch (InvocationTargetException e) {
+            runFailed("Constructor thew an exception. Class: " + testClass.getName());
+        }
+        return null;
+    }
+
+    private boolean shouldRunSingleTestMethod(String testMethodName,
+            Class<? extends Test> testClass) {
+        return testMethodName != null && TestCase.class.isAssignableFrom(testClass);
+    }
+
+    private Test getTest(Class clazz) {
+        if (TestSuiteProvider.class.isAssignableFrom(clazz)) {
+            try {
+                TestSuiteProvider testSuiteProvider =
+                        (TestSuiteProvider) clazz.getConstructor().newInstance();
+                return testSuiteProvider.getTestSuite();
+            } catch (InstantiationException e) {
+                runFailed("Could not instantiate test suite provider. Class: " + clazz.getName());
+            } catch (IllegalAccessException e) {
+                runFailed("Illegal access of test suite provider. Class: " + clazz.getName());
+            } catch (InvocationTargetException e) {
+                runFailed("Invocation exception test suite provider. Class: " + clazz.getName());
+            } catch (NoSuchMethodException e) {
+                runFailed("No such method on test suite provider. Class: " + clazz.getName());
+            }
+        }
+        return getTest(clazz.getName());
+    }
+
+    protected TestResult createTestResult() {
+        if (mSkipExecution) {
+            return new NoExecTestResult();
+        }
+        return new TestResult();
+    }
+
+    void setSkipExecution(boolean skip) {
+        mSkipExecution = skip;
+    }
+
+    public List<TestCase> getTestCases() {
+        return mTestCases;
+    }
+
+    public String getTestClassName() {
+        return mTestClassName;
+    }
+
+    public TestResult getTestResult() {
+        return mTestResult;
+    }
+
+    public void runTest() {
+        runTest(createTestResult());
+    }
+
+    public void runTest(TestResult testResult) {
+        mTestResult = testResult;
+
+        for (TestListener testListener : mTestListeners) {
+            mTestResult.addListener(testListener);
+        }
+
+        Context testContext = mInstrumentation == null ? mContext : mInstrumentation.getContext();
+        for (TestCase testCase : mTestCases) {
+            setContextIfAndroidTestCase(testCase, mContext, testContext);
+            setInstrumentationIfInstrumentationTestCase(testCase, mInstrumentation);
+            testCase.run(mTestResult);
+        }
+    }
+
+    private void setContextIfAndroidTestCase(Test test, Context context, Context testContext) {
+        if (AndroidTestCase.class.isAssignableFrom(test.getClass())) {
+            ((AndroidTestCase) test).setContext(context);
+            ((AndroidTestCase) test).setTestContext(testContext);
+        }
+    }
+
+    public void setContext(Context context) {
+        mContext = context;
+    }
+
+    private void setInstrumentationIfInstrumentationTestCase(
+            Test test, Instrumentation instrumentation) {
+        if (InstrumentationTestCase.class.isAssignableFrom(test.getClass())) {
+            ((InstrumentationTestCase) test).injectInstrumentation(instrumentation);
+        }
+    }
+
+    public void setInstrumentation(Instrumentation instrumentation) {
+        mInstrumentation = instrumentation;
+    }
+
+    /**
+     * @deprecated Incorrect spelling,
+     * use {@link #setInstrumentation(android.app.Instrumentation)} instead.
+     */
+    @Deprecated
+    public void setInstrumentaiton(Instrumentation instrumentation) {
+        setInstrumentation(instrumentation);
+    }
+
+    @Override
+    protected Class loadSuiteClass(String suiteClassName) throws ClassNotFoundException {
+        return mContext.getClassLoader().loadClass(suiteClassName);
+    }
+
+    public void testStarted(String testName) {
+    }
+
+    public void testEnded(String testName) {
+    }
+
+    public void testFailed(int status, Test test, Throwable t) {
+    }
+
+    protected void runFailed(String message) {
+        throw new RuntimeException(message);
+    }
+}
diff --git a/android/test/ApplicationTestCase.java b/android/test/ApplicationTestCase.java
new file mode 100644
index 0000000..4d73f53
--- /dev/null
+++ b/android/test/ApplicationTestCase.java
@@ -0,0 +1,181 @@
+/*
+ * Copyright (C) 2008 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.test;
+
+import android.app.Application;
+import android.app.Instrumentation;
+import android.content.Context;
+
+/**
+ * This test case provides a framework in which you can test Application classes in
+ * a controlled environment.  It provides basic support for the lifecycle of a
+ * Application, and hooks by which you can inject various dependencies and control
+ * the environment in which your Application is tested.
+ *
+ * <p><b>Lifecycle Support.</b>
+ * Every Application is designed to be accessed within a specific sequence of
+ * method calls (see {@link android.app.Application} for more details).
+ * In order to support the lifecycle of a Application, this test case will make the
+ * following calls at the following times.
+ *
+ * <ul><li>The test case will not call onCreate() until your test calls
+ * {@link #createApplication()}.  This gives you a chance
+ * to set up or adjust any additional framework or test logic before
+ * onCreate().</li>
+ * <li>After your test completes, the test case {@link #tearDown} method is
+ * automatically called, and it will stop & destroy your application by calling its
+ * onDestroy() method.</li>
+ * </ul>
+ *
+ * <p><b>Dependency Injection.</b>
+ * Every Application has one inherent dependency, the {@link android.content.Context Context} in
+ * which it runs.
+ * This framework allows you to inject a modified, mock, or isolated replacement for this
+ * dependencies, and thus perform a true unit test.
+ *
+ * <p>If simply run your tests as-is, your Application will be injected with a fully-functional
+ * Context.
+ * You can create and inject alternative types of Contexts by calling
+ * {@link AndroidTestCase#setContext(Context) setContext()}.  You must do this <i>before</i> calling
+ * {@link #createApplication()}.  The test framework provides a
+ * number of alternatives for Context, including {@link android.test.mock.MockContext MockContext},
+ * {@link android.test.RenamingDelegatingContext RenamingDelegatingContext}, and
+ * {@link android.content.ContextWrapper ContextWrapper}.
+ *
+ * @deprecated Use
+ * <a href="{@docRoot}reference/android/support/test/InstrumentationRegistry.html">
+ * InstrumentationRegistry</a> instead. New tests should be written using the
+ * <a href="{@docRoot}tools/testing-support-library/index.html">Android Testing Support Library</a>.
+ */
+@Deprecated
+public abstract class ApplicationTestCase<T extends Application> extends AndroidTestCase {
+
+    Class<T> mApplicationClass;
+
+    private Context mSystemContext;
+
+    public ApplicationTestCase(Class<T> applicationClass) {
+        mApplicationClass = applicationClass;
+    }
+
+    private T mApplication;
+    private boolean mAttached = false;
+    private boolean mCreated = false;
+
+    /**
+     * @return Returns the actual Application under test.
+     */
+    public T getApplication() {
+        return mApplication;
+    }
+
+    /**
+     * This will do the work to instantiate the Application under test.  After this, your test
+     * code must also start and stop the Application.
+     */
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        // get the real context, before the individual tests have a chance to muck with it
+        mSystemContext = getContext();
+    }
+
+    /**
+     * Load and attach the application under test.
+     */
+    private void setupApplication() {
+        mApplication = null;
+        try {
+            mApplication = (T) Instrumentation.newApplication(mApplicationClass, getContext());
+        } catch (Exception e) {
+            assertNotNull(mApplication);
+        }
+        mAttached = true;
+    }
+
+    /**
+     * Start the Application under test, in the same way as if it was started by the system.
+     * If you use this method to start the Application, it will automatically
+     * be stopped by {@link #tearDown}.  If you wish to inject a specialized Context for your
+     * test, by calling {@link AndroidTestCase#setContext(Context) setContext()},
+     * you must do so  before calling this method.
+     */
+    final protected void createApplication() {
+        assertFalse(mCreated);
+
+        if (!mAttached) {
+            setupApplication();
+        }
+        assertNotNull(mApplication);
+
+        mApplication.onCreate();
+        mCreated = true;
+    }
+
+    /**
+     * This will make the necessary calls to terminate the Application under test (it will
+     * call onTerminate().  Ordinarily this will be called automatically (by {@link #tearDown}, but
+     * you can call it directly from your test in order to check for proper shutdown behaviors.
+     */
+    final protected void terminateApplication() {
+        if (mCreated) {
+            mApplication.onTerminate();
+        }
+    }
+
+    /**
+     * Shuts down the Application under test.  Also makes sure all resources are cleaned up and
+     * garbage collected before moving on to the next
+     * test.  Subclasses that override this method should make sure they call super.tearDown()
+     * at the end of the overriding method.
+     *
+     * @throws Exception
+     */
+    @Override
+    protected void tearDown() throws Exception {
+        terminateApplication();
+        mApplication = null;
+
+        // Scrub out members - protects against memory leaks in the case where someone
+        // creates a non-static inner class (thus referencing the test case) and gives it to
+        // someone else to hold onto
+        scrubClass(ApplicationTestCase.class);
+
+        super.tearDown();
+    }
+
+    /**
+     * Return a real (not mocked or instrumented) system Context that can be used when generating
+     * Mock or other Context objects for your Application under test.
+     *
+     * @return Returns a reference to a normal Context.
+     */
+    public Context getSystemContext() {
+        return mSystemContext;
+    }
+
+    /**
+     * This test simply confirms that the Application class can be instantiated properly.
+     *
+     * @throws Exception
+     */
+    final public void testApplicationTestCaseSetUpProperly() throws Exception {
+        setupApplication();
+        assertNotNull("Application class could not be instantiated successfully", mApplication);
+    }
+}
diff --git a/android/test/AssertionFailedError.java b/android/test/AssertionFailedError.java
new file mode 100644
index 0000000..fc3e98e
--- /dev/null
+++ b/android/test/AssertionFailedError.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2008 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.test;
+
+/**
+ * Thrown when an assertion failed.
+ *
+ * @deprecated use junit.framework.AssertionFailedError
+ */
+@Deprecated
+public class AssertionFailedError extends Error {
+
+    /**
+     * It is more typical to call {@link #AssertionFailedError(String)}.
+     */
+    public AssertionFailedError() {
+    }
+
+    public AssertionFailedError(String errorMessage) {
+        super(errorMessage);
+    }
+}
diff --git a/android/test/ClassPathPackageInfoSource.java b/android/test/ClassPathPackageInfoSource.java
new file mode 100644
index 0000000..755b540
--- /dev/null
+++ b/android/test/ClassPathPackageInfoSource.java
@@ -0,0 +1,262 @@
+/*
+ * Copyright (C) 2008 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.test;
+
+import android.util.Log;
+import dalvik.system.DexFile;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.TreeSet;
+import java.util.regex.Pattern;
+
+/**
+ * Generate {@link ClassPathPackageInfo}s by scanning apk paths.
+ *
+ * {@hide} Not needed for 1.0 SDK.
+ */
+@Deprecated
+public class ClassPathPackageInfoSource {
+
+    private static final ClassLoader CLASS_LOADER
+            = ClassPathPackageInfoSource.class.getClassLoader();
+
+    private static String[] apkPaths;
+
+    private static ClassPathPackageInfoSource classPathSource;
+
+    private final SimpleCache<String, ClassPathPackageInfo> cache =
+            new SimpleCache<String, ClassPathPackageInfo>() {
+                @Override
+                protected ClassPathPackageInfo load(String pkgName) {
+                    return createPackageInfo(pkgName);
+                }
+            };
+
+    // The class path of the running application
+    private final String[] classPath;
+
+    private final ClassLoader classLoader;
+
+    private ClassPathPackageInfoSource(ClassLoader classLoader) {
+        this.classLoader = classLoader;
+        classPath = getClassPath();
+    }
+
+    static void setApkPaths(String[] apkPaths) {
+        ClassPathPackageInfoSource.apkPaths = apkPaths;
+    }
+
+    public static ClassPathPackageInfoSource forClassPath(ClassLoader classLoader) {
+        if (classPathSource == null) {
+            classPathSource = new ClassPathPackageInfoSource(classLoader);
+        }
+        return classPathSource;
+    }
+
+    public Set<Class<?>> getTopLevelClassesRecursive(String packageName) {
+        ClassPathPackageInfo packageInfo = cache.get(packageName);
+        return packageInfo.getTopLevelClassesRecursive();
+    }
+
+    private ClassPathPackageInfo createPackageInfo(String packageName) {
+        Set<String> subpackageNames = new TreeSet<String>();
+        Set<String> classNames = new TreeSet<String>();
+        Set<Class<?>> topLevelClasses = new HashSet<>();
+        findClasses(packageName, classNames, subpackageNames);
+        for (String className : classNames) {
+            if (className.endsWith(".R") || className.endsWith(".Manifest")) {
+                // Don't try to load classes that are generated. They usually aren't in test apks.
+                continue;
+            }
+
+            try {
+                // We get errors in the emulator if we don't use the caller's class loader.
+                topLevelClasses.add(Class.forName(className, false,
+                        (classLoader != null) ? classLoader : CLASS_LOADER));
+            } catch (ClassNotFoundException | NoClassDefFoundError e) {
+                // Should not happen unless there is a generated class that is not included in
+                // the .apk.
+                Log.w("ClassPathPackageInfoSource", "Cannot load class. "
+                        + "Make sure it is in your apk. Class name: '" + className
+                        + "'. Message: " + e.getMessage(), e);
+            }
+        }
+        return new ClassPathPackageInfo(packageName, subpackageNames,
+                topLevelClasses);
+    }
+
+    /**
+     * Finds all classes and sub packages that are below the packageName and
+     * add them to the respective sets. Searches the package on the whole class
+     * path.
+     */
+    private void findClasses(String packageName, Set<String> classNames,
+            Set<String> subpackageNames) {
+        for (String entryName : classPath) {
+            File classPathEntry = new File(entryName);
+
+            // Forge may not have brought over every item in the classpath. Be
+            // polite and ignore missing entries.
+            if (classPathEntry.exists()) {
+                try {
+                    if (entryName.endsWith(".apk")) {
+                        findClassesInApk(entryName, packageName, classNames, subpackageNames);
+                    } else {
+                        // scan the directories that contain apk files.
+                        for (String apkPath : apkPaths) {
+                            File file = new File(apkPath);
+                            scanForApkFiles(file, packageName, classNames, subpackageNames);
+                        }
+                    }
+                } catch (IOException e) {
+                    throw new AssertionError("Can't read classpath entry " +
+                            entryName + ": " + e.getMessage());
+                }
+            }
+        }
+    }
+
+    private void scanForApkFiles(File source, String packageName,
+            Set<String> classNames, Set<String> subpackageNames) throws IOException {
+        if (source.getPath().endsWith(".apk")) {
+            findClassesInApk(source.getPath(), packageName, classNames, subpackageNames);
+        } else {
+            File[] files = source.listFiles();
+            if (files != null) {
+                for (File file : files) {
+                    scanForApkFiles(file, packageName, classNames, subpackageNames);
+                }
+            }
+        }
+    }
+
+    /**
+     * Finds all classes and sub packages that are below the packageName and
+     * add them to the respective sets. Searches the package in a single apk file.
+     */
+    private void findClassesInApk(String apkPath, String packageName,
+            Set<String> classNames, Set<String> subpackageNames)
+            throws IOException {
+
+        DexFile dexFile = null;
+        try {
+            dexFile = new DexFile(apkPath);
+            Enumeration<String> apkClassNames = dexFile.entries();
+            while (apkClassNames.hasMoreElements()) {
+                String className = apkClassNames.nextElement();
+
+                if (className.startsWith(packageName)) {
+                    String subPackageName = packageName;
+                    int lastPackageSeparator = className.lastIndexOf('.');
+                    if (lastPackageSeparator > 0) {
+                        subPackageName = className.substring(0, lastPackageSeparator);
+                    }
+                    if (subPackageName.length() > packageName.length()) {
+                        subpackageNames.add(subPackageName);
+                    } else if (isToplevelClass(className)) {
+                        classNames.add(className);
+                    }
+                }
+            }
+        } catch (IOException e) {
+            if (false) {
+                Log.w("ClassPathPackageInfoSource",
+                        "Error finding classes at apk path: " + apkPath, e);
+            }
+        } finally {
+            if (dexFile != null) {
+                // Todo: figure out why closing causes a dalvik error resulting in vm shutdown.
+//                dexFile.close();
+            }
+        }
+    }
+
+    /**
+     * Checks if a given file name represents a toplevel class.
+     */
+    private static boolean isToplevelClass(String fileName) {
+        return fileName.indexOf('$') < 0;
+    }
+
+    /**
+     * Gets the class path from the System Property "java.class.path" and splits
+     * it up into the individual elements.
+     */
+    private static String[] getClassPath() {
+        String classPath = System.getProperty("java.class.path");
+        String separator = System.getProperty("path.separator", ":");
+        return classPath.split(Pattern.quote(separator));
+    }
+
+    /**
+     * The Package object doesn't allow you to iterate over the contained
+     * classes and subpackages of that package.  This is a version that does.
+     */
+    private class ClassPathPackageInfo {
+
+        private final String packageName;
+        private final Set<String> subpackageNames;
+        private final Set<Class<?>> topLevelClasses;
+
+        private ClassPathPackageInfo(String packageName,
+                Set<String> subpackageNames, Set<Class<?>> topLevelClasses) {
+            this.packageName = packageName;
+            this.subpackageNames = Collections.unmodifiableSet(subpackageNames);
+            this.topLevelClasses = Collections.unmodifiableSet(topLevelClasses);
+        }
+
+        private Set<ClassPathPackageInfo> getSubpackages() {
+            Set<ClassPathPackageInfo> info = new HashSet<>();
+            for (String name : subpackageNames) {
+                info.add(cache.get(name));
+            }
+            return info;
+        }
+
+        private Set<Class<?>> getTopLevelClassesRecursive() {
+            Set<Class<?>> set = new HashSet<>();
+            addTopLevelClassesTo(set);
+            return set;
+        }
+
+        private void addTopLevelClassesTo(Set<Class<?>> set) {
+            set.addAll(topLevelClasses);
+            for (ClassPathPackageInfo info : getSubpackages()) {
+                info.addTopLevelClassesTo(set);
+            }
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (obj instanceof ClassPathPackageInfo) {
+                ClassPathPackageInfo that = (ClassPathPackageInfo) obj;
+                return (this.packageName).equals(that.packageName);
+            }
+            return false;
+        }
+
+        @Override
+        public int hashCode() {
+            return packageName.hashCode();
+        }
+    }
+}
diff --git a/android/test/ComparisonFailure.java b/android/test/ComparisonFailure.java
new file mode 100644
index 0000000..d86b700
--- /dev/null
+++ b/android/test/ComparisonFailure.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2008 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.test;
+
+/**
+ * Thrown when an assert equals for Strings failed.
+ * 
+ * @deprecated use org.junit.ComparisonFailure
+ */
+@Deprecated
+public class ComparisonFailure extends AssertionFailedError {
+    private junit.framework.ComparisonFailure mComparison;
+
+    public ComparisonFailure(String message, String expected, String actual) {
+        mComparison = new junit.framework.ComparisonFailure(message, expected, actual);
+    }
+
+    public String getMessage() {
+        return mComparison.getMessage();
+    }
+}
diff --git a/android/test/FlakyTest.java b/android/test/FlakyTest.java
new file mode 100644
index 0000000..4e5c4e3
--- /dev/null
+++ b/android/test/FlakyTest.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2008 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.test;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.lang.annotation.ElementType;
+
+/**
+ * This annotation can be used on an {@link android.test.InstrumentationTestCase}'s
+ * test methods. When the annotation is present, the test method is re-executed if
+ * the test fails. The total number of executions is specified by the tolerance and
+ * defaults to 1.
+ *
+ * @deprecated Use
+ * <a href="{@docRoot}reference/android/support/test/filters/FlakyTest.html">
+ * FlakyTest</a> instead. New tests should be written using the
+ * <a href="{@docRoot}tools/testing-support-library/index.html">Android Testing Support Library</a>.
+ */
+@Deprecated
+@Target(ElementType.METHOD)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface FlakyTest {
+    /**
+     * Indicates how many times a test can run and fail before being reported
+     * as a failed test. If the tolerance factor is less than 1, the test runs
+     * only once.
+     *
+     * @return The total number of allowed run, the default is 1.
+     */
+    int tolerance() default 1;
+}
diff --git a/android/test/InstrumentationTestCase.java b/android/test/InstrumentationTestCase.java
new file mode 100644
index 0000000..a48a56c
--- /dev/null
+++ b/android/test/InstrumentationTestCase.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2019 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.test;
+
+import android.compat.annotation.UnsupportedAppUsage;
+
+import junit.framework.TestCase;
+
+import java.lang.reflect.Method;
+
+/**
+ * @deprecated Stub only
+ */
+@SuppressWarnings({ "unchecked", "deprecation", "all" })
+@Deprecated
+public class InstrumentationTestCase extends TestCase {
+
+    /**
+     * Stub only
+     */
+    @UnsupportedAppUsage
+    private void runMethod(Method runMethod, int tolerance) throws Throwable {
+        throw new RuntimeException("Stub!");
+    }
+}
diff --git a/android/test/InstrumentationTestRunner.java b/android/test/InstrumentationTestRunner.java
new file mode 100644
index 0000000..b2582c1
--- /dev/null
+++ b/android/test/InstrumentationTestRunner.java
@@ -0,0 +1,854 @@
+/*
+ * 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.test;
+
+import android.test.suitebuilder.annotation.MediumTest;
+import android.test.suitebuilder.annotation.SmallTest;
+import com.android.internal.util.Predicate;
+
+import android.app.Activity;
+import android.app.Instrumentation;
+import android.os.Bundle;
+import android.os.Debug;
+import android.os.Looper;
+import android.test.suitebuilder.TestMethod;
+import android.test.suitebuilder.TestPredicates;
+import android.test.suitebuilder.TestSuiteBuilder;
+import android.test.suitebuilder.annotation.LargeTest;
+import android.util.Log;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.PrintStream;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+
+import junit.framework.AssertionFailedError;
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestListener;
+import junit.framework.TestResult;
+import junit.framework.TestSuite;
+import junit.runner.BaseTestRunner;
+import junit.textui.ResultPrinter;
+
+import static android.test.suitebuilder.TestPredicates.hasAnnotation;
+
+/**
+ * An {@link Instrumentation} that runs various types of {@link junit.framework.TestCase}s against
+ * an Android package (application).
+ *
+ * <div class="special reference">
+ * <h3>Developer Guides</h3>
+ * <p>For more information about application testing, read the
+ * <a href="{@docRoot}guide/topics/testing/index.html">Testing</a> developer guide.</p>
+ * </div>
+ *
+ * <h3>Typical Usage</h3>
+ * <ol>
+ * <li>Write {@link junit.framework.TestCase}s that perform unit, functional, or performance tests
+ * against the classes in your package.  Typically these are subclassed from:
+ *   <ul><li>{@link android.test.ActivityInstrumentationTestCase2}</li>
+ *   <li>{@link android.test.ActivityUnitTestCase}</li>
+ *   <li>{@link android.test.AndroidTestCase}</li>
+ *   <li>{@link android.test.ApplicationTestCase}</li>
+ *   <li>{@link android.test.InstrumentationTestCase}</li>
+ *   <li>{@link android.test.ProviderTestCase}</li>
+ *   <li>{@link android.test.ServiceTestCase}</li>
+ *   <li>{@link android.test.SingleLaunchActivityTestCase}</li></ul>
+ * <li>Set the <code>android:targetPackage</code> attribute of the <code>&lt;instrumentation&gt;</code>
+ * element in the test package's manifest. You should set the attribute value
+ * to the package name of the target application under test.
+ * <li>Run the instrumentation using "adb shell am instrument -w",
+ * with no optional arguments, to run all tests (except performance tests).
+ * <li>Run the instrumentation using "adb shell am instrument -w",
+ * with the argument '-e func true' to run all functional tests. These are tests that derive from
+ * {@link android.test.InstrumentationTestCase}.
+ * <li>Run the instrumentation using "adb shell am instrument -w",
+ * with the argument '-e unit true' to run all unit tests. These are tests that <i>do not</i>derive
+ * from {@link android.test.InstrumentationTestCase} (and are not performance tests).
+ * <li>Run the instrumentation using "adb shell am instrument -w",
+ * with the argument '-e class' set to run an individual {@link junit.framework.TestCase}.
+ * </ol>
+ * <p/>
+ * <b>Running all tests:</b> adb shell am instrument -w
+ * com.android.foo/android.test.InstrumentationTestRunner
+ * <p/>
+ * <b>Running all small tests:</b> adb shell am instrument -w
+ * -e size small
+ * com.android.foo/android.test.InstrumentationTestRunner
+ * <p/>
+ * <b>Running all medium tests:</b> adb shell am instrument -w
+ * -e size medium
+ * com.android.foo/android.test.InstrumentationTestRunner
+ * <p/>
+ * <b>Running all large tests:</b> adb shell am instrument -w
+ * -e size large
+ * com.android.foo/android.test.InstrumentationTestRunner
+ * <p/>
+ * <b>Filter test run to tests with given annotation:</b> adb shell am instrument -w
+ * -e annotation com.android.foo.MyAnnotation
+ * com.android.foo/android.test.InstrumentationTestRunner
+ * <p/>
+ * If used with other options, the resulting test run will contain the union of the two options.
+ * e.g. "-e size large -e annotation com.android.foo.MyAnnotation" will run only tests with both
+ * the {@link LargeTest} and "com.android.foo.MyAnnotation" annotations.
+ * <p/>
+ * <b>Filter test run to tests <i>without</i> given annotation:</b> adb shell am instrument -w
+ * -e notAnnotation com.android.foo.MyAnnotation
+ * com.android.foo/android.test.InstrumentationTestRunner
+ * <p/>
+ * <b>Running a single testcase:</b> adb shell am instrument -w
+ * -e class com.android.foo.FooTest
+ * com.android.foo/android.test.InstrumentationTestRunner
+ * <p/>
+ * <b>Running a single test:</b> adb shell am instrument -w
+ * -e class com.android.foo.FooTest#testFoo
+ * com.android.foo/android.test.InstrumentationTestRunner
+ * <p/>
+ * <b>Running multiple tests:</b> adb shell am instrument -w
+ * -e class com.android.foo.FooTest,com.android.foo.TooTest
+ * com.android.foo/android.test.InstrumentationTestRunner
+ * <p/>
+ * <b>Running all tests in a java package:</b> adb shell am instrument -w
+ * -e package com.android.foo.subpkg
+ *  com.android.foo/android.test.InstrumentationTestRunner
+ * <p/>
+ * <b>Including performance tests:</b> adb shell am instrument -w
+ * -e perf true
+ * com.android.foo/android.test.InstrumentationTestRunner
+ * <p/>
+ * <b>To debug your tests, set a break point in your code and pass:</b>
+ * -e debug true
+ * <p/>
+ * <b>To run in 'log only' mode</b>
+ * -e log true
+ * This option will load and iterate through all test classes and methods, but will bypass actual
+ * test execution. Useful for quickly obtaining info on the tests to be executed by an
+ * instrumentation command.
+ * <p/>
+ * <b>To generate EMMA code coverage:</b>
+ * -e coverage true
+ * Note: this requires an emma instrumented build. By default, the code coverage results file
+ * will be saved in a /data/<app>/coverage.ec file, unless overridden by coverageFile flag (see
+ * below)
+ * <p/>
+ * <b> To specify EMMA code coverage results file path:</b>
+ * -e coverageFile /sdcard/myFile.ec
+ * <br/>
+ * in addition to the other arguments.
+ * @deprecated Use
+ * <a href="{@docRoot}reference/android/support/test/runner/AndroidJUnitRunner.html">
+ * AndroidJUnitRunner</a> instead. New tests should be written using the
+ * <a href="{@docRoot}tools/testing-support-library/index.html">Android Testing Support Library</a>.
+ */
+
+/* (not JavaDoc)
+ * Although not necessary in most case, another way to use this class is to extend it and have the
+ * derived class return the desired test suite from the {@link #getTestSuite()} method. The test
+ * suite returned from this method will be used if no target class is defined in the meta-data or
+ * command line argument parameters. If a derived class is used it needs to be added as an
+ * instrumentation to the AndroidManifest.xml and the command to run it would look like:
+ * <p/>
+ * adb shell am instrument -w com.android.foo/<i>com.android.FooInstrumentationTestRunner</i>
+ * <p/>
+ * Where <i>com.android.FooInstrumentationTestRunner</i> is the derived class.
+ *
+ * This model is used by many existing app tests, but can probably be deprecated.
+ */
+@Deprecated
+public class InstrumentationTestRunner extends Instrumentation implements TestSuiteProvider {
+
+    /** @hide */
+    static final String ARGUMENT_TEST_CLASS = "class";
+    /** @hide */
+    private static final String ARGUMENT_TEST_PACKAGE = "package";
+    /** @hide */
+    private static final String ARGUMENT_TEST_SIZE_PREDICATE = "size";
+    /** @hide */
+    static final String ARGUMENT_DELAY_MSEC = "delay_msec";
+
+    private static final String SMALL_SUITE = "small";
+    private static final String MEDIUM_SUITE = "medium";
+    private static final String LARGE_SUITE = "large";
+
+    private static final String ARGUMENT_LOG_ONLY = "log";
+    /** @hide */
+    static final String ARGUMENT_ANNOTATION = "annotation";
+    /** @hide */
+    static final String ARGUMENT_NOT_ANNOTATION = "notAnnotation";
+
+    private static final Predicate<TestMethod> SELECT_SMALL = hasAnnotation(SmallTest.class);
+
+    private static final Predicate<TestMethod> SELECT_MEDIUM = hasAnnotation(MediumTest.class);
+
+    private static final Predicate<TestMethod> SELECT_LARGE = hasAnnotation(LargeTest.class);
+
+    /**
+     * This constant defines the maximum allowed runtime (in ms) for a test included in the "small"
+     * suite. It is used to make an educated guess at what suite an unlabeled test belongs.
+     */
+    private static final float SMALL_SUITE_MAX_RUNTIME = 100;
+
+    /**
+     * This constant defines the maximum allowed runtime (in ms) for a test included in the
+     * "medium" suite. It is used to make an educated guess at what suite an unlabeled test belongs.
+     */
+    private static final float MEDIUM_SUITE_MAX_RUNTIME = 1000;
+
+    /*
+     * The following keys are used in the status bundle to provide structured reports to
+     * an IInstrumentationWatcher.
+     */
+
+    /**
+     * This value, if stored with key {@link android.app.Instrumentation#REPORT_KEY_IDENTIFIER},
+     * identifies InstrumentationTestRunner as the source of the report.  This is sent with all
+     * status messages.
+     */
+    public static final String REPORT_VALUE_ID = "InstrumentationTestRunner";
+    /**
+     * If included in the status or final bundle sent to an IInstrumentationWatcher, this key
+     * identifies the total number of tests that are being run.  This is sent with all status
+     * messages.
+     */
+    public static final String REPORT_KEY_NUM_TOTAL = "numtests";
+    /**
+     * If included in the status or final bundle sent to an IInstrumentationWatcher, this key
+     * identifies the sequence number of the current test.  This is sent with any status message
+     * describing a specific test being started or completed.
+     */
+    public static final String REPORT_KEY_NUM_CURRENT = "current";
+    /**
+     * If included in the status or final bundle sent to an IInstrumentationWatcher, this key
+     * identifies the name of the current test class.  This is sent with any status message
+     * describing a specific test being started or completed.
+     */
+    public static final String REPORT_KEY_NAME_CLASS = "class";
+    /**
+     * If included in the status or final bundle sent to an IInstrumentationWatcher, this key
+     * identifies the name of the current test.  This is sent with any status message
+     * describing a specific test being started or completed.
+     */
+    public static final String REPORT_KEY_NAME_TEST = "test";
+    /**
+     * If included in the status or final bundle sent to an IInstrumentationWatcher, this key
+     * reports the run time in seconds of the current test.
+     */
+    private static final String REPORT_KEY_RUN_TIME = "runtime";
+    /**
+     * If included in the status or final bundle sent to an IInstrumentationWatcher, this key
+     * reports the number of total iterations of the current test.
+     */
+    private static final String REPORT_KEY_NUM_ITERATIONS = "numiterations";
+    /**
+     * If included in the status or final bundle sent to an IInstrumentationWatcher, this key
+     * reports the guessed suite assignment for the current test.
+     */
+    private static final String REPORT_KEY_SUITE_ASSIGNMENT = "suiteassignment";
+    /**
+     * If included in the status or final bundle sent to an IInstrumentationWatcher, this key
+     * identifies the path to the generated code coverage file.
+     */
+    private static final String REPORT_KEY_COVERAGE_PATH = "coverageFilePath";
+
+    /**
+     * The test is starting.
+     */
+    public static final int REPORT_VALUE_RESULT_START = 1;
+    /**
+     * The test completed successfully.
+     */
+    public static final int REPORT_VALUE_RESULT_OK = 0;
+    /**
+     * The test completed with an error.
+     */
+    public static final int REPORT_VALUE_RESULT_ERROR = -1;
+    /**
+     * The test completed with a failure.
+     */
+    public static final int REPORT_VALUE_RESULT_FAILURE = -2;
+    /**
+     * If included in the status bundle sent to an IInstrumentationWatcher, this key
+     * identifies a stack trace describing an error or failure.  This is sent with any status
+     * message describing a specific test being completed.
+     */
+    public static final String REPORT_KEY_STACK = "stack";
+
+    // Default file name for code coverage
+    private static final String DEFAULT_COVERAGE_FILE_NAME = "coverage.ec";
+
+    private static final String LOG_TAG = "InstrumentationTestRunner";
+
+    private final Bundle mResults = new Bundle();
+    private Bundle mArguments;
+    private AndroidTestRunner mTestRunner;
+    private boolean mDebug;
+    private boolean mJustCount;
+    private boolean mSuiteAssignmentMode;
+    private int mTestCount;
+    private String mPackageOfTests;
+    private boolean mCoverage;
+    private String mCoverageFilePath;
+    private int mDelayMsec;
+
+    @Override
+    public void onCreate(Bundle arguments) {
+        super.onCreate(arguments);
+        mArguments = arguments;
+
+        // Apk paths used to search for test classes when using TestSuiteBuilders.
+        String[] apkPaths =
+                {getTargetContext().getPackageCodePath(), getContext().getPackageCodePath()};
+        ClassPathPackageInfoSource.setApkPaths(apkPaths);
+
+        Predicate<TestMethod> testSizePredicate = null;
+        Predicate<TestMethod> testAnnotationPredicate = null;
+        Predicate<TestMethod> testNotAnnotationPredicate = null;
+        String testClassesArg = null;
+        boolean logOnly = false;
+
+        if (arguments != null) {
+            // Test class name passed as an argument should override any meta-data declaration.
+            testClassesArg = arguments.getString(ARGUMENT_TEST_CLASS);
+            mDebug = getBooleanArgument(arguments, "debug");
+            mJustCount = getBooleanArgument(arguments, "count");
+            mSuiteAssignmentMode = getBooleanArgument(arguments, "suiteAssignment");
+            mPackageOfTests = arguments.getString(ARGUMENT_TEST_PACKAGE);
+            testSizePredicate = getSizePredicateFromArg(
+                    arguments.getString(ARGUMENT_TEST_SIZE_PREDICATE));
+            testAnnotationPredicate = getAnnotationPredicate(
+                    arguments.getString(ARGUMENT_ANNOTATION));
+            testNotAnnotationPredicate = getNotAnnotationPredicate(
+                    arguments.getString(ARGUMENT_NOT_ANNOTATION));
+
+            logOnly = getBooleanArgument(arguments, ARGUMENT_LOG_ONLY);
+            mCoverage = getBooleanArgument(arguments, "coverage");
+            mCoverageFilePath = arguments.getString("coverageFile");
+
+            try {
+                Object delay = arguments.get(ARGUMENT_DELAY_MSEC);  // Accept either string or int
+                if (delay != null) mDelayMsec = Integer.parseInt(delay.toString());
+            } catch (NumberFormatException e) {
+                Log.e(LOG_TAG, "Invalid delay_msec parameter", e);
+            }
+        }
+
+        TestSuiteBuilder testSuiteBuilder = new TestSuiteBuilder(getClass().getName(),
+                getTargetContext().getClassLoader());
+
+        if (testSizePredicate != null) {
+            testSuiteBuilder.addRequirements(testSizePredicate);
+        }
+        if (testAnnotationPredicate != null) {
+            testSuiteBuilder.addRequirements(testAnnotationPredicate);
+        }
+        if (testNotAnnotationPredicate != null) {
+            testSuiteBuilder.addRequirements(testNotAnnotationPredicate);
+        }
+
+        if (testClassesArg == null) {
+            if (mPackageOfTests != null) {
+                testSuiteBuilder.includePackages(mPackageOfTests);
+            } else {
+                TestSuite testSuite = getTestSuite();
+                if (testSuite != null) {
+                    testSuiteBuilder.addTestSuite(testSuite);
+                } else {
+                    // no package or class bundle arguments were supplied, and no test suite
+                    // provided so add all tests in application
+                    testSuiteBuilder.includePackages("");
+                }
+            }
+        } else {
+            parseTestClasses(testClassesArg, testSuiteBuilder);
+        }
+
+        testSuiteBuilder.addRequirements(getBuilderRequirements());
+
+        mTestRunner = getAndroidTestRunner();
+        mTestRunner.setContext(getTargetContext());
+        mTestRunner.setInstrumentation(this);
+        mTestRunner.setSkipExecution(logOnly);
+        mTestRunner.setTest(testSuiteBuilder.build());
+        mTestCount = mTestRunner.getTestCases().size();
+        if (mSuiteAssignmentMode) {
+            mTestRunner.addTestListener(new SuiteAssignmentPrinter());
+        } else {
+            WatcherResultPrinter resultPrinter = new WatcherResultPrinter(mTestCount);
+            mTestRunner.addTestListener(new TestPrinter("TestRunner", false));
+            mTestRunner.addTestListener(resultPrinter);
+        }
+        start();
+    }
+
+    /**
+     * Get the arguments passed to this instrumentation.
+     *
+     * @return the Bundle object
+     */
+    public Bundle getArguments() {
+        return mArguments;
+    }
+
+    /**
+     * Add a {@link TestListener}
+     * @hide
+     */
+    protected void addTestListener(TestListener listener){
+        if(mTestRunner!=null && listener!=null){
+            mTestRunner.addTestListener(listener);
+        }
+    }
+
+    List<Predicate<TestMethod>> getBuilderRequirements() {
+        return new ArrayList<Predicate<TestMethod>>();
+    }
+
+    /**
+     * Parses and loads the specified set of test classes
+     *
+     * @param testClassArg - comma-separated list of test classes and methods
+     * @param testSuiteBuilder - builder to add tests to
+     */
+    private void parseTestClasses(String testClassArg, TestSuiteBuilder testSuiteBuilder) {
+        String[] testClasses = testClassArg.split(",");
+        for (String testClass : testClasses) {
+            parseTestClass(testClass, testSuiteBuilder);
+        }
+    }
+
+    /**
+     * Parse and load the given test class and, optionally, method
+     *
+     * @param testClassName - full package name of test class and optionally method to add.
+     *        Expected format: com.android.TestClass#testMethod
+     * @param testSuiteBuilder - builder to add tests to
+     */
+    private void parseTestClass(String testClassName, TestSuiteBuilder testSuiteBuilder) {
+        int methodSeparatorIndex = testClassName.indexOf('#');
+        String testMethodName = null;
+
+        if (methodSeparatorIndex > 0) {
+            testMethodName = testClassName.substring(methodSeparatorIndex + 1);
+            testClassName = testClassName.substring(0, methodSeparatorIndex);
+        }
+        testSuiteBuilder.addTestClassByName(testClassName, testMethodName, getTargetContext());
+    }
+
+    protected AndroidTestRunner getAndroidTestRunner() {
+        return new AndroidTestRunner();
+    }
+
+    private boolean getBooleanArgument(Bundle arguments, String tag) {
+        String tagString = arguments.getString(tag);
+        return tagString != null && Boolean.parseBoolean(tagString);
+    }
+
+    /*
+     * Returns the size predicate object, corresponding to the "size" argument value.
+     */
+    private Predicate<TestMethod> getSizePredicateFromArg(String sizeArg) {
+
+        if (SMALL_SUITE.equals(sizeArg)) {
+            return SELECT_SMALL;
+        } else if (MEDIUM_SUITE.equals(sizeArg)) {
+            return SELECT_MEDIUM;
+        } else if (LARGE_SUITE.equals(sizeArg)) {
+            return SELECT_LARGE;
+        } else {
+            return null;
+        }
+    }
+
+   /**
+    * Returns the test predicate object, corresponding to the annotation class value provided via
+    * the {@link #ARGUMENT_ANNOTATION} argument.
+    *
+    * @return the predicate or <code>null</code>
+    */
+    private Predicate<TestMethod> getAnnotationPredicate(String annotationClassName) {
+        Class<? extends Annotation> annotationClass = getAnnotationClass(annotationClassName);
+        if (annotationClass != null) {
+            return hasAnnotation(annotationClass);
+        }
+        return null;
+    }
+
+    /**
+     * Returns the negative test predicate object, corresponding to the annotation class value
+     * provided via the {@link #ARGUMENT_NOT_ANNOTATION} argument.
+     *
+     * @return the predicate or <code>null</code>
+     */
+     private Predicate<TestMethod> getNotAnnotationPredicate(String annotationClassName) {
+         Class<? extends Annotation> annotationClass = getAnnotationClass(annotationClassName);
+         if (annotationClass != null) {
+             return TestPredicates.not(hasAnnotation(annotationClass));
+         }
+         return null;
+     }
+
+    /**
+     * Helper method to return the annotation class with specified name
+     *
+     * @param annotationClassName the fully qualified name of the class
+     * @return the annotation class or <code>null</code>
+     */
+    private Class<? extends Annotation> getAnnotationClass(String annotationClassName) {
+        if (annotationClassName == null) {
+            return null;
+        }
+        try {
+           Class<?> annotationClass = Class.forName(annotationClassName);
+           if (annotationClass.isAnnotation()) {
+               return (Class<? extends Annotation>)annotationClass;
+           } else {
+               Log.e(LOG_TAG, String.format("Provided annotation value %s is not an Annotation",
+                       annotationClassName));
+           }
+        } catch (ClassNotFoundException e) {
+            Log.e(LOG_TAG, String.format("Could not find class for specified annotation %s",
+                    annotationClassName));
+        }
+        return null;
+    }
+
+    /**
+     * Initialize the current thread as a looper.
+     * <p/>
+     * Exposed for unit testing.
+     */
+    void prepareLooper() {
+        Looper.prepare();
+    }
+
+    @Override
+    public void onStart() {
+        prepareLooper();
+
+        if (mJustCount) {
+            mResults.putString(Instrumentation.REPORT_KEY_IDENTIFIER, REPORT_VALUE_ID);
+            mResults.putInt(REPORT_KEY_NUM_TOTAL, mTestCount);
+            finish(Activity.RESULT_OK, mResults);
+        } else {
+            if (mDebug) {
+                Debug.waitForDebugger();
+            }
+
+            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+            PrintStream writer = new PrintStream(byteArrayOutputStream);
+            try {
+                StringResultPrinter resultPrinter = new StringResultPrinter(writer);
+
+                mTestRunner.addTestListener(resultPrinter);
+
+                long startTime = System.currentTimeMillis();
+                mTestRunner.runTest();
+                long runTime = System.currentTimeMillis() - startTime;
+
+                resultPrinter.printResult(mTestRunner.getTestResult(), runTime);
+            } catch (Throwable t) {
+                // catch all exceptions so a more verbose error message can be outputted
+                writer.println(String.format("Test run aborted due to unexpected exception: %s",
+                                t.getMessage()));
+                t.printStackTrace(writer);
+            } finally {
+                mResults.putString(Instrumentation.REPORT_KEY_STREAMRESULT,
+                        String.format("\nTest results for %s=%s",
+                        mTestRunner.getTestClassName(),
+                        byteArrayOutputStream.toString()));
+
+                if (mCoverage) {
+                    generateCoverageReport();
+                }
+                writer.close();
+
+                finish(Activity.RESULT_OK, mResults);
+            }
+        }
+    }
+
+    public TestSuite getTestSuite() {
+        return getAllTests();
+    }
+
+    /**
+     * Override this to define all of the tests to run in your package.
+     */
+    public TestSuite getAllTests() {
+        return null;
+    }
+
+    /**
+     * Override this to provide access to the class loader of your package.
+     */
+    public ClassLoader getLoader() {
+        return null;
+    }
+
+    private void generateCoverageReport() {
+        // use reflection to call emma dump coverage method, to avoid
+        // always statically compiling against emma jar
+        String coverageFilePath = getCoverageFilePath();
+        java.io.File coverageFile = new java.io.File(coverageFilePath);
+        try {
+            Class<?> emmaRTClass = Class.forName("com.vladium.emma.rt.RT");
+            Method dumpCoverageMethod = emmaRTClass.getMethod("dumpCoverageData",
+                    coverageFile.getClass(), boolean.class, boolean.class);
+
+            dumpCoverageMethod.invoke(null, coverageFile, false, false);
+            // output path to generated coverage file so it can be parsed by a test harness if
+            // needed
+            mResults.putString(REPORT_KEY_COVERAGE_PATH, coverageFilePath);
+            // also output a more user friendly msg
+            final String currentStream = mResults.getString(
+                    Instrumentation.REPORT_KEY_STREAMRESULT);
+            mResults.putString(Instrumentation.REPORT_KEY_STREAMRESULT,
+                String.format("%s\nGenerated code coverage data to %s", currentStream,
+                coverageFilePath));
+        } catch (ClassNotFoundException e) {
+            reportEmmaError("Is emma jar on classpath?", e);
+        } catch (SecurityException e) {
+            reportEmmaError(e);
+        } catch (NoSuchMethodException e) {
+            reportEmmaError(e);
+        } catch (IllegalArgumentException e) {
+            reportEmmaError(e);
+        } catch (IllegalAccessException e) {
+            reportEmmaError(e);
+        } catch (InvocationTargetException e) {
+            reportEmmaError(e);
+        }
+    }
+
+    private String getCoverageFilePath() {
+        if (mCoverageFilePath == null) {
+            return getTargetContext().getFilesDir().getAbsolutePath() + File.separator +
+                   DEFAULT_COVERAGE_FILE_NAME;
+        } else {
+            return mCoverageFilePath;
+        }
+    }
+
+    private void reportEmmaError(Exception e) {
+        reportEmmaError("", e);
+    }
+
+    private void reportEmmaError(String hint, Exception e) {
+        String msg = "Failed to generate emma coverage. " + hint;
+        Log.e(LOG_TAG, msg, e);
+        mResults.putString(Instrumentation.REPORT_KEY_STREAMRESULT, "\nError: " + msg);
+    }
+
+    // TODO kill this, use status() and prettyprint model for better output
+    private class StringResultPrinter extends ResultPrinter {
+
+        public StringResultPrinter(PrintStream writer) {
+            super(writer);
+        }
+
+        public synchronized void printResult(TestResult result, long runTime) {
+            printHeader(runTime);
+            printFooter(result);
+        }
+    }
+
+    /**
+     * This class sends status reports back to the IInstrumentationWatcher about
+     * which suite each test belongs.
+     */
+    private class SuiteAssignmentPrinter implements TestListener {
+
+        private Bundle mTestResult;
+        private long mStartTime;
+        private long mEndTime;
+        private boolean mTimingValid;
+
+        public SuiteAssignmentPrinter() {
+        }
+
+        /**
+         * send a status for the start of a each test, so long tests can be seen as "running"
+         */
+        public void startTest(Test test) {
+            mTimingValid = true;
+            mStartTime = System.currentTimeMillis();
+        }
+
+        /**
+         * @see junit.framework.TestListener#addError(Test, Throwable)
+         */
+        public void addError(Test test, Throwable t) {
+            mTimingValid = false;
+        }
+
+        /**
+         * @see junit.framework.TestListener#addFailure(Test, AssertionFailedError)
+         */
+        public void addFailure(Test test, AssertionFailedError t) {
+            mTimingValid = false;
+        }
+
+        /**
+         * @see junit.framework.TestListener#endTest(Test)
+         */
+        public void endTest(Test test) {
+            float runTime;
+            String assignmentSuite;
+            mEndTime = System.currentTimeMillis();
+            mTestResult = new Bundle();
+
+            if (!mTimingValid || mStartTime < 0) {
+                assignmentSuite = "NA";
+                runTime = -1;
+            } else {
+                runTime = mEndTime - mStartTime;
+                if (runTime < SMALL_SUITE_MAX_RUNTIME
+                        && !InstrumentationTestCase.class.isAssignableFrom(test.getClass())) {
+                    assignmentSuite = SMALL_SUITE;
+                } else if (runTime < MEDIUM_SUITE_MAX_RUNTIME) {
+                    assignmentSuite = MEDIUM_SUITE;
+                } else {
+                    assignmentSuite = LARGE_SUITE;
+                }
+            }
+            // Clear mStartTime so that we can verify that it gets set next time.
+            mStartTime = -1;
+
+            mTestResult.putString(Instrumentation.REPORT_KEY_STREAMRESULT,
+                    test.getClass().getName() + "#" + ((TestCase) test).getName()
+                    + "\nin " + assignmentSuite + " suite\nrunTime: "
+                    + String.valueOf(runTime) + "\n");
+            mTestResult.putFloat(REPORT_KEY_RUN_TIME, runTime);
+            mTestResult.putString(REPORT_KEY_SUITE_ASSIGNMENT, assignmentSuite);
+
+            sendStatus(0, mTestResult);
+        }
+    }
+
+    /**
+     * This class sends status reports back to the IInstrumentationWatcher
+     */
+    private class WatcherResultPrinter implements TestListener {
+        private final Bundle mResultTemplate;
+        Bundle mTestResult;
+        int mTestNum = 0;
+        int mTestResultCode = 0;
+        String mTestClass = null;
+
+        public WatcherResultPrinter(int numTests) {
+            mResultTemplate = new Bundle();
+            mResultTemplate.putString(Instrumentation.REPORT_KEY_IDENTIFIER, REPORT_VALUE_ID);
+            mResultTemplate.putInt(REPORT_KEY_NUM_TOTAL, numTests);
+        }
+
+        /**
+         * send a status for the start of a each test, so long tests can be seen
+         * as "running"
+         */
+        public void startTest(Test test) {
+            String testClass = test.getClass().getName();
+            String testName = ((TestCase)test).getName();
+            mTestResult = new Bundle(mResultTemplate);
+            mTestResult.putString(REPORT_KEY_NAME_CLASS, testClass);
+            mTestResult.putString(REPORT_KEY_NAME_TEST, testName);
+            mTestResult.putInt(REPORT_KEY_NUM_CURRENT, ++mTestNum);
+            // pretty printing
+            if (testClass != null && !testClass.equals(mTestClass)) {
+                mTestResult.putString(Instrumentation.REPORT_KEY_STREAMRESULT,
+                        String.format("\n%s:", testClass));
+                mTestClass = testClass;
+            } else {
+                mTestResult.putString(Instrumentation.REPORT_KEY_STREAMRESULT, "");
+            }
+
+            Method testMethod = null;
+            try {
+                testMethod = test.getClass().getMethod(testName);
+                // Report total number of iterations, if test is repetitive
+                if (testMethod.isAnnotationPresent(RepetitiveTest.class)) {
+                    int numIterations = testMethod.getAnnotation(
+                        RepetitiveTest.class).numIterations();
+                    mTestResult.putInt(REPORT_KEY_NUM_ITERATIONS, numIterations);
+                }
+            } catch (NoSuchMethodException e) {
+                // ignore- the test with given name does not exist. Will be handled during test
+                // execution
+            }
+
+            // The delay_msec parameter is normally used to provide buffers of idle time
+            // for power measurement purposes. To make sure there is a delay before and after
+            // every test in a suite, we delay *after* every test (see endTest below) and also
+            // delay *before* the first test. So, delay test1 delay test2 delay.
+
+            try {
+                if (mTestNum == 1) Thread.sleep(mDelayMsec);
+            } catch (InterruptedException e) {
+                throw new IllegalStateException(e);
+            }
+
+            sendStatus(REPORT_VALUE_RESULT_START, mTestResult);
+            mTestResultCode = 0;
+        }
+
+        /**
+         * @see junit.framework.TestListener#addError(Test, Throwable)
+         */
+        public void addError(Test test, Throwable t) {
+            mTestResult.putString(REPORT_KEY_STACK, BaseTestRunner.getFilteredTrace(t));
+            mTestResultCode = REPORT_VALUE_RESULT_ERROR;
+            // pretty printing
+            mTestResult.putString(Instrumentation.REPORT_KEY_STREAMRESULT,
+                String.format("\nError in %s:\n%s",
+                    ((TestCase)test).getName(), BaseTestRunner.getFilteredTrace(t)));
+        }
+
+        /**
+         * @see junit.framework.TestListener#addFailure(Test, AssertionFailedError)
+         */
+        public void addFailure(Test test, AssertionFailedError t) {
+            mTestResult.putString(REPORT_KEY_STACK, BaseTestRunner.getFilteredTrace(t));
+            mTestResultCode = REPORT_VALUE_RESULT_FAILURE;
+            // pretty printing
+            mTestResult.putString(Instrumentation.REPORT_KEY_STREAMRESULT,
+                String.format("\nFailure in %s:\n%s",
+                    ((TestCase)test).getName(), BaseTestRunner.getFilteredTrace(t)));
+        }
+
+        /**
+         * @see junit.framework.TestListener#endTest(Test)
+         */
+        public void endTest(Test test) {
+            if (mTestResultCode == 0) {
+                mTestResult.putString(Instrumentation.REPORT_KEY_STREAMRESULT, ".");
+            }
+            sendStatus(mTestResultCode, mTestResult);
+
+            try { // Sleep after every test, if specified
+                Thread.sleep(mDelayMsec);
+            } catch (InterruptedException e) {
+                throw new IllegalStateException(e);
+            }
+        }
+
+        // TODO report the end of the cycle
+    }
+}
diff --git a/android/test/InstrumentationTestSuite.java b/android/test/InstrumentationTestSuite.java
new file mode 100644
index 0000000..a53fa26
--- /dev/null
+++ b/android/test/InstrumentationTestSuite.java
@@ -0,0 +1,80 @@
+/*
+ * 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.test;
+
+import android.app.Instrumentation;
+
+import junit.framework.TestSuite;
+import junit.framework.Test;
+import junit.framework.TestResult;
+
+/**
+ * A {@link junit.framework.TestSuite} that injects {@link android.app.Instrumentation} into
+ * {@link InstrumentationTestCase} before running them.
+ *
+ * @deprecated Use
+ * <a href="{@docRoot}reference/android/support/test/InstrumentationRegistry.html">
+ * InstrumentationRegistry</a> instead. New tests should be written using the
+ * <a href="{@docRoot}tools/testing-support-library/index.html">Android Testing Support Library</a>.
+ */
+@Deprecated
+public class InstrumentationTestSuite extends TestSuite {
+
+    private final Instrumentation mInstrumentation;
+
+    /**
+     * @param instr The instrumentation that will be injected into each
+     *   test before running it.
+     */
+    public InstrumentationTestSuite(Instrumentation instr) {
+        mInstrumentation = instr;
+    }
+
+
+    public InstrumentationTestSuite(String name, Instrumentation instr) {
+        super(name);
+        mInstrumentation = instr;
+    }
+
+    /**
+     * @param theClass Inspected for methods starting with 'test'
+     * @param instr The instrumentation to inject into each test before
+     *   running.
+     */
+    public InstrumentationTestSuite(final Class theClass, Instrumentation instr) {
+        super(theClass);
+        mInstrumentation = instr;
+    }
+
+
+    @Override
+    public void addTestSuite(Class testClass) {
+        addTest(new InstrumentationTestSuite(testClass, mInstrumentation));
+    }
+
+
+    @Override
+    public void runTest(Test test, TestResult result) {
+
+        if (test instanceof InstrumentationTestCase) {
+            ((InstrumentationTestCase) test).injectInstrumentation(mInstrumentation);
+        }
+
+        // run the test as usual
+        super.runTest(test, result);
+    }
+}
diff --git a/android/test/IsolatedContext.java b/android/test/IsolatedContext.java
new file mode 100644
index 0000000..dd4a9a3
--- /dev/null
+++ b/android/test/IsolatedContext.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2008 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.test;
+
+import android.accounts.AccountManager;
+import android.content.BroadcastReceiver;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.ContextWrapper;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.ServiceConnection;
+import android.content.pm.PackageManager;
+import android.net.Uri;
+import android.test.mock.MockAccountManager;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.Executor;
+
+
+/**
+ * A mock context which prevents its users from talking to the rest of the device while
+ * stubbing enough methods to satify code that tries to talk to other packages.
+ *
+ * @deprecated New tests should be written using the
+ * <a href="{@docRoot}tools/testing-support-library/index.html">Android Testing Support Library</a>.
+ */
+@Deprecated
+public class IsolatedContext extends ContextWrapper {
+
+    private ContentResolver mResolver;
+    private final AccountManager mMockAccountManager;
+
+    private List<Intent> mBroadcastIntents = new ArrayList<>();
+
+    public IsolatedContext(
+            ContentResolver resolver, Context targetContext) {
+        super(targetContext);
+        mResolver = resolver;
+        mMockAccountManager = MockAccountManager.newMockAccountManager(IsolatedContext.this);
+    }
+
+    /** Returns the list of intents that were broadcast since the last call to this method. */
+    public List<Intent> getAndClearBroadcastIntents() {
+        List<Intent> intents = mBroadcastIntents;
+        mBroadcastIntents = new ArrayList<>();
+        return intents;
+    }
+
+    @Override
+    public ContentResolver getContentResolver() {
+        // We need to return the real resolver so that MailEngine.makeRight can get to the
+        // subscribed feeds provider. TODO: mock out subscribed feeds too.
+        return mResolver;
+    }
+
+    @Override
+    public boolean bindService(Intent service, ServiceConnection conn, int flags) {
+        return false;
+    }
+
+    @Override
+    public boolean bindService(Intent service, int flags, Executor executor,
+            ServiceConnection conn) {
+        return false;
+    }
+
+    @Override
+    public boolean bindIsolatedService(Intent service, int flags, String instanceName,
+            Executor executor, ServiceConnection conn) {
+        return false;
+    }
+
+    @Override
+    public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
+        return null;
+    }
+
+    @Override
+    public void unregisterReceiver(BroadcastReceiver receiver) {
+        // Ignore
+    }
+
+    @Override
+    public void sendBroadcast(Intent intent) {
+        mBroadcastIntents.add(intent);
+    }
+
+    @Override
+    public void sendOrderedBroadcast(Intent intent, String receiverPermission) {
+        mBroadcastIntents.add(intent);
+    }
+
+    @Override
+    public int checkUriPermission(
+            Uri uri, String readPermission, String writePermission, int pid,
+            int uid, int modeFlags) {
+        return PackageManager.PERMISSION_GRANTED;
+    }
+
+    @Override
+    public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
+        return PackageManager.PERMISSION_GRANTED;
+    }
+
+    @Override
+    public Object getSystemService(String name) {
+        if (Context.ACCOUNT_SERVICE.equals(name)) {
+            return mMockAccountManager;
+        }
+        // No other services exist in this context.
+        return null;
+    }
+
+    @Override
+    public File getFilesDir() {
+        return new File("/dev/null");
+    }
+}
diff --git a/android/test/LaunchPerformanceBase.java b/android/test/LaunchPerformanceBase.java
new file mode 100644
index 0000000..62c90d6
--- /dev/null
+++ b/android/test/LaunchPerformanceBase.java
@@ -0,0 +1,53 @@
+/*
+ * 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.test;
+
+import android.app.Instrumentation;
+import android.content.Intent;
+import android.os.Bundle;
+
+
+/**
+ * Base class for all launch performance Instrumentation classes.
+ *
+ * @hide
+ */
+@Deprecated
+public class LaunchPerformanceBase extends Instrumentation {
+
+    public static final String LOG_TAG = "Launch Performance";
+
+    protected Bundle mResults;
+    protected Intent mIntent;
+
+    public LaunchPerformanceBase() {
+        mResults = new Bundle();
+        mIntent = new Intent(Intent.ACTION_MAIN);
+        mIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        setAutomaticPerformanceSnapshots();
+    }
+
+    /**
+     * Launches intent, and waits for idle before returning.
+     *
+     * @hide
+     */
+    protected void LaunchApp() {
+        startActivitySync(mIntent);
+        waitForIdleSync();
+    }
+}
diff --git a/android/test/LoaderTestCase.java b/android/test/LoaderTestCase.java
new file mode 100644
index 0000000..c8564c2
--- /dev/null
+++ b/android/test/LoaderTestCase.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2010 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.test;
+
+import android.content.Loader;
+import android.content.Loader.OnLoadCompleteListener;
+import android.os.AsyncTask;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+
+import java.util.concurrent.ArrayBlockingQueue;
+
+/**
+ * A convenience class for testing {@link Loader}s. This test case
+ * provides a simple way to synchronously get the result from a Loader making
+ * it easy to assert that the Loader returns the expected result.
+ */
+public class LoaderTestCase extends AndroidTestCase {
+    static {
+        // Force class loading of AsyncTask on the main thread so that it's handlers are tied to
+        // the main thread and responses from the worker thread get delivered on the main thread.
+        // The tests are run on another thread, allowing them to block waiting on a response from
+        // the code running on the main thread. The main thread can't block since the AysncTask
+        // results come in via the event loop.
+        new AsyncTask<Void, Void, Void>() {
+            @Override
+            protected Void doInBackground(Void... args) {return null;}
+            @Override
+            protected void onPostExecute(Void result) {}
+        };
+    }
+
+    /**
+     * Runs a Loader synchronously and returns the result of the load. The loader will
+     * be started, stopped, and destroyed by this method so it cannot be reused.
+     *
+     * @param loader The loader to run synchronously
+     * @return The result from the loader
+     */
+    public <T> T getLoaderResultSynchronously(final Loader<T> loader) {
+        // The test thread blocks on this queue until the loader puts it's result in
+        final ArrayBlockingQueue<T> queue = new ArrayBlockingQueue<T>(1);
+
+        // This callback runs on the "main" thread and unblocks the test thread
+        // when it puts the result into the blocking queue
+        final OnLoadCompleteListener<T> listener = new OnLoadCompleteListener<T>() {
+            @Override
+            public void onLoadComplete(Loader<T> completedLoader, T data) {
+                // Shut the loader down
+                completedLoader.unregisterListener(this);
+                completedLoader.stopLoading();
+                completedLoader.reset();
+
+                // Store the result, unblocking the test thread
+                queue.add(data);
+            }
+        };
+
+        // This handler runs on the "main" thread of the process since AsyncTask
+        // is documented as needing to run on the main thread and many Loaders use
+        // AsyncTask
+        final Handler mainThreadHandler = new Handler(Looper.getMainLooper()) {
+            @Override
+            public void handleMessage(Message msg) {
+                loader.registerListener(0, listener);
+                loader.startLoading();
+            }
+        };
+
+        // Ask the main thread to start the loading process
+        mainThreadHandler.sendEmptyMessage(0);
+
+        // Block on the queue waiting for the result of the load to be inserted
+        T result;
+        while (true) {
+            try {
+                result = queue.take();
+                break;
+            } catch (InterruptedException e) {
+                throw new RuntimeException("waiting thread interrupted", e);
+            }
+        }
+
+        return result;
+    }
+}
diff --git a/android/test/MoreAsserts.java b/android/test/MoreAsserts.java
new file mode 100644
index 0000000..d33911a
--- /dev/null
+++ b/android/test/MoreAsserts.java
@@ -0,0 +1,585 @@
+/*
+ * 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.test;
+
+import junit.framework.Assert;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.ArrayList;
+import java.util.regex.MatchResult;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Contains additional assertion methods not found in JUnit.
+ * @deprecated Use
+ * <a href="https://github.com/hamcrest">Hamcrest matchers</a> instead.
+ */
+@Deprecated
+public final class MoreAsserts {
+
+    private MoreAsserts() { }
+
+    /**
+     * Asserts that the class  {@code expected} is assignable from the object
+     * {@code actual}. This verifies {@code expected} is a parent class or a
+     * interface that {@code actual} implements.
+     */
+    public static void assertAssignableFrom(Class<?> expected, Object actual) {
+        assertAssignableFrom(expected, actual.getClass());
+    }
+
+    /**
+     * Asserts that class {@code expected} is assignable from the class
+     * {@code actual}. This verifies {@code expected} is a parent class or a
+     * interface that {@code actual} implements.
+     */
+    public static void assertAssignableFrom(Class<?> expected, Class<?> actual) {
+        Assert.assertTrue(
+                "Expected " + expected.getCanonicalName() +
+                        " to be assignable from actual class " + actual.getCanonicalName(),
+                expected.isAssignableFrom(actual));
+    }
+
+    /**
+     * Asserts that {@code actual} is not equal {@code unexpected}, according
+     * to both {@code ==} and {@link Object#equals}.
+     */
+    public static void assertNotEqual(
+            String message, Object unexpected, Object actual) {
+        if (equal(unexpected, actual)) {
+            failEqual(message, unexpected);
+        }
+    }
+
+    /**
+     * Variant of {@link #assertNotEqual(String,Object,Object)} using a
+     * generic message.
+     */
+    public static void assertNotEqual(Object unexpected, Object actual) {
+        assertNotEqual(null, unexpected, actual);
+    }
+
+    /**
+     * Asserts that array {@code actual} is the same size and every element equals
+     * those in array {@code expected}. On failure, message indicates specific
+     * element mismatch.
+     */
+    public static void assertEquals(
+            String message, byte[] expected, byte[] actual) {
+        if (expected.length != actual.length) {
+            failWrongLength(message, expected.length, actual.length);
+        }
+        for (int i = 0; i < expected.length; i++) {
+            if (expected[i] != actual[i]) {
+                failWrongElement(message, i, expected[i], actual[i]);
+            }
+        }
+    }
+
+    /**
+     * Asserts that array {@code actual} is the same size and every element equals
+     * those in array {@code expected}. On failure, message indicates specific
+     * element mismatch.
+     */
+    public static void assertEquals(byte[] expected, byte[] actual) {
+        assertEquals(null, expected, actual);
+    }
+
+    /**
+     * Asserts that array {@code actual} is the same size and every element equals
+     * those in array {@code expected}. On failure, message indicates first
+     * specific element mismatch.
+     */
+    public static void assertEquals(
+            String message, int[] expected, int[] actual) {
+        if (expected.length != actual.length) {
+            failWrongLength(message, expected.length, actual.length);
+        }
+        for (int i = 0; i < expected.length; i++) {
+            if (expected[i] != actual[i]) {
+                failWrongElement(message, i, expected[i], actual[i]);
+            }
+        }
+    }
+
+    /**
+     * Asserts that array {@code actual} is the same size and every element equals
+     * those in array {@code expected}. On failure, message indicates first
+     * specific element mismatch.
+     */
+    public static void assertEquals(int[] expected, int[] actual) {
+        assertEquals(null, expected, actual);
+    }
+
+    /**
+     * @hide Asserts that array {@code actual} is the same size and every element equals
+     * those in array {@code expected}. On failure, message indicates first
+     * specific element mismatch.
+     */
+    public static void assertEquals(
+            String message, long[] expected, long[] actual) {
+        if (expected.length != actual.length) {
+            failWrongLength(message, expected.length, actual.length);
+        }
+        for (int i = 0; i < expected.length; i++) {
+            if (expected[i] != actual[i]) {
+                failWrongElement(message, i, expected[i], actual[i]);
+            }
+        }
+    }
+
+    /**
+     * @hide Asserts that array {@code actual} is the same size and every element equals
+     * those in array {@code expected}. On failure, message indicates first
+     * specific element mismatch.
+     */
+    public static void assertEquals(long[] expected, long[] actual) {
+        assertEquals(null, expected, actual);
+    }
+
+
+    /**
+     * Asserts that array {@code actual} is the same size and every element equals
+     * those in array {@code expected}. On failure, message indicates first
+     * specific element mismatch.
+     */
+    public static void assertEquals(
+            String message, double[] expected, double[] actual) {
+        if (expected.length != actual.length) {
+            failWrongLength(message, expected.length, actual.length);
+        }
+        for (int i = 0; i < expected.length; i++) {
+            if (expected[i] != actual[i]) {
+                failWrongElement(message, i, expected[i], actual[i]);
+            }
+        }
+    }
+
+    /**
+     * Asserts that array {@code actual} is the same size and every element equals
+     * those in array {@code expected}. On failure, message indicates first
+     * specific element mismatch.
+     */
+    public static void assertEquals(double[] expected, double[] actual) {
+        assertEquals(null, expected, actual);
+    }
+
+    /**
+     * Asserts that array {@code actual} is the same size and every element
+     * is the same as those in array {@code expected}. Note that this uses
+     * {@code equals()} instead of {@code ==} to compare the objects.
+     * {@code null} will be considered equal to {@code null} (unlike SQL).
+     * On failure, message indicates first specific element mismatch.
+     */
+    public static void assertEquals(
+            String message, Object[] expected, Object[] actual) {
+        if (expected.length != actual.length) {
+            failWrongLength(message, expected.length, actual.length);
+        }
+        for (int i = 0; i < expected.length; i++) {
+            Object exp = expected[i];
+            Object act = actual[i];
+            // The following borrowed from java.util.equals(Object[], Object[]).
+            if (!((exp==null) ? act==null : exp.equals(act))) {
+                failWrongElement(message, i, exp, act);
+            }
+        }
+    }
+
+    /**
+     * Asserts that array {@code actual} is the same size and every element
+     * is the same as those in array {@code expected}. Note that this uses
+     * {@code ==} instead of {@code equals()} to compare the objects.
+     * On failure, message indicates first specific element mismatch.
+     */
+    public static void assertEquals(Object[] expected, Object[] actual) {
+        assertEquals(null, expected, actual);
+    }
+
+    /** Asserts that two sets contain the same elements. */
+    public static void assertEquals(
+            String message, Set<? extends Object> expected, Set<? extends Object> actual) {
+        Set<Object> onlyInExpected = new HashSet<Object>(expected);
+        onlyInExpected.removeAll(actual);
+        Set<Object> onlyInActual = new HashSet<Object>(actual);
+        onlyInActual.removeAll(expected);
+        if (onlyInExpected.size() != 0 || onlyInActual.size() != 0) {
+            Set<Object> intersection = new HashSet<Object>(expected);
+            intersection.retainAll(actual);
+            failWithMessage(
+                    message,
+                    "Sets do not match.\nOnly in expected: " + onlyInExpected
+                    + "\nOnly in actual: " + onlyInActual
+                    + "\nIntersection: " + intersection);
+        }
+    }
+
+    /** Asserts that two sets contain the same elements. */
+    public static void assertEquals(Set<? extends Object> expected, Set<? extends Object> actual) {
+        assertEquals(null, expected, actual);
+    }
+
+    /**
+     * Asserts that {@code expectedRegex} exactly matches {@code actual} and
+     * fails with {@code message} if it does not.  The MatchResult is returned
+     * in case the test needs access to any captured groups.  Note that you can
+     * also use this for a literal string, by wrapping your expected string in
+     * {@link Pattern#quote}.
+     */
+    public static MatchResult assertMatchesRegex(
+            String message, String expectedRegex, String actual) {
+        if (actual == null) {
+            failNotMatches(message, expectedRegex, actual);
+        }
+        Matcher matcher = getMatcher(expectedRegex, actual);
+        if (!matcher.matches()) {
+            failNotMatches(message, expectedRegex, actual);
+        }
+        return matcher;
+    }
+
+    /**
+     * Variant of {@link #assertMatchesRegex(String,String,String)} using a
+     * generic message.
+     */
+    public static MatchResult assertMatchesRegex(
+            String expectedRegex, String actual) {
+        return assertMatchesRegex(null, expectedRegex, actual);
+    }
+
+    /**
+     * Asserts that {@code expectedRegex} matches any substring of {@code actual}
+     * and fails with {@code message} if it does not.  The Matcher is returned in
+     * case the test needs access to any captured groups.  Note that you can also
+     * use this for a literal string, by wrapping your expected string in
+     * {@link Pattern#quote}.
+     */
+    public static MatchResult assertContainsRegex(
+            String message, String expectedRegex, String actual) {
+        if (actual == null) {
+            failNotContains(message, expectedRegex, actual);
+        }
+        Matcher matcher = getMatcher(expectedRegex, actual);
+        if (!matcher.find()) {
+            failNotContains(message, expectedRegex, actual);
+        }
+        return matcher;
+    }
+
+    /**
+     * Variant of {@link #assertContainsRegex(String,String,String)} using a
+     * generic message.
+     */
+    public static MatchResult assertContainsRegex(
+            String expectedRegex, String actual) {
+        return assertContainsRegex(null, expectedRegex, actual);
+    }
+
+    /**
+     * Asserts that {@code expectedRegex} does not exactly match {@code actual},
+     * and fails with {@code message} if it does. Note that you can also use
+     * this for a literal string, by wrapping your expected string in
+     * {@link Pattern#quote}.
+     */
+    public static void assertNotMatchesRegex(
+            String message, String expectedRegex, String actual) {
+        Matcher matcher = getMatcher(expectedRegex, actual);
+        if (matcher.matches()) {
+            failMatch(message, expectedRegex, actual);
+        }
+    }
+
+    /**
+     * Variant of {@link #assertNotMatchesRegex(String,String,String)} using a
+     * generic message.
+     */
+    public static void assertNotMatchesRegex(
+            String expectedRegex, String actual) {
+        assertNotMatchesRegex(null, expectedRegex, actual);
+    }
+
+    /**
+     * Asserts that {@code expectedRegex} does not match any substring of
+     * {@code actual}, and fails with {@code message} if it does.  Note that you
+     * can also use this for a literal string, by wrapping your expected string
+     * in {@link Pattern#quote}.
+     */
+    public static void assertNotContainsRegex(
+            String message, String expectedRegex, String actual) {
+        Matcher matcher = getMatcher(expectedRegex, actual);
+        if (matcher.find()) {
+            failContains(message, expectedRegex, actual);
+        }
+    }
+
+    /**
+     * Variant of {@link #assertNotContainsRegex(String,String,String)} using a
+     * generic message.
+     */
+    public static void assertNotContainsRegex(
+            String expectedRegex, String actual) {
+        assertNotContainsRegex(null, expectedRegex, actual);
+    }
+
+    /**
+     * Asserts that {@code actual} contains precisely the elements
+     * {@code expected}, and in the same order.
+     */
+    public static void assertContentsInOrder(
+            String message, Iterable<?> actual, Object... expected) {
+        ArrayList actualList = new ArrayList();
+        for (Object o : actual) {
+            actualList.add(o);
+        }
+        Assert.assertEquals(message, Arrays.asList(expected), actualList);
+    }
+
+    /**
+     * Variant of assertContentsInOrder(String, Iterable<?>, Object...)
+     * using a generic message.
+     */
+    public static void assertContentsInOrder(
+            Iterable<?> actual, Object... expected) {
+        assertContentsInOrder((String) null, actual, expected);
+    }
+
+    /**
+     * Asserts that {@code actual} contains precisely the elements
+     * {@code expected}, but in any order.
+     */
+    public static void assertContentsInAnyOrder(String message, Iterable<?> actual,
+            Object... expected) {
+        HashMap<Object, Object> expectedMap = new HashMap<Object, Object>(expected.length);
+        for (Object expectedObj : expected) {
+            expectedMap.put(expectedObj, expectedObj);
+        }
+
+        for (Object actualObj : actual) {
+            if (expectedMap.remove(actualObj) == null) {
+                failWithMessage(message, "Extra object in actual: (" + actualObj.toString() + ")");
+            }
+        }
+
+        if (expectedMap.size() > 0) {
+            failWithMessage(message, "Extra objects in expected.");
+        }
+    }
+
+    /**
+     * Variant of assertContentsInAnyOrder(String, Iterable<?>, Object...)
+     * using a generic message.
+     */
+    public static void assertContentsInAnyOrder(Iterable<?> actual, Object... expected) {
+        assertContentsInAnyOrder((String)null, actual, expected);
+    }
+
+    /**
+     * Asserts that {@code iterable} is empty.
+     */
+    public static void assertEmpty(String message, Iterable<?> iterable) {
+        if (iterable.iterator().hasNext()) {
+            failNotEmpty(message, iterable.toString());
+        }
+    }
+
+    /**
+     * Variant of {@link #assertEmpty(String, Iterable)} using a
+     * generic message.
+     */
+    public static void assertEmpty(Iterable<?> iterable) {
+        assertEmpty(null, iterable);
+    }
+
+    /**
+     * Asserts that {@code map} is empty.
+     */
+    public static void assertEmpty(String message, Map<?,?> map) {
+        if (!map.isEmpty()) {
+            failNotEmpty(message, map.toString());
+        }
+    }
+
+    /**
+     * Variant of {@link #assertEmpty(String, Map)} using a generic
+     * message.
+     */
+    public  static void assertEmpty(Map<?,?> map) {
+        assertEmpty(null, map);
+    }
+
+    /**
+     * Asserts that {@code iterable} is not empty.
+     */
+    public static void assertNotEmpty(String message, Iterable<?> iterable) {
+        if (!iterable.iterator().hasNext()) {
+            failEmpty(message);
+        }
+    }
+
+    /**
+     * Variant of assertNotEmpty(String, Iterable<?>)
+     * using a generic message.
+     */
+    public static void assertNotEmpty(Iterable<?> iterable) {
+        assertNotEmpty(null, iterable);
+    }
+
+    /**
+     * Asserts that {@code map} is not empty.
+     */
+    public static void assertNotEmpty(String message, Map<?,?> map) {
+        if (map.isEmpty()) {
+            failEmpty(message);
+        }
+    }
+
+    /**
+     * Variant of {@link #assertNotEmpty(String, Map)} using a generic
+     * message.
+     */
+    public static void assertNotEmpty(Map<?,?> map) {
+        assertNotEmpty(null, map);
+    }
+
+    /**
+     * Utility for testing equals() and hashCode() results at once.
+     * Tests that lhs.equals(rhs) matches expectedResult, as well as
+     * rhs.equals(lhs).  Also tests that hashCode() return values are
+     * equal if expectedResult is true.  (hashCode() is not tested if
+     * expectedResult is false, as unequal objects can have equal hashCodes.)
+     *
+     * @param lhs An Object for which equals() and hashCode() are to be tested.
+     * @param rhs As lhs.
+     * @param expectedResult True if the objects should compare equal,
+     *   false if not.
+     */
+    public static void checkEqualsAndHashCodeMethods(
+            String message, Object lhs, Object rhs, boolean expectedResult) {
+
+        if ((lhs == null) && (rhs == null)) {
+            Assert.assertTrue(
+                    "Your check is dubious...why would you expect null != null?",
+                    expectedResult);
+            return;
+        }
+
+        if ((lhs == null) || (rhs == null)) {
+            Assert.assertFalse(
+                    "Your check is dubious...why would you expect an object "
+                            + "to be equal to null?", expectedResult);
+        }
+
+        if (lhs != null) {
+            Assert.assertEquals(message, expectedResult, lhs.equals(rhs));
+        }
+        if (rhs != null) {
+            Assert.assertEquals(message, expectedResult, rhs.equals(lhs));
+        }
+
+        if (expectedResult) {
+            String hashMessage =
+                    "hashCode() values for equal objects should be the same";
+            if (message != null) {
+                hashMessage += ": " + message;
+            }
+            Assert.assertTrue(hashMessage, lhs.hashCode() == rhs.hashCode());
+        }
+    }
+
+    /**
+     * Variant of
+     * checkEqualsAndHashCodeMethods(String,Object,Object,boolean...)}
+     * using a generic message.
+     */
+    public static void checkEqualsAndHashCodeMethods(Object lhs, Object rhs,
+            boolean expectedResult) {
+        checkEqualsAndHashCodeMethods((String) null, lhs, rhs, expectedResult);
+    }
+
+    private static Matcher getMatcher(String expectedRegex, String actual) {
+        Pattern pattern = Pattern.compile(expectedRegex);
+        return pattern.matcher(actual);
+    }
+
+    private static void failEqual(String message, Object unexpected) {
+        failWithMessage(message, "expected not to be:<" + unexpected + ">");
+    }
+
+    private static void failWrongLength(
+            String message, int expected, int actual) {
+        failWithMessage(message, "expected array length:<" + expected
+                + "> but was:<" + actual + '>');
+    }
+
+    private static void failWrongElement(
+            String message, int index, Object expected, Object actual) {
+        failWithMessage(message, "expected array element[" + index + "]:<"
+                + expected + "> but was:<" + actual + '>');
+    }
+
+    private static void failNotMatches(
+            String message, String expectedRegex, String actual) {
+        String actualDesc = (actual == null) ? "null" : ('<' + actual + '>');
+        failWithMessage(message, "expected to match regex:<" + expectedRegex
+                + "> but was:" + actualDesc);
+    }
+
+    private static void failNotContains(
+            String message, String expectedRegex, String actual) {
+        String actualDesc = (actual == null) ? "null" : ('<' + actual + '>');
+        failWithMessage(message, "expected to contain regex:<" + expectedRegex
+                + "> but was:" + actualDesc);
+    }
+
+    private static void failMatch(
+            String message, String expectedRegex, String actual) {
+        failWithMessage(message, "expected not to match regex:<" + expectedRegex
+                + "> but was:<" + actual + '>');
+    }
+
+    private static void failContains(
+            String message, String expectedRegex, String actual) {
+        failWithMessage(message, "expected not to contain regex:<" + expectedRegex
+                + "> but was:<" + actual + '>');
+    }
+
+    private static void failNotEmpty(
+            String message, String actual) {
+        failWithMessage(message, "expected to be empty, but contained: <"
+                + actual + ">");
+    }
+
+    private static void failEmpty(String message) {
+        failWithMessage(message, "expected not to be empty, but was");
+    }
+
+    private static void failWithMessage(String userMessage, String ourMessage) {
+        Assert.fail((userMessage == null)
+                ? ourMessage
+                : userMessage + ' ' + ourMessage);
+    }
+
+    private static boolean equal(Object a, Object b) {
+        return a == b || (a != null && a.equals(b));
+    }
+
+}
diff --git a/android/test/NoExecTestResult.java b/android/test/NoExecTestResult.java
new file mode 100644
index 0000000..a01b6aa
--- /dev/null
+++ b/android/test/NoExecTestResult.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2008 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.test;
+
+import junit.framework.TestCase;
+import junit.framework.TestResult;
+
+/**
+ * A benign test result that does no actually test execution, just runs
+ * through the motions
+ *
+ * {@hide} Not needed for SDK.
+ */
+@Deprecated
+class NoExecTestResult extends TestResult {
+
+    /**
+     * Override parent to just inform listeners of test,
+     * and skip test execution.
+     */
+    @Override
+    protected void run(final TestCase test) {
+        startTest(test);
+        endTest(test);
+    }
+
+}
diff --git a/android/test/PerformanceTestCase.java b/android/test/PerformanceTestCase.java
new file mode 100644
index 0000000..2584da2
--- /dev/null
+++ b/android/test/PerformanceTestCase.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2006 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.test;
+
+/**
+ * More complex interface performance for test cases.
+ *
+ * If you want your test to be used as a performance test, you must
+ * implement this interface.
+ *
+ * @deprecated Use
+ * <a href="{@docRoot}reference/android/support/test/runner/AndroidJUnitRunner.html">
+ * AndroidJUnitRunner</a> instead. New tests should be written using the
+ * <a href="{@docRoot}tools/testing-support-library/index.html">Android Testing Support Library</a>.
+ */
+@Deprecated
+public interface PerformanceTestCase
+{
+    /**
+     * Callbacks for {@link PerformanceTestCase}.
+     */
+    public interface Intermediates
+    {
+        void setInternalIterations(int count);
+        void startTiming(boolean realTime);
+        void addIntermediate(String name);
+        void addIntermediate(String name, long timeInNS);
+        void finishTiming(boolean realTime);
+    }
+
+    /**
+     * Set up to begin performance tests. The 'intermediates' is a
+     * communication channel to send back intermediate performance numbers --
+     * if you use it, you will probably want to ensure your test is only
+     * executed once by returning 1.  Otherwise, return 0 to allow the test
+     * harness to decide the number of iterations.
+     *
+     * <p>If you return a non-zero iteration count, you should call
+     * {@link Intermediates#startTiming intermediates.startTiming} and
+     * {@link Intermediates#finishTiming intermediates.endTiming} to report the
+     * duration of the test whose performance should actually be measured.
+     *
+     * @param intermediates Callback for sending intermediate results.
+     *
+     * @return int Maximum number of iterations to run, or 0 to let the caller
+     * decide.
+     */
+    int startPerformance(Intermediates intermediates);
+
+    /**
+     * This method is used to determine what modes this test case can run in.
+     *
+     * @return true if this test case can only be run in performance mode.
+     */
+    boolean isPerformanceOnly();
+}
+
diff --git a/android/test/ProviderTestCase.java b/android/test/ProviderTestCase.java
new file mode 100644
index 0000000..4108f34
--- /dev/null
+++ b/android/test/ProviderTestCase.java
@@ -0,0 +1,114 @@
+/*
+ * 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.test;
+
+import android.content.ContentProvider;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.test.mock.MockContext;
+import android.test.mock.MockContentResolver;
+import android.database.DatabaseUtils;
+
+/**
+ * If you would like to test a single content provider with an
+ * {@link InstrumentationTestCase}, this provides some of the boiler plate in {@link #setUp} and
+ * {@link #tearDown}.
+ *
+ * @deprecated this class extends InstrumentationTestCase but should extend AndroidTestCase. Use
+ * ProviderTestCase2, which corrects this problem, instead.
+ */
+@Deprecated
+public abstract class ProviderTestCase<T extends ContentProvider>
+       extends InstrumentationTestCase {
+
+    Class<T> mProviderClass;
+    String mProviderAuthority;
+
+    private IsolatedContext mProviderContext;
+    private MockContentResolver mResolver;
+
+    public ProviderTestCase(Class<T> providerClass, String providerAuthority) {
+        mProviderClass = providerClass;
+        mProviderAuthority = providerAuthority;
+    }
+
+    /**
+     * The content provider that will be set up for use in each test method.
+     */
+    private T mProvider;
+
+    public T getProvider() {
+        return mProvider;
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        mResolver = new MockContentResolver();
+        final String filenamePrefix = "test.";
+        RenamingDelegatingContext targetContextWrapper = new RenamingDelegatingContext(
+                new MockContext(), // The context that most methods are delegated to
+                getInstrumentation().getTargetContext(), // The context that file methods are delegated to
+                filenamePrefix);
+        mProviderContext = new IsolatedContext(mResolver, targetContextWrapper);
+
+        mProvider = ProviderTestCase2.createProviderForTest(
+                mProviderContext, mProviderClass, mProviderAuthority);
+        mResolver.addProvider(mProviderAuthority, getProvider());
+    }
+
+    /**
+     * Tears down the environment for the test fixture.
+     * <p>
+     * Calls {@link android.content.ContentProvider#shutdown()} on the
+     * {@link android.content.ContentProvider} represented by mProvider.
+     */
+    @Override
+    protected void tearDown() throws Exception {
+        mProvider.shutdown();
+        super.tearDown();
+    }
+
+    public MockContentResolver getMockContentResolver() {
+        return mResolver;
+    }
+
+    public IsolatedContext getMockContext() {
+        return mProviderContext;
+    }
+
+    public static <T extends ContentProvider> ContentResolver newResolverWithContentProviderFromSql(
+            Context targetContext, Class<T> providerClass, String authority,
+            String databaseName, int databaseVersion, String sql)
+            throws IllegalAccessException, InstantiationException {
+        final String filenamePrefix = "test.";
+        MockContentResolver resolver = new MockContentResolver();
+        RenamingDelegatingContext targetContextWrapper = new RenamingDelegatingContext(
+                new MockContext(), // The context that most methods are delegated to
+                targetContext, // The context that file methods are delegated to
+                filenamePrefix);
+        Context context = new IsolatedContext(
+                resolver, targetContextWrapper);
+        DatabaseUtils.createDbFromSqlStatements(context, databaseName, databaseVersion, sql);
+
+        T provider = ProviderTestCase2.createProviderForTest(context, providerClass, authority);
+        resolver.addProvider(authority, provider);
+
+        return resolver;
+    }
+}
diff --git a/android/test/ProviderTestCase2.java b/android/test/ProviderTestCase2.java
new file mode 100644
index 0000000..be18b53
--- /dev/null
+++ b/android/test/ProviderTestCase2.java
@@ -0,0 +1,238 @@
+/*
+ * 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.test;
+
+import android.content.ContentProvider;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.pm.ProviderInfo;
+import android.content.res.Resources;
+import android.test.mock.MockContentProvider;
+import android.test.mock.MockContext;
+import android.test.mock.MockContentResolver;
+import android.database.DatabaseUtils;
+
+import java.io.File;
+
+/**
+ * This test case class provides a framework for testing a single
+ * {@link ContentProvider} and for testing your app code with an
+ * isolated content provider. Instead of using the system map of
+ * providers that is based on the manifests of other applications, the test
+ * case creates its own internal map. It then uses this map to resolve providers
+ * given an authority. This allows you to inject test providers and to null out
+ * providers that you do not want to use.
+ * <p>
+ *      This test case also sets up the following mock objects:
+ * </p>
+ * <ul>
+ *      <li>
+ *          An {@link android.test.IsolatedContext} that stubs out Context methods that might
+ *          affect the rest of the running system, while allowing tests to do real file and
+ *          database work.
+ *      </li>
+ *      <li>
+ *          A {@link android.test.mock.MockContentResolver} that provides the functionality of a
+ *          regular content resolver, but uses {@link IsolatedContext}. It stubs out
+ *          {@link ContentResolver#notifyChange(Uri, ContentObserver, boolean)} to
+ *          prevent the test from affecting the running system.
+ *      </li>
+ *      <li>
+ *          An instance of the provider under test, running in an {@link IsolatedContext}.
+ *      </li>
+ * </ul>
+ * <p>
+ *      This framework is set up automatically by the base class' {@link #setUp()} method. If you
+ *      override this method, you must call the super method as the first statement in
+ *      your override.
+ * </p>
+ * <p>
+ *     In order for their tests to be run, concrete subclasses must provide their own
+ *     constructor with no arguments. This constructor must call
+ *     {@link #ProviderTestCase2(Class, String)} as  its first operation.
+ * </p>
+ * For more information on content provider testing, please see
+ * <a href="{@docRoot}tools/testing/contentprovider_testing.html">Content Provider Testing</a>.
+ */
+public abstract class ProviderTestCase2<T extends ContentProvider> extends AndroidTestCase {
+
+    Class<T> mProviderClass;
+    String mProviderAuthority;
+
+    private IsolatedContext mProviderContext;
+    private MockContentResolver mResolver;
+
+    private class MockContext2 extends MockContext {
+
+        @Override
+        public Resources getResources() {
+            return getContext().getResources();
+        }
+
+        @Override
+        public File getDir(String name, int mode) {
+            // name the directory so the directory will be separated from
+            // one created through the regular Context
+            return getContext().getDir("mockcontext2_" + name, mode);
+        }
+
+        @Override
+        public Context getApplicationContext() {
+            return this;
+        }
+    }
+    /**
+     * Constructor.
+     *
+     * @param providerClass The class name of the provider under test
+     * @param providerAuthority The provider's authority string
+     */
+    public ProviderTestCase2(Class<T> providerClass, String providerAuthority) {
+        mProviderClass = providerClass;
+        mProviderAuthority = providerAuthority;
+    }
+
+    private T mProvider;
+
+    /**
+     * Returns the content provider created by this class in the {@link #setUp()} method.
+     * @return T An instance of the provider class given as a parameter to the test case class.
+     */
+    public T getProvider() {
+        return mProvider;
+    }
+
+    /**
+     * Sets up the environment for the test fixture.
+     * <p>
+     * Creates a new
+     * {@link android.test.mock.MockContentResolver}, a new IsolatedContext
+     * that isolates the provider's file operations, and a new instance of
+     * the provider under test within the isolated environment.
+     * </p>
+     *
+     * @throws Exception
+     */
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        mResolver = new MockContentResolver();
+        final String filenamePrefix = "test.";
+        RenamingDelegatingContext targetContextWrapper = new
+                RenamingDelegatingContext(
+                new MockContext2(), // The context that most methods are
+                                    //delegated to
+                getContext(), // The context that file methods are delegated to
+                filenamePrefix);
+        mProviderContext = new IsolatedContext(mResolver, targetContextWrapper);
+        mProvider = createProviderForTest(mProviderContext, mProviderClass, mProviderAuthority);
+        mResolver.addProvider(mProviderAuthority, getProvider());
+    }
+
+    /**
+     * Creates and sets up a new instance of the provider.
+     */
+    static <T extends ContentProvider> T createProviderForTest(
+            Context context, Class<T> providerClass, String authority)
+            throws IllegalAccessException, InstantiationException {
+        T instance = providerClass.newInstance();
+        ProviderInfo providerInfo = new ProviderInfo();
+        providerInfo.authority = authority;
+        MockContentProvider.attachInfoForTesting(instance, context, providerInfo);
+        return instance;
+    }
+
+    /**
+     * Tears down the environment for the test fixture.
+     * <p>
+     * Calls {@link android.content.ContentProvider#shutdown()} on the
+     * {@link android.content.ContentProvider} represented by mProvider.
+     */
+    @Override
+    protected void tearDown() throws Exception {
+        mProvider.shutdown();
+        super.tearDown();
+    }
+
+    /**
+     * Gets the {@link MockContentResolver} created by this class during initialization. You
+     * must use the methods of this resolver to access the provider under test.
+     *
+     * @return A {@link MockContentResolver} instance.
+     */
+    public MockContentResolver getMockContentResolver() {
+        return mResolver;
+    }
+
+    /**
+     * Gets the {@link IsolatedContext} created by this class during initialization.
+     * @return The {@link IsolatedContext} instance
+     */
+    public IsolatedContext getMockContext() {
+        return mProviderContext;
+    }
+
+    /**
+     * <p>
+     *      Creates a new content provider of the same type as that passed to the test case class,
+     *      with an authority name set to the authority parameter, and using an SQLite database as
+     *      the underlying data source. The SQL statement parameter is used to create the database.
+     *      This method also creates a new {@link MockContentResolver} and adds the provider to it.
+     * </p>
+     * <p>
+     *      Both the new provider and the new resolver are put into an {@link IsolatedContext}
+     *      that uses the targetContext parameter for file operations and a {@link MockContext}
+     *      for everything else. The IsolatedContext prepends the filenamePrefix parameter to
+     *      file, database, and directory names.
+     * </p>
+     * <p>
+     *      This is a convenience method for creating a "mock" provider that can contain test data.
+     * </p>
+     *
+     * @param targetContext The context to use as the basis of the IsolatedContext
+     * @param filenamePrefix A string that is prepended to file, database, and directory names
+     * @param providerClass The type of the provider being tested
+     * @param authority The authority string to associated with the test provider
+     * @param databaseName The name assigned to the database
+     * @param databaseVersion The version assigned to the database
+     * @param sql A string containing the SQL statements that are needed to create the desired
+     * database and its tables. The format is the same as that generated by the
+     * <a href="http://www.sqlite.org/sqlite.html">sqlite3</a> tool's <code>.dump</code> command.
+     * @return ContentResolver A new {@link MockContentResolver} linked to the provider
+     *
+     * @throws IllegalAccessException
+     * @throws InstantiationException
+     */
+    public static <T extends ContentProvider> ContentResolver newResolverWithContentProviderFromSql(
+            Context targetContext, String filenamePrefix, Class<T> providerClass, String authority,
+            String databaseName, int databaseVersion, String sql)
+            throws IllegalAccessException, InstantiationException {
+        MockContentResolver resolver = new MockContentResolver();
+        RenamingDelegatingContext targetContextWrapper = new RenamingDelegatingContext(
+                new MockContext(), // The context that most methods are delegated to
+                targetContext, // The context that file methods are delegated to
+                filenamePrefix);
+        Context context = new IsolatedContext(resolver, targetContextWrapper);
+        DatabaseUtils.createDbFromSqlStatements(context, databaseName, databaseVersion, sql);
+
+        T provider = createProviderForTest(context, providerClass, authority);
+        resolver.addProvider(authority, provider);
+
+        return resolver;
+    }
+}
diff --git a/android/test/RenamingDelegatingContext.java b/android/test/RenamingDelegatingContext.java
new file mode 100644
index 0000000..10ccebc
--- /dev/null
+++ b/android/test/RenamingDelegatingContext.java
@@ -0,0 +1,257 @@
+/*
+ * 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.test;
+
+import android.content.Context;
+import android.content.ContextWrapper;
+import android.content.ContentProvider;
+import android.database.DatabaseErrorHandler;
+import android.database.sqlite.SQLiteDatabase;
+import android.test.mock.MockContentProvider;
+import android.util.Log;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.nio.file.attribute.PosixFilePermission;
+import java.nio.file.attribute.PosixFilePermissions;
+import java.util.EnumSet;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * This is a class which delegates to the given context, but performs database
+ * and file operations with a renamed database/file name (prefixes default
+ * names with a given prefix).
+ *
+ * @deprecated New tests should be written using the
+ * <a href="{@docRoot}tools/testing-support-library/index.html">Android Testing Support Library</a>.
+ */
+@Deprecated
+public class RenamingDelegatingContext extends ContextWrapper {
+
+    private Context mFileContext;
+    private String mFilePrefix = null;
+    private File mCacheDir;
+    private final Object mSync = new Object();
+
+    private Set<String> mDatabaseNames = new HashSet<>();
+    private Set<String> mFileNames = new HashSet<>();
+
+    public static <T extends ContentProvider> T providerWithRenamedContext(
+            Class<T> contentProvider, Context c, String filePrefix)
+            throws IllegalAccessException, InstantiationException {
+        return providerWithRenamedContext(contentProvider, c, filePrefix, false);
+    }
+
+    public static <T extends ContentProvider> T providerWithRenamedContext(
+            Class<T> contentProvider, Context c, String filePrefix,
+            boolean allowAccessToExistingFilesAndDbs)
+            throws IllegalAccessException, InstantiationException {
+        Class<T> mProviderClass = contentProvider;
+        T mProvider = mProviderClass.newInstance();
+        RenamingDelegatingContext mContext = new RenamingDelegatingContext(c, filePrefix);
+        if (allowAccessToExistingFilesAndDbs) {
+            mContext.makeExistingFilesAndDbsAccessible();
+        }
+        MockContentProvider.attachInfoForTesting(mProvider, mContext, null);
+        return mProvider;
+    }
+
+    /**
+     * Makes accessible all files and databases whose names match the filePrefix that was passed to
+     * the constructor. Normally only files and databases that were created through this context are
+     * accessible.
+     */
+    public void makeExistingFilesAndDbsAccessible() {
+        String[] databaseList = mFileContext.databaseList();
+        for (String diskName : databaseList) {
+            if (shouldDiskNameBeVisible(diskName)) {
+                mDatabaseNames.add(publicNameFromDiskName(diskName));
+            }
+        }
+        String[] fileList = mFileContext.fileList();
+        for (String diskName : fileList) {
+            if (shouldDiskNameBeVisible(diskName)) {
+                mFileNames.add(publicNameFromDiskName(diskName));
+            }
+        }
+    }
+
+    /**
+     * Returns if the given diskName starts with the given prefix or not.
+     * @param diskName name of the database/file.
+     */
+    boolean shouldDiskNameBeVisible(String diskName) {
+        return diskName.startsWith(mFilePrefix);
+    }
+
+    /**
+     * Returns the public name (everything following the prefix) of the given diskName.
+     * @param diskName name of the database/file.
+     */
+    String publicNameFromDiskName(String diskName) {
+        if (!shouldDiskNameBeVisible(diskName)) {
+            throw new IllegalArgumentException("disk file should not be visible: " + diskName);
+        }
+        return diskName.substring(mFilePrefix.length(), diskName.length());
+    }
+
+    /**
+     * @param context : the context that will be delegated.
+     * @param filePrefix : a prefix with which database and file names will be
+     * prefixed.
+     */
+    public RenamingDelegatingContext(Context context, String filePrefix) {
+        super(context);
+        mFileContext = context;
+        mFilePrefix = filePrefix;
+    }
+
+    /**
+     * @param context : the context that will be delegated.
+     * @param fileContext : the context that file and db methods will be delegated to
+     * @param filePrefix : a prefix with which database and file names will be
+     * prefixed.
+     */
+    public RenamingDelegatingContext(Context context, Context fileContext, String filePrefix) {
+        super(context);
+        mFileContext = fileContext;
+        mFilePrefix = filePrefix;
+    }
+
+    public String getDatabasePrefix() {
+        return mFilePrefix;
+    }
+
+    private String renamedFileName(String name) {
+        return mFilePrefix + name;
+    }
+
+    @Override
+    public SQLiteDatabase openOrCreateDatabase(String name,
+            int mode, SQLiteDatabase.CursorFactory factory) {
+        final String internalName = renamedFileName(name);
+        if (!mDatabaseNames.contains(name)) {
+            mDatabaseNames.add(name);
+            mFileContext.deleteDatabase(internalName);
+        }
+        return mFileContext.openOrCreateDatabase(internalName, mode, factory);
+    }
+
+    @Override
+    public SQLiteDatabase openOrCreateDatabase(String name,
+            int mode, SQLiteDatabase.CursorFactory factory, DatabaseErrorHandler errorHandler) {
+        final String internalName = renamedFileName(name);
+        if (!mDatabaseNames.contains(name)) {
+            mDatabaseNames.add(name);
+            mFileContext.deleteDatabase(internalName);
+        }
+        return mFileContext.openOrCreateDatabase(internalName, mode, factory, errorHandler);
+    }
+
+    @Override
+    public boolean deleteDatabase(String name) {
+        if (mDatabaseNames.contains(name)) {
+            mDatabaseNames.remove(name);
+            return mFileContext.deleteDatabase(renamedFileName(name));
+        } else {
+            return false;
+        }
+    }
+
+    @Override
+    public File getDatabasePath(String name) {
+        return mFileContext.getDatabasePath(renamedFileName(name));
+    }
+
+    @Override
+    public String[] databaseList() {
+        return mDatabaseNames.toArray(new String[]{});
+    }
+
+    @Override
+    public FileInputStream openFileInput(String name)
+            throws FileNotFoundException {
+        final String internalName = renamedFileName(name);
+        if (mFileNames.contains(name)) {
+            return mFileContext.openFileInput(internalName);
+        } else {
+            throw new FileNotFoundException(internalName);
+        }
+    }
+
+    @Override
+    public FileOutputStream openFileOutput(String name, int mode)
+            throws FileNotFoundException {
+        mFileNames.add(name);
+        return mFileContext.openFileOutput(renamedFileName(name), mode);
+    }
+
+    @Override
+    public File getFileStreamPath(String name) {
+        return mFileContext.getFileStreamPath(renamedFileName(name));
+    }
+
+    @Override
+    public boolean deleteFile(String name) {
+        if (mFileNames.contains(name)) {
+            mFileNames.remove(name);
+            return mFileContext.deleteFile(renamedFileName(name));
+        } else {
+            return false;
+        }
+    }
+
+    @Override
+    public String[] fileList() {
+        return mFileNames.toArray(new String[]{});
+    }
+
+    /**
+     * In order to support calls to getCacheDir(), we create a temp cache dir (inside the real
+     * one) and return it instead.  This code is basically getCacheDir(), except it uses the real
+     * cache dir as the parent directory and creates a test cache dir inside that.
+     */
+    @Override
+    public File getCacheDir() {
+        synchronized (mSync) {
+            if (mCacheDir == null) {
+                mCacheDir = new File(mFileContext.getCacheDir(), renamedFileName("cache"));
+            }
+            if (!mCacheDir.exists()) {
+                if(!mCacheDir.mkdirs()) {
+                    Log.w("RenamingDelegatingContext", "Unable to create cache directory");
+                    return null;
+                }
+                try {
+                    // Give the directory all possible permissions.
+                    Files.setPosixFilePermissions(mCacheDir.toPath(),
+                            EnumSet.allOf(PosixFilePermission.class));
+                } catch (IOException e) {
+                    Log.e("RenamingDelegatingContext",
+                            "Could not set permissions of test cacheDir", e);
+                }
+            }
+        }
+        return mCacheDir;
+    }
+}
diff --git a/android/test/RepetitiveTest.java b/android/test/RepetitiveTest.java
new file mode 100644
index 0000000..13e89d2
--- /dev/null
+++ b/android/test/RepetitiveTest.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2010 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.test;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * This annotation can be used on an {@link android.test.InstrumentationTestCase}'s test methods.
+ * When the annotation is present, the test method is executed the number of times specified by
+ * numIterations and defaults to 1.
+ *
+ * @deprecated New tests should be written using the
+ * <a href="{@docRoot}tools/testing-support-library/index.html">Android Testing Support Library</a>.
+ */
+@Deprecated
+@Target(ElementType.METHOD)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface RepetitiveTest {
+    /**
+     * Indicates the number of times a test case should be run.
+     *
+     * @return The total number of iterations, the default is 1.
+     */
+    int numIterations() default 1;
+}
diff --git a/android/test/ServiceTestCase.java b/android/test/ServiceTestCase.java
new file mode 100644
index 0000000..cd54955
--- /dev/null
+++ b/android/test/ServiceTestCase.java
@@ -0,0 +1,338 @@
+/*
+ * Copyright (C) 2008 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.test;
+
+import android.app.Application;
+import android.app.Service;
+import android.content.Context;
+import android.content.Intent;
+import android.os.IBinder;
+import android.test.mock.MockApplication;
+
+import android.test.mock.MockService;
+import java.util.Random;
+
+/**
+ * This test case provides a framework in which you can test Service classes in
+ * a controlled environment.  It provides basic support for the lifecycle of a
+ * Service, and hooks with which you can inject various dependencies and control
+ * the environment in which your Service is tested.
+ *
+ * <div class="special reference">
+ * <h3>Developer Guides</h3>
+ * <p>For more information about application testing, read the
+ * <a href="{@docRoot}guide/topics/testing/index.html">Testing</a> developer guide.</p>
+ * </div>
+ *
+ * <p><b>Lifecycle Support.</b>
+ * A Service is accessed with a specific sequence of
+ * calls, as described in the
+ * <a href="http://developer.android.com/guide/topics/fundamentals/services.html">Services</a>
+ * document. In order to support the lifecycle of a Service,
+ * <code>ServiceTestCase</code> enforces this protocol:
+ *
+ * <ul>
+ *      <li>
+ *          The {@link #setUp()} method is called before each test method. The base implementation
+ *          gets the system context. If you override <code>setUp()</code>, you must call
+ *          <code>super.setUp()</code> as the first statement in your override.
+ *      </li>
+ *      <li>
+ *          The test case waits to call {@link android.app.Service#onCreate()} until one of your
+ *          test methods calls {@link #startService} or {@link #bindService}.  This gives you an
+ *          opportunity to set up or adjust any additional framework or test logic before you test
+ *          the running service.
+ *      </li>
+ *      <li>
+ *          When one of your test methods calls {@link #startService ServiceTestCase.startService()}
+ *          or {@link #bindService  ServiceTestCase.bindService()}, the test case calls
+ *          {@link android.app.Service#onCreate() Service.onCreate()} and then calls either
+ *          {@link android.app.Service#startService(Intent) Service.startService(Intent)} or
+ *          {@link android.app.Service#bindService(Intent, ServiceConnection, int)
+ *          Service.bindService(Intent, ServiceConnection, int)}, as appropriate. It also stores
+ *          values needed to track and support the lifecycle.
+ *      </li>
+ *      <li>
+ *          After each test method finishes, the test case calls the {@link #tearDown} method. This
+ *          method stops and destroys the service with the appropriate calls, depending on how the
+ *          service was started. If you override <code>tearDown()</code>, your must call the
+ *          <code>super.tearDown()</code> as the last statement in your override.
+ *      </li>
+ * </ul>
+ *
+ * <p>
+ *      <strong>Dependency Injection.</strong>
+ *      A service has two inherent dependencies, its {@link android.content.Context Context} and its
+ *      associated {@link android.app.Application Application}. The ServiceTestCase framework
+ *      allows you to inject modified, mock, or isolated replacements for these dependencies, and
+ *      thus perform unit tests with controlled dependencies in an isolated environment.
+ * </p>
+ * <p>
+ *      By default, the test case is injected with a full system context and a generic
+ *      {@link android.test.mock.MockApplication MockApplication} object. You can inject
+ *      alternatives to either of these by invoking
+ *      {@link AndroidTestCase#setContext(Context) setContext()} or
+ *      {@link #setApplication setApplication()}.  You must do this <em>before</em> calling
+ *      startService() or bindService().  The test framework provides a
+ *      number of alternatives for Context, including
+ *      {@link android.test.mock.MockContext MockContext},
+ *      {@link android.test.RenamingDelegatingContext RenamingDelegatingContext},
+ *      {@link android.content.ContextWrapper ContextWrapper}, and
+ *      {@link android.test.IsolatedContext}.
+ *
+ * @deprecated Use
+ * <a href="{@docRoot}reference/android/support/test/rule/ServiceTestRule.html">
+ * ServiceTestRule</a> instead. New tests should be written using the
+ * <a href="{@docRoot}tools/testing-support-library/index.html">Android Testing Support Library</a>.
+ */
+@Deprecated
+public abstract class ServiceTestCase<T extends Service> extends AndroidTestCase {
+
+    Class<T> mServiceClass;
+
+    private Context mSystemContext;
+    private Application mApplication;
+
+    /**
+     * Constructor
+     * @param serviceClass The type of the service under test.
+     */
+    public ServiceTestCase(Class<T> serviceClass) {
+        mServiceClass = serviceClass;
+    }
+
+    private T mService;
+    private boolean mServiceAttached = false;
+    private boolean mServiceCreated = false;
+    private boolean mServiceStarted = false;
+    private boolean mServiceBound = false;
+    private Intent mServiceIntent = null;
+    private int mServiceId;
+
+    /**
+     * @return An instance of the service under test. This instance is created automatically when
+     * a test calls {@link #startService} or {@link #bindService}.
+     */
+    public T getService() {
+        return mService;
+    }
+
+    /**
+     * Gets the current system context and stores it.
+     *
+     * Extend this method to do your own test initialization. If you do so, you
+     * must call <code>super.setUp()</code> as the first statement in your override. The method is
+     * called before each test method is executed.
+     */
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        // get the real context, before the individual tests have a chance to muck with it
+        mSystemContext = getContext();
+
+    }
+
+    /**
+     * Creates the service under test and attaches all injected dependencies
+     * (Context, Application) to it.  This is called automatically by {@link #startService} or
+     * by {@link #bindService}.
+     * If you need to call {@link AndroidTestCase#setContext(Context) setContext()} or
+     * {@link #setApplication setApplication()}, do so before calling this method.
+     */
+    protected void setupService() {
+        mService = null;
+        try {
+            mService = mServiceClass.newInstance();
+        } catch (Exception e) {
+            assertNotNull(mService);
+        }
+        if (getApplication() == null) {
+            setApplication(new MockApplication());
+        }
+        MockService.attachForTesting(
+                mService, getContext(), mServiceClass.getName(), getApplication());
+
+        assertNotNull(mService);
+
+        mServiceId = new Random().nextInt();
+        mServiceAttached = true;
+    }
+
+    /**
+     * Starts the service under test, in the same way as if it were started by
+     * {@link android.content.Context#startService(Intent) Context.startService(Intent)} with
+     * an {@link android.content.Intent} that identifies a service.
+     * If you use this method to start the service, it is automatically stopped by
+     * {@link #tearDown}.
+     *
+     * @param intent An Intent that identifies a service, of the same form as the Intent passed to
+     * {@link android.content.Context#startService(Intent) Context.startService(Intent)}.
+     */
+    protected void startService(Intent intent) {
+        if (!mServiceAttached) {
+            setupService();
+        }
+        assertNotNull(mService);
+
+        if (!mServiceCreated) {
+            mService.onCreate();
+            mServiceCreated = true;
+        }
+        mService.onStartCommand(intent, 0, mServiceId);
+
+        mServiceStarted = true;
+    }
+
+    /**
+     * <p>
+     *      Starts the service under test, in the same way as if it were started by
+     *      {@link android.content.Context#bindService(Intent, ServiceConnection, int)
+     *      Context.bindService(Intent, ServiceConnection, flags)} with an
+     *      {@link android.content.Intent} that identifies a service.
+     * </p>
+     * <p>
+     *      Notice that the parameters are different. You do not provide a
+     *      {@link android.content.ServiceConnection} object or the flags parameter. Instead,
+     *      you only provide the Intent. The method returns an object whose type is a
+     *      subclass of {@link android.os.IBinder}, or null if the method fails. An IBinder
+     *      object refers to a communication channel between the application and
+     *      the service. The flag is assumed to be {@link android.content.Context#BIND_AUTO_CREATE}.
+     * </p>
+     * <p>
+     *      See <a href="{@docRoot}guide/components/aidl.html">Designing a Remote Interface
+     *      Using AIDL</a> for more information about the communication channel object returned
+     *      by this method.
+     * </p>
+     * Note:  To be able to use bindService in a test, the service must implement getService()
+     * method. An example of this is in the ApiDemos sample application, in the
+     * LocalService demo.
+     *
+     * @param intent An Intent object of the form expected by
+     * {@link android.content.Context#bindService}.
+     *
+     * @return An object whose type is a subclass of IBinder, for making further calls into
+     * the service.
+     */
+    protected IBinder bindService(Intent intent) {
+        if (!mServiceAttached) {
+            setupService();
+        }
+        assertNotNull(mService);
+
+        if (!mServiceCreated) {
+            mService.onCreate();
+            mServiceCreated = true;
+        }
+        // no extras are expected by unbind
+        mServiceIntent = intent.cloneFilter();
+        IBinder result = mService.onBind(intent);
+
+        mServiceBound = true;
+        return result;
+    }
+
+    /**
+     * Makes the necessary calls to stop (or unbind) the service under test, and
+     * calls onDestroy().  Ordinarily this is called automatically (by {@link #tearDown}, but
+     * you can call it directly from your test in order to check for proper shutdown behavior.
+     */
+    protected void shutdownService() {
+        if (mServiceStarted) {
+            mService.stopSelf();
+            mServiceStarted = false;
+        } else if (mServiceBound) {
+            mService.onUnbind(mServiceIntent);
+            mServiceBound = false;
+        }
+        if (mServiceCreated) {
+            mService.onDestroy();
+            mServiceCreated = false;
+        }
+    }
+
+    /**
+     * <p>
+     *      Shuts down the service under test.  Ensures all resources are cleaned up and
+     *      garbage collected before moving on to the next test. This method is called after each
+     *      test method.
+     * </p>
+     * <p>
+     *      Subclasses that override this method must call <code>super.tearDown()</code> as their
+     *      last statement.
+     * </p>
+     *
+     * @throws Exception
+     */
+    @Override
+    protected void tearDown() throws Exception {
+        shutdownService();
+        mService = null;
+
+        // Scrub out members - protects against memory leaks in the case where someone
+        // creates a non-static inner class (thus referencing the test case) and gives it to
+        // someone else to hold onto
+        scrubClass(ServiceTestCase.class);
+
+        super.tearDown();
+    }
+
+    /**
+     * Sets the application that is used during the test.  If you do not call this method,
+     * a new {@link android.test.mock.MockApplication MockApplication} object is used.
+     *
+     * @param application The Application object that is used by the service under test.
+     *
+     * @see #getApplication()
+     */
+    public void setApplication(Application application) {
+        mApplication = application;
+    }
+
+    /**
+     * Returns the Application object in use by the service under test.
+     *
+     * @return The application object.
+     *
+     * @see #setApplication
+     */
+    public Application getApplication() {
+        return mApplication;
+    }
+
+    /**
+     * Returns the real system context that is saved by {@link #setUp()}. Use it to create
+     * mock or other types of context objects for the service under test.
+     *
+     * @return A normal system context.
+     */
+    public Context getSystemContext() {
+        return mSystemContext;
+    }
+
+    /**
+     * Tests that {@link #setupService()} runs correctly and issues an
+     * {@link junit.framework.Assert#assertNotNull(String, Object)} if it does.
+     * You can override this test method if you wish.
+     *
+     * @throws Exception
+     */
+    public void testServiceTestCaseSetUpProperly() throws Exception {
+        setupService();
+        assertNotNull("service should be launched successfully", mService);
+    }
+}
diff --git a/android/test/SimpleCache.java b/android/test/SimpleCache.java
new file mode 100644
index 0000000..46143e4
--- /dev/null
+++ b/android/test/SimpleCache.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2008 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.test;
+
+import java.util.HashMap;
+import java.util.Map;
+
+@Deprecated
+abstract class SimpleCache<K, V> {
+    private Map<K, V> map = new HashMap<K, V>();
+
+    protected abstract V load(K key);
+
+    final V get(K key) {
+        if (map.containsKey(key)) {
+            return map.get(key);
+        }
+        V value = load(key);
+        map.put(key, value);
+        return value;
+    }
+}
diff --git a/android/test/SingleLaunchActivityTestCase.java b/android/test/SingleLaunchActivityTestCase.java
new file mode 100644
index 0000000..af1448e
--- /dev/null
+++ b/android/test/SingleLaunchActivityTestCase.java
@@ -0,0 +1,91 @@
+/*
+ * 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.test;
+
+import android.app.Activity;
+
+/**
+ * If you would like to test a single activity with an
+ * {@link android.test.InstrumentationTestCase}, this provides some of the boiler plate to
+ * launch and finish the activity in {@link #setUp} and {@link #tearDown}.
+ *
+ * This launches the activity only once for the entire class instead of doing it
+ * in every setup / teardown call.
+ *
+ * @deprecated Use
+ * <a href="{@docRoot}reference/android/support/test/rule/ActivityTestRule.html">
+ * ActivityTestRule</a> instead. New tests should be written using the
+ * <a href="{@docRoot}tools/testing-support-library/index.html">Android Testing Support Library</a>.
+ */
+@Deprecated
+public abstract class SingleLaunchActivityTestCase<T extends Activity>
+        extends InstrumentationTestCase {
+
+    String mPackage;
+    Class<T> mActivityClass;
+    private static int sTestCaseCounter = 0;
+    private static boolean sActivityLaunchedFlag = false;
+
+    /**
+     * <b>NOTE:</b> The parameter <i>pkg</i> must refer to the package identifier of the
+     * package hosting the activity to be launched, which is specified in the AndroidManifest.xml
+     * file.  This is not necessarily the same as the java package name.
+     *
+     * @param pkg The package hosting the activity to be launched.
+     * @param activityClass The activity to test.
+     */
+    public SingleLaunchActivityTestCase(String pkg, Class<T> activityClass) {
+        mPackage = pkg;
+        mActivityClass = activityClass;
+        sTestCaseCounter ++;
+    }
+
+    /**
+     * The activity that will be set up for use in each test method.
+     */
+    private static Activity sActivity;
+
+    public T getActivity() {
+        return (T) sActivity;
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        // If it is the first test case, launch the activity.
+        if (!sActivityLaunchedFlag) {
+            // by default, not in touch mode
+            getInstrumentation().setInTouchMode(false);
+            sActivity = launchActivity(mPackage, mActivityClass, null);
+            sActivityLaunchedFlag = true;
+        }
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        // If it is the last test case, call finish on the activity.
+        sTestCaseCounter --;
+        if (sTestCaseCounter == 0) {
+            sActivity.finish();
+        }
+        super.tearDown();
+    }
+
+    public void testActivityTestCaseSetUpProperly() throws Exception {
+        assertNotNull("activity should be launched successfully", sActivity);
+    }
+}
diff --git a/android/test/SyncBaseInstrumentation.java b/android/test/SyncBaseInstrumentation.java
new file mode 100644
index 0000000..de36b4f
--- /dev/null
+++ b/android/test/SyncBaseInstrumentation.java
@@ -0,0 +1,85 @@
+/*
+ * 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.test;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.os.Bundle;
+import android.os.SystemClock;
+import android.net.Uri;
+import android.accounts.Account;
+
+/**
+ * If you would like to test sync a single provider with an
+ * {@link InstrumentationTestCase}, this provides some of the boiler plate in {@link #setUp} and
+ * {@link #tearDown}.
+ *
+ * @deprecated Use
+ * <a href="{@docRoot}reference/android/support/test/InstrumentationRegistry.html">
+ * InstrumentationRegistry</a> instead. New tests should be written using the
+ * <a href="{@docRoot}tools/testing-support-library/index.html">Android Testing Support Library</a>.
+ */
+@Deprecated
+public class SyncBaseInstrumentation extends InstrumentationTestCase {
+    private Context mTargetContext;
+    ContentResolver mContentResolver;
+    private static final int MAX_TIME_FOR_SYNC_IN_MINS = 20;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mTargetContext = getInstrumentation().getTargetContext();
+        mContentResolver = mTargetContext.getContentResolver();
+    }
+
+    /**
+     * Syncs the specified provider.
+     * @throws Exception
+     */
+    protected void syncProvider(Uri uri, String accountName, String authority) throws Exception {
+        Bundle extras = new Bundle();
+        extras.putBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_SETTINGS, true);
+        Account account = new Account(accountName, "com.google");
+
+        ContentResolver.requestSync(account, authority, extras);
+        long startTimeInMillis = SystemClock.elapsedRealtime();
+        long endTimeInMillis = startTimeInMillis + MAX_TIME_FOR_SYNC_IN_MINS * 60000;
+
+        int counter = 0;
+        // Making sure race condition does not occur when en entry have been removed from pending
+        // and active tables and loaded in memory (therefore sync might be still in progress)
+        while (counter < 2) {
+            // Sleep for 1 second.
+            Thread.sleep(1000);
+            // Finish test if time to sync has exceeded max time.
+            if (SystemClock.elapsedRealtime() > endTimeInMillis) {
+                break;
+            }
+
+            if (ContentResolver.isSyncActive(account, authority)) {
+                counter = 0;
+                continue;
+            }
+            counter++;
+        }
+    }
+
+    protected void cancelSyncsandDisableAutoSync() {
+        ContentResolver.setMasterSyncAutomatically(false);
+        ContentResolver.cancelSync(null /* all accounts */, null /* all authorities */);
+    }
+}
diff --git a/android/test/TestCaseUtil.java b/android/test/TestCaseUtil.java
new file mode 100644
index 0000000..1562909
--- /dev/null
+++ b/android/test/TestCaseUtil.java
@@ -0,0 +1,131 @@
+/*
+ * 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.test;
+
+import java.util.ArrayList;
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+import junit.runner.BaseTestRunner;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * @hide - This is part of a framework that is under development and should not be used for
+ * active development.
+ */
+@Deprecated
+public class TestCaseUtil {
+
+    private TestCaseUtil() {
+    }
+
+    public static List<? extends Test> getTests(Test test, boolean flatten) {
+        return getTests(test, flatten, new HashSet<Class<?>>());
+    }
+
+    private static List<? extends Test> getTests(Test test, boolean flatten,
+            Set<Class<?>> seen) {
+        List<Test> testCases = new ArrayList<>();
+        if (test != null) {
+
+            Test workingTest = null;
+            /*
+             * If we want to run a single TestCase method only, we must not
+             * invoke the suite() method, because we will run all test methods
+             * of the class then.
+             */
+            if (test instanceof TestCase &&
+                    ((TestCase)test).getName() == null) {
+                workingTest = invokeSuiteMethodIfPossible(test.getClass(),
+                        seen);
+            }
+            if (workingTest == null) {
+                workingTest = test;
+            }
+
+            if (workingTest instanceof TestSuite) {
+                TestSuite testSuite = (TestSuite) workingTest;
+                Enumeration enumeration = testSuite.tests();
+                while (enumeration.hasMoreElements()) {
+                    Test childTest = (Test) enumeration.nextElement();
+                    if (flatten) {
+                        testCases.addAll(getTests(childTest, flatten, seen));
+                    } else {
+                        testCases.add(childTest);
+                    }
+                }
+            } else {
+                testCases.add(workingTest);
+            }
+        }
+        return testCases;
+    }
+
+    static Test invokeSuiteMethodIfPossible(Class testClass,
+            Set<Class<?>> seen) {
+        try {
+            Method suiteMethod = testClass.getMethod(
+                    BaseTestRunner.SUITE_METHODNAME, new Class[0]);
+            /*
+             * Additional check necessary: If a TestCase contains a suite()
+             * method that returns a TestSuite including the TestCase itself,
+             * we need to stop the recursion. We use a set of classes to
+             * remember which classes' suite() methods were already invoked.
+             */
+            if (Modifier.isStatic(suiteMethod.getModifiers())
+                    && !seen.contains(testClass)) {
+                seen.add(testClass);
+                try {
+                    return (Test) suiteMethod.invoke(null, (Object[]) null);
+                } catch (InvocationTargetException e) {
+                    // do nothing
+                } catch (IllegalAccessException e) {
+                    // do nothing
+                }
+            }
+        } catch (NoSuchMethodException e) {
+            // do nothing
+        }
+        return null;
+    }
+
+    static String getTestName(Test test) {
+        if (test instanceof TestCase) {
+            TestCase testCase = (TestCase) test;
+            return testCase.getName();
+        } else if (test instanceof TestSuite) {
+            TestSuite testSuite = (TestSuite) test;
+            String name = testSuite.getName();
+            if (name != null) {
+                int index = name.lastIndexOf(".");
+                if (index > -1) {
+                    return name.substring(index + 1);
+                } else {
+                    return name;
+                }
+            }
+        }
+        return "";
+    }
+}
diff --git a/android/test/TestPrinter.java b/android/test/TestPrinter.java
new file mode 100644
index 0000000..01d392d
--- /dev/null
+++ b/android/test/TestPrinter.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2006 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.test;
+
+import android.util.Log;
+import junit.framework.Test;
+import junit.framework.TestListener;
+
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Prints the test progress to stdout. Android includes a default
+ * implementation and calls these methods to print out test progress; you
+ * probably will not need to create or extend this class or call its methods manually.
+ * See the full {@link android.test} package description for information about
+ * getting test results.
+ *
+ * {@hide} Not needed for 1.0 SDK.
+ */
+@Deprecated
+class TestPrinter implements TestListener {
+
+    private String mTag;
+    private boolean mOnlyFailures;
+    private Set<String> mFailedTests = new HashSet<String>();
+
+
+    TestPrinter(String tag, boolean onlyFailures) {
+        mTag = tag;
+        mOnlyFailures = onlyFailures;
+    }
+
+    private void started(String className) {
+        if (!mOnlyFailures) {
+            Log.i(mTag, "started: " + className);
+        }
+    }
+
+    private void finished(String className) {
+        if (!mOnlyFailures) {
+            Log.i(mTag, "finished: " + className);
+        }
+    }
+
+    private void passed(String className) {
+        if (!mOnlyFailures) {
+            Log.i(mTag, "passed: " + className);
+        }
+    }
+
+    private void failed(String className, Throwable exception) {
+        Log.i(mTag, "failed: " + className);
+        Log.i(mTag, "----- begin exception -----");
+        Log.i(mTag, "", exception);
+        Log.i(mTag, "----- end exception -----");
+    }
+
+    private void failed(Test test, Throwable t) {
+        mFailedTests.add(test.toString());
+        failed(test.toString(), t);
+    }
+
+    public void addError(Test test, Throwable t) {
+        failed(test, t);
+    }
+
+    public void addFailure(Test test, junit.framework.AssertionFailedError t) {
+        failed(test, t);
+    }
+
+    public void endTest(Test test) {
+        finished(test.toString());
+        if (!mFailedTests.contains(test.toString())) {
+            passed(test.toString());
+        }
+        mFailedTests.remove(test.toString());
+    }
+
+    public void startTest(Test test) {
+        started(test.toString());
+    }
+}
diff --git a/android/test/TestSuiteProvider.java b/android/test/TestSuiteProvider.java
new file mode 100644
index 0000000..12cfcb7
--- /dev/null
+++ b/android/test/TestSuiteProvider.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2008 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.test;
+
+import junit.framework.TestSuite;
+
+/**
+ * Implementors will know how to get a test suite.
+ *
+ * @deprecated Use
+ * <a href="{@docRoot}reference/android/support/test/runner/AndroidJUnitRunner.html">
+ * AndroidJUnitRunner</a> instead. New tests should be written using the
+ * <a href="{@docRoot}tools/testing-support-library/index.html">Android Testing Support Library</a>.
+ */
+@Deprecated
+public interface TestSuiteProvider {
+
+    TestSuite getTestSuite();
+}
diff --git a/android/test/TouchUtils.java b/android/test/TouchUtils.java
new file mode 100644
index 0000000..f2f0be7
--- /dev/null
+++ b/android/test/TouchUtils.java
@@ -0,0 +1,834 @@
+/*
+ * 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.test;
+
+import android.app.Activity;
+import android.app.Instrumentation;
+import android.graphics.Point;
+import android.os.SystemClock;
+import android.view.Display;
+import android.view.Gravity;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewConfiguration;
+import android.view.ViewGroup;
+
+/**
+ * Reusable methods for generating touch events. These methods can be used with
+ * InstrumentationTestCase or ActivityInstrumentationTestCase2 to simulate user interaction with
+ * the application through a touch screen.
+ *
+ * @deprecated Use
+ * <a href="{@docRoot}training/testing/ui-testing/espresso-testing.html">Espresso UI testing
+ * framework</a> instead. New tests should be written using the
+ * <a href="{@docRoot}tools/testing-support-library/index.html">Android Testing Support Library</a>.
+ */
+@Deprecated
+public class TouchUtils {
+
+    /**
+     * Simulate touching in the center of the screen and dragging one quarter of the way down
+     * @param test The test case that is being run
+     *
+     * @deprecated {@link android.test.ActivityInstrumentationTestCase} is deprecated in favor of
+     * {@link android.test.ActivityInstrumentationTestCase2}, which provides more options for
+     * configuring the Activity under test
+     */
+    @Deprecated
+    public static void dragQuarterScreenDown(ActivityInstrumentationTestCase test) {
+        dragQuarterScreenDown(test, test.getActivity());
+    }
+
+    /**
+     * Simulate touching in the center of the screen and dragging one quarter of the way down
+     * @param test The test case that is being run
+     * @param activity The activity that is in the foreground of the test case
+     */
+    public static void dragQuarterScreenDown(InstrumentationTestCase test, Activity activity) {
+        Display display = activity.getWindowManager().getDefaultDisplay();
+        final Point size = new Point();
+        display.getSize(size);
+
+        final float x = size.x / 2.0f;
+        final float fromY = size.y * 0.5f;
+        final float toY = size.y * 0.75f;
+
+        drag(test, x, x, fromY, toY, 4);
+    }
+
+    /**
+     * Simulate touching in the center of the screen and dragging one quarter of the way up
+     * @param test The test case that is being run
+     *
+     * @deprecated {@link android.test.ActivityInstrumentationTestCase} is deprecated in favor of
+     * {@link android.test.ActivityInstrumentationTestCase2}, which provides more options for
+     * configuring the Activity under test
+     */
+    @Deprecated
+    public static void dragQuarterScreenUp(ActivityInstrumentationTestCase test) {
+        dragQuarterScreenUp(test, test.getActivity());
+    }
+
+    /**
+     * Simulate touching in the center of the screen and dragging one quarter of the way up
+     * @param test The test case that is being run
+     * @param activity The activity that is in the foreground of the test case
+     */
+    public static void dragQuarterScreenUp(InstrumentationTestCase test, Activity activity) {
+        Display display = activity.getWindowManager().getDefaultDisplay();
+        final Point size = new Point();
+        display.getSize(size);
+
+        final float x = size.x / 2.0f;
+        final float fromY = size.y * 0.5f;
+        final float toY = size.y * 0.25f;
+
+        drag(test, x, x, fromY, toY, 4);
+    }
+
+    /**
+     * Scroll a ViewGroup to the bottom by repeatedly calling
+     * {@link #dragQuarterScreenUp(InstrumentationTestCase, Activity)}
+     *
+     * @param test The test case that is being run
+     * @param v The ViewGroup that should be dragged
+     *
+     * @deprecated {@link android.test.ActivityInstrumentationTestCase} is deprecated in favor of
+     * {@link android.test.ActivityInstrumentationTestCase2}, which provides more options for
+     * configuring the Activity under test
+     */
+    @Deprecated
+    public static void scrollToBottom(ActivityInstrumentationTestCase test, ViewGroup v) {
+        scrollToBottom(test, test.getActivity(), v);
+    }
+
+    /**
+     * Scroll a ViewGroup to the bottom by repeatedly calling
+     * {@link #dragQuarterScreenUp(InstrumentationTestCase, Activity)}
+     *
+     * @param test The test case that is being run
+     * @param activity The activity that is in the foreground of the test case
+     * @param v The ViewGroup that should be dragged
+     */
+    public static void scrollToBottom(InstrumentationTestCase test, Activity activity,
+            ViewGroup v) {
+        ViewStateSnapshot prev;
+        ViewStateSnapshot next = new ViewStateSnapshot(v);
+        do {
+            prev = next;
+            TouchUtils.dragQuarterScreenUp(test, activity);
+            next = new ViewStateSnapshot(v);
+        } while (!prev.equals(next));
+    }
+
+    /**
+     * Scroll a ViewGroup to the top by repeatedly calling
+     * {@link #dragQuarterScreenDown(InstrumentationTestCase, Activity)}
+     *
+     * @param test The test case that is being run
+     * @param v The ViewGroup that should be dragged
+     *
+     * @deprecated {@link android.test.ActivityInstrumentationTestCase} is deprecated in favor of
+     * {@link android.test.ActivityInstrumentationTestCase2}, which provides more options for
+     * configuring the Activity under test
+     */
+    @Deprecated
+    public static void scrollToTop(ActivityInstrumentationTestCase test, ViewGroup v) {
+        scrollToTop(test, test.getActivity(), v);
+    }
+
+    /**
+     * Scroll a ViewGroup to the top by repeatedly calling
+     * {@link #dragQuarterScreenDown(InstrumentationTestCase, Activity)}
+     *
+     * @param test The test case that is being run
+     * @param activity The activity that is in the foreground of the test case
+     * @param v The ViewGroup that should be dragged
+     */
+    public static void scrollToTop(InstrumentationTestCase test, Activity activity, ViewGroup v) {
+        ViewStateSnapshot prev;
+        ViewStateSnapshot next = new ViewStateSnapshot(v);
+        do {
+            prev = next;
+            TouchUtils.dragQuarterScreenDown(test, activity);
+            next = new ViewStateSnapshot(v);
+        } while (!prev.equals(next));
+    }
+
+    /**
+     * Simulate touching the center of a view and dragging to the bottom of the screen.
+     *
+     * @param test The test case that is being run
+     * @param v The view that should be dragged
+     *
+     * @deprecated {@link android.test.ActivityInstrumentationTestCase} is deprecated in favor of
+     * {@link android.test.ActivityInstrumentationTestCase2}, which provides more options for
+     * configuring the Activity under test
+     */
+    @Deprecated
+    public static void dragViewToBottom(ActivityInstrumentationTestCase test, View v) {
+        dragViewToBottom(test, test.getActivity(), v, 4);
+    }
+
+    /**
+     * Simulate touching the center of a view and dragging to the bottom of the screen.
+     *
+     * @param test The test case that is being run
+     * @param activity The activity that is in the foreground of the test case
+     * @param v The view that should be dragged
+     */
+    public static void dragViewToBottom(InstrumentationTestCase test, Activity activity, View v) {
+        dragViewToBottom(test, activity, v, 4);
+    }
+
+    /**
+     * Simulate touching the center of a view and dragging to the bottom of the screen.
+     *
+     * @param test The test case that is being run
+     * @param v The view that should be dragged
+     * @param stepCount How many move steps to include in the drag
+     *
+     * @deprecated {@link android.test.ActivityInstrumentationTestCase} is deprecated in favor of
+     * {@link android.test.ActivityInstrumentationTestCase2}, which provides more options for
+     * configuring the Activity under test
+     */
+    @Deprecated
+    public static void dragViewToBottom(ActivityInstrumentationTestCase test, View v,
+            int stepCount) {
+        dragViewToBottom(test, test.getActivity(), v, stepCount);
+    }
+
+    /**
+     * Simulate touching the center of a view and dragging to the bottom of the screen.
+     *
+     * @param test The test case that is being run
+     * @param activity The activity that is in the foreground of the test case
+     * @param v The view that should be dragged
+     * @param stepCount How many move steps to include in the drag
+     */
+    public static void dragViewToBottom(InstrumentationTestCase test, Activity activity, View v,
+            int stepCount) {
+        int screenHeight =
+                activity.getWindowManager().getCurrentWindowMetrics().getBounds().height();
+
+        int[] xy = new int[2];
+        v.getLocationOnScreen(xy);
+
+        final int viewWidth = v.getWidth();
+        final int viewHeight = v.getHeight();
+
+        final float x = xy[0] + (viewWidth / 2.0f);
+        float fromY = xy[1] + (viewHeight / 2.0f);
+        float toY = screenHeight - 1;
+
+        drag(test, x, x, fromY, toY, stepCount);
+    }
+
+    /**
+     * Simulate touching the center of a view and releasing quickly (before the tap timeout).
+     *
+     * @param test The test case that is being run
+     * @param v The view that should be clicked
+     */
+    public static void tapView(InstrumentationTestCase test, View v) {
+        int[] xy = new int[2];
+        v.getLocationOnScreen(xy);
+
+        final int viewWidth = v.getWidth();
+        final int viewHeight = v.getHeight();
+
+        final float x = xy[0] + (viewWidth / 2.0f);
+        float y = xy[1] + (viewHeight / 2.0f);
+
+        Instrumentation inst = test.getInstrumentation();
+
+        long downTime = SystemClock.uptimeMillis();
+        long eventTime = SystemClock.uptimeMillis();
+
+        MotionEvent event = MotionEvent.obtain(downTime, eventTime,
+                MotionEvent.ACTION_DOWN, x, y, 0);
+        inst.sendPointerSync(event);
+        inst.waitForIdleSync();
+
+        eventTime = SystemClock.uptimeMillis();
+        final int touchSlop = ViewConfiguration.get(v.getContext()).getScaledTouchSlop();
+        event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_MOVE,
+                x + (touchSlop / 2.0f), y + (touchSlop / 2.0f), 0);
+        inst.sendPointerSync(event);
+        inst.waitForIdleSync();
+
+        eventTime = SystemClock.uptimeMillis();
+        event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_UP, x, y, 0);
+        inst.sendPointerSync(event);
+        inst.waitForIdleSync();
+    }
+
+    /**
+     * Simulate touching the center of a view and cancelling (so no onClick should
+     * fire, etc).
+     *
+     * @param test The test case that is being run
+     * @param v The view that should be clicked
+     */
+    public static void touchAndCancelView(InstrumentationTestCase test, View v) {
+        int[] xy = new int[2];
+        v.getLocationOnScreen(xy);
+
+        final int viewWidth = v.getWidth();
+        final int viewHeight = v.getHeight();
+
+        final float x = xy[0] + (viewWidth / 2.0f);
+        float y = xy[1] + (viewHeight / 2.0f);
+
+        Instrumentation inst = test.getInstrumentation();
+
+        long downTime = SystemClock.uptimeMillis();
+        long eventTime = SystemClock.uptimeMillis();
+
+        MotionEvent event = MotionEvent.obtain(downTime, eventTime,
+                MotionEvent.ACTION_DOWN, x, y, 0);
+        inst.sendPointerSync(event);
+        inst.waitForIdleSync();
+
+        eventTime = SystemClock.uptimeMillis();
+        final int touchSlop = ViewConfiguration.get(v.getContext()).getScaledTouchSlop();
+        event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_CANCEL,
+                x + (touchSlop / 2.0f), y + (touchSlop / 2.0f), 0);
+        inst.sendPointerSync(event);
+        inst.waitForIdleSync();
+
+    }
+
+    /**
+     * Simulate touching the center of a view and releasing.
+     *
+     * @param test The test case that is being run
+     * @param v The view that should be clicked
+     */
+    public static void clickView(InstrumentationTestCase test, View v) {
+        int[] xy = new int[2];
+        v.getLocationOnScreen(xy);
+
+        final int viewWidth = v.getWidth();
+        final int viewHeight = v.getHeight();
+
+        final float x = xy[0] + (viewWidth / 2.0f);
+        float y = xy[1] + (viewHeight / 2.0f);
+
+        Instrumentation inst = test.getInstrumentation();
+
+        long downTime = SystemClock.uptimeMillis();
+        long eventTime = SystemClock.uptimeMillis();
+
+        MotionEvent event = MotionEvent.obtain(downTime, eventTime,
+                MotionEvent.ACTION_DOWN, x, y, 0);
+        inst.sendPointerSync(event);
+        inst.waitForIdleSync();
+
+
+        eventTime = SystemClock.uptimeMillis();
+        final int touchSlop = ViewConfiguration.get(v.getContext()).getScaledTouchSlop();
+        event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_MOVE,
+                x + (touchSlop / 2.0f), y + (touchSlop / 2.0f), 0);
+        inst.sendPointerSync(event);
+        inst.waitForIdleSync();
+
+        eventTime = SystemClock.uptimeMillis();
+        event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_UP, x, y, 0);
+        inst.sendPointerSync(event);
+        inst.waitForIdleSync();
+
+        try {
+            Thread.sleep(1000);
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * Simulate touching the center of a view, holding until it is a long press, and then releasing.
+     *
+     * @param test The test case that is being run
+     * @param v The view that should be clicked
+     *
+     * @deprecated {@link android.test.ActivityInstrumentationTestCase} is deprecated in favor of
+     * {@link android.test.ActivityInstrumentationTestCase2}, which provides more options for
+     * configuring the Activity under test
+     */
+    @Deprecated
+    public static void longClickView(ActivityInstrumentationTestCase test, View v) {
+        longClickView((InstrumentationTestCase) test, v);
+    }
+
+    /**
+     * Simulate touching the center of a view, holding until it is a long press, and then releasing.
+     *
+     * @param test The test case that is being run
+     * @param v The view that should be clicked
+     */
+    public static void longClickView(InstrumentationTestCase test, View v) {
+        int[] xy = new int[2];
+        v.getLocationOnScreen(xy);
+
+        final int viewWidth = v.getWidth();
+        final int viewHeight = v.getHeight();
+
+        final float x = xy[0] + (viewWidth / 2.0f);
+        float y = xy[1] + (viewHeight / 2.0f);
+
+        Instrumentation inst = test.getInstrumentation();
+
+        long downTime = SystemClock.uptimeMillis();
+        long eventTime = SystemClock.uptimeMillis();
+
+        MotionEvent event = MotionEvent.obtain(downTime, eventTime,
+                MotionEvent.ACTION_DOWN, x, y, 0);
+        inst.sendPointerSync(event);
+        inst.waitForIdleSync();
+
+        eventTime = SystemClock.uptimeMillis();
+        final int touchSlop = ViewConfiguration.get(v.getContext()).getScaledTouchSlop();
+        event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_MOVE,
+                x + touchSlop / 2, y + touchSlop / 2, 0);
+        inst.sendPointerSync(event);
+        inst.waitForIdleSync();
+
+        try {
+            Thread.sleep((long)(ViewConfiguration.getLongPressTimeout() * 1.5f));
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+        }
+
+        eventTime = SystemClock.uptimeMillis();
+        event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_UP, x, y, 0);
+        inst.sendPointerSync(event);
+        inst.waitForIdleSync();
+    }
+
+    /**
+     * Simulate touching the center of a view and dragging to the top of the screen.
+     *
+     * @param test The test case that is being run
+     * @param v The view that should be dragged
+     *
+     * @deprecated {@link android.test.ActivityInstrumentationTestCase} is deprecated in favor of
+     * {@link android.test.ActivityInstrumentationTestCase2}, which provides more options for
+     * configuring the Activity under test
+     */
+    @Deprecated
+    public static void dragViewToTop(ActivityInstrumentationTestCase test, View v) {
+        dragViewToTop((InstrumentationTestCase) test, v, 4);
+    }
+
+    /**
+     * Simulate touching the center of a view and dragging to the top of the screen.
+     *
+     * @param test The test case that is being run
+     * @param v The view that should be dragged
+     * @param stepCount How many move steps to include in the drag
+     *
+     * @deprecated {@link android.test.ActivityInstrumentationTestCase} is deprecated in favor of
+     * {@link android.test.ActivityInstrumentationTestCase2}, which provides more options for
+     * configuring the Activity under test
+     */
+    @Deprecated
+    public static void dragViewToTop(ActivityInstrumentationTestCase test, View v, int stepCount) {
+        dragViewToTop((InstrumentationTestCase) test, v, stepCount);
+    }
+
+    /**
+     * Simulate touching the center of a view and dragging to the top of the screen.
+     *
+     * @param test The test case that is being run
+     * @param v The view that should be dragged
+     */
+    public static void dragViewToTop(InstrumentationTestCase test, View v) {
+        dragViewToTop(test, v, 4);
+    }
+
+    /**
+     * Simulate touching the center of a view and dragging to the top of the screen.
+     *
+     * @param test The test case that is being run
+     * @param v The view that should be dragged
+     * @param stepCount How many move steps to include in the drag
+     */
+    public static void dragViewToTop(InstrumentationTestCase test, View v, int stepCount) {
+        int[] xy = new int[2];
+        v.getLocationOnScreen(xy);
+
+        final int viewWidth = v.getWidth();
+        final int viewHeight = v.getHeight();
+
+        final float x = xy[0] + (viewWidth / 2.0f);
+        float fromY = xy[1] + (viewHeight / 2.0f);
+        float toY = 0;
+
+        drag(test, x, x, fromY, toY, stepCount);
+    }
+
+    /**
+     * Get the location of a view. Use the gravity param to specify which part of the view to
+     * return.
+     *
+     * @param v View to find
+     * @param gravity A combination of (TOP, CENTER_VERTICAL, BOTTOM) and (LEFT, CENTER_HORIZONTAL,
+     *        RIGHT)
+     * @param xy Result
+     */
+    private static void getStartLocation(View v, int gravity, int[] xy) {
+        v.getLocationOnScreen(xy);
+
+        final int viewWidth = v.getWidth();
+        final int viewHeight = v.getHeight();
+
+        switch (gravity & Gravity.VERTICAL_GRAVITY_MASK) {
+        case Gravity.TOP:
+            break;
+        case Gravity.CENTER_VERTICAL:
+            xy[1] += viewHeight / 2;
+            break;
+        case Gravity.BOTTOM:
+            xy[1] += viewHeight - 1;
+            break;
+        default:
+            // Same as top -- do nothing
+        }
+
+        switch (gravity & Gravity.HORIZONTAL_GRAVITY_MASK) {
+        case Gravity.LEFT:
+            break;
+        case Gravity.CENTER_HORIZONTAL:
+            xy[0] += viewWidth / 2;
+            break;
+        case Gravity.RIGHT:
+            xy[0] += viewWidth - 1;
+            break;
+        default:
+            // Same as left -- do nothing
+        }
+    }
+
+    /**
+     * Simulate touching a view and dragging it by the specified amount.
+     *
+     * @param test The test case that is being run
+     * @param v The view that should be dragged
+     * @param gravity Which part of the view to use for the initial down event. A combination of
+     *        (TOP, CENTER_VERTICAL, BOTTOM) and (LEFT, CENTER_HORIZONTAL, RIGHT)
+     * @param deltaX Amount to drag horizontally in pixels
+     * @param deltaY Amount to drag vertically in pixels
+     *
+     * @return distance in pixels covered by the drag
+     *
+     * @deprecated {@link android.test.ActivityInstrumentationTestCase} is deprecated in favor of
+     * {@link android.test.ActivityInstrumentationTestCase2}, which provides more options for
+     * configuring the Activity under test
+     */
+    @Deprecated
+    public static int dragViewBy(ActivityInstrumentationTestCase test, View v, int gravity,
+            int deltaX, int deltaY) {
+        return dragViewBy((InstrumentationTestCase) test, v, gravity, deltaX, deltaY);
+    }
+
+    /**
+     * Simulate touching a view and dragging it by the specified amount.
+     *
+     * @param test The test case that is being run
+     * @param v The view that should be dragged
+     * @param gravity Which part of the view to use for the initial down event. A combination of
+     *        (TOP, CENTER_VERTICAL, BOTTOM) and (LEFT, CENTER_HORIZONTAL, RIGHT)
+     * @param deltaX Amount to drag horizontally in pixels
+     * @param deltaY Amount to drag vertically in pixels
+     *
+     * @return distance in pixels covered by the drag
+     *
+     * @deprecated {@link android.test.ActivityInstrumentationTestCase} is deprecated in favor of
+     * {@link android.test.ActivityInstrumentationTestCase2}, which provides more options for
+     * configuring the Activity under test
+     */
+    @Deprecated
+    public static int dragViewBy(InstrumentationTestCase test, View v, int gravity, int deltaX,
+            int deltaY) {
+        int[] xy = new int[2];
+
+        getStartLocation(v, gravity, xy);
+
+        final int fromX = xy[0];
+        final int fromY = xy[1];
+
+        int distance = (int) Math.hypot(deltaX, deltaY);
+
+        drag(test, fromX, fromX + deltaX, fromY, fromY + deltaY, distance);
+
+        return distance;
+    }
+
+    /**
+     * Simulate touching a view and dragging it to a specified location.
+     *
+     * @param test The test case that is being run
+     * @param v The view that should be dragged
+     * @param gravity Which part of the view to use for the initial down event. A combination of
+     *        (TOP, CENTER_VERTICAL, BOTTOM) and (LEFT, CENTER_HORIZONTAL, RIGHT)
+     * @param toX Final location of the view after dragging
+     * @param toY Final location of the view after dragging
+     *
+     * @return distance in pixels covered by the drag
+     *
+     * @deprecated {@link android.test.ActivityInstrumentationTestCase} is deprecated in favor of
+     * {@link android.test.ActivityInstrumentationTestCase2}, which provides more options for
+     * configuring the Activity under test
+     */
+    @Deprecated
+    public static int dragViewTo(ActivityInstrumentationTestCase test, View v, int gravity, int toX,
+            int toY) {
+        return dragViewTo((InstrumentationTestCase) test, v, gravity, toX, toY);
+    }
+
+    /**
+     * Simulate touching a view and dragging it to a specified location.
+     *
+     * @param test The test case that is being run
+     * @param v The view that should be dragged
+     * @param gravity Which part of the view to use for the initial down event. A combination of
+     *        (TOP, CENTER_VERTICAL, BOTTOM) and (LEFT, CENTER_HORIZONTAL, RIGHT)
+     * @param toX Final location of the view after dragging
+     * @param toY Final location of the view after dragging
+     *
+     * @return distance in pixels covered by the drag
+     */
+    public static int dragViewTo(InstrumentationTestCase test, View v, int gravity, int toX,
+            int toY) {
+        int[] xy = new int[2];
+
+        getStartLocation(v, gravity, xy);
+
+        final int fromX = xy[0];
+        final int fromY = xy[1];
+
+        int deltaX = fromX - toX;
+        int deltaY = fromY - toY;
+
+        int distance = (int)Math.hypot(deltaX, deltaY);
+        drag(test, fromX, toX, fromY, toY, distance);
+
+        return distance;
+    }
+
+    /**
+     * Simulate touching a view and dragging it to a specified location. Only moves horizontally.
+     *
+     * @param test The test case that is being run
+     * @param v The view that should be dragged
+     * @param gravity Which part of the view to use for the initial down event. A combination of
+     *        (TOP, CENTER_VERTICAL, BOTTOM) and (LEFT, CENTER_HORIZONTAL, RIGHT)
+     * @param toX Final location of the view after dragging
+     *
+     * @return distance in pixels covered by the drag
+     *
+     * @deprecated {@link android.test.ActivityInstrumentationTestCase} is deprecated in favor of
+     * {@link android.test.ActivityInstrumentationTestCase2}, which provides more options for
+     * configuring the Activity under test
+     */
+    @Deprecated
+    public static int dragViewToX(ActivityInstrumentationTestCase test, View v, int gravity,
+            int toX) {
+        return dragViewToX((InstrumentationTestCase) test, v, gravity, toX);
+    }
+
+    /**
+     * Simulate touching a view and dragging it to a specified location. Only moves horizontally.
+     *
+     * @param test The test case that is being run
+     * @param v The view that should be dragged
+     * @param gravity Which part of the view to use for the initial down event. A combination of
+     *        (TOP, CENTER_VERTICAL, BOTTOM) and (LEFT, CENTER_HORIZONTAL, RIGHT)
+     * @param toX Final location of the view after dragging
+     *
+     * @return distance in pixels covered by the drag
+     */
+    public static int dragViewToX(InstrumentationTestCase test, View v, int gravity, int toX) {
+        int[] xy = new int[2];
+
+        getStartLocation(v, gravity, xy);
+
+        final int fromX = xy[0];
+        final int fromY = xy[1];
+
+        int deltaX = fromX - toX;
+
+        drag(test, fromX, toX, fromY, fromY, deltaX);
+
+        return deltaX;
+    }
+
+    /**
+     * Simulate touching a view and dragging it to a specified location. Only moves vertically.
+     *
+     * @param test The test case that is being run
+     * @param v The view that should be dragged
+     * @param gravity Which part of the view to use for the initial down event. A combination of
+     *        (TOP, CENTER_VERTICAL, BOTTOM) and (LEFT, CENTER_HORIZONTAL, RIGHT)
+     * @param toY Final location of the view after dragging
+     *
+     * @return distance in pixels covered by the drag
+     *
+     * @deprecated {@link android.test.ActivityInstrumentationTestCase} is deprecated in favor of
+     * {@link android.test.ActivityInstrumentationTestCase2}, which provides more options for
+     * configuring the Activity under test
+     */
+    @Deprecated
+    public static int dragViewToY(ActivityInstrumentationTestCase test, View v, int gravity,
+            int toY) {
+        return dragViewToY((InstrumentationTestCase) test, v, gravity, toY);
+    }
+
+    /**
+     * Simulate touching a view and dragging it to a specified location. Only moves vertically.
+     *
+     * @param test The test case that is being run
+     * @param v The view that should be dragged
+     * @param gravity Which part of the view to use for the initial down event. A combination of
+     *        (TOP, CENTER_VERTICAL, BOTTOM) and (LEFT, CENTER_HORIZONTAL, RIGHT)
+     * @param toY Final location of the view after dragging
+     *
+     * @return distance in pixels covered by the drag
+     */
+    public static int dragViewToY(InstrumentationTestCase test, View v, int gravity, int toY) {
+        int[] xy = new int[2];
+
+        getStartLocation(v, gravity, xy);
+
+        final int fromX = xy[0];
+        final int fromY = xy[1];
+
+        int deltaY = fromY - toY;
+
+        drag(test, fromX, fromX, fromY, toY, deltaY);
+
+        return deltaY;
+    }
+
+
+    /**
+     * Simulate touching a specific location and dragging to a new location.
+     *
+     * @param test The test case that is being run
+     * @param fromX X coordinate of the initial touch, in screen coordinates
+     * @param toX Xcoordinate of the drag destination, in screen coordinates
+     * @param fromY X coordinate of the initial touch, in screen coordinates
+     * @param toY Y coordinate of the drag destination, in screen coordinates
+     * @param stepCount How many move steps to include in the drag
+     *
+     * @deprecated {@link android.test.ActivityInstrumentationTestCase} is deprecated in favor of
+     * {@link android.test.ActivityInstrumentationTestCase2}, which provides more options for
+     * configuring the Activity under test
+     */
+    @Deprecated
+    public static void drag(ActivityInstrumentationTestCase test, float fromX, float toX,
+            float fromY, float toY, int stepCount) {
+        drag((InstrumentationTestCase) test, fromX, toX, fromY, toY, stepCount);
+    }
+
+    /**
+     * Simulate touching a specific location and dragging to a new location.
+     *
+     * @param test The test case that is being run
+     * @param fromX X coordinate of the initial touch, in screen coordinates
+     * @param toX Xcoordinate of the drag destination, in screen coordinates
+     * @param fromY X coordinate of the initial touch, in screen coordinates
+     * @param toY Y coordinate of the drag destination, in screen coordinates
+     * @param stepCount How many move steps to include in the drag
+     */
+    public static void drag(InstrumentationTestCase test, float fromX, float toX, float fromY,
+            float toY, int stepCount) {
+        Instrumentation inst = test.getInstrumentation();
+
+        long downTime = SystemClock.uptimeMillis();
+        long eventTime = SystemClock.uptimeMillis();
+
+        float y = fromY;
+        float x = fromX;
+
+        float yStep = (toY - fromY) / stepCount;
+        float xStep = (toX - fromX) / stepCount;
+
+        MotionEvent event = MotionEvent.obtain(downTime, eventTime,
+                MotionEvent.ACTION_DOWN, x, y, 0);
+        inst.sendPointerSync(event);
+        for (int i = 0; i < stepCount; ++i) {
+            y += yStep;
+            x += xStep;
+            eventTime = SystemClock.uptimeMillis();
+            event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_MOVE, x, y, 0);
+            inst.sendPointerSync(event);
+        }
+
+        eventTime = SystemClock.uptimeMillis();
+        event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_UP, x, y, 0);
+        inst.sendPointerSync(event);
+        inst.waitForIdleSync();
+    }
+
+    private static class ViewStateSnapshot {
+        final View mFirst;
+        final View mLast;
+        final int mFirstTop;
+        final int mLastBottom;
+        final int mChildCount;
+        private ViewStateSnapshot(ViewGroup viewGroup) {
+            mChildCount = viewGroup.getChildCount();
+            if (mChildCount == 0) {
+                mFirst = mLast = null;
+                mFirstTop = mLastBottom = Integer.MIN_VALUE;
+            } else {
+                mFirst = viewGroup.getChildAt(0);
+                mLast = viewGroup.getChildAt(mChildCount - 1);
+                mFirstTop = mFirst.getTop();
+                mLastBottom = mLast.getBottom();
+            }
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (this == o) {
+                return true;
+            }
+            if (o == null || getClass() != o.getClass()) {
+                return false;
+            }
+
+            final ViewStateSnapshot that = (ViewStateSnapshot) o;
+            return mFirstTop == that.mFirstTop &&
+                    mLastBottom == that.mLastBottom &&
+                    mFirst == that.mFirst &&
+                    mLast == that.mLast &&
+                    mChildCount == that.mChildCount;
+        }
+
+        @Override
+        public int hashCode() {
+            int result = mFirst != null ? mFirst.hashCode() : 0;
+            result = 31 * result + (mLast != null ? mLast.hashCode() : 0);
+            result = 31 * result + mFirstTop;
+            result = 31 * result + mLastBottom;
+            result = 31 * result + mChildCount;
+            return result;
+        }
+    }
+}
diff --git a/android/test/UiThreadTest.java b/android/test/UiThreadTest.java
new file mode 100644
index 0000000..cd06ab8
--- /dev/null
+++ b/android/test/UiThreadTest.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2008 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.test;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.lang.annotation.ElementType;
+
+/**
+ * This annotation can be used on an {@link InstrumentationTestCase}'s test methods.
+ * When the annotation is present, the test method is executed on the application's
+ * main thread (or UI thread.) Note that instrumentation methods may not be used
+ * when this annotation is present.
+ *
+ * @deprecated Use
+ * <a href="{@docRoot}reference/android/support/test/annotation/UiThreadTest.html">
+ * UiThreadTest</a> instead. New tests should be written using the
+ * <a href="{@docRoot}tools/testing-support-library/index.html">Android Testing Support Library</a>.
+ */
+@Deprecated
+@Target(ElementType.METHOD)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface UiThreadTest {
+}
diff --git a/android/test/ViewAsserts.java b/android/test/ViewAsserts.java
new file mode 100644
index 0000000..00ab443
--- /dev/null
+++ b/android/test/ViewAsserts.java
@@ -0,0 +1,381 @@
+/*
+ * 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.test;
+
+import static junit.framework.Assert.*;
+
+import android.view.View;
+import android.view.ViewGroup;
+
+/**
+ * Some useful assertions about views.
+ *
+ * @deprecated Use
+ * <a href="{@docRoot}reference/android/support/test/espresso/matcher/ViewMatchers.html">Espresso
+ * View Matchers</a> instead. New test should be written using the
+ * <a href="{@docRoot}tools/testing-support-library/index.html">Android Testing Support Library</a>.
+ * For more information about UI testing, take the
+ * <a href="{@docRoot}tools/testing-support-library/index.html">Espresso UI testing</a> training.
+ */
+@Deprecated
+public class ViewAsserts {
+
+    private ViewAsserts() {}
+
+    /**
+     * Assert that view is on the screen.
+     * @param origin The root view of the screen.
+     * @param view The view.
+     */
+    static public void assertOnScreen(View origin, View view) {
+        int[] xy = new int[2];
+        view.getLocationOnScreen(xy);
+
+        int[] xyRoot = new int[2];
+        origin.getLocationOnScreen(xyRoot);
+
+        int y = xy[1] - xyRoot[1];
+
+        assertTrue("view should have positive y coordinate on screen",
+                y  >= 0);
+
+        assertTrue("view should have y location on screen less than drawing "
+                + "height of root view",
+                y <= view.getRootView().getHeight());
+    }
+
+    /**
+     * Assert that view is below the visible screen.
+     * @param origin The root view of the screen.
+     * @param view The view
+     */
+    static public void assertOffScreenBelow(View origin, View view) {
+        int[] xy = new int[2];
+        view.getLocationOnScreen(xy);
+
+        int[] xyRoot = new int[2];
+        origin.getLocationOnScreen(xyRoot);
+
+        int y = xy[1] - xyRoot[1];
+
+        assertTrue("view should have y location on screen greater than drawing "
+                + "height of origen view (" + y + " is not greater than "
+                + origin.getHeight() + ")",
+                y > origin.getHeight());
+    }
+
+    /**
+     * Assert that view is above the visible screen.
+     * @param origin Te root view of the screen.
+     * @param view The view
+     */
+    static public void assertOffScreenAbove(View origin, View view) {
+        int[] xy = new int[2];
+        view.getLocationOnScreen(xy);
+
+        int[] xyRoot = new int[2];
+        origin.getLocationOnScreen(xyRoot);
+
+        int y = xy[1] - xyRoot[1];
+
+        assertTrue("view should have y location less than that of origin view",
+                y < 0);
+    }
+
+    /**
+     * Assert that a view has a particular x and y position on the visible screen.
+     * @param origin The root view of the screen.
+     * @param view The view.
+     * @param x The expected x coordinate.
+     * @param y The expected y coordinate.
+     */
+    static public void assertHasScreenCoordinates(View origin, View view, int x, int y) {
+        int[] xy = new int[2];
+        view.getLocationOnScreen(xy);
+
+        int[] xyRoot = new int[2];
+        origin.getLocationOnScreen(xyRoot);
+
+        assertEquals("x coordinate", x, xy[0] - xyRoot[0]);
+        assertEquals("y coordinate", y, xy[1] - xyRoot[1]);
+    }
+
+    /**
+     * Assert that two views are aligned on their baseline, that is that their baselines
+     * are on the same y location.
+     *
+     * @param first The first view
+     * @param second The second view
+     */
+    static public void assertBaselineAligned(View first, View second) {
+        int[] xy = new int[2];
+        first.getLocationOnScreen(xy);
+        int firstTop = xy[1] + first.getBaseline();
+
+        second.getLocationOnScreen(xy);
+        int secondTop = xy[1] + second.getBaseline();
+
+        assertEquals("views are not baseline aligned", firstTop, secondTop);
+    }
+
+    /**
+     * Assert that two views are right aligned, that is that their right edges
+     * are on the same x location.
+     *
+     * @param first The first view
+     * @param second The second view
+     */
+    static public void assertRightAligned(View first, View second) {
+        int[] xy = new int[2];
+        first.getLocationOnScreen(xy);
+        int firstRight = xy[0] + first.getMeasuredWidth();
+
+        second.getLocationOnScreen(xy);
+        int secondRight = xy[0] + second.getMeasuredWidth();
+
+        assertEquals("views are not right aligned", firstRight, secondRight);
+    }
+
+    /**
+     * Assert that two views are right aligned, that is that their right edges
+     * are on the same x location, with respect to the specified margin.
+     *
+     * @param first The first view
+     * @param second The second view
+     * @param margin The margin between the first view and the second view
+     */
+    static public void assertRightAligned(View first, View second, int margin) {
+        int[] xy = new int[2];
+        first.getLocationOnScreen(xy);
+        int firstRight = xy[0] + first.getMeasuredWidth();
+
+        second.getLocationOnScreen(xy);
+        int secondRight = xy[0] + second.getMeasuredWidth();
+
+        assertEquals("views are not right aligned", Math.abs(firstRight - secondRight), margin);
+    }
+
+    /**
+     * Assert that two views are left aligned, that is that their left edges
+     * are on the same x location.
+     *
+     * @param first The first view
+     * @param second The second view
+     */
+    static public void assertLeftAligned(View first, View second) {
+        int[] xy = new int[2];
+        first.getLocationOnScreen(xy);
+        int firstLeft = xy[0];
+
+        second.getLocationOnScreen(xy);
+        int secondLeft = xy[0];
+
+        assertEquals("views are not left aligned", firstLeft, secondLeft);
+    }
+
+    /**
+     * Assert that two views are left aligned, that is that their left edges
+     * are on the same x location, with respect to the specified margin.
+     *
+     * @param first The first view
+     * @param second The second view
+     * @param margin The margin between the first view and the second view
+     */
+    static public void assertLeftAligned(View first, View second, int margin) {
+        int[] xy = new int[2];
+        first.getLocationOnScreen(xy);
+        int firstLeft = xy[0];
+
+        second.getLocationOnScreen(xy);
+        int secondLeft = xy[0];
+
+        assertEquals("views are not left aligned", Math.abs(firstLeft - secondLeft), margin);
+    }
+
+    /**
+     * Assert that two views are bottom aligned, that is that their bottom edges
+     * are on the same y location.
+     *
+     * @param first The first view
+     * @param second The second view
+     */
+    static public void assertBottomAligned(View first, View second) {
+        int[] xy = new int[2];
+        first.getLocationOnScreen(xy);
+        int firstBottom = xy[1] + first.getMeasuredHeight();
+
+        second.getLocationOnScreen(xy);
+        int secondBottom = xy[1] + second.getMeasuredHeight();
+
+        assertEquals("views are not bottom aligned", firstBottom, secondBottom);
+    }
+
+    /**
+     * Assert that two views are bottom aligned, that is that their bottom edges
+     * are on the same y location, with respect to the specified margin.
+     *
+     * @param first The first view
+     * @param second The second view
+     * @param margin The margin between the first view and the second view
+     */
+    static public void assertBottomAligned(View first, View second, int margin) {
+        int[] xy = new int[2];
+        first.getLocationOnScreen(xy);
+        int firstBottom = xy[1] + first.getMeasuredHeight();
+
+        second.getLocationOnScreen(xy);
+        int secondBottom = xy[1] + second.getMeasuredHeight();
+
+        assertEquals("views are not bottom aligned", Math.abs(firstBottom - secondBottom), margin);
+    }
+
+    /**
+     * Assert that two views are top aligned, that is that their top edges
+     * are on the same y location.
+     *
+     * @param first The first view
+     * @param second The second view
+     */
+    static public void assertTopAligned(View first, View second) {
+        int[] xy = new int[2];
+        first.getLocationOnScreen(xy);
+        int firstTop = xy[1];
+
+        second.getLocationOnScreen(xy);
+        int secondTop = xy[1];
+
+        assertEquals("views are not top aligned", firstTop, secondTop);
+    }
+
+    /**
+     * Assert that two views are top aligned, that is that their top edges
+     * are on the same y location, with respect to the specified margin.
+     *
+     * @param first The first view
+     * @param second The second view
+     * @param margin The margin between the first view and the second view
+     */
+    static public void assertTopAligned(View first, View second, int margin) {
+        int[] xy = new int[2];
+        first.getLocationOnScreen(xy);
+        int firstTop = xy[1];
+
+        second.getLocationOnScreen(xy);
+        int secondTop = xy[1];
+
+        assertEquals("views are not top aligned", Math.abs(firstTop - secondTop), margin);
+    }
+
+    /**
+     * Assert that the <code>test</code> view is horizontally center aligned
+     * with respect to the <code>reference</code> view.
+     *
+     * @param reference The reference view
+     * @param test The view that should be center aligned with the reference view
+     */
+    static public void assertHorizontalCenterAligned(View reference, View test) {
+        int[] xy = new int[2];
+        reference.getLocationOnScreen(xy);
+        int referenceLeft = xy[0];
+
+        test.getLocationOnScreen(xy);
+        int testLeft = xy[0];
+
+        int center = (reference.getMeasuredWidth() - test.getMeasuredWidth()) / 2;
+        int delta = testLeft - referenceLeft;
+
+        assertEquals("views are not horizontally center aligned", center, delta);
+    }
+
+    /**
+     * Assert that the <code>test</code> view is vertically center aligned
+     * with respect to the <code>reference</code> view.
+     *
+     * @param reference The reference view
+     * @param test The view that should be center aligned with the reference view
+     */
+    static public void assertVerticalCenterAligned(View reference, View test) {
+        int[] xy = new int[2];
+        reference.getLocationOnScreen(xy);
+        int referenceTop = xy[1];
+
+        test.getLocationOnScreen(xy);
+        int testTop = xy[1];
+
+        int center = (reference.getMeasuredHeight() - test.getMeasuredHeight()) / 2;
+        int delta = testTop - referenceTop;
+
+        assertEquals("views are not vertically center aligned", center, delta);
+    }
+
+    /**
+     * Assert the specified group's integrity. The children count should be >= 0 and each
+     * child should be non-null.
+     *
+     * @param parent The group whose integrity to check
+     */
+    static public void assertGroupIntegrity(ViewGroup parent) {
+        final int count = parent.getChildCount();
+        assertTrue("child count should be >= 0", count >= 0);
+
+        for (int i = 0; i < count; i++) {
+            assertNotNull("group should not contain null children", parent.getChildAt(i));
+            assertSame(parent, parent.getChildAt(i).getParent());
+        }
+    }
+
+    /**
+     * Assert that the specified group contains a specific child once and only once.
+     *
+     * @param parent The group
+     * @param child The child that should belong to group
+     */
+    static public void assertGroupContains(ViewGroup parent, View child) {
+        final int count = parent.getChildCount();
+        assertTrue("Child count should be >= 0", count >= 0);
+
+        boolean found = false;
+        for (int i = 0; i < count; i++) {
+            if (parent.getChildAt(i) == child) {
+                if (!found) {
+                    found = true;
+                } else {
+                    assertTrue("child " + child + " is duplicated in parent", false);
+                }
+            }
+        }
+
+        assertTrue("group does not contain " + child, found);
+    }
+
+    /**
+     * Assert that the specified group does not contain a specific child.
+     *
+     * @param parent The group
+     * @param child The child that should not belong to group
+     */
+    static public void assertGroupNotContains(ViewGroup parent, View child) {
+        final int count = parent.getChildCount();
+        assertTrue("Child count should be >= 0", count >= 0);
+
+        for (int i = 0; i < count; i++) {
+            if (parent.getChildAt(i) == child) {
+                assertTrue("child " + child + " is found in parent", false);
+            }
+        }
+    }
+}
diff --git a/android/test/mock/MockAccountManager.java b/android/test/mock/MockAccountManager.java
new file mode 100644
index 0000000..c9b4c7b
--- /dev/null
+++ b/android/test/mock/MockAccountManager.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2017 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.test.mock;
+
+import android.accounts.Account;
+import android.accounts.AccountManager;
+import android.accounts.AccountManagerCallback;
+import android.accounts.AccountManagerFuture;
+import android.accounts.AuthenticatorException;
+import android.accounts.OnAccountsUpdateListener;
+import android.accounts.OperationCanceledException;
+import android.content.Context;
+import android.os.Handler;
+import java.io.IOException;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * A mock {@link android.accounts.AccountManager} class.
+ *
+ * <p>Provided for use by {@code android.test.IsolatedContext}.
+ *
+ * @deprecated Use a mocking framework like <a href="https://github.com/mockito/mockito">Mockito</a>.
+ * New tests should be written using the
+ * <a href="{@docRoot}
+ * tools/testing-support-library/index.html">Android Testing Support Library</a>.
+ */
+@Deprecated
+public class MockAccountManager {
+
+    /**
+     * Create a new mock {@link AccountManager} instance.
+     *
+     * @param context the {@link Context} to which the returned object belongs.
+     * @return the new instance.
+     */
+    public static AccountManager newMockAccountManager(Context context) {
+        return new MockAccountManagerImpl(context);
+    }
+
+    private MockAccountManager() {
+    }
+
+    private static class MockAccountManagerImpl extends AccountManager {
+
+        MockAccountManagerImpl(Context context) {
+            super(context, null /* IAccountManager */, null /* handler */);
+        }
+
+        public void addOnAccountsUpdatedListener(OnAccountsUpdateListener listener,
+                Handler handler, boolean updateImmediately) {
+            // do nothing
+        }
+
+        public Account[] getAccounts() {
+            return new Account[] {};
+        }
+
+        public AccountManagerFuture<Account[]> getAccountsByTypeAndFeatures(
+                final String type, final String[] features,
+                AccountManagerCallback<Account[]> callback, Handler handler) {
+            return new MockAccountManagerFuture<Account[]>(new Account[0]);
+        }
+
+        public String blockingGetAuthToken(Account account, String authTokenType,
+                boolean notifyAuthFailure)
+                throws OperationCanceledException, IOException, AuthenticatorException {
+            return null;
+        }
+    }
+
+    /**
+     * A very simple AccountManagerFuture class
+     * that returns what ever was passed in
+     */
+    private static class MockAccountManagerFuture<T>
+            implements AccountManagerFuture<T> {
+
+        T mResult;
+
+        MockAccountManagerFuture(T result) {
+            mResult = result;
+        }
+
+        public boolean cancel(boolean mayInterruptIfRunning) {
+            return false;
+        }
+
+        public boolean isCancelled() {
+            return false;
+        }
+
+        public boolean isDone() {
+            return true;
+        }
+
+        public T getResult()
+                throws OperationCanceledException, IOException, AuthenticatorException {
+            return mResult;
+        }
+
+        public T getResult(long timeout, TimeUnit unit)
+                throws OperationCanceledException, IOException, AuthenticatorException {
+            return getResult();
+        }
+    }
+}
diff --git a/android/test/mock/MockApplication.java b/android/test/mock/MockApplication.java
new file mode 100644
index 0000000..3257ecf
--- /dev/null
+++ b/android/test/mock/MockApplication.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2008 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.test.mock;
+
+import android.app.Application;
+import android.content.res.Configuration;
+
+/**
+ * A mock {@link android.app.Application} class.  All methods are non-functional and throw
+ * {@link java.lang.UnsupportedOperationException}.  Override it as necessary to provide the
+ * operations that you need.
+ *
+ * @deprecated Use a mocking framework like <a href="https://github.com/mockito/mockito">Mockito</a>.
+ * New tests should be written using the
+ * <a href="{@docRoot}tools/testing-support-library/index.html">Android Testing Support Library</a>.
+ */
+@Deprecated
+public class MockApplication extends Application {
+
+    public MockApplication() {
+    }
+
+    @Override
+    public void onCreate() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void onTerminate() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void onConfigurationChanged(Configuration newConfig) {
+        throw new UnsupportedOperationException();
+    }
+}
diff --git a/android/test/mock/MockContentProvider.java b/android/test/mock/MockContentProvider.java
new file mode 100644
index 0000000..d1d64d3
--- /dev/null
+++ b/android/test/mock/MockContentProvider.java
@@ -0,0 +1,358 @@
+/*
+ * Copyright (C) 2009 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.test.mock;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.ContentProvider;
+import android.content.ContentProviderOperation;
+import android.content.ContentProviderResult;
+import android.content.ContentResolver;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.IContentProvider;
+import android.content.Intent;
+import android.content.OperationApplicationException;
+import android.content.pm.PathPermission;
+import android.content.pm.ProviderInfo;
+import android.content.res.AssetFileDescriptor;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.ICancellationSignal;
+import android.os.ParcelFileDescriptor;
+import android.os.RemoteCallback;
+import android.os.RemoteException;
+
+import java.io.FileNotFoundException;
+import java.util.ArrayList;
+
+/**
+ * Mock implementation of ContentProvider.  All methods are non-functional and throw
+ * {@link java.lang.UnsupportedOperationException}.  Tests can extend this class to
+ * implement behavior needed for tests.
+ */
+public class MockContentProvider extends ContentProvider {
+    /*
+     * Note: if you add methods to ContentProvider, you must add similar methods to
+     *       MockContentProvider.
+     */
+
+    /**
+     * IContentProvider that directs all calls to this MockContentProvider.
+     */
+    private class InversionIContentProvider implements IContentProvider {
+        @Override
+        public ContentProviderResult[] applyBatch(String callingPackage,
+                @Nullable String featureId, String authority,
+                ArrayList<ContentProviderOperation> operations)
+                throws RemoteException, OperationApplicationException {
+            return MockContentProvider.this.applyBatch(authority, operations);
+        }
+
+        @Override
+        public int bulkInsert(String callingPackage, @Nullable String featureId, Uri url,
+                ContentValues[] initialValues) throws RemoteException {
+            return MockContentProvider.this.bulkInsert(url, initialValues);
+        }
+
+        @Override
+        public int delete(String callingPackage, @Nullable String featureId, Uri url,
+                Bundle extras) throws RemoteException {
+            return MockContentProvider.this.delete(url, extras);
+        }
+
+        @Override
+        public String getType(Uri url) throws RemoteException {
+            return MockContentProvider.this.getType(url);
+        }
+
+        @Override
+        public void getTypeAsync(Uri uri, RemoteCallback callback) throws RemoteException {
+            MockContentProvider.this.getTypeAsync(uri, callback);
+        }
+
+        @Override
+        public Uri insert(String callingPackage, @Nullable String featureId, Uri url,
+                ContentValues initialValues, Bundle extras) throws RemoteException {
+            return MockContentProvider.this.insert(url, initialValues, extras);
+        }
+
+        @Override
+        public AssetFileDescriptor openAssetFile(String callingPackage,
+                @Nullable String featureId, Uri url, String mode, ICancellationSignal signal)
+                throws RemoteException, FileNotFoundException {
+            return MockContentProvider.this.openAssetFile(url, mode);
+        }
+
+        @Override
+        public ParcelFileDescriptor openFile(String callingPackage, @Nullable String featureId,
+                Uri url, String mode, ICancellationSignal signal, IBinder callerToken)
+                throws RemoteException, FileNotFoundException {
+            return MockContentProvider.this.openFile(url, mode);
+        }
+
+        @Override
+        public Cursor query(String callingPackage, @Nullable String featureId, Uri url,
+                @Nullable String[] projection, @Nullable Bundle queryArgs,
+                @Nullable ICancellationSignal cancellationSignal) throws RemoteException {
+            return MockContentProvider.this.query(url, projection, queryArgs, null);
+        }
+
+        @Override
+        public int update(String callingPackage, @Nullable String featureId, Uri url,
+                ContentValues values, Bundle extras) throws RemoteException {
+            return MockContentProvider.this.update(url, values, extras);
+        }
+
+        @Override
+        public Bundle call(String callingPackage, @Nullable String featureId, String authority,
+                String method, String request, Bundle args) throws RemoteException {
+            return MockContentProvider.this.call(authority, method, request, args);
+        }
+
+        @Override
+        public IBinder asBinder() {
+            return MockContentProvider.this.getIContentProviderBinder();
+        }
+
+        @Override
+        public String[] getStreamTypes(Uri url, String mimeTypeFilter) throws RemoteException {
+            return MockContentProvider.this.getStreamTypes(url, mimeTypeFilter);
+        }
+
+        @Override
+        public AssetFileDescriptor openTypedAssetFile(String callingPackage,
+                @Nullable String featureId, Uri url, String mimeType, Bundle opts,
+                ICancellationSignal signal) throws RemoteException, FileNotFoundException {
+            return MockContentProvider.this.openTypedAssetFile(url, mimeType, opts);
+        }
+
+        @Override
+        public ICancellationSignal createCancellationSignal() throws RemoteException {
+            return null;
+        }
+
+        @Override
+        public Uri canonicalize(String callingPkg, @Nullable String featureId, Uri uri)
+                throws RemoteException {
+            return MockContentProvider.this.canonicalize(uri);
+        }
+
+        @Override
+        public void canonicalizeAsync(String callingPkg, String featureId, Uri uri,
+                RemoteCallback callback) {
+            MockContentProvider.this.canonicalizeAsync(uri, callback);
+        }
+
+        @Override
+        public Uri uncanonicalize(String callingPkg, @Nullable String featureId, Uri uri)
+                throws RemoteException {
+            return MockContentProvider.this.uncanonicalize(uri);
+        }
+
+        @Override
+        public boolean refresh(String callingPkg, @Nullable String featureId, Uri url,
+                Bundle args, ICancellationSignal cancellationSignal) throws RemoteException {
+            return MockContentProvider.this.refresh(url, args);
+        }
+
+        @Override
+        public int checkUriPermission(String callingPkg, @Nullable String featureId, Uri uri,
+                int uid, int modeFlags) {
+            return MockContentProvider.this.checkUriPermission(uri, uid, modeFlags);
+        }
+    }
+    private final InversionIContentProvider mIContentProvider = new InversionIContentProvider();
+
+    /**
+     * A constructor using {@link MockContext} instance as a Context in it.
+     */
+    protected MockContentProvider() {
+        super(new MockContext(), "", "", null);
+    }
+
+    /**
+     * A constructor accepting a Context instance, which is supposed to be the subclasss of
+     * {@link MockContext}.
+     */
+    public MockContentProvider(Context context) {
+        super(context, "", "", null);
+    }
+
+    /**
+     * A constructor which initialize four member variables which
+     * {@link android.content.ContentProvider} have internally.
+     *
+     * @param context A Context object which should be some mock instance (like the
+     * instance of {@link android.test.mock.MockContext}).
+     * @param readPermission The read permision you want this instance should have in the
+     * test, which is available via {@link #getReadPermission()}.
+     * @param writePermission The write permission you want this instance should have
+     * in the test, which is available via {@link #getWritePermission()}.
+     * @param pathPermissions The PathPermissions you want this instance should have
+     * in the test, which is available via {@link #getPathPermissions()}.
+     */
+    public MockContentProvider(Context context,
+            String readPermission,
+            String writePermission,
+            PathPermission[] pathPermissions) {
+        super(context, readPermission, writePermission, pathPermissions);
+    }
+
+    @Override
+    public int delete(Uri uri, String selection, String[] selectionArgs) {
+        throw new UnsupportedOperationException("unimplemented mock method");
+    }
+
+    @Override
+    public String getType(Uri uri) {
+        throw new UnsupportedOperationException("unimplemented mock method");
+    }
+
+    /**
+     * @hide
+     */
+    @SuppressWarnings("deprecation")
+    public void getTypeAsync(Uri uri, RemoteCallback remoteCallback) {
+        AsyncTask.SERIAL_EXECUTOR.execute(() -> {
+            final Bundle bundle = new Bundle();
+            bundle.putString(ContentResolver.REMOTE_CALLBACK_RESULT, getType(uri));
+            remoteCallback.sendResult(bundle);
+        });
+    }
+
+    @Override
+    public Uri insert(Uri uri, ContentValues values) {
+        throw new UnsupportedOperationException("unimplemented mock method");
+    }
+
+    @Override
+    public boolean onCreate() {
+        throw new UnsupportedOperationException("unimplemented mock method");
+    }
+
+    @Override
+    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
+            String sortOrder) {
+        throw new UnsupportedOperationException("unimplemented mock method");
+    }
+
+    @Override
+    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
+        throw new UnsupportedOperationException("unimplemented mock method");
+    }
+
+    /**
+     * If you're reluctant to implement this manually, please just call super.bulkInsert().
+     */
+    @Override
+    public int bulkInsert(Uri uri, ContentValues[] values) {
+        throw new UnsupportedOperationException("unimplemented mock method");
+    }
+
+    @Override
+    public void attachInfo(Context context, ProviderInfo info) {
+        throw new UnsupportedOperationException("unimplemented mock method");
+    }
+
+    @Override
+    public ContentProviderResult[] applyBatch(ArrayList<ContentProviderOperation> operations) {
+        throw new UnsupportedOperationException("unimplemented mock method");
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    public Bundle call(String method, String request, Bundle args) {
+        throw new UnsupportedOperationException("unimplemented mock method call");
+    }
+
+    @Override
+    public String[] getStreamTypes(Uri url, String mimeTypeFilter) {
+        throw new UnsupportedOperationException("unimplemented mock method call");
+    }
+
+    @Override
+    public AssetFileDescriptor openTypedAssetFile(Uri url, String mimeType, Bundle opts) {
+        throw new UnsupportedOperationException("unimplemented mock method call");
+    }
+
+    /**
+     * @hide
+     */
+    @SuppressWarnings("deprecation")
+    public void canonicalizeAsync(Uri uri, RemoteCallback callback) {
+        AsyncTask.SERIAL_EXECUTOR.execute(() -> {
+            final Bundle bundle = new Bundle();
+            bundle.putParcelable(ContentResolver.REMOTE_CALLBACK_RESULT, canonicalize(uri));
+            callback.sendResult(bundle);
+        });
+    }
+
+    /**
+     * @hide
+     */
+    public boolean refresh(Uri url, Bundle args) {
+        throw new UnsupportedOperationException("unimplemented mock method call");
+    }
+
+    /** {@hide} */
+    @Override
+    public int checkUriPermission(@NonNull Uri uri, int uid, @Intent.AccessUriMode int modeFlags) {
+        throw new UnsupportedOperationException("unimplemented mock method call");
+    }
+
+    /**
+     * Returns IContentProvider which calls back same methods in this class.
+     * By overriding this class, we avoid the mechanism hidden behind ContentProvider
+     * (IPC, etc.)
+     *
+     * @hide
+     */
+    @Override
+    public final IContentProvider getIContentProvider() {
+        return mIContentProvider;
+    }
+
+    /**
+     * @hide
+     */
+    public IBinder getIContentProviderBinder() {
+        throw new UnsupportedOperationException("unimplemented mock method");
+    }
+
+    /**
+     * Like {@link #attachInfo(Context, android.content.pm.ProviderInfo)}, but for use
+     * when directly instantiating the provider for testing.
+     *
+     * <p>Provided for use by {@code android.test.ProviderTestCase2} and
+     * {@code android.test.RenamingDelegatingContext}.
+     *
+     * @deprecated Use a mocking framework like <a href="https://github.com/mockito/mockito">Mockito</a>.
+     * New tests should be written using the
+     * <a href="{@docRoot}tools/testing-support-library/index.html">Android Testing Support Library</a>.
+     */
+    @Deprecated
+    public static void attachInfoForTesting(
+            ContentProvider provider, Context context, ProviderInfo providerInfo) {
+        provider.attachInfoForTesting(context, providerInfo);
+    }
+}
diff --git a/android/test/mock/MockContentResolver.java b/android/test/mock/MockContentResolver.java
new file mode 100644
index 0000000..8f4bccc
--- /dev/null
+++ b/android/test/mock/MockContentResolver.java
@@ -0,0 +1,179 @@
+/*
+ * Copyright (C) 2008 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.test.mock;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.ContentProvider;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.IContentProvider;
+import android.database.ContentObserver;
+import android.net.Uri;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * <p>
+ *      An extension of {@link android.content.ContentResolver} that is designed for
+ *      testing.
+ * </p>
+ * <p>
+ *      MockContentResolver overrides Android's normal way of resolving providers by
+ *      authority. To have access to a provider based on its authority, users of
+ *      MockContentResolver first instantiate the provider and
+ *      use {@link MockContentResolver#addProvider(String, ContentProvider)}. Resolution of an
+ *      authority occurs entirely within MockContentResolver.
+ * </p>
+ * <p>
+ *      Users can also set an authority's entry in the map to null, so that a provider is completely
+ *      mocked out.
+ * </p>
+ *
+ * <div class="special reference">
+ * <h3>Developer Guides</h3>
+ * <p>For more information about application testing, read the
+ * <a href="{@docRoot}guide/topics/testing/index.html">Testing</a> developer guide.</p>
+ * </div>
+ */
+public class MockContentResolver extends ContentResolver {
+    Map<String, ContentProvider> mProviders;
+
+    /**
+     * Creates a local map of providers. This map is used instead of the global
+     * map when an API call tries to acquire a provider.
+     */
+    public MockContentResolver() {
+        this(null);
+    }
+
+    /**
+     * Creates a local map of providers. This map is used instead of the global
+     * map when an API call tries to acquire a provider.
+     */
+    public MockContentResolver(Context context) {
+        super(context);
+        mProviders = new HashMap<>();
+    }
+
+    /**
+     * Adds access to a provider based on its authority
+     *
+     * @param name The authority name associated with the provider.
+     * @param provider An instance of {@link android.content.ContentProvider} or one of its
+     * subclasses, or null.
+     */
+    public void addProvider(String name, ContentProvider provider) {
+
+        /*
+         * Maps the authority to the provider locally.
+         */
+        mProviders.put(name, provider);
+    }
+
+    /** @hide */
+    @Override
+    protected IContentProvider acquireProvider(Context context, String name) {
+        return acquireExistingProvider(context, name);
+    }
+
+    /** @hide */
+    @Override
+    protected IContentProvider acquireExistingProvider(Context context, String name) {
+
+        /*
+         * Gets the content provider from the local map
+         */
+        final ContentProvider provider = mProviders.get(name);
+
+        if (provider != null) {
+            return provider.getIContentProvider();
+        } else {
+            return null;
+        }
+    }
+
+    /** @hide */
+    @Override
+    public boolean releaseProvider(IContentProvider provider) {
+        return true;
+    }
+
+    /** @hide */
+    @Override
+    protected IContentProvider acquireUnstableProvider(Context c, String name) {
+        return acquireProvider(c, name);
+    }
+
+    /** @hide */
+    @Override
+    public boolean releaseUnstableProvider(IContentProvider icp) {
+        return releaseProvider(icp);
+    }
+
+    /** @hide */
+    @Override
+    public void unstableProviderDied(IContentProvider icp) {
+    }
+
+    /**
+     * Overrides the behavior from the parent class to completely ignore any
+     * content notifications sent to this object. This effectively hides clients
+     * from observers elsewhere in the system.
+     */
+    @Override
+    public void notifyChange(@NonNull Uri uri, @Nullable ContentObserver observer) {
+    }
+
+    /**
+     * Overrides the behavior from the parent class to completely ignore any
+     * content notifications sent to this object. This effectively hides clients
+     * from observers elsewhere in the system.
+     *
+     * @deprecated callers should consider migrating to
+     *             {@link #notifyChange(Uri, ContentObserver, int)}, as it
+     *             offers support for many more options than just
+     *             {@link #NOTIFY_SYNC_TO_NETWORK}.
+     */
+    @Override
+    @Deprecated
+    public void notifyChange(@NonNull Uri uri, @Nullable ContentObserver observer,
+            boolean syncToNetwork) {
+    }
+
+    /**
+     * Overrides the behavior from the parent class to completely ignore any
+     * content notifications sent to this object. This effectively hides clients
+     * from observers elsewhere in the system.
+     */
+    @Override
+    public void notifyChange(@NonNull Uri uri, @Nullable ContentObserver observer,
+            @NotifyFlags int flags) {
+    }
+
+    /**
+     * Overrides the behavior from the parent class to completely ignore any
+     * content notifications sent to this object. This effectively hides clients
+     * from observers elsewhere in the system.
+     */
+    @Override
+    public void notifyChange(@NonNull Collection<Uri> uris, @Nullable ContentObserver observer,
+            @NotifyFlags int flags) {
+    }
+}
diff --git a/android/test/mock/MockContext.java b/android/test/mock/MockContext.java
new file mode 100644
index 0000000..cf3b03c
--- /dev/null
+++ b/android/test/mock/MockContext.java
@@ -0,0 +1,937 @@
+/*
+ * 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.test.mock;
+
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.app.IApplicationThread;
+import android.app.IServiceConnection;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.IntentSender;
+import android.content.ServiceConnection;
+import android.content.SharedPreferences;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.res.AssetManager;
+import android.content.res.Configuration;
+import android.content.res.Resources;
+import android.database.DatabaseErrorHandler;
+import android.database.sqlite.SQLiteDatabase;
+import android.graphics.Bitmap;
+import android.graphics.drawable.Drawable;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.UserHandle;
+import android.view.Display;
+import android.view.DisplayAdjustments;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.concurrent.Executor;
+
+/**
+ * A mock {@link android.content.Context} class.  All methods are non-functional and throw
+ * {@link java.lang.UnsupportedOperationException}.  You can use this to inject other dependencies,
+ * mocks, or monitors into the classes you are testing.
+ */
+public class MockContext extends Context {
+
+    @Override
+    public AssetManager getAssets() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Resources getResources() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public PackageManager getPackageManager() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public ContentResolver getContentResolver() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Looper getMainLooper() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Executor getMainExecutor() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Context getApplicationContext() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setTheme(int resid) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Resources.Theme getTheme() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public ClassLoader getClassLoader() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public String getPackageName() {
+        throw new UnsupportedOperationException();
+    }
+
+    /** @hide */
+    @Override
+    public String getBasePackageName() {
+        throw new UnsupportedOperationException();
+    }
+
+    /** @hide */
+    @Override
+    public String getOpPackageName() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public ApplicationInfo getApplicationInfo() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public String getPackageResourcePath() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public String getPackageCodePath() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public SharedPreferences getSharedPreferences(String name, int mode) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** @removed */
+    @Override
+    public SharedPreferences getSharedPreferences(File file, int mode) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** @hide */
+    @Override
+    public void reloadSharedPreferences() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean moveSharedPreferencesFrom(Context sourceContext, String name) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean deleteSharedPreferences(String name) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public FileInputStream openFileInput(String name) throws FileNotFoundException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public FileOutputStream openFileOutput(String name, int mode) throws FileNotFoundException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean deleteFile(String name) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public File getFileStreamPath(String name) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** @removed */
+    @Override
+    public File getSharedPreferencesPath(String name) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public String[] fileList() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public File getDataDir() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public File getFilesDir() {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * {@inheritDoc Context#getCrateDir()}
+     * @hide
+     */
+    @Override
+    public File getCrateDir(@NonNull String crateId) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public File getNoBackupFilesDir() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public File getExternalFilesDir(String type) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public File getObbDir() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public File getCacheDir() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public File getCodeCacheDir() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public File getExternalCacheDir() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public File getDir(String name, int mode) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public SQLiteDatabase openOrCreateDatabase(String file, int mode,
+            SQLiteDatabase.CursorFactory factory) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public SQLiteDatabase openOrCreateDatabase(String file, int mode,
+            SQLiteDatabase.CursorFactory factory, DatabaseErrorHandler errorHandler) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public File getDatabasePath(String name) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public String[] databaseList() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean moveDatabaseFrom(Context sourceContext, String name) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean deleteDatabase(String name) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Drawable getWallpaper() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Drawable peekWallpaper() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public int getWallpaperDesiredMinimumWidth() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public int getWallpaperDesiredMinimumHeight() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setWallpaper(Bitmap bitmap) throws IOException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setWallpaper(InputStream data) throws IOException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void clearWallpaper() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void startActivity(Intent intent) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void startActivity(Intent intent, Bundle options) {
+        startActivity(intent);
+    }
+
+    @Override
+    public void startActivities(Intent[] intents) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void startActivities(Intent[] intents, Bundle options) {
+        startActivities(intents);
+    }
+
+    @Override
+    public void startIntentSender(IntentSender intent,
+            Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags)
+            throws IntentSender.SendIntentException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void startIntentSender(IntentSender intent,
+            Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags,
+            Bundle options) throws IntentSender.SendIntentException {
+        startIntentSender(intent, fillInIntent, flagsMask, flagsValues, extraFlags);
+    }
+
+    @Override
+    public void sendBroadcast(Intent intent) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void sendBroadcast(Intent intent, String receiverPermission) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** @hide */
+    @Override
+    public void sendBroadcastMultiplePermissions(Intent intent, String[] receiverPermissions) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** @hide */
+    @Override
+    public void sendBroadcastAsUserMultiplePermissions(Intent intent, UserHandle user,
+            String[] receiverPermissions) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** @hide */
+    @SystemApi
+    @Override
+    public void sendBroadcast(Intent intent, String receiverPermission, Bundle options) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** @hide */
+    @Override
+    public void sendBroadcast(Intent intent, String receiverPermission, int appOp) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void sendOrderedBroadcast(Intent intent,
+            String receiverPermission) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void sendOrderedBroadcast(Intent intent, String receiverPermission,
+            BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData,
+           Bundle initialExtras) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** @hide */
+    @SystemApi
+    @Override
+    public void sendOrderedBroadcast(Intent intent, String receiverPermission,
+            Bundle options, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData,
+            Bundle initialExtras) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** @hide */
+    @Override
+    public void sendOrderedBroadcast(Intent intent, String receiverPermission, int appOp,
+            BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData,
+           Bundle initialExtras) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void sendBroadcastAsUser(Intent intent, UserHandle user) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void sendBroadcastAsUser(Intent intent, UserHandle user,
+            String receiverPermission) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** @hide */
+    @SystemApi
+    @Override
+    public void sendBroadcastAsUser(Intent intent, UserHandle user,
+            String receiverPermission, Bundle options) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** @hide */
+    @Override
+    public void sendBroadcastAsUser(Intent intent, UserHandle user,
+            String receiverPermission, int appOp) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user,
+            String receiverPermission, BroadcastReceiver resultReceiver, Handler scheduler,
+            int initialCode, String initialData, Bundle initialExtras) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** @hide */
+    @Override
+    public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user,
+            String receiverPermission, int appOp, BroadcastReceiver resultReceiver,
+            Handler scheduler, int initialCode, String initialData, Bundle initialExtras) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** @hide */
+    @Override
+    public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user,
+            String receiverPermission, int appOp, Bundle options, BroadcastReceiver resultReceiver,
+            Handler scheduler, int initialCode, String initialData, Bundle initialExtras) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void sendOrderedBroadcast(Intent intent, String receiverPermission,
+            String receiverAppOp, BroadcastReceiver resultReceiver, Handler scheduler,
+            int initialCode, String initialData, Bundle initialExtras) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** @hide */
+    @Override
+    public void sendOrderedBroadcast(Intent intent, int initialCode, String receiverPermission,
+            String receiverAppOp, BroadcastReceiver resultReceiver, Handler scheduler,
+            String initialData, Bundle initialExtras, Bundle options) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void sendStickyBroadcast(Intent intent) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void sendStickyOrderedBroadcast(Intent intent,
+            BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData,
+           Bundle initialExtras) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void removeStickyBroadcast(Intent intent) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void sendStickyBroadcastAsUser(Intent intent, UserHandle user) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** @hide */
+    @Override
+    public void sendStickyBroadcastAsUser(Intent intent, UserHandle user, Bundle options) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void sendStickyOrderedBroadcastAsUser(Intent intent,
+            UserHandle user, BroadcastReceiver resultReceiver,
+            Handler scheduler, int initialCode, String initialData,
+            Bundle initialExtras) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void removeStickyBroadcastAsUser(Intent intent, UserHandle user) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
+            int flags) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
+            String broadcastPermission, Handler scheduler) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
+            String broadcastPermission, Handler scheduler, int flags) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** @hide */
+    @Override
+    @SystemApi
+    public Intent registerReceiverForAllUsers(BroadcastReceiver receiver,
+            IntentFilter filter, String broadcastPermission, Handler scheduler) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** @hide */
+    @Override
+    public Intent registerReceiverAsUser(BroadcastReceiver receiver, UserHandle user,
+            IntentFilter filter, String broadcastPermission, Handler scheduler) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void unregisterReceiver(BroadcastReceiver receiver) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public ComponentName startService(Intent service) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public ComponentName startForegroundService(Intent service) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean stopService(Intent service) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** @hide */
+    @Override
+    public ComponentName startServiceAsUser(Intent service, UserHandle user) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** @hide */
+    @Override
+    public ComponentName startForegroundServiceAsUser(Intent service, UserHandle user) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** @hide */
+    @Override
+    public boolean stopServiceAsUser(Intent service, UserHandle user) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean bindService(Intent service, ServiceConnection conn, int flags) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean bindService(Intent service, int flags, Executor executor,
+            ServiceConnection conn) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean bindIsolatedService(Intent service, int flags, String instanceName,
+            Executor executor, ServiceConnection conn) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** @hide */
+    @Override
+    public boolean bindServiceAsUser(Intent service, ServiceConnection conn, int flags,
+            UserHandle user) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void updateServiceGroup(ServiceConnection conn, int group, int importance) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void unbindService(ServiceConnection conn) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean startInstrumentation(ComponentName className,
+            String profileFile, Bundle arguments) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Object getSystemService(String name) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public String getSystemServiceName(Class<?> serviceClass) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public int checkPermission(String permission, int pid, int uid) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** @hide */
+    @Override
+    public int checkPermission(String permission, int pid, int uid, IBinder callerToken) {
+        return checkPermission(permission, pid, uid);
+    }
+
+    @Override
+    public int checkCallingPermission(String permission) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public int checkCallingOrSelfPermission(String permission) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public int checkSelfPermission(String permission) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void enforcePermission(
+            String permission, int pid, int uid, String message) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void enforceCallingPermission(String permission, String message) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void enforceCallingOrSelfPermission(String permission, String message) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void grantUriPermission(String toPackage, Uri uri, int modeFlags) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void revokeUriPermission(Uri uri, int modeFlags) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void revokeUriPermission(String targetPackage, Uri uri, int modeFlags) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** @hide */
+    @Override
+    public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags, IBinder callerToken) {
+        return checkUriPermission(uri, pid, uid, modeFlags);
+    }
+
+    @Override
+    public int checkCallingUriPermission(Uri uri, int modeFlags) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public int checkCallingOrSelfUriPermission(Uri uri, int modeFlags) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public int checkUriPermission(Uri uri, String readPermission,
+            String writePermission, int pid, int uid, int modeFlags) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void enforceUriPermission(
+            Uri uri, int pid, int uid, int modeFlags, String message) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void enforceCallingUriPermission(
+            Uri uri, int modeFlags, String message) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void enforceCallingOrSelfUriPermission(
+            Uri uri, int modeFlags, String message) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void enforceUriPermission(
+            Uri uri, String readPermission, String writePermission,
+            int pid, int uid, int modeFlags, String message) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Context createPackageContext(String packageName, int flags)
+            throws PackageManager.NameNotFoundException {
+        throw new UnsupportedOperationException();
+    }
+
+    /** {@hide} */
+    @Override
+    public Context createApplicationContext(ApplicationInfo application, int flags)
+            throws PackageManager.NameNotFoundException {
+        return null;
+    }
+
+    /** @hide */
+    @Override
+    public Context createContextForSplit(String splitName)
+            throws PackageManager.NameNotFoundException {
+        throw new UnsupportedOperationException();
+    }
+
+    /** {@hide} */
+    @Override
+    public Context createPackageContextAsUser(String packageName, int flags, UserHandle user)
+            throws PackageManager.NameNotFoundException {
+        throw new UnsupportedOperationException();
+    }
+
+    /** {@hide} */
+    @Override
+    public Context createContextAsUser(UserHandle user, @CreatePackageOptions int flags) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** {@hide} */
+    @Override
+    public int getUserId() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Context createConfigurationContext(Configuration overrideConfiguration) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Context createDisplayContext(Display display) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public @NonNull Context createWindowContext(int type, Bundle options) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean isRestricted() {
+        throw new UnsupportedOperationException();
+    }
+
+    /** @hide */
+    @Override
+    public DisplayAdjustments getDisplayAdjustments(int displayId) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Display getDisplay() {
+        throw new UnsupportedOperationException();
+    }
+
+    /** @hide */
+    @Override
+    public Display getDisplayNoVerify() {
+        throw new UnsupportedOperationException();
+    }
+
+    /** @hide */
+    @Override
+    public int getDisplayId() {
+        throw new UnsupportedOperationException();
+    }
+
+    /** @hide */
+    @Override
+    public void updateDisplay(int displayId) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public File[] getExternalFilesDirs(String type) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public File[] getObbDirs() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public File[] getExternalCacheDirs() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public File[] getExternalMediaDirs() {
+        throw new UnsupportedOperationException();
+    }
+
+    /** @hide **/
+    @Override
+    public File getPreloadsFileCache() { throw new UnsupportedOperationException(); }
+
+    @Override
+    public Context createDeviceProtectedStorageContext() {
+        throw new UnsupportedOperationException();
+    }
+
+    /** {@hide} */
+    @SystemApi
+    @Override
+    public Context createCredentialProtectedStorageContext() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean isDeviceProtectedStorage() {
+        throw new UnsupportedOperationException();
+    }
+
+    /** {@hide} */
+    @SystemApi
+    @Override
+    public boolean isCredentialProtectedStorage() {
+        throw new UnsupportedOperationException();
+    }
+
+    /** {@hide} */
+    @Override
+    public boolean canLoadUnsafeResources() {
+        throw new UnsupportedOperationException();
+    }
+
+    /** {@hide} */
+    @Override
+    public IBinder getActivityToken() {
+        throw new UnsupportedOperationException();
+    }
+
+    /** {@hide} */
+    @Override
+    public IServiceConnection getServiceDispatcher(ServiceConnection conn, Handler handler,
+            int flags) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** {@hide} */
+    @Override
+    public IApplicationThread getIApplicationThread() {
+        throw new UnsupportedOperationException();
+    }
+
+    /** {@hide} */
+    @Override
+    public Handler getMainThreadHandler() {
+        throw new UnsupportedOperationException();
+    }
+
+    /** {@hide} */
+    @Override
+    public boolean isUiContext() {
+        throw new UnsupportedOperationException();
+    }
+}
diff --git a/android/test/mock/MockCursor.java b/android/test/mock/MockCursor.java
new file mode 100644
index 0000000..f69db2c
--- /dev/null
+++ b/android/test/mock/MockCursor.java
@@ -0,0 +1,259 @@
+/*
+ * Copyright (C) 2009 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.test.mock;
+
+import android.content.ContentResolver;
+import android.database.CharArrayBuffer;
+import android.database.ContentObserver;
+import android.database.Cursor;
+import android.database.DataSetObserver;
+import android.net.Uri;
+import android.os.Bundle;
+
+import java.util.List;
+
+/**
+ * A mock {@link android.database.Cursor} class that isolates the test code from real
+ * Cursor implementation.
+ *
+ * <p>
+ * All methods including ones related to querying the state of the cursor are
+ * are non-functional and throw {@link java.lang.UnsupportedOperationException}.
+ *
+ * @deprecated Use a mocking framework like <a href="https://github.com/mockito/mockito">Mockito</a>.
+ * New tests should be written using the
+ * <a href="{@docRoot}tools/testing-support-library/index.html">Android Testing Support Library</a>.
+ */
+@Deprecated
+public class MockCursor implements Cursor {
+    @Override
+    public int getColumnCount() {
+        throw new UnsupportedOperationException("unimplemented mock method");
+    }
+
+    @Override
+    public int getColumnIndex(String columnName) {
+        throw new UnsupportedOperationException("unimplemented mock method");
+    }
+
+    @Override
+    public int getColumnIndexOrThrow(String columnName) {
+        throw new UnsupportedOperationException("unimplemented mock method");
+    }
+
+    @Override
+    public String getColumnName(int columnIndex) {
+        throw new UnsupportedOperationException("unimplemented mock method");
+    }
+
+    @Override
+    public String[] getColumnNames() {
+        throw new UnsupportedOperationException("unimplemented mock method");
+    }
+
+    @Override
+    public int getCount() {
+        throw new UnsupportedOperationException("unimplemented mock method");
+    }
+
+    @Override
+    public boolean isNull(int columnIndex) {
+        throw new UnsupportedOperationException("unimplemented mock method");
+    }
+
+    @Override
+    public int getInt(int columnIndex) {
+        throw new UnsupportedOperationException("unimplemented mock method");
+    }
+
+    @Override
+    public long getLong(int columnIndex) {
+        throw new UnsupportedOperationException("unimplemented mock method");
+    }
+
+    @Override
+    public short getShort(int columnIndex) {
+        throw new UnsupportedOperationException("unimplemented mock method");
+    }
+
+    @Override
+    public float getFloat(int columnIndex) {
+        throw new UnsupportedOperationException("unimplemented mock method");
+    }
+
+    @Override
+    public double getDouble(int columnIndex) {
+        throw new UnsupportedOperationException("unimplemented mock method");
+    }
+
+    @Override
+    public byte[] getBlob(int columnIndex) {
+        throw new UnsupportedOperationException("unimplemented mock method");
+    }
+
+    @Override
+    public String getString(int columnIndex) {
+        throw new UnsupportedOperationException("unimplemented mock method");
+    }
+
+    @Override
+    public void setExtras(Bundle extras) {
+        throw new UnsupportedOperationException("unimplemented mock method");
+    }
+
+    @Override
+    public Bundle getExtras() {
+        throw new UnsupportedOperationException("unimplemented mock method");
+    }
+
+    @Override
+    public int getPosition() {
+        throw new UnsupportedOperationException("unimplemented mock method");
+    }
+
+    @Override
+    public boolean isAfterLast() {
+        throw new UnsupportedOperationException("unimplemented mock method");
+    }
+
+    @Override
+    public boolean isBeforeFirst() {
+        throw new UnsupportedOperationException("unimplemented mock method");
+    }
+
+    @Override
+    public boolean isFirst() {
+        throw new UnsupportedOperationException("unimplemented mock method");
+    }
+
+    @Override
+    public boolean isLast() {
+        throw new UnsupportedOperationException("unimplemented mock method");
+    }
+
+    @Override
+    public boolean move(int offset) {
+        throw new UnsupportedOperationException("unimplemented mock method");
+    }
+
+    @Override
+    public boolean moveToFirst() {
+        throw new UnsupportedOperationException("unimplemented mock method");
+    }
+
+    @Override
+    public boolean moveToLast() {
+        throw new UnsupportedOperationException("unimplemented mock method");
+    }
+
+    @Override
+    public boolean moveToNext() {
+        throw new UnsupportedOperationException("unimplemented mock method");
+    }
+
+    @Override
+    public boolean moveToPrevious() {
+        throw new UnsupportedOperationException("unimplemented mock method");
+    }
+
+    @Override
+    public boolean moveToPosition(int position) {
+        throw new UnsupportedOperationException("unimplemented mock method");
+    }
+
+    @Override
+    public void copyStringToBuffer(int columnIndex, CharArrayBuffer buffer) {
+        throw new UnsupportedOperationException("unimplemented mock method");
+    }
+
+    @Override
+    @Deprecated
+    public void deactivate() {
+        throw new UnsupportedOperationException("unimplemented mock method");
+    }
+
+    @Override
+    public void close() {
+        throw new UnsupportedOperationException("unimplemented mock method");
+    }
+
+    @Override
+    public boolean isClosed() {
+        throw new UnsupportedOperationException("unimplemented mock method");
+    }
+
+    @Override
+    @Deprecated
+    public boolean requery() {
+        throw new UnsupportedOperationException("unimplemented mock method");
+    }
+
+    @Override
+    public void registerContentObserver(ContentObserver observer) {
+        throw new UnsupportedOperationException("unimplemented mock method");
+    }
+
+    @Override
+    public void registerDataSetObserver(DataSetObserver observer) {
+        throw new UnsupportedOperationException("unimplemented mock method");
+    }
+
+    @Override
+    public Bundle respond(Bundle extras) {
+        throw new UnsupportedOperationException("unimplemented mock method");
+    }
+
+    @Override
+    public boolean getWantsAllOnMoveCalls() {
+        throw new UnsupportedOperationException("unimplemented mock method");
+    }
+
+    @Override
+    public void setNotificationUri(ContentResolver cr, Uri uri) {
+        throw new UnsupportedOperationException("unimplemented mock method");
+    }
+
+    @Override
+    public void setNotificationUris(ContentResolver cr, List<Uri> uris) {
+        throw new UnsupportedOperationException("unimplemented mock method");
+    }
+
+    @Override
+    public Uri getNotificationUri() {
+        throw new UnsupportedOperationException("unimplemented mock method");
+    }
+
+    @Override
+    public List<Uri> getNotificationUris() {
+        throw new UnsupportedOperationException("unimplemented mock method");
+    }
+
+    @Override
+    public void unregisterContentObserver(ContentObserver observer) {
+        throw new UnsupportedOperationException("unimplemented mock method");
+    }
+
+    @Override
+    public void unregisterDataSetObserver(DataSetObserver observer) {
+        throw new UnsupportedOperationException("unimplemented mock method");
+    }
+
+    @Override
+    public int getType(int columnIndex) {
+        throw new UnsupportedOperationException("unimplemented mock method");
+    }
+}
\ No newline at end of file
diff --git a/android/test/mock/MockDialogInterface.java b/android/test/mock/MockDialogInterface.java
new file mode 100644
index 0000000..d0a5a09
--- /dev/null
+++ b/android/test/mock/MockDialogInterface.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2008 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.test.mock;
+
+import android.content.DialogInterface;
+
+/**
+ * A mock {@link android.content.DialogInterface} class.  All methods are non-functional and throw
+ * {@link java.lang.UnsupportedOperationException}. Override it to provide the operations that you
+ * need.
+ *
+ * @deprecated Use a mocking framework like <a href="https://github.com/mockito/mockito">Mockito</a>.
+ * New tests should be written using the
+ * <a href="{@docRoot}tools/testing-support-library/index.html">Android Testing Support Library</a>.
+ */
+@Deprecated
+public class MockDialogInterface implements DialogInterface {
+    public void cancel() {
+        throw new UnsupportedOperationException("not implemented yet");
+    }
+
+    public void dismiss() {
+        throw new UnsupportedOperationException("not implemented yet");
+    }
+}
diff --git a/android/test/mock/MockIContentProvider.java b/android/test/mock/MockIContentProvider.java
new file mode 100644
index 0000000..223bcc5
--- /dev/null
+++ b/android/test/mock/MockIContentProvider.java
@@ -0,0 +1,182 @@
+/*
+ * Copyright (C) 2009 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.test.mock;
+
+import android.annotation.Nullable;
+import android.content.ContentProviderOperation;
+import android.content.ContentProviderResult;
+import android.content.ContentResolver;
+import android.content.ContentValues;
+import android.content.EntityIterator;
+import android.content.IContentProvider;
+import android.content.res.AssetFileDescriptor;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.ICancellationSignal;
+import android.os.ParcelFileDescriptor;
+import android.os.RemoteCallback;
+import android.os.RemoteException;
+
+import java.io.FileNotFoundException;
+import java.util.ArrayList;
+
+/**
+ * Mock implementation of IContentProvider.  All methods are non-functional and throw
+ * {@link java.lang.UnsupportedOperationException}.  Tests can extend this class to
+ * implement behavior needed for tests.
+ *
+ * @hide - @hide because this exposes bulkQuery() and call(), which must also be hidden.
+ */
+public class MockIContentProvider implements IContentProvider {
+    @Override
+    public int bulkInsert(String callingPackage, @Nullable String featureId, Uri url,
+            ContentValues[] initialValues) {
+        throw new UnsupportedOperationException("unimplemented mock method");
+    }
+
+    @Override
+    @SuppressWarnings("unused")
+    public int delete(String callingPackage, @Nullable String featureId, Uri url,
+            Bundle extras) throws RemoteException {
+        throw new UnsupportedOperationException("unimplemented mock method");
+    }
+
+    @Override
+    public String getType(Uri url) {
+        throw new UnsupportedOperationException("unimplemented mock method");
+    }
+
+    @Override
+    @SuppressWarnings("deprecation")
+    public void getTypeAsync(Uri uri, RemoteCallback remoteCallback) {
+        AsyncTask.SERIAL_EXECUTOR.execute(() -> {
+            final Bundle bundle = new Bundle();
+            bundle.putString(ContentResolver.REMOTE_CALLBACK_RESULT, getType(uri));
+            remoteCallback.sendResult(bundle);
+        });
+    }
+
+    @Override
+    @SuppressWarnings("unused")
+    public Uri insert(String callingPackage, @Nullable String featureId, Uri url,
+            ContentValues initialValues, Bundle extras) throws RemoteException {
+        throw new UnsupportedOperationException("unimplemented mock method");
+    }
+
+    @Override
+    public ParcelFileDescriptor openFile(String callingPackage, @Nullable String featureId,
+            Uri url, String mode, ICancellationSignal signal, IBinder callerToken) {
+        throw new UnsupportedOperationException("unimplemented mock method");
+    }
+
+    @Override
+    public AssetFileDescriptor openAssetFile(String callingPackage, @Nullable String featureId,
+            Uri uri, String mode, ICancellationSignal signal) {
+        throw new UnsupportedOperationException("unimplemented mock method");
+    }
+
+    @Override
+    public ContentProviderResult[] applyBatch(String callingPackage, @Nullable String featureId,
+            String authority, ArrayList<ContentProviderOperation> operations) {
+        throw new UnsupportedOperationException("unimplemented mock method");
+    }
+
+    @Override
+    public Cursor query(String callingPackage, @Nullable String featureId, Uri url,
+            @Nullable String[] projection, @Nullable Bundle queryArgs,
+            @Nullable ICancellationSignal cancellationSignal) {
+        throw new UnsupportedOperationException("unimplemented mock method");
+    }
+
+    public EntityIterator queryEntities(Uri url, String selection, String[] selectionArgs,
+            String sortOrder) {
+        throw new UnsupportedOperationException("unimplemented mock method");
+    }
+
+    @Override
+    public int update(String callingPackage, @Nullable String featureId, Uri url,
+            ContentValues values, Bundle extras) throws RemoteException {
+        throw new UnsupportedOperationException("unimplemented mock method");
+    }
+
+    @Override
+    public Bundle call(String callingPackage, @Nullable String featureId, String authority,
+            String method, String request, Bundle args) throws RemoteException {
+        throw new UnsupportedOperationException("unimplemented mock method");
+    }
+
+    @Override
+    public IBinder asBinder() {
+        throw new UnsupportedOperationException("unimplemented mock method");
+    }
+
+    @Override
+    public String[] getStreamTypes(Uri url, String mimeTypeFilter) throws RemoteException {
+        throw new UnsupportedOperationException("unimplemented mock method");
+    }
+
+    @Override
+    public AssetFileDescriptor openTypedAssetFile(String callingPackage,
+            @Nullable String featureId, Uri url, String mimeType, Bundle opts,
+            ICancellationSignal signal) throws RemoteException, FileNotFoundException {
+        throw new UnsupportedOperationException("unimplemented mock method");
+    }
+
+    @Override
+    public ICancellationSignal createCancellationSignal() throws RemoteException {
+        throw new UnsupportedOperationException("unimplemented mock method");
+    }
+
+    @Override
+    public Uri canonicalize(String callingPkg, @Nullable String featureId, Uri uri) {
+        throw new UnsupportedOperationException("unimplemented mock method");
+    }
+
+    @Override
+    @SuppressWarnings("deprecation")
+    public void canonicalizeAsync(String callingPkg, String featureId, Uri uri,
+            RemoteCallback remoteCallback) {
+        AsyncTask.SERIAL_EXECUTOR.execute(() -> {
+            final Bundle bundle = new Bundle();
+            bundle.putParcelable(ContentResolver.REMOTE_CALLBACK_RESULT,
+                    canonicalize(callingPkg, featureId, uri));
+            remoteCallback.sendResult(bundle);
+        });
+    }
+
+    @Override
+    public Uri uncanonicalize(String callingPkg, @Nullable String featureId, Uri uri)
+            throws RemoteException {
+        throw new UnsupportedOperationException("unimplemented mock method");
+    }
+
+    @Override
+    public boolean refresh(String callingPkg, @Nullable String featureId, Uri url, Bundle args,
+            ICancellationSignal cancellationSignal) throws RemoteException {
+        throw new UnsupportedOperationException("unimplemented mock method");
+    }
+
+    /** {@hide} */
+    @Override
+    public int checkUriPermission(String callingPkg, @Nullable String featureId, Uri uri, int uid,
+            int modeFlags) {
+        throw new UnsupportedOperationException("unimplemented mock method call");
+    }
+}
diff --git a/android/test/mock/MockPackageManager.java b/android/test/mock/MockPackageManager.java
new file mode 100644
index 0000000..5f95bc1
--- /dev/null
+++ b/android/test/mock/MockPackageManager.java
@@ -0,0 +1,1252 @@
+/*
+ * Copyright (C) 2008 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.test.mock;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.IntentSender;
+import android.content.pm.ActivityInfo;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.ChangedPackages;
+import android.content.pm.FeatureInfo;
+import android.content.pm.IPackageDataObserver;
+import android.content.pm.IPackageDeleteObserver;
+import android.content.pm.IPackageStatsObserver;
+import android.content.pm.InstantAppInfo;
+import android.content.pm.InstrumentationInfo;
+import android.content.pm.IntentFilterVerificationInfo;
+import android.content.pm.KeySet;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageInstaller;
+import android.content.pm.PackageItemInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PermissionGroupInfo;
+import android.content.pm.PermissionInfo;
+import android.content.pm.ProviderInfo;
+import android.content.pm.ResolveInfo;
+import android.content.pm.ServiceInfo;
+import android.content.pm.SharedLibraryInfo;
+import android.content.pm.VerifierDeviceIdentity;
+import android.content.pm.VersionedPackage;
+import android.content.pm.dex.ArtManager;
+import android.content.res.Resources;
+import android.content.res.XmlResourceParser;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+import android.os.Handler;
+import android.os.PersistableBundle;
+import android.os.UserHandle;
+import android.os.storage.VolumeInfo;
+
+import java.util.List;
+import java.util.Set;
+
+/**
+ * A mock {@link android.content.pm.PackageManager} class.  All methods are non-functional and throw
+ * {@link java.lang.UnsupportedOperationException}. Override it to provide the operations that you
+ * need.
+ *
+ * @deprecated Use a mocking framework like <a href="https://github.com/mockito/mockito">Mockito</a>.
+ * New tests should be written using the
+ * <a href="{@docRoot}tools/testing-support-library/index.html">Android Testing Support Library</a>.
+ */
+@Deprecated
+public class MockPackageManager extends PackageManager {
+
+    @Override
+    public PackageInfo getPackageInfo(String packageName, int flags) throws NameNotFoundException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public PackageInfo getPackageInfo(VersionedPackage versionedPackage,
+            int flags) throws NameNotFoundException {
+        throw new UnsupportedOperationException();
+    }
+
+    /** @hide */
+    @Override
+    public PackageInfo getPackageInfoAsUser(String packageName, int flags, int userId)
+            throws NameNotFoundException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public String[] currentToCanonicalPackageNames(String[] names) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public String[] canonicalToCurrentPackageNames(String[] names) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Intent getLaunchIntentForPackage(String packageName) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Intent getLeanbackLaunchIntentForPackage(String packageName) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** @hide */
+    @Override
+    public Intent getCarLaunchIntentForPackage(String packageName) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public int[] getPackageGids(String packageName) throws NameNotFoundException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public int[] getPackageGids(String packageName, int flags) throws NameNotFoundException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public int getPackageUid(String packageName, int flags) throws NameNotFoundException {
+        throw new UnsupportedOperationException();
+    }
+
+    /** @hide */
+    @Override
+    public int getPackageUidAsUser(String packageName, int flags, int userHandle)
+            throws NameNotFoundException {
+        throw new UnsupportedOperationException();
+    }
+
+    /** @hide */
+    @Override
+    public int getPackageUidAsUser(String packageName, int userHandle)
+            throws NameNotFoundException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public PermissionInfo getPermissionInfo(String name, int flags)
+    throws NameNotFoundException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public List<PermissionInfo> queryPermissionsByGroup(String group, int flags)
+            throws NameNotFoundException {
+        throw new UnsupportedOperationException();
+    }
+
+    /** @hide */
+    @Override
+    public boolean arePermissionsIndividuallyControlled() {
+        return false;
+    }
+
+    /** @hide */
+    @Override
+    public boolean isWirelessConsentModeEnabled() {
+        return false;
+    }
+
+    @Override
+    public PermissionGroupInfo getPermissionGroupInfo(String name,
+            int flags) throws NameNotFoundException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public List<PermissionGroupInfo> getAllPermissionGroups(int flags) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public ApplicationInfo getApplicationInfo(String packageName, int flags)
+            throws NameNotFoundException {
+        throw new UnsupportedOperationException();
+    }
+
+    /** @hide */
+    @Override
+    public ApplicationInfo getApplicationInfoAsUser(String packageName, int flags, int userId)
+            throws NameNotFoundException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public ActivityInfo getActivityInfo(ComponentName className, int flags)
+    throws NameNotFoundException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public ActivityInfo getReceiverInfo(ComponentName className, int flags)
+    throws NameNotFoundException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public ServiceInfo getServiceInfo(ComponentName className, int flags)
+    throws NameNotFoundException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public ProviderInfo getProviderInfo(ComponentName className, int flags)
+    throws NameNotFoundException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public List<PackageInfo> getInstalledPackages(int flags) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public List<PackageInfo> getPackagesHoldingPermissions(String[] permissions,
+            int flags) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** @hide */
+    @Override
+    public List<PackageInfo> getInstalledPackagesAsUser(int flags, int userId) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public int checkPermission(String permName, String pkgName) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean canRequestPackageInstalls() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean isPermissionRevokedByPolicy(String permName, String pkgName) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** @hide */
+    @Override
+    public String getPermissionControllerPackageName() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean addPermission(PermissionInfo info) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean addPermissionAsync(PermissionInfo info) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void removePermission(String name) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** @hide */
+    @Override
+    public void grantRuntimePermission(String packageName, String permissionName,
+            UserHandle user) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** @hide */
+    @Override
+    public void revokeRuntimePermission(String packageName, String permissionName,
+            UserHandle user) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** @hide */
+    @Override
+    public int getPermissionFlags(String permissionName, String packageName, UserHandle user) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** @hide */
+    @Override
+    public void updatePermissionFlags(String permissionName, String packageName,
+            int flagMask, int flagValues, UserHandle user) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** @hide */
+    @Override
+    public @NonNull Set<String> getWhitelistedRestrictedPermissions(
+            @NonNull String packageName, @PermissionWhitelistFlags int whitelistFlags) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** @hide */
+    @Override
+    public boolean addWhitelistedRestrictedPermission(@NonNull String packageName,
+            @NonNull String permission, @PermissionWhitelistFlags int whitelistFlags) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** @hide */
+    @Override
+    public boolean removeWhitelistedRestrictedPermission(@NonNull String packageName,
+            @NonNull String permission, @PermissionWhitelistFlags int whitelistFlags) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** @hide */
+    @Override
+    public boolean shouldShowRequestPermissionRationale(String permission) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** @hide */
+    @Override
+    public void addOnPermissionsChangeListener(OnPermissionsChangedListener listener) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** @hide */
+    @Override
+    public void removeOnPermissionsChangeListener(OnPermissionsChangedListener listener) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public int checkSignatures(String pkg1, String pkg2) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public int checkSignatures(int uid1, int uid2) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public String[] getPackagesForUid(int uid) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public String getNameForUid(int uid) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** @hide */
+    @Override
+    public String[] getNamesForUids(int uid[]) {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * @hide - to match hiding in superclass
+     */
+    @Override
+    public int getUidForSharedUser(String sharedUserName) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public List<ApplicationInfo> getInstalledApplications(int flags) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** @hide */
+    @Override
+    public List<ApplicationInfo> getInstalledApplicationsAsUser(int flags, int userId) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** @hide */
+    @Override
+    public List<InstantAppInfo> getInstantApps() {
+        throw new UnsupportedOperationException();
+    }
+
+    /** @hide */
+    @Override
+    public Drawable getInstantAppIcon(String packageName) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** @hide */
+    @Override
+    public byte[] getInstantAppCookie() {
+        throw new UnsupportedOperationException();
+    }
+
+    /** @hide */
+    @Override
+    public boolean isInstantApp() {
+        throw new UnsupportedOperationException();
+    }
+
+    /** @hide */
+    @Override
+    public boolean isInstantApp(String packageName) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** @hide */
+    @Override
+    public int getInstantAppCookieMaxBytes() {
+        throw new UnsupportedOperationException();
+    }
+
+    /** @hide */
+    @Override
+    public int getInstantAppCookieMaxSize() {
+        throw new UnsupportedOperationException();
+    }
+
+    /** @hide */
+    @Override
+    public void clearInstantAppCookie() {
+        throw new UnsupportedOperationException();
+    }
+
+    /** @hide */
+    @Override
+    public void updateInstantAppCookie(@NonNull byte[] cookie) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** @hide */
+    @Override
+    public boolean setInstantAppCookie(@NonNull byte[] cookie) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** @hide */
+    @Override
+    public ChangedPackages getChangedPackages(int sequenceNumber) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public ResolveInfo resolveActivity(Intent intent, int flags) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** @hide */
+    @Override
+    public ResolveInfo resolveActivityAsUser(Intent intent, int flags, int userId) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public List<ResolveInfo> queryIntentActivities(Intent intent, int flags) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** @hide */
+    @Override
+    public List<ResolveInfo> queryIntentActivitiesAsUser(Intent intent,
+                                                   int flags, int userId) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public List<ResolveInfo> queryIntentActivityOptions(ComponentName caller,
+            Intent[] specifics, Intent intent, int flags) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public List<ResolveInfo> queryBroadcastReceivers(Intent intent, int flags) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** @hide */
+    @Override
+    public List<ResolveInfo> queryBroadcastReceiversAsUser(Intent intent, int flags, int userId) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public ResolveInfo resolveService(Intent intent, int flags) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public ResolveInfo resolveServiceAsUser(Intent intent, int flags, int userId) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public List<ResolveInfo> queryIntentServices(Intent intent, int flags) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** @hide */
+    @Override
+    public List<ResolveInfo> queryIntentServicesAsUser(Intent intent, int flags, int userId) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** @hide */
+    @Override
+    public List<ResolveInfo> queryIntentContentProvidersAsUser(
+            Intent intent, int flags, int userId) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public List<ResolveInfo> queryIntentContentProviders(Intent intent, int flags) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public ProviderInfo resolveContentProvider(String name, int flags) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** @hide */
+    @Override
+    public ProviderInfo resolveContentProviderAsUser(String name, int flags, int userId) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public List<ProviderInfo> queryContentProviders(String processName, int uid, int flags) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public InstrumentationInfo getInstrumentationInfo(ComponentName className, int flags)
+    throws NameNotFoundException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public List<InstrumentationInfo> queryInstrumentation(
+            String targetPackage, int flags) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Drawable getDrawable(String packageName, int resid, ApplicationInfo appInfo) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Drawable getActivityIcon(ComponentName activityName)
+    throws NameNotFoundException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Drawable getActivityIcon(Intent intent) throws NameNotFoundException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Drawable getDefaultActivityIcon() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Drawable getActivityBanner(ComponentName activityName)
+            throws NameNotFoundException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Drawable getActivityBanner(Intent intent) throws NameNotFoundException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Drawable getApplicationBanner(ApplicationInfo info) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Drawable getApplicationBanner(String packageName) throws NameNotFoundException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Drawable getApplicationIcon(ApplicationInfo info) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Drawable getApplicationIcon(String packageName) throws NameNotFoundException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Drawable getActivityLogo(ComponentName activityName) throws NameNotFoundException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Drawable getActivityLogo(Intent intent) throws NameNotFoundException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Drawable getApplicationLogo(ApplicationInfo info) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Drawable getApplicationLogo(String packageName) throws NameNotFoundException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Drawable getUserBadgedIcon(Drawable icon, UserHandle user) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Drawable getUserBadgedDrawableForDensity(Drawable drawable, UserHandle user,
+            Rect badgeLocation,
+            int badgeDensity) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** @hide */
+    @Override
+    public Drawable getUserBadgeForDensity(UserHandle user, int density) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** @hide */
+    @Override
+    public Drawable getUserBadgeForDensityNoBackground(UserHandle user, int density) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public CharSequence getUserBadgedLabel(CharSequence label, UserHandle user) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public CharSequence getText(String packageName, int resid, ApplicationInfo appInfo) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public XmlResourceParser getXml(String packageName, int resid,
+            ApplicationInfo appInfo) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public CharSequence getApplicationLabel(ApplicationInfo info) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Resources getResourcesForActivity(ComponentName activityName)
+    throws NameNotFoundException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Resources getResourcesForApplication(ApplicationInfo app) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Resources getResourcesForApplication(String appPackageName)
+    throws NameNotFoundException {
+        throw new UnsupportedOperationException();
+    }
+
+    /** @hide */
+    @Override
+    public Resources getResourcesForApplicationAsUser(String appPackageName, int userId) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public PackageInfo getPackageArchiveInfo(String archiveFilePath, int flags) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setInstallerPackageName(String targetPackage,
+            String installerPackageName) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** @hide */
+    @Override
+    public void setUpdateAvailable(String packageName, boolean updateAvailable) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public String getInstallerPackageName(String packageName) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** {@hide} */
+    @Override
+    public int getMoveStatus(int moveId) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** {@hide} */
+    @Override
+    public void registerMoveCallback(MoveCallback callback, Handler handler) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** {@hide} */
+    @Override
+    public void unregisterMoveCallback(MoveCallback callback) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** {@hide} */
+    @Override
+    public int movePackage(String packageName, VolumeInfo vol) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** {@hide} */
+    @Override
+    public VolumeInfo getPackageCurrentVolume(ApplicationInfo app) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** {@hide} */
+    @Override
+    public List<VolumeInfo> getPackageCandidateVolumes(ApplicationInfo app) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** {@hide} */
+    @Override
+    public int movePrimaryStorage(VolumeInfo vol) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** {@hide} */
+    @Override
+    public VolumeInfo getPrimaryStorageCurrentVolume() {
+        throw new UnsupportedOperationException();
+    }
+
+    /** {@hide} */
+    @Override
+    public List<VolumeInfo> getPrimaryStorageCandidateVolumes() {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * @hide - to match hiding in superclass
+     */
+    @Override
+    public void clearApplicationUserData(
+            String packageName, IPackageDataObserver observer) {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * @hide - to match hiding in superclass
+     */
+    @Override
+    public void deleteApplicationCacheFiles(
+            String packageName, IPackageDataObserver observer) {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * @hide - to match hiding in superclass
+     */
+    @Override
+    public void deleteApplicationCacheFilesAsUser(String packageName, int userId,
+            IPackageDataObserver observer) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** {@hide} */
+    @Override
+    public void freeStorageAndNotify(String volumeUuid, long idealStorageSize,
+            IPackageDataObserver observer) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** {@hide} */
+    @Override
+    public void freeStorage(String volumeUuid, long idealStorageSize, IntentSender pi) {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * @hide - to match hiding in superclass
+     */
+    @Override
+    public void deletePackage(String packageName, IPackageDeleteObserver observer, int flags) {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * @hide - to match hiding in superclass
+     */
+    @Override
+    public void deletePackageAsUser(String packageName, IPackageDeleteObserver observer,
+            int flags, int userId) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void addPackageToPreferred(String packageName) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void removePackageFromPreferred(String packageName) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public List<PackageInfo> getPreferredPackages(int flags) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setComponentEnabledSetting(ComponentName componentName,
+            int newState, int flags) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public int getComponentEnabledSetting(ComponentName componentName) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setApplicationEnabledSetting(String packageName, int newState, int flags) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public int getApplicationEnabledSetting(String packageName) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** @hide */
+    @Override
+    public void flushPackageRestrictionsAsUser(int userId) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void addPreferredActivity(IntentFilter filter,
+            int match, ComponentName[] set, ComponentName activity) {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * @hide - to match hiding in superclass
+     */
+    @Override
+    public void replacePreferredActivity(IntentFilter filter,
+            int match, ComponentName[] set, ComponentName activity) {
+        throw new UnsupportedOperationException();
+    }
+
+
+    @Override
+    public void clearPackagePreferredActivities(String packageName) {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * @hide - to match hiding in superclass
+     */
+    @Override
+    public void getPackageSizeInfoAsUser(String packageName, int userHandle,
+            IPackageStatsObserver observer) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public int getPreferredActivities(List<IntentFilter> outFilters,
+            List<ComponentName> outActivities, String packageName) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** @hide - hidden in superclass */
+    @Override
+    public ComponentName getHomeActivities(List<ResolveInfo> outActivities) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public String[] getSystemSharedLibraryNames() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public @NonNull List<SharedLibraryInfo> getSharedLibraries(int flags) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** @hide */
+    @Override
+    public @NonNull List<SharedLibraryInfo> getSharedLibrariesAsUser(int flags, int userId) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** @hide */
+    @Override
+    public @NonNull String getServicesSystemSharedLibraryPackageName() {
+        throw new UnsupportedOperationException();
+    }
+
+    /** @hide */
+    @Override
+    public @NonNull String getSharedSystemSharedLibraryPackageName() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public FeatureInfo[] getSystemAvailableFeatures() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean hasSystemFeature(String name) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean hasSystemFeature(String name, int version) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean isSafeMode() {
+        throw new UnsupportedOperationException();
+    }
+
+    /** @hide */
+    @Override
+    public KeySet getKeySetByAlias(String packageName, String alias) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** @hide */
+    @Override
+    public KeySet getSigningKeySet(String packageName) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** @hide */
+    @Override
+    public boolean isSignedBy(String packageName, KeySet ks) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** @hide */
+    @Override
+    public boolean isSignedByExactly(String packageName, KeySet ks) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** @hide */
+    @Override
+    public String[] setPackagesSuspended(String[] packageNames, boolean hidden,
+            PersistableBundle appExtras, PersistableBundle launcherExtras, String dialogMessage) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** @hide */
+    @Override
+    public boolean isPackageSuspendedForUser(String packageName, int userId) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** @hide */
+    @Override
+    public void setApplicationCategoryHint(String packageName, int categoryHint) {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden,
+            UserHandle user) {
+        return false;
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    public boolean getApplicationHiddenSettingAsUser(String packageName, UserHandle user) {
+        return false;
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    public int installExistingPackage(String packageName) throws NameNotFoundException {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    public int installExistingPackage(String packageName, int installReason)
+            throws NameNotFoundException {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    public int installExistingPackageAsUser(String packageName, int userId)
+            throws NameNotFoundException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void verifyPendingInstall(int id, int verificationCode) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void extendVerificationTimeout(int id, int verificationCodeAtTimeout,
+            long millisecondsToDelay) {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    public void verifyIntentFilter(int id, int verificationCode, List<String> outFailedDomains) {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    public int getIntentVerificationStatusAsUser(String packageName, int userId) {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    public boolean updateIntentVerificationStatusAsUser(String packageName, int status, int userId) {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    public List<IntentFilterVerificationInfo> getIntentFilterVerifications(String packageName) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public List<IntentFilter> getAllIntentFilters(String packageName) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** {@removed} */
+    @Deprecated
+    public String getDefaultBrowserPackageName(int userId) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** {@hide} */
+    @Override
+    public String getDefaultBrowserPackageNameAsUser(int userId) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** {@removed} */
+    @Deprecated
+    public boolean setDefaultBrowserPackageName(String packageName, int userId) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** {@hide} */
+    @Override
+    public boolean setDefaultBrowserPackageNameAsUser(String packageName, int userId) {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    public VerifierDeviceIdentity getVerifierDeviceIdentity() {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    public boolean isUpgrade() {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    public boolean isDeviceUpgrading() {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    public void addCrossProfileIntentFilter(IntentFilter filter, int sourceUserId, int targetUserId,
+            int flags) {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    public void clearCrossProfileIntentFilters(int sourceUserId) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** {@hide} */
+    public PackageInstaller getPackageInstaller() {
+        throw new UnsupportedOperationException();
+    }
+
+    /** {@hide} */
+    @Override
+    public boolean isPackageAvailable(String packageName) {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * @hide
+     */
+    public Drawable loadItemIcon(PackageItemInfo itemInfo, ApplicationInfo appInfo) {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * @hide
+     */
+    public Drawable loadUnbadgedItemIcon(PackageItemInfo itemInfo, ApplicationInfo appInfo) {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * @hide
+     */
+    public int getInstallReason(String packageName, UserHandle user) {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    public ComponentName getInstantAppResolverSettingsComponent() {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    public ComponentName getInstantAppInstallerComponent() {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * @hide
+     */
+    public String getInstantAppAndroidId(String packageName, UserHandle user) {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    public void registerDexModule(String dexModulePath,
+            @Nullable DexModuleRegisterCallback callback) {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    public ArtManager getArtManager() {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    public void setHarmfulAppWarning(String packageName, CharSequence warning) {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    public CharSequence getHarmfulAppWarning(String packageName) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean hasSigningCertificate(
+            String packageName, byte[] certificate, @PackageManager.CertificateInputType int type) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean hasSigningCertificate(
+            int uid, byte[] certificate, @PackageManager.CertificateInputType int type) {
+        throw new UnsupportedOperationException();
+    }
+}
diff --git a/android/test/mock/MockResources.java b/android/test/mock/MockResources.java
new file mode 100644
index 0000000..880343e
--- /dev/null
+++ b/android/test/mock/MockResources.java
@@ -0,0 +1,227 @@
+/*
+ * Copyright (C) 2008 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.test.mock;
+
+import android.content.res.AssetManager;
+import android.content.res.Resources;
+import android.content.res.Configuration;
+import android.content.res.TypedArray;
+import android.content.res.ColorStateList;
+import android.content.res.XmlResourceParser;
+import android.content.res.AssetFileDescriptor;
+import android.util.DisplayMetrics;
+import android.util.TypedValue;
+import android.util.AttributeSet;
+import android.graphics.drawable.Drawable;
+import android.graphics.Movie;
+
+import java.io.InputStream;
+
+/**
+ * A mock {@link android.content.res.Resources} class. All methods are non-functional and throw
+ * {@link java.lang.UnsupportedOperationException}. Override it to provide the operations that you
+ * need.
+ *
+ * @deprecated Use a mocking framework like <a href="https://github.com/mockito/mockito">Mockito</a>.
+ * New tests should be written using the
+ * <a href="{@docRoot}tools/testing-support-library/index.html">Android Testing Support Library</a>.
+ */
+@Deprecated
+public class MockResources extends Resources {
+
+    public MockResources() {
+        super(new AssetManager(), null, null);
+    }
+
+    @Override
+    public void updateConfiguration(Configuration config, DisplayMetrics metrics) {
+        // this method is called from the constructor, so we just do nothing
+    }
+
+    @Override
+    public CharSequence getText(int id) throws NotFoundException {
+        throw new UnsupportedOperationException("mock object, not implemented");
+    }
+
+    @Override
+    public CharSequence getQuantityText(int id, int quantity) throws NotFoundException {
+        throw new UnsupportedOperationException("mock object, not implemented");
+    }
+
+    @Override
+    public String getString(int id) throws NotFoundException {
+        throw new UnsupportedOperationException("mock object, not implemented");
+    }
+
+    @Override
+    public String getString(int id, Object... formatArgs) throws NotFoundException {
+        throw new UnsupportedOperationException("mock object, not implemented");
+    }
+
+    @Override
+    public String getQuantityString(int id, int quantity, Object... formatArgs)
+            throws NotFoundException {
+        throw new UnsupportedOperationException("mock object, not implemented");
+    }
+
+    @Override
+    public String getQuantityString(int id, int quantity) throws NotFoundException {
+        throw new UnsupportedOperationException("mock object, not implemented");
+    }
+
+    @Override
+    public CharSequence getText(int id, CharSequence def) {
+        throw new UnsupportedOperationException("mock object, not implemented");
+    }
+
+    @Override
+    public CharSequence[] getTextArray(int id) throws NotFoundException {
+        throw new UnsupportedOperationException("mock object, not implemented");
+    }
+
+    @Override
+    public String[] getStringArray(int id) throws NotFoundException {
+        throw new UnsupportedOperationException("mock object, not implemented");
+    }
+
+    @Override
+    public int[] getIntArray(int id) throws NotFoundException {
+        throw new UnsupportedOperationException("mock object, not implemented");
+    }
+
+    @Override
+    public TypedArray obtainTypedArray(int id) throws NotFoundException {
+        throw new UnsupportedOperationException("mock object, not implemented");
+    }
+
+    @Override
+    public float getDimension(int id) throws NotFoundException {
+        throw new UnsupportedOperationException("mock object, not implemented");
+    }
+
+    @Override
+    public int getDimensionPixelOffset(int id) throws NotFoundException {
+        throw new UnsupportedOperationException("mock object, not implemented");
+    }
+
+    @Override
+    public int getDimensionPixelSize(int id) throws NotFoundException {
+        throw new UnsupportedOperationException("mock object, not implemented");
+    }
+
+    @Override
+    public Drawable getDrawable(int id) throws NotFoundException {
+        throw new UnsupportedOperationException("mock object, not implemented");
+    }
+
+    @Override
+    public Movie getMovie(int id) throws NotFoundException {
+        throw new UnsupportedOperationException("mock object, not implemented");
+    }
+
+    @Override
+    public int getColor(int id) throws NotFoundException {
+        throw new UnsupportedOperationException("mock object, not implemented");
+    }
+
+    @Override
+    public ColorStateList getColorStateList(int id) throws NotFoundException {
+        throw new UnsupportedOperationException("mock object, not implemented");
+    }
+
+    @Override
+    public int getInteger(int id) throws NotFoundException {
+        throw new UnsupportedOperationException("mock object, not implemented");
+    }
+
+    @Override
+    public XmlResourceParser getLayout(int id) throws NotFoundException {
+        throw new UnsupportedOperationException("mock object, not implemented");
+    }
+
+    @Override
+    public XmlResourceParser getAnimation(int id) throws NotFoundException {
+        throw new UnsupportedOperationException("mock object, not implemented");
+    }
+
+    @Override
+    public XmlResourceParser getXml(int id) throws NotFoundException {
+        throw new UnsupportedOperationException("mock object, not implemented");
+    }
+
+    @Override
+    public InputStream openRawResource(int id) throws NotFoundException {
+        throw new UnsupportedOperationException("mock object, not implemented");
+    }
+
+    @Override
+    public AssetFileDescriptor openRawResourceFd(int id) throws NotFoundException {
+        throw new UnsupportedOperationException("mock object, not implemented");
+    }
+
+    @Override
+    public void getValue(int id, TypedValue outValue, boolean resolveRefs)
+            throws NotFoundException {
+        throw new UnsupportedOperationException("mock object, not implemented");
+    }
+
+    @Override
+    public void getValue(String name, TypedValue outValue, boolean resolveRefs)
+            throws NotFoundException {
+        throw new UnsupportedOperationException("mock object, not implemented");
+    }
+
+    @Override
+    public TypedArray obtainAttributes(AttributeSet set, int[] attrs) {
+        throw new UnsupportedOperationException("mock object, not implemented");
+    }
+
+    @Override
+    public DisplayMetrics getDisplayMetrics() {
+        throw new UnsupportedOperationException("mock object, not implemented");
+    }
+
+    @Override
+    public Configuration getConfiguration() {
+        throw new UnsupportedOperationException("mock object, not implemented");
+    }
+
+    @Override
+    public int getIdentifier(String name, String defType, String defPackage) {
+        throw new UnsupportedOperationException("mock object, not implemented");
+    }
+
+    @Override
+    public String getResourceName(int resid) throws NotFoundException {
+        throw new UnsupportedOperationException("mock object, not implemented");
+    }
+
+    @Override
+    public String getResourcePackageName(int resid) throws NotFoundException {
+        throw new UnsupportedOperationException("mock object, not implemented");
+    }
+
+    @Override
+    public String getResourceTypeName(int resid) throws NotFoundException {
+        throw new UnsupportedOperationException("mock object, not implemented");
+    }
+
+    @Override
+    public String getResourceEntryName(int resid) throws NotFoundException {
+        throw new UnsupportedOperationException("mock object, not implemented");
+    }
+}
diff --git a/android/test/mock/MockService.java b/android/test/mock/MockService.java
new file mode 100644
index 0000000..dbba4f3
--- /dev/null
+++ b/android/test/mock/MockService.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2017 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.test.mock;
+
+import android.app.Application;
+import android.app.Service;
+import android.content.Context;
+
+/**
+ * A mock {@link android.app.Service} class.
+ *
+ * <p>Provided for use by {@code android.test.ServiceTestCase}.
+ *
+ * @deprecated Use a mocking framework like <a href="https://github.com/mockito/mockito">Mockito</a>.
+ * New tests should be written using the
+ * <a href="{@docRoot}tools/testing-support-library/index.html">Android Testing Support Library</a>.
+ */
+@Deprecated
+public class MockService {
+
+    public static <T extends Service> void attachForTesting(Service service, Context context,
+            String serviceClassName,
+            Application application) {
+        service.attach(
+                context,
+                null,               // ActivityThread not actually used in Service
+                serviceClassName,
+                null,               // token not needed when not talking with the activity manager
+                application,
+                null                // mocked services don't talk with the activity manager
+        );
+    }
+
+    private MockService() {
+    }
+}
diff --git a/android/test/suitebuilder/AssignableFrom.java b/android/test/suitebuilder/AssignableFrom.java
new file mode 100644
index 0000000..84db066
--- /dev/null
+++ b/android/test/suitebuilder/AssignableFrom.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2008 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.test.suitebuilder;
+
+import com.android.internal.util.Predicate;
+
+class AssignableFrom implements Predicate<TestMethod> {
+
+    private final Class<?> root;
+
+    AssignableFrom(Class<?> root) {
+        this.root = root;
+    }
+
+    public boolean apply(TestMethod testMethod) {
+        return root.isAssignableFrom(testMethod.getEnclosingClass());
+    }
+}
diff --git a/android/test/suitebuilder/SmokeTestSuiteBuilder.java b/android/test/suitebuilder/SmokeTestSuiteBuilder.java
new file mode 100644
index 0000000..01e7ec6
--- /dev/null
+++ b/android/test/suitebuilder/SmokeTestSuiteBuilder.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2008 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.test.suitebuilder;
+
+/**
+ * A suite builder that runs smoke tests.
+ * 
+ * {@hide} Not needed for 1.0 SDK.
+ */
+public class SmokeTestSuiteBuilder extends TestSuiteBuilder {
+
+    public SmokeTestSuiteBuilder(Class clazz) {
+        this(clazz.getName(), clazz.getClassLoader());
+    }
+
+
+    public SmokeTestSuiteBuilder(String name, ClassLoader classLoader) {
+        super(name, classLoader);
+        addRequirements(TestPredicates.SELECT_SMOKE);
+    }
+}
diff --git a/android/test/suitebuilder/TestGrouping.java b/android/test/suitebuilder/TestGrouping.java
new file mode 100644
index 0000000..030bc42
--- /dev/null
+++ b/android/test/suitebuilder/TestGrouping.java
@@ -0,0 +1,229 @@
+/*
+ * Copyright (C) 2008 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.test.suitebuilder;
+
+import android.test.ClassPathPackageInfoSource;
+import android.util.Log;
+import com.android.internal.util.Predicate;
+import junit.framework.TestCase;
+
+import java.io.Serializable;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+/**
+ * Represents a collection of test classes present on the classpath. You can add individual classes
+ * or entire packages. By default sub-packages are included recursively, but methods are
+ * provided to allow for arbitrary inclusion or exclusion of sub-packages. Typically a
+ * {@link TestGrouping} will have only one root package, but this is not a requirement.
+ * 
+ * {@hide} Not needed for 1.0 SDK.
+ */
+class TestGrouping {
+
+    private static final String LOG_TAG = "TestGrouping";
+
+    private final SortedSet<Class<? extends TestCase>> testCaseClasses;
+
+    static final Comparator<Class<? extends TestCase>> SORT_BY_SIMPLE_NAME
+            = new SortBySimpleName();
+
+    static final Comparator<Class<? extends TestCase>> SORT_BY_FULLY_QUALIFIED_NAME
+            = new SortByFullyQualifiedName();
+
+    private final ClassLoader classLoader;
+
+    TestGrouping(Comparator<Class<? extends TestCase>> comparator, ClassLoader classLoader) {
+        testCaseClasses = new TreeSet<Class<? extends TestCase>>(comparator);
+        this.classLoader = classLoader;
+    }
+
+    /**
+     * @return A list of all tests in the package, including small, medium, large,
+     *         flaky, and suppressed tests. Includes sub-packages recursively.
+     */
+    public List<TestMethod> getTests() {
+        List<TestMethod> testMethods = new ArrayList<TestMethod>();
+        for (Class<? extends TestCase> testCase : testCaseClasses) {
+            for (Method testMethod : getTestMethods(testCase)) {
+                testMethods.add(new TestMethod(testMethod, testCase));
+            }
+        }
+        return testMethods;
+    }
+
+    private List<Method> getTestMethods(Class<? extends TestCase> testCaseClass) {
+        List<Method> methods = Arrays.asList(testCaseClass.getMethods());
+        return select(methods, new TestMethodPredicate());
+    }
+
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+        TestGrouping other = (TestGrouping) o;
+        if (!this.testCaseClasses.equals(other.testCaseClasses)) {
+            return false;
+        }
+        return this.testCaseClasses.comparator().equals(other.testCaseClasses.comparator());
+    }
+
+    public int hashCode() {
+        return testCaseClasses.hashCode();
+    }
+
+    /**
+     * Include all tests in the given packages and all their sub-packages, unless otherwise
+     * specified. Each of the given packages must contain at least one test class, either directly
+     * or in a sub-package.
+     *
+     * @param packageNames Names of packages to add.
+     */
+    void addPackagesRecursive(String... packageNames) {
+        for (String packageName : packageNames) {
+            List<Class<? extends TestCase>> addedClasses = testCaseClassesInPackage(packageName);
+            if (addedClasses.isEmpty()) {
+                Log.w(LOG_TAG, "Invalid Package: '" + packageName
+                        + "' could not be found or has no tests");
+            }
+            testCaseClasses.addAll(addedClasses);
+        }
+    }
+
+    /**
+     * Exclude all tests in the given packages and all their sub-packages, unless otherwise
+     * specified.
+     *
+     * @param packageNames Names of packages to remove.
+     */
+    void removePackagesRecursive(String... packageNames) {
+        for (String packageName : packageNames) {
+            testCaseClasses.removeAll(testCaseClassesInPackage(packageName));
+        }
+    }
+
+    private List<Class<? extends TestCase>> testCaseClassesInPackage(String packageName) {
+        ClassPathPackageInfoSource source = ClassPathPackageInfoSource.forClassPath(classLoader);
+
+        return selectTestClasses(source.getTopLevelClassesRecursive(packageName));
+    }
+
+    @SuppressWarnings("unchecked")
+    private List<Class<? extends TestCase>> selectTestClasses(Set<Class<?>> allClasses) {
+        List<Class<? extends TestCase>> testClasses = new ArrayList<Class<? extends TestCase>>();
+        for (Class<?> testClass : select(allClasses,
+                new TestCasePredicate())) {
+            testClasses.add((Class<? extends TestCase>) testClass);
+        }
+        return testClasses;
+    }
+
+    private <T> List<T> select(Collection<T> items, Predicate<T> predicate) {
+        ArrayList<T> selectedItems = new ArrayList<T>();
+        for (T item : items) {
+            if (predicate.apply(item)) {
+                selectedItems.add(item);
+            }
+        }
+        return selectedItems;
+    }
+
+    /**
+     * Sort classes by their simple names (i.e. without the package prefix), using
+     * their packages to sort classes with the same name.
+     */
+    private static class SortBySimpleName
+            implements Comparator<Class<? extends TestCase>>, Serializable {
+
+        public int compare(Class<? extends TestCase> class1,
+                Class<? extends TestCase> class2) {
+            int result = class1.getSimpleName().compareTo(class2.getSimpleName());
+            if (result != 0) {
+                return result;
+            }
+            return class1.getName().compareTo(class2.getName());
+        }
+    }
+
+    /**
+     * Sort classes by their fully qualified names (i.e. with the package
+     * prefix).
+     */
+    private static class SortByFullyQualifiedName
+            implements Comparator<Class<? extends TestCase>>, Serializable {
+
+        public int compare(Class<? extends TestCase> class1,
+                Class<? extends TestCase> class2) {
+            return class1.getName().compareTo(class2.getName());
+        }
+    }
+
+    private static class TestCasePredicate implements Predicate<Class<?>> {
+
+        public boolean apply(Class aClass) {
+            int modifiers = ((Class<?>) aClass).getModifiers();
+            return TestCase.class.isAssignableFrom((Class<?>) aClass)
+                    && Modifier.isPublic(modifiers)
+                    && !Modifier.isAbstract(modifiers)
+                    && hasValidConstructor((Class<?>) aClass);
+        }
+
+        @SuppressWarnings("unchecked")
+        private boolean hasValidConstructor(java.lang.Class<?> aClass) {
+            // The cast below is not necessary with the Java 5 compiler, but necessary with the Java 6 compiler,
+            // where the return type of Class.getDeclaredConstructors() was changed
+            // from Constructor<T>[] to Constructor<?>[]
+            Constructor<? extends TestCase>[] constructors
+                    = (Constructor<? extends TestCase>[]) aClass.getConstructors();
+            for (Constructor<? extends TestCase> constructor : constructors) {
+                if (Modifier.isPublic(constructor.getModifiers())) {
+                    java.lang.Class[] parameterTypes = constructor.getParameterTypes();
+                    if (parameterTypes.length == 0 ||
+                            (parameterTypes.length == 1 && parameterTypes[0] == String.class)) {
+                        return true;
+                    }
+                }
+            }
+            Log.i(LOG_TAG, String.format(
+                    "TestCase class %s is missing a public constructor with no parameters " +
+                    "or a single String parameter - skipping",
+                    aClass.getName()));
+            return false;
+        }
+    }
+
+    private static class TestMethodPredicate implements Predicate<Method> {
+
+        public boolean apply(Method method) {
+            return ((method.getParameterTypes().length == 0) &&
+                    (method.getName().startsWith("test")) &&
+                    (method.getReturnType().getSimpleName().equals("void")));
+        }
+    }
+}
diff --git a/android/test/suitebuilder/TestMethod.java b/android/test/suitebuilder/TestMethod.java
new file mode 100644
index 0000000..ae1db5e
--- /dev/null
+++ b/android/test/suitebuilder/TestMethod.java
@@ -0,0 +1,150 @@
+/*
+ * Copyright (C) 2008 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.test.suitebuilder;
+
+import junit.framework.TestCase;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+/**
+ * Represents a test to be run. Can be constructed without instantiating the TestCase or even
+ * loading the class.
+ *
+ * @deprecated New tests should be written using the
+ * <a href="{@docRoot}tools/testing-support-library/index.html">Android Testing Support Library</a>.
+ */
+@Deprecated
+public class TestMethod {
+
+    private final String enclosingClassname;
+    private final String testMethodName;
+    private final Class<? extends TestCase> enclosingClass;
+
+    public TestMethod(Method method, Class<? extends TestCase> enclosingClass) {
+        this(method.getName(), enclosingClass);
+    }
+
+    public TestMethod(String methodName, Class<? extends TestCase> enclosingClass) {
+        this.enclosingClass = enclosingClass;
+        this.enclosingClassname = enclosingClass.getName();
+        this.testMethodName = methodName;
+    }
+    
+    public TestMethod(TestCase testCase) {
+        this(testCase.getName(), testCase.getClass());
+    }
+
+    public String getName() {
+        return testMethodName;
+    }
+
+    public String getEnclosingClassname() {
+        return enclosingClassname;
+    }
+
+    public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
+        try {
+            return getEnclosingClass().getMethod(getName()).getAnnotation(annotationClass);
+        } catch (NoSuchMethodException e) {
+            return null;
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    public Class<? extends TestCase> getEnclosingClass() {
+        return enclosingClass;
+    }
+
+    public TestCase createTest()
+            throws InvocationTargetException, IllegalAccessException, InstantiationException {
+        return instantiateTest(enclosingClass, testMethodName);
+    }
+
+    @SuppressWarnings("unchecked")
+    private TestCase instantiateTest(Class testCaseClass, String testName)
+            throws InvocationTargetException, IllegalAccessException, InstantiationException {
+        Constructor[] constructors = testCaseClass.getConstructors();
+
+        if (constructors.length == 0) {
+            return instantiateTest(testCaseClass.getSuperclass(), testName);
+        } else {
+            for (Constructor constructor : constructors) {
+                Class[] params = constructor.getParameterTypes();
+                if (noargsConstructor(params)) {
+                    TestCase test = ((Constructor<? extends TestCase>) constructor).newInstance();
+                    // JUnit will run just the one test if you call
+                    // {@link TestCase#setName(String)}
+                    test.setName(testName);
+                    return test;
+                } else if (singleStringConstructor(params)) {
+                    return ((Constructor<? extends TestCase>) constructor)
+                            .newInstance(testName);
+                }
+            }
+        }
+        throw new RuntimeException("Unable to locate a constructor for "
+                + testCaseClass.getName());
+    }
+
+    private boolean singleStringConstructor(Class[] params) {
+        return (params.length == 1) && (params[0].equals(String.class));
+    }
+
+    private boolean noargsConstructor(Class[] params) {
+        return params.length == 0;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+
+        TestMethod that = (TestMethod) o;
+
+        if (enclosingClassname != null
+                ? !enclosingClassname.equals(that.enclosingClassname)
+                : that.enclosingClassname != null) {
+            return false;
+        }
+        if (testMethodName != null
+                ? !testMethodName.equals(that.testMethodName)
+                : that.testMethodName != null) {
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result;
+        result = (enclosingClassname != null ? enclosingClassname.hashCode() : 0);
+        result = 31 * result + (testMethodName != null ? testMethodName.hashCode() : 0);
+        return result;
+    }
+
+    @Override
+    public String toString() {
+        return enclosingClassname + "." + testMethodName;
+    }
+}
diff --git a/android/test/suitebuilder/TestPredicates.java b/android/test/suitebuilder/TestPredicates.java
new file mode 100644
index 0000000..616d1a9
--- /dev/null
+++ b/android/test/suitebuilder/TestPredicates.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2008 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.test.suitebuilder;
+
+import android.test.InstrumentationTestCase;
+import android.test.suitebuilder.annotation.Smoke;
+import android.test.suitebuilder.annotation.Suppress;
+import com.android.internal.util.Predicate;
+import java.lang.annotation.Annotation;
+
+/**
+ * {@hide} Not needed for 1.0 SDK.
+ */
+public class TestPredicates {
+
+    static final Predicate<TestMethod> REJECT_INSTRUMENTATION =
+            not(new AssignableFrom(InstrumentationTestCase.class));
+
+    static final Predicate<TestMethod> SELECT_SMOKE = hasAnnotation(Smoke.class);
+
+    static final Predicate<TestMethod> REJECT_SUPPRESSED = not(hasAnnotation(Suppress.class));
+
+    /**
+     * Return a predicate that checks to see if a {@link TestMethod} has an instance of the supplied
+     * annotation class, either on the method or on the containing class.
+     */
+    public static Predicate<TestMethod> hasAnnotation(Class<? extends Annotation> annotationClass) {
+        return new HasAnnotation(annotationClass);
+    }
+
+    private static class HasAnnotation implements Predicate<TestMethod> {
+
+        private final Class<? extends Annotation> annotationClass;
+
+        private HasAnnotation(Class<? extends Annotation> annotationClass) {
+            this.annotationClass = annotationClass;
+        }
+
+        @Override
+        public boolean apply(TestMethod testMethod) {
+            return testMethod.getAnnotation(annotationClass) != null ||
+                    testMethod.getEnclosingClass().getAnnotation(annotationClass) != null;
+        }
+    }
+
+    /**
+     * Returns a Predicate that evaluates to true iff the given Predicate
+     * evaluates to false.
+     */
+    public static <T> Predicate<T> not(Predicate<? super T> predicate) {
+        return new NotPredicate<T>(predicate);
+    }
+
+    private static class NotPredicate<T> implements Predicate<T> {
+        private final Predicate<? super T> predicate;
+
+        private NotPredicate(Predicate<? super T> predicate) {
+            this.predicate = predicate;
+        }
+
+        public boolean apply(T t) {
+            return !predicate.apply(t);
+        }
+    }
+}
diff --git a/android/test/suitebuilder/TestSuiteBuilder.java b/android/test/suitebuilder/TestSuiteBuilder.java
new file mode 100644
index 0000000..2857696
--- /dev/null
+++ b/android/test/suitebuilder/TestSuiteBuilder.java
@@ -0,0 +1,278 @@
+/*
+ * Copyright (C) 2008 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.test.suitebuilder;
+
+import android.content.Context;
+import android.test.AndroidTestRunner;
+import android.test.TestCaseUtil;
+import android.util.Log;
+import com.android.internal.util.Predicate;
+import static android.test.suitebuilder.TestGrouping.SORT_BY_FULLY_QUALIFIED_NAME;
+import static android.test.suitebuilder.TestPredicates.REJECT_SUPPRESSED;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+import java.util.List;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.ArrayList;
+import java.util.Collections;
+
+/**
+ * Build suites based on a combination of included packages, excluded packages,
+ * and predicates that must be satisfied.
+ *
+ * @deprecated New tests should be written using the
+ * <a href="{@docRoot}tools/testing-support-library/index.html">Android Testing Support Library</a>.
+ */
+@Deprecated
+public class TestSuiteBuilder {
+
+    private final TestGrouping testGrouping;
+    private final Set<Predicate<TestMethod>> predicates = new HashSet<Predicate<TestMethod>>();
+    private List<TestCase> testCases;
+    private TestSuite rootSuite;
+    private TestSuite suiteForCurrentClass;
+    private String currentClassname;
+    private String suiteName;
+
+    /**
+     * The given name is automatically prefixed with the package containing the tests to be run.
+     * If more than one package is specified, the first is used.
+     *
+     * @param clazz Use the class from your .apk. Use the class name for the test suite name.
+     *              Use the class' classloader in order to load classes for testing.
+     *              This is needed when running in the emulator.
+     */
+    public TestSuiteBuilder(Class clazz) {
+        this(clazz.getName(), clazz.getClassLoader());
+    }
+
+    public TestSuiteBuilder(String name, ClassLoader classLoader) {
+        this.suiteName = name;
+        this.testGrouping = new TestGrouping(SORT_BY_FULLY_QUALIFIED_NAME, classLoader);
+        this.testCases = new ArrayList<>();
+        addRequirements(REJECT_SUPPRESSED);
+    }
+
+    /** @hide pending API Council approval */
+    public TestSuiteBuilder addTestClassByName(String testClassName, String testMethodName,
+            Context context) {
+
+        AndroidTestRunner atr = new AndroidTestRunner();
+        atr.setContext(context);
+        atr.setTestClassName(testClassName, testMethodName);
+
+        this.testCases.addAll(atr.getTestCases());
+        return this;
+    }
+
+    /** @hide pending API Council approval */
+    public TestSuiteBuilder addTestSuite(TestSuite testSuite) {
+        for (TestCase testCase : (List<TestCase>) TestCaseUtil.getTests(testSuite, true)) {
+            this.testCases.add(testCase);
+        }
+        return this;
+    }
+
+    /**
+     * Include all tests that satisfy the requirements in the given packages and all sub-packages,
+     * unless otherwise specified.
+     *
+     * @param packageNames Names of packages to add.
+     * @return The builder for method chaining.
+     */
+    public TestSuiteBuilder includePackages(String... packageNames) {
+        testGrouping.addPackagesRecursive(packageNames);
+        return this;
+    }
+
+    /**
+     * Exclude all tests in the given packages and all sub-packages, unless otherwise specified.
+     *
+     * @param packageNames Names of packages to remove.
+     * @return The builder for method chaining.
+     */
+    public TestSuiteBuilder excludePackages(String... packageNames) {
+        testGrouping.removePackagesRecursive(packageNames);
+        return this;
+    }
+
+    /**
+     * Exclude tests that fail to satisfy all of the given predicates.
+     *
+     * @param predicates Predicates to add to the list of requirements.
+     * @return The builder for method chaining.
+     * @hide
+     */
+    public TestSuiteBuilder addRequirements(List<Predicate<TestMethod>> predicates) {
+        this.predicates.addAll(predicates);
+        return this;
+    }
+
+    /**
+     * Include all junit tests that satisfy the requirements in the calling class' package and all
+     * sub-packages.
+     *
+     * @return The builder for method chaining.
+     */
+    public final TestSuiteBuilder includeAllPackagesUnderHere() {
+        StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();
+
+        String callingClassName = null;
+        String thisClassName = TestSuiteBuilder.class.getName();
+
+        // We want to get the package of this method's calling class. This method's calling class
+        // should be one level below this class in the stack trace.
+        for (int i = 0; i < stackTraceElements.length; i++) {
+            StackTraceElement element = stackTraceElements[i];
+            if (thisClassName.equals(element.getClassName())
+                    && "includeAllPackagesUnderHere".equals(element.getMethodName())) {
+                // We've found this class in the call stack. The calling class must be the
+                // next class in the stack.
+                callingClassName = stackTraceElements[i + 1].getClassName();
+                break;
+            }
+        }
+
+        String packageName = parsePackageNameFromClassName(callingClassName);
+        return includePackages(packageName);
+    }
+
+    /**
+     * Override the default name for the suite being built. This should generally be called if you
+     * call {@code addRequirements(com.android.internal.util.Predicate[])} to make it clear which
+     * tests will be included. The name you specify is automatically prefixed with the package
+     * containing the tests to be run. If more than one package is specified, the first is used.
+     *
+     * @param newSuiteName Prefix of name to give the suite being built.
+     * @return The builder for method chaining.
+     */
+    public TestSuiteBuilder named(String newSuiteName) {
+        suiteName = newSuiteName;
+        return this;
+    }
+
+    /**
+     * Call this method once you've configured your builder as desired.
+     *
+     * @return The suite containing the requested tests.
+     */
+    public final TestSuite build() {
+        rootSuite = new TestSuite(getSuiteName());
+
+        // Keep track of current class so we know when to create a new sub-suite.
+        currentClassname = null;
+        try {
+            for (TestMethod test : testGrouping.getTests()) {
+                if (satisfiesAllPredicates(test)) {
+                    addTest(test);
+                }
+            }
+            if (testCases.size() > 0) {
+                for (TestCase testCase : testCases) {
+                    if (satisfiesAllPredicates(new TestMethod(testCase))) {
+                        addTest(testCase);
+                    }
+                }
+            }
+        } catch (Exception exception) {
+            Log.i("TestSuiteBuilder", "Failed to create test.", exception);
+            TestSuite suite = new TestSuite(getSuiteName());
+            suite.addTest(new FailedToCreateTests(exception));
+            return suite;
+        }
+        return rootSuite;
+    }
+
+    /**
+     * Subclasses use this method to determine the name of the suite.
+     *
+     * @return The package and suite name combined.
+     */
+    protected String getSuiteName() {
+        return suiteName;
+    }
+
+    /**
+     * Exclude tests that fail to satisfy all of the given predicates. If you call this method, you
+     * probably also want to call {@link #named(String)} to override the default suite name.
+     *
+     * @param predicates Predicates to add to the list of requirements.
+     * @return The builder for method chaining.
+     * @hide
+     */
+    public final TestSuiteBuilder addRequirements(Predicate<TestMethod>... predicates) {
+        ArrayList<Predicate<TestMethod>> list = new ArrayList<Predicate<TestMethod>>();
+        Collections.addAll(list, predicates);
+        return addRequirements(list);
+    }
+
+    /**
+     * A special {@link junit.framework.TestCase} used to indicate a failure during the build()
+     * step.
+     *
+     * @deprecated New tests should be written using the
+     * <a href="{@docRoot}tools/testing-support-library/index.html">Android Testing Support Library</a>.
+     */
+    @Deprecated
+    public static class FailedToCreateTests extends TestCase {
+        private final Exception exception;
+
+        public FailedToCreateTests(Exception exception) {
+            super("testSuiteConstructionFailed");
+            this.exception = exception;
+        }
+
+        public void testSuiteConstructionFailed() {
+            throw new RuntimeException("Exception during suite construction", exception);
+        }
+    }
+
+    private boolean satisfiesAllPredicates(TestMethod test) {
+        for (Predicate<TestMethod> predicate : predicates) {
+            if (!predicate.apply(test)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    private void addTest(TestMethod testMethod) throws Exception {
+        addSuiteIfNecessary(testMethod.getEnclosingClassname());
+        suiteForCurrentClass.addTest(testMethod.createTest());
+    }
+
+    private void addTest(Test test) {
+        addSuiteIfNecessary(test.getClass().getName());
+        suiteForCurrentClass.addTest(test);
+    }
+
+    private void addSuiteIfNecessary(String parentClassname) {
+        if (!parentClassname.equals(currentClassname)) {
+            currentClassname = parentClassname;
+            suiteForCurrentClass = new TestSuite(parentClassname);
+            rootSuite.addTest(suiteForCurrentClass);
+        }
+    }
+
+    private static String parsePackageNameFromClassName(String className) {
+        return className.substring(0, className.lastIndexOf('.'));
+    }
+}
diff --git a/android/test/suitebuilder/UnitTestSuiteBuilder.java b/android/test/suitebuilder/UnitTestSuiteBuilder.java
new file mode 100644
index 0000000..a746b35
--- /dev/null
+++ b/android/test/suitebuilder/UnitTestSuiteBuilder.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2008 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.test.suitebuilder;
+
+/**
+ * A suite builder that finds unit tests.
+ *
+ * {@hide} Not needed for 1.0 SDK.
+ */
+public class UnitTestSuiteBuilder extends TestSuiteBuilder {
+
+    public UnitTestSuiteBuilder(Class clazz) {
+        this(clazz.getName(), clazz.getClassLoader());
+    }
+
+
+    public UnitTestSuiteBuilder(String name, ClassLoader classLoader) {
+        super(name, classLoader);
+        addRequirements(TestPredicates.REJECT_INSTRUMENTATION);
+    }
+}
diff --git a/android/test/suitebuilder/annotation/LargeTest.java b/android/test/suitebuilder/annotation/LargeTest.java
new file mode 100644
index 0000000..dc77ee6
--- /dev/null
+++ b/android/test/suitebuilder/annotation/LargeTest.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2008 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.test.suitebuilder.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Marks a test that should run as part of the large tests.
+ *
+ * @deprecated Use
+ * <a href="{@docRoot}reference/android/support/test/filters/LargeTest.html">
+ * LargeTest</a> instead. New tests should be written using the
+ * <a href="{@docRoot}tools/testing-support-library/index.html">Android Testing Support Library</a>.
+ */
+@Deprecated
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.METHOD, ElementType.TYPE})
+public @interface LargeTest {
+}
diff --git a/android/test/suitebuilder/annotation/MediumTest.java b/android/test/suitebuilder/annotation/MediumTest.java
new file mode 100644
index 0000000..b941da0
--- /dev/null
+++ b/android/test/suitebuilder/annotation/MediumTest.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2008 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.test.suitebuilder.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Marks a test that should run as part of the medium tests.
+ *
+ * @deprecated Use
+ * <a href="{@docRoot}reference/android/support/test/filters/MediumTest.html">
+ * MediumTest</a> instead. New tests should be written using the
+ * <a href="{@docRoot}tools/testing-support-library/index.html">Android Testing Support Library</a>.
+ */
+@Deprecated
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.METHOD, ElementType.TYPE})
+public @interface MediumTest {
+}
diff --git a/android/test/suitebuilder/annotation/SmallTest.java b/android/test/suitebuilder/annotation/SmallTest.java
new file mode 100644
index 0000000..d3c74f0
--- /dev/null
+++ b/android/test/suitebuilder/annotation/SmallTest.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2008 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.test.suitebuilder.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Marks a test that should run as part of the small tests.
+ *
+ * @deprecated Use
+ * <a href="{@docRoot}reference/android/support/test/filters/SmallTest.html">
+ * SmallTest</a> instead. New tests should be written using the
+ * <a href="{@docRoot}tools/testing-support-library/index.html">Android Testing Support Library</a>.
+ */
+@Deprecated
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.METHOD, ElementType.TYPE})
+public @interface SmallTest {
+}
diff --git a/android/test/suitebuilder/annotation/Smoke.java b/android/test/suitebuilder/annotation/Smoke.java
new file mode 100644
index 0000000..3456371
--- /dev/null
+++ b/android/test/suitebuilder/annotation/Smoke.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2008 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.test.suitebuilder.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Marks a test that should run as part of the smoke tests.
+ * The <code>android.test.suitebuilder.SmokeTestSuiteBuilder</code>
+ * will run all tests with this annotation.
+ *
+ * @deprecated New tests should be written using the
+ * <a href="{@docRoot}tools/testing-support-library/index.html">Android Testing Support Library</a>.
+ */
+@Deprecated
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.METHOD, ElementType.TYPE})
+public @interface Smoke {
+}
diff --git a/android/test/suitebuilder/annotation/Suppress.java b/android/test/suitebuilder/annotation/Suppress.java
new file mode 100644
index 0000000..629a3cf
--- /dev/null
+++ b/android/test/suitebuilder/annotation/Suppress.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2008 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.test.suitebuilder.annotation;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.lang.annotation.ElementType;
+
+/**
+ * Use this annotation on test classes or test methods that should not be included in a test
+ * suite. If the annotation appears on the class then no tests in that class will be included. If
+ * the annotation appears only on a test method then only that method will be excluded.
+ *
+ * @deprecated Use
+ * <a href="{@docRoot}reference/android/support/test/filters/Suppress.html">
+ * Suppress</a> instead. New tests should be written using the
+ * <a href="{@docRoot}tools/testing-support-library/index.html">Android Testing Support Library</a>.
+ */
+@Deprecated
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.METHOD, ElementType.TYPE})
+public @interface Suppress {
+}
