diff --git a/CtsHostLibraryList.mk b/CtsHostLibraryList.mk
index 36291d5..ac9a700 100644
--- a/CtsHostLibraryList.mk
+++ b/CtsHostLibraryList.mk
@@ -12,5 +12,4 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-CTS_HOST_LIBRARY_JARS := \
-	$(HOST_OUT_JAVA_LIBRARIES)/CtsTestAnnotationsHostLib.jar
+CTS_HOST_LIBRARY_JARS := 
diff --git a/apps/CtsVerifier/AndroidManifest.xml b/apps/CtsVerifier/AndroidManifest.xml
index 24e9fdc..e104d82 100644
--- a/apps/CtsVerifier/AndroidManifest.xml
+++ b/apps/CtsVerifier/AndroidManifest.xml
@@ -69,32 +69,23 @@
             <meta-data android:name="test_category" android:value="@string/test_category_sensors" />
         </activity>
 
-        <activity android:name=".sensors.MagnetometerTestActivity" android:label="@string/snsr_mag_test"
-                android:screenOrientation="nosensor">
+        <activity android:name=".audioquality.AudioQualityVerifierActivity"
+                android:label="@string/aq_verifier">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.cts.intent.category.MANUAL_TEST" />
             </intent-filter>
-            <meta-data android:name="test_category" android:value="@string/test_category_sensors" />
+            <meta-data android:name="test_category" android:value="@string/test_category_audio" />
         </activity>
 
-      <activity android:name=".audioquality.AudioQualityVerifierActivity"
-              android:label="@string/aq_verifier">
-          <intent-filter>
-              <action android:name="android.intent.action.MAIN" />
-              <category android:name="android.cts.intent.category.MANUAL_TEST" />
-          </intent-filter>
-          <meta-data android:name="test_category" android:value="@string/test_category_audio" />
-      </activity>
-      
-      <activity android:name=".audioquality.CalibrateVolumeActivity"
-                android:label="@string/aq_calibrate_volume_name" />
-      
-      <activity android:name=".audioquality.ViewResultsActivity"
-                android:label="@string/aq_view_results_name" />
+        <activity android:name=".audioquality.CalibrateVolumeActivity"
+                  android:label="@string/aq_calibrate_volume_name" />
 
-      <service android:name=".audioquality.ExperimentService" />
-      
+        <activity android:name=".audioquality.ViewResultsActivity"
+                  android:label="@string/aq_view_results_name" />
+
+        <service android:name=".audioquality.ExperimentService" />
+
    </application>
 
 </manifest> 
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/MagnetometerTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/MagnetometerTestActivity.java
deleted file mode 100644
index f3ba411..0000000
--- a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/MagnetometerTestActivity.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * 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 com.android.cts.verifier.sensors;
-
-import com.android.cts.verifier.PassFailButtons;
-import com.android.cts.verifier.R;
-
-import android.content.Context;
-import android.hardware.Sensor;
-import android.hardware.SensorManager;
-import android.opengl.GLSurfaceView;
-import android.os.Bundle;
-
-/**
- * CTS Verifier case for verifying correct integration of accelerometer.
- * Displays a wedge using OpenGL that, on a correctly-integrated device, always
- * points down.
- */
-public class MagnetometerTestActivity extends PassFailButtons.Activity {
-    private GLSurfaceView mGLSurfaceView;
-
-    private AccelerometerTestRenderer mListener;
-
-    private SensorManager mSensorManager;
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-
-        mSensorManager = (SensorManager) getApplicationContext().getSystemService(
-                Context.SENSOR_SERVICE);
-        AccelerometerTestRenderer renderer = new MagnetometerTestRenderer(this);
-        mListener = renderer;
-
-        setContentView(R.layout.pass_fail_gl);
-        setPassFailButtonClickListeners();
-        setInfoResources(R.string.snsr_mag_test, R.string.snsr_mag_test_info, -1);
-        mGLSurfaceView = (GLSurfaceView) findViewById(R.id.gl_surface_view);
-        mGLSurfaceView.setRenderer(renderer);
-    }
-
-    @Override
-    protected void onPause() {
-        super.onPause();
-        mSensorManager.unregisterListener(mListener);
-        mGLSurfaceView.onPause();
-    }
-
-    @Override
-    protected void onResume() {
-        super.onResume();
-        mSensorManager.registerListener(mListener, mSensorManager.getSensorList(
-                Sensor.TYPE_MAGNETIC_FIELD).get(0), SensorManager.SENSOR_DELAY_UI);
-        mGLSurfaceView.onResume();
-    }
-}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/MagnetometerTestRenderer.java b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/MagnetometerTestRenderer.java
deleted file mode 100644
index b5d4587..0000000
--- a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/MagnetometerTestRenderer.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * 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 com.android.cts.verifier.sensors;
-
-import android.content.Context;
-import android.hardware.Sensor;
-import android.hardware.SensorEvent;
-
-public class MagnetometerTestRenderer extends AccelerometerTestRenderer {
-    public MagnetometerTestRenderer(Context context) {
-        super(context);
-    }
-
-    @Override
-    public void onSensorChanged(SensorEvent event) {
-        if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
-            /*
-             * The base class is written for accelerometer, where the vector
-             * points *away* from the thing being measured (i.e. gravity). But
-             * our vector points *toward* the thing being measured (i.e.
-             * magnetic north pole). Accordingly, the base class has an
-             * inversion to handle that that doesn't apply to us, so the
-             * simplest method is just to flip our vector to point in the exact
-             * opposite direction and then everything works out in the base
-             * class.
-             */
-            event.values[0] *= -1;
-            event.values[1] *= -1;
-            event.values[2] *= -1;
-
-            // rest of method is the same as in base class
-            normalize(event.values);
-            event.values[1] *= -1;
-            crossProduct(event.values, Z_AXIS, mCrossProd);
-            mAngle = (float) Math.acos(dotProduct(event.values, Z_AXIS));
-        }
-    }
-}
diff --git a/development/ide/eclipse/.classpath b/development/ide/eclipse/.classpath
index ee4a413..8d10955 100644
--- a/development/ide/eclipse/.classpath
+++ b/development/ide/eclipse/.classpath
@@ -2,7 +2,6 @@
 <classpath>
     <classpathentry kind="src" path="cts/apps/CtsVerifier/src"/>
     <classpathentry kind="src" path="cts/apps/CtsVerifier/tests/src"/>
-    <classpathentry kind="src" path="cts/libs/annotation/src"/>
     <classpathentry kind="src" path="cts/libs/vogar-expect/src"/>
     <classpathentry kind="src" path="cts/tests/ApiDemosReferenceTest/src"/>
     <classpathentry kind="src" path="cts/tests/ProcessTest/src"/>
@@ -59,7 +58,6 @@
     <classpathentry kind="src" path="cts/tools/host/test"/>
     <classpathentry kind="src" path="cts/tools/signature-tools/src"/>
     <classpathentry kind="src" path="cts/tools/signature-tools/test"/>
-    <classpathentry kind="src" path="cts/tools/spec-progress/src"/>
     <classpathentry kind="src" path="cts/tools/utils"/>
     <classpathentry kind="src" path="cts/tools/vm-tests/src"/>
     <classpathentry kind="src" path="out/target/common/obj/APPS/CtsAccessibilityServiceTestCases_intermediates/src/src"/>
diff --git a/libs/annotation/Android.mk b/libs/annotation/Android.mk
deleted file mode 100644
index 3a4dd82..0000000
--- a/libs/annotation/Android.mk
+++ /dev/null
@@ -1,30 +0,0 @@
-#
-# 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.
-#
-
-# Build static Java library for APKs like the CTS tests. 
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-LOCAL_MODULE := CtsTestAnnotationsLib
-LOCAL_MODULE_TAGS := optional
-include $(BUILD_STATIC_JAVA_LIBRARY)
-
-# Build the annotations for the host to use.
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-LOCAL_MODULE := CtsTestAnnotationsHostLib
-LOCAL_MODULE_TAGS := optional
-include $(BUILD_HOST_JAVA_LIBRARY)
diff --git a/libs/annotation/src/android/annotation/cts/RequiredFeatures.java b/libs/annotation/src/android/annotation/cts/RequiredFeatures.java
deleted file mode 100644
index 8675b34..0000000
--- a/libs/annotation/src/android/annotation/cts/RequiredFeatures.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * 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.annotation.cts;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * Annotation for specifying what features are needed to run a test. The device must have all the
- * features specified by the annotation in order to be executed.
- * <p>
- * Examples:
- * <pre>
- * @RequiredFeatures(PackageManager.FEATURE_WIFI)
- * @RequiredFeatures({PackageManager.FEATURE_TELEPHONY, PackageManager.FEATURE_TELEPHONY_CDMA})
- * </pre>
- */
-@Retention(RetentionPolicy.RUNTIME)
-@Target({ElementType.TYPE, ElementType.METHOD})
-public @interface RequiredFeatures {
-    String[] value();
-}
diff --git a/tests/Android.mk b/tests/Android.mk
index d3ecabe..641d053 100644
--- a/tests/Android.mk
+++ b/tests/Android.mk
@@ -24,7 +24,6 @@
               src/android/os/cts/IEmptyService.aidl
 
 LOCAL_JAVA_LIBRARIES := android.test.runner
-LOCAL_STATIC_JAVA_LIBRARIES := CtsTestAnnotationsLib
 
 LOCAL_JNI_SHARED_LIBRARIES := libcts_jni
 
diff --git a/tests/AndroidManifest.xml b/tests/AndroidManifest.xml
index 6f302a6..c881e28 100644
--- a/tests/AndroidManifest.xml
+++ b/tests/AndroidManifest.xml
@@ -653,6 +653,14 @@
             </intent-filter>
         </activity>
 
+        <activity android:name="android.webkit.cts.WebDriverStubActivity"
+            android:label="WebDriverStubActivity">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+            </intent-filter>
+        </activity>
+
         <activity android:name="android.app.cts.ChildActivity"
                         android:label="ChildActivity" />
 
@@ -943,6 +951,13 @@
         <activity android:name="android.app.cts.ActivityManagerMemoryClassTestActivity"
                 android:process=":memoryclass" />
 
+        <service android:name="android.speech.tts.cts.StubTextToSpeechService">
+            <intent-filter>
+                <action android:name="android.intent.action.TTS_SERVICE" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+        </service>
+
     </application>
 
     <!--Test for PackageManager, please put this at the very beginning-->
diff --git a/tests/assets/webkit/form_page.html b/tests/assets/webkit/form_page.html
new file mode 100644
index 0000000..a1fe48a
--- /dev/null
+++ b/tests/assets/webkit/form_page.html
@@ -0,0 +1,87 @@
+<!-- Copyright (C) 2011 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.
+-->
+
+<html>
+<head>
+    <title>Test Page</title>
+</head>
+<body>
+  <a id="tagA">Tag A</a>
+  <a name="text"></a>
+  <a id=someTextId>Some text&nbsp;</a>
+  <a id=nestedLinkId>Is not nested, and is not unique!</a>
+  <a class="divClass">Outter text</a>
+  <a id="outter" name="foo">Foo</a>
+
+  <div id=divId name="firstDiv">A div
+    <a id=nestedLinkId class="divClass" name="nestedLink">Nested text</a>
+    <a id="n1" name="linkn1">a nested link</a>
+    <a id="inner" name="foo">Foo</a>
+    <span id="n1" name="spann1"></span>
+    <a name=nested>Nested text</a>
+  </div>
+  <p id="spaces">     </p>
+  <p id="empty"></p>
+  <a name=foo href="foo" id="linkWithEqualsSign">Link=equalssign</a>
+  <p id="self-closed" />Here is some content that should not be in the previous p tag
+
+  <p class=" spaceAround ">Spaced out</p>
+
+  <a name="text" id="emptyLink"> </a>
+  <p id="spaces">     </p>
+  <p id="empty"></p>
+  <p id="self-closed"/>
+
+  <div>
+  <a id="id1" href="#">Foo</a>
+  <ul id="id2" />
+  <span id="id3"/>
+  <p id="id3">A paragraph</p>
+  </div>
+
+  <input name="inputDisabled" id="inputDisabled" disabled="disabled"> </input>
+  <span id="my_span">
+    <div>first_div</div>
+    <div>second_div</div>
+    <span>first_span</span>
+    <span>second_span</span>
+    <a id="Foo">Foo</a>
+  </span>
+
+  <select name="selectomatic">
+          <option id="one" selected="selected">One</option>
+          <option id="two">Two</option>
+          <option id="four">Four</option>
+          <option>Still learning how to count, apparently</option>
+  </select>
+
+  <select name="multi" id="multi" multiple="multiple">
+         <option id="eggs" selected="selected">Eggs</option>
+         <option id="ham" >Ham</option>
+         <option selected="selected">Sausages</option>
+         <option>Onion gravy</option>
+  </select>
+
+  <input type="radio" id="cheese" name="snack" value="cheese"/>Cheese<br/>
+  <input type="radio" id="peas" name="snack" value="peas"/>Peas<br/>
+  <input type="radio" id="cheese_and_peas" name="snack" value="cheese and peas" checked/>Cheese and peas<br/>
+  <input type="radio" id="nothing" name="snack" value="nowt" disabled="disabled"/>Not a sausage
+
+  <input type="hidden" name="hidden" value="fromage" />
+  Here's a checkbox: <input type="checkbox" id="checky" name="checky" value="furrfu"/><br/>
+
+
+</body>
+</html>
diff --git a/tests/core/ctscore.mk b/tests/core/ctscore.mk
index 7131e82..11fc253 100644
--- a/tests/core/ctscore.mk
+++ b/tests/core/ctscore.mk
@@ -18,7 +18,6 @@
 LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
 
 LOCAL_JAVA_LIBRARIES := android.test.runner bouncycastle
-LOCAL_STATIC_JAVA_LIBRARIES += CtsTestAnnotationsLib
 
 LOCAL_PROGUARD_ENABLED := disabled
 
diff --git a/tests/core/runner/src/android/test/InstrumentationCtsTestRunner.java b/tests/core/runner/src/android/test/InstrumentationCtsTestRunner.java
index 21eb2a6..5aa2c3b 100644
--- a/tests/core/runner/src/android/test/InstrumentationCtsTestRunner.java
+++ b/tests/core/runner/src/android/test/InstrumentationCtsTestRunner.java
@@ -22,11 +22,8 @@
 import dalvik.annotation.BrokenTest;
 import dalvik.annotation.SideEffect;
 
-import android.annotation.cts.RequiredFeatures;
-import android.app.Instrumentation;
 import android.app.KeyguardManager;
 import android.content.Context;
-import android.content.pm.FeatureInfo;
 import android.content.pm.PackageManager;
 import android.os.Bundle;
 import android.test.suitebuilder.TestMethod;
@@ -36,10 +33,7 @@
 import java.io.File;
 import java.lang.reflect.Field;
 import java.lang.reflect.Modifier;
-import java.util.Collections;
-import java.util.HashSet;
 import java.util.List;
-import java.util.Set;
 import java.util.TimeZone;
 
 import junit.framework.AssertionFailedError;
@@ -67,8 +61,6 @@
 
     private static final String REPORT_VALUE_ID = "InstrumentationCtsTestRunner";
 
-    private static final int REPORT_VALUE_RESULT_OMITTED = -3;
-
     /**
      * True if (and only if) we are running in single-test mode (as opposed to
      * batch mode).
@@ -235,8 +227,6 @@
                 Predicates.not(new HasAnnotation(BrokenTest.class));
         builderRequirements.add(brokenTestPredicate);
 
-        builderRequirements.add(getFeaturePredicate());
-
         if (!mSingleTest) {
             Predicate<TestMethod> sideEffectPredicate =
                     Predicates.not(new HasAnnotation(SideEffect.class));
@@ -244,64 +234,4 @@
         }
         return builderRequirements;
     }
-
-    /**
-     * Send back an indication that a test was omitted. InstrumentationTestRunner won't run omitted
-     * tests, but CTS needs to know that the test was omitted. Otherwise, it will attempt to rerun
-     * the test thinking that ADB must have crashed or something.
-     */
-    private void sendOmittedStatus(TestMethod t) {
-        Bundle bundle = new Bundle();
-        bundle.putString(Instrumentation.REPORT_KEY_IDENTIFIER, REPORT_VALUE_ID);
-        bundle.putInt(InstrumentationTestRunner.REPORT_KEY_NUM_TOTAL, 1);
-        bundle.putInt(InstrumentationTestRunner.REPORT_KEY_NUM_CURRENT, 1);
-        bundle.putString(InstrumentationTestRunner.REPORT_KEY_NAME_CLASS,
-                t.getEnclosingClassname());
-        bundle.putString(InstrumentationTestRunner.REPORT_KEY_NAME_TEST,
-                t.getName());
-
-        // First status message causes CTS to print out the test name like "Class#test..."
-        sendStatus(InstrumentationTestRunner.REPORT_VALUE_RESULT_START, bundle);
-
-        // Second status message causes CTS to complete the line like "Class#test...(omitted)"
-        sendStatus(REPORT_VALUE_RESULT_OMITTED, bundle);
-    }
-
-
-    private Predicate<TestMethod> getFeaturePredicate() {
-        return new Predicate<TestMethod>() {
-            public boolean apply(TestMethod t) {
-                if (isValidTest(t)) {
-                    // InstrumentationTestRunner will run the test and send back results.
-                    return true;
-                } else {
-                    // InstrumentationTestRunner WON'T run the test, so send back omitted status.
-                    sendOmittedStatus(t);
-                    return false;
-                }
-            }
-
-            private boolean isValidTest(TestMethod t) {
-                Set<String> features = new HashSet<String>();
-                add(features, t.getAnnotation(RequiredFeatures.class));
-                add(features, t.getEnclosingClass().getAnnotation(RequiredFeatures.class));
-
-                // Run the test only if the device supports all the features.
-                PackageManager packageManager = getContext().getPackageManager();
-                FeatureInfo[] featureInfos = packageManager.getSystemAvailableFeatures();
-                if (featureInfos != null) {
-                    for (FeatureInfo featureInfo : featureInfos) {
-                        features.remove(featureInfo.name);
-                    }
-                }
-                return features.isEmpty();
-            }
-
-            private void add(Set<String> features, RequiredFeatures annotation) {
-                if (annotation != null) {
-                    Collections.addAll(features, annotation.value());
-                }
-            }
-        };
-    }
 }
diff --git a/tests/expectations/knownfailures-3.0_r1.txt b/tests/expectations/knownfailures-3.0_r1.txt
index 405729d..a13d081 100644
--- a/tests/expectations/knownfailures-3.0_r1.txt
+++ b/tests/expectations/knownfailures-3.0_r1.txt
@@ -28,6 +28,8 @@
   description: "Flakey",
   names: [
     "android.hardware.cts.CameraTest#testSetPreviewDisplay",
+    "android.view.cts.GestureDetectorTest#testOnTouchEvent",
+    "android.view.cts.ViewTest#testWindowVisibilityChanged",
     "android.webkit.cts.WebChromeClientTest#testOnReceivedIcon",
     "android.widget.cts.AbsListViewTest#testGetContextMenuInfo"
   ]
diff --git a/tests/jni/Android.mk b/tests/jni/Android.mk
index d787d68..ed4c46f 100644
--- a/tests/jni/Android.mk
+++ b/tests/jni/Android.mk
@@ -22,7 +22,8 @@
 LOCAL_MODULE_TAGS := optional
 
 LOCAL_SRC_FILES := \
-		CtsJniOnLoad.cpp
+		CtsJniOnLoad.cpp \
+		android_os_cts_FileUtils.cpp
 
 LOCAL_C_INCLUDES := $(JNI_H_INCLUDE) 
 
diff --git a/tests/jni/CtsJniOnLoad.cpp b/tests/jni/CtsJniOnLoad.cpp
index b6177a1..d6a1d2b 100644
--- a/tests/jni/CtsJniOnLoad.cpp
+++ b/tests/jni/CtsJniOnLoad.cpp
@@ -21,6 +21,8 @@
 extern int register_android_os_cts_CpuFeatures(JNIEnv*);
 #endif
 
+extern int register_android_os_cts_FileUtils(JNIEnv*);
+
 jint JNI_OnLoad(JavaVM *vm, void *reserved) {
     JNIEnv *env = NULL;
 
@@ -34,5 +36,9 @@
     }
 #endif
 
+    if (register_android_os_cts_FileUtils(env)) {
+        return JNI_ERR;
+    }
+
     return JNI_VERSION_1_4;
 }
diff --git a/tests/jni/android_os_cts_FileUtils.cpp b/tests/jni/android_os_cts_FileUtils.cpp
new file mode 100644
index 0000000..d78d26c
--- /dev/null
+++ b/tests/jni/android_os_cts_FileUtils.cpp
@@ -0,0 +1,142 @@
+/* 
+ * Copyright (C) 2011 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.
+ */
+
+#include <grp.h>
+#include <jni.h>
+#include <pwd.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+static jclass gFileStatusClass;
+static jfieldID gFileStatusDevFieldID;
+static jfieldID gFileStatusInoFieldID;
+static jfieldID gFileStatusModeFieldID;
+static jfieldID gFileStatusNlinkFieldID;
+static jfieldID gFileStatusUidFieldID;
+static jfieldID gFileStatusGidFieldID;
+static jfieldID gFileStatusSizeFieldID;
+static jfieldID gFileStatusBlksizeFieldID;
+static jfieldID gFileStatusBlocksFieldID;
+static jfieldID gFileStatusAtimeFieldID;
+static jfieldID gFileStatusMtimeFieldID;
+static jfieldID gFileStatusCtimeFieldID;
+
+/*
+ * Native methods used by
+ * cts/tests/src/android/os/cts/FileUtils.java
+ *
+ * Copied from hidden API: frameworks/base/core/jni/android_os_FileUtils.cpp
+ */
+
+jboolean android_os_cts_FileUtils_getFileStatus(JNIEnv* env, jobject thiz,
+        jstring path, jobject fileStatus, jboolean statLinks)
+{
+    const char* pathStr = env->GetStringUTFChars(path, NULL);
+    jboolean ret = false;
+    struct stat s;
+
+    int res = statLinks == true ? lstat(pathStr, &s) : stat(pathStr, &s);
+
+    if (res == 0) {
+        ret = true;
+        if (fileStatus != NULL) {
+            env->SetIntField(fileStatus, gFileStatusDevFieldID, s.st_dev);
+            env->SetIntField(fileStatus, gFileStatusInoFieldID, s.st_ino);
+            env->SetIntField(fileStatus, gFileStatusModeFieldID, s.st_mode);
+            env->SetIntField(fileStatus, gFileStatusNlinkFieldID, s.st_nlink);
+            env->SetIntField(fileStatus, gFileStatusUidFieldID, s.st_uid);
+            env->SetIntField(fileStatus, gFileStatusGidFieldID, s.st_gid);
+            env->SetLongField(fileStatus, gFileStatusSizeFieldID, s.st_size);
+            env->SetIntField(fileStatus, gFileStatusBlksizeFieldID, s.st_blksize);
+            env->SetLongField(fileStatus, gFileStatusBlocksFieldID, s.st_blocks);
+            env->SetLongField(fileStatus, gFileStatusAtimeFieldID, s.st_atime);
+            env->SetLongField(fileStatus, gFileStatusMtimeFieldID, s.st_mtime);
+            env->SetLongField(fileStatus, gFileStatusCtimeFieldID, s.st_ctime);
+        }
+    }
+
+    env->ReleaseStringUTFChars(path, pathStr);
+
+    return ret;
+}
+
+jstring android_os_cts_FileUtils_getUserName(JNIEnv* env, jobject thiz,
+        jint uid)
+{
+    struct passwd *pwd = getpwuid(uid);
+    return env->NewStringUTF(pwd->pw_name);
+}
+
+jstring android_os_cts_FileUtils_getGroupName(JNIEnv* env, jobject thiz,
+        jint gid)
+{
+    struct group *grp = getgrgid(gid);
+    return env->NewStringUTF(grp->gr_name);
+}
+
+jint android_os_cts_FileUtils_setPermissions(JNIEnv* env, jobject clazz,
+        jstring file, jint mode)
+{
+    const char *fileStr = env->GetStringUTFChars(file, NULL);
+    if (fileStr == NULL) {
+        return -1;
+    }
+
+    if (strlen(fileStr) <= 0) {
+        env->ReleaseStringUTFChars(file, fileStr);
+        return ENOENT;
+    } 
+
+    jint returnValue = chmod(fileStr, mode) == 0 ? 0 : errno;
+    env->ReleaseStringUTFChars(file, fileStr);
+    return returnValue;
+}
+
+static JNINativeMethod gMethods[] = {
+    {  "getFileStatus", "(Ljava/lang/String;Landroid/os/cts/FileUtils$FileStatus;Z)Z",
+            (void *) android_os_cts_FileUtils_getFileStatus  },
+    {  "getUserName", "(I)Ljava/lang/String;",
+            (void *) android_os_cts_FileUtils_getUserName  },
+    {  "getGroupName", "(I)Ljava/lang/String;",
+            (void *) android_os_cts_FileUtils_getGroupName  },
+    {  "setPermissions", "(Ljava/lang/String;I)I",
+            (void *) android_os_cts_FileUtils_setPermissions },
+};
+
+int register_android_os_cts_FileUtils(JNIEnv* env)
+{
+    jclass clazz = env->FindClass("android/os/cts/FileUtils");
+
+    gFileStatusClass = env->FindClass("android/os/cts/FileUtils$FileStatus");
+    gFileStatusDevFieldID = env->GetFieldID(gFileStatusClass, "dev", "I");
+    gFileStatusInoFieldID = env->GetFieldID(gFileStatusClass, "ino", "I");
+    gFileStatusModeFieldID = env->GetFieldID(gFileStatusClass, "mode", "I");
+    gFileStatusNlinkFieldID = env->GetFieldID(gFileStatusClass, "nlink", "I");
+    gFileStatusUidFieldID = env->GetFieldID(gFileStatusClass, "uid", "I");
+    gFileStatusGidFieldID = env->GetFieldID(gFileStatusClass, "gid", "I");
+    gFileStatusSizeFieldID = env->GetFieldID(gFileStatusClass, "size", "J");
+    gFileStatusBlksizeFieldID = env->GetFieldID(gFileStatusClass, "blksize", "I");
+    gFileStatusBlocksFieldID = env->GetFieldID(gFileStatusClass, "blocks", "J");
+    gFileStatusAtimeFieldID = env->GetFieldID(gFileStatusClass, "atime", "J");
+    gFileStatusMtimeFieldID = env->GetFieldID(gFileStatusClass, "mtime", "J");
+    gFileStatusCtimeFieldID = env->GetFieldID(gFileStatusClass, "ctime", "J");
+
+    return env->RegisterNatives(clazz, gMethods, 
+            sizeof(gMethods) / sizeof(JNINativeMethod)); 
+}
diff --git a/tests/res/raw/test1.obb b/tests/res/raw/test1.obb
new file mode 100644
index 0000000..a6b3e1c
--- /dev/null
+++ b/tests/res/raw/test1.obb
Binary files differ
diff --git a/tests/res/raw/test1_nosig.obb b/tests/res/raw/test1_nosig.obb
new file mode 100644
index 0000000..5c3573f
--- /dev/null
+++ b/tests/res/raw/test1_nosig.obb
Binary files differ
diff --git a/tests/res/raw/test1_wrongpackage.obb b/tests/res/raw/test1_wrongpackage.obb
new file mode 100644
index 0000000..d0aafe1
--- /dev/null
+++ b/tests/res/raw/test1_wrongpackage.obb
Binary files differ
diff --git a/tests/src/android/os/cts/FileUtils.java b/tests/src/android/os/cts/FileUtils.java
new file mode 100644
index 0000000..feaf7d7
--- /dev/null
+++ b/tests/src/android/os/cts/FileUtils.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2011 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.os.cts;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+/** Bits and pieces copied from hidden API of android.os.FileUtils. */
+public class FileUtils {
+
+    public static final int S_IFSOCK = 0140000;
+    public static final int S_IFLNK = 0120000;
+    public static final int S_IFREG = 0100000;
+    public static final int S_IFBLK = 0060000;
+    public static final int S_IFDIR = 0040000;
+    public static final int S_IFCHR = 0020000;
+    public static final int S_IFIFO = 0010000;
+
+    public static final int S_ISUID = 0004000;
+    public static final int S_ISGID = 0002000;
+    public static final int S_ISVTX = 0001000;
+
+    public static final int S_IRWXU = 00700;
+    public static final int S_IRUSR = 00400;
+    public static final int S_IWUSR = 00200;
+    public static final int S_IXUSR = 00100;
+
+    public static final int S_IRWXG = 00070;
+    public static final int S_IRGRP = 00040;
+    public static final int S_IWGRP = 00020;
+    public static final int S_IXGRP = 00010;
+
+    public static final int S_IRWXO = 00007;
+    public static final int S_IROTH = 00004;
+    public static final int S_IWOTH = 00002;
+    public static final int S_IXOTH = 00001;
+
+    static {
+        System.loadLibrary("cts_jni");
+    }
+
+    public static class FileStatus {
+
+        public int dev;
+        public int ino;
+        public int mode;
+        public int nlink;
+        public int uid;
+        public int gid;
+        public int rdev;
+        public long size;
+        public int blksize;
+        public long blocks;
+        public long atime;
+        public long mtime;
+        public long ctime;
+
+        public boolean hasModeFlag(int flag) {
+            return (mode & flag) == flag;
+        }
+    }
+
+    /**
+     * @param path of the file to stat
+     * @param status object to set the fields on
+     * @param statLinks or don't stat links (lstat vs stat)
+     * @return whether or not we were able to stat the file
+     */
+    public native static boolean getFileStatus(String path, FileStatus status, boolean statLinks);
+
+    public native static String getUserName(int uid);
+
+    public native static String getGroupName(int gid);
+
+    public native static int setPermissions(String file, int mode);
+
+    /**
+     * Copy data from a source stream to destFile.
+     * Return true if succeed, return false if failed.
+     */
+    public static boolean copyToFile(InputStream inputStream, File destFile) {
+        try {
+            if (destFile.exists()) {
+                destFile.delete();
+            }
+            FileOutputStream out = new FileOutputStream(destFile);
+            try {
+                byte[] buffer = new byte[4096];
+                int bytesRead;
+                while ((bytesRead = inputStream.read(buffer)) >= 0) {
+                    out.write(buffer, 0, bytesRead);
+                }
+            } finally {
+                out.flush();
+                try {
+                    out.getFD().sync();
+                } catch (IOException e) {
+                }
+                out.close();
+            }
+            return true;
+        } catch (IOException e) {
+            return false;
+        }
+    }
+}
diff --git a/tests/src/android/speech/tts/cts/StubTextToSpeechService.java b/tests/src/android/speech/tts/cts/StubTextToSpeechService.java
new file mode 100644
index 0000000..ed675df
--- /dev/null
+++ b/tests/src/android/speech/tts/cts/StubTextToSpeechService.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2011 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.speech.tts.cts;
+
+import android.media.AudioFormat;
+import android.speech.tts.SynthesisRequest;
+import android.speech.tts.TextToSpeech;
+import android.speech.tts.TextToSpeechService;
+
+/**
+ * Stub implementation of {@link TextToSpeechService}. Used for testing the
+ * TTS engine API.
+ */
+public class StubTextToSpeechService extends TextToSpeechService {
+
+    public static final String TEXT_STREAM = "stream";
+    public static final String TEXT_COMPLETE = "complete";
+
+    @Override
+    protected String[] onGetLanguage() {
+        return new String[] { "eng", "USA", "" };
+    }
+
+    @Override
+    protected int onIsLanguageAvailable(String lang, String country, String variant) {
+        return TextToSpeech.LANG_AVAILABLE;
+    }
+
+    @Override
+    protected int onLoadLanguage(String lang, String country, String variant) {
+        return TextToSpeech.LANG_AVAILABLE;
+    }
+
+    @Override
+    protected void onStop() {
+    }
+
+    @Override
+    protected void onSynthesizeText(SynthesisRequest request) {
+        if (TEXT_STREAM.equals(request.getText())) {
+            synthesizeStreaming(request);
+        } else {
+            synthesizeComplete(request);
+        }
+    }
+
+    private void synthesizeStreaming(SynthesisRequest request) {
+        if (request.start(16000, AudioFormat.ENCODING_PCM_16BIT, 1) != TextToSpeech.SUCCESS) {
+            return;
+        }
+        byte[] data = { 0x01, 0x2 };
+        if (request.audioAvailable(data, 0, data.length) != TextToSpeech.SUCCESS) {
+            return;
+        }
+        if (request.done() != TextToSpeech.SUCCESS) {
+            return;
+        }
+    }
+
+    private void synthesizeComplete(SynthesisRequest request) {
+        byte[] data = { 0x01, 0x2 };
+        if (request.completeAudioAvailable(16000, AudioFormat.ENCODING_PCM_16BIT, 1,
+                data, 0, data.length) != TextToSpeech.SUCCESS) {
+            return;
+        }
+    }
+
+}
diff --git a/tests/src/android/webkit/cts/CtsTestServer.java b/tests/src/android/webkit/cts/CtsTestServer.java
index 91f4f1e..707455b 100644
--- a/tests/src/android/webkit/cts/CtsTestServer.java
+++ b/tests/src/android/webkit/cts/CtsTestServer.java
@@ -79,6 +79,7 @@
 
     public static final String FAVICON_PATH = "/favicon.ico";
     public static final String USERAGENT_PATH = "/useragent.html";
+    public static final String TEST_DOWNLOAD_PATH = "/download.html";
     public static final String ASSET_PREFIX = "/assets/";
     public static final String FAVICON_ASSET_PATH = ASSET_PREFIX + "webkit/favicon.png";
     public static final String APPCACHE_PATH = "/appcache.html";
@@ -350,6 +351,10 @@
         return sb.toString();
     }
 
+    public String getTestDownloadUrl() {
+        return getBaseUri() + TEST_DOWNLOAD_PATH;
+    }
+
     public String getLastRequestUrl() {
         return mLastQuery;
     }
@@ -501,6 +506,10 @@
             }
             response.setEntity(createEntity("<html><head><title>" + agent + "</title></head>" +
                     "<body>" + agent + "</body></html>"));
+        } else if (path.equals(TEST_DOWNLOAD_PATH)) {
+            response = createResponse(HttpStatus.SC_OK);
+            response.setHeader("Content-Length", "0");
+            response.setEntity(createEntity(""));
         } else if (path.equals(SHUTDOWN_PREFIX)) {
             response = createResponse(HttpStatus.SC_OK);
             // We cannot close the socket here, because we need to respond.
diff --git a/tests/src/android/webkit/cts/WebDriverStubActivity.java b/tests/src/android/webkit/cts/WebDriverStubActivity.java
new file mode 100644
index 0000000..092156b
--- /dev/null
+++ b/tests/src/android/webkit/cts/WebDriverStubActivity.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2011 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.webkit.cts;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.webkit.WebSettings;
+import android.webkit.WebView;
+import android.webkit.webdriver.WebDriver;
+
+/**
+ * A stub activity for WebDriver tests.
+ */
+public class WebDriverStubActivity extends Activity {
+    private WebDriver mDriver;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        WebView view = new WebView(this);
+
+        WebSettings settings = view.getSettings();
+        settings.setJavaScriptCanOpenWindowsAutomatically(true);
+        settings.setSupportMultipleWindows(true);
+        settings.setBuiltInZoomControls(true);
+        settings.setJavaScriptEnabled(true);
+        settings.setAppCacheEnabled(true);
+        settings.setDatabaseEnabled(true);
+        settings.setDomStorageEnabled(true);
+        settings.setGeolocationEnabled(true);
+        settings.setSaveFormData(true);
+
+        mDriver = new WebDriver(view);
+
+        setContentView(view);
+    }
+
+    public WebDriver getDriver() {
+        return mDriver;
+    }
+}
diff --git a/tests/tests/app/Android.mk b/tests/tests/app/Android.mk
index 46cd43b..a9b75df 100644
--- a/tests/tests/app/Android.mk
+++ b/tests/tests/app/Android.mk
@@ -22,7 +22,6 @@
 LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
 
 LOCAL_JAVA_LIBRARIES := android.test.runner
-LOCAL_STATIC_JAVA_LIBRARIES := CtsTestAnnotationsLib
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
diff --git a/tests/tests/app/src/android/app/cts/DownloadManagerTest.java b/tests/tests/app/src/android/app/cts/DownloadManagerTest.java
new file mode 100644
index 0000000..fbe57c4
--- /dev/null
+++ b/tests/tests/app/src/android/app/cts/DownloadManagerTest.java
@@ -0,0 +1,183 @@
+/*
+ * Copyright (C) 2011 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.app.cts;
+
+import android.app.DownloadManager;
+import android.app.DownloadManager.Query;
+import android.app.DownloadManager.Request;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.database.Cursor;
+import android.net.Uri;
+import android.test.AndroidTestCase;
+import android.view.animation.cts.DelayedCheck;
+import android.webkit.cts.CtsTestServer;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+public class DownloadManagerTest extends AndroidTestCase {
+
+    private DownloadManager mDownloadManager;
+
+    private CtsTestServer mWebServer;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mDownloadManager = (DownloadManager) mContext.getSystemService(Context.DOWNLOAD_SERVICE);
+        mWebServer = new CtsTestServer(mContext);
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+        mWebServer.shutdown();
+    }
+
+    public void testDownloadManager() throws Exception {
+        DownloadCompleteReceiver receiver = new DownloadCompleteReceiver();
+        try {
+            removeAllDownloads();
+
+            IntentFilter intentFilter = new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE);
+            mContext.registerReceiver(receiver, intentFilter);
+
+            long goodId = mDownloadManager.enqueue(new Request(getGoodUrl()));
+            long badId = mDownloadManager.enqueue(new Request(getBadUrl()));
+
+            int allDownloads = getTotalNumberDownloads();
+            assertEquals(2, allDownloads);
+
+            assertDownloadQueryableById(goodId);
+            assertDownloadQueryableById(badId);
+
+            receiver.waitForDownloadComplete();
+
+            assertDownloadQueryableByStatus(DownloadManager.STATUS_SUCCESSFUL);
+            assertDownloadQueryableByStatus(DownloadManager.STATUS_FAILED);
+
+            assertRemoveDownload(goodId, allDownloads - 1);
+            assertRemoveDownload(badId, allDownloads - 2);
+        } finally {
+            mContext.unregisterReceiver(receiver);
+        }
+    }
+
+    private class DownloadCompleteReceiver extends BroadcastReceiver {
+
+        private final CountDownLatch mReceiveLatch = new CountDownLatch(2);
+
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            mReceiveLatch.countDown();
+        }
+
+        public void waitForDownloadComplete() throws InterruptedException {
+            assertTrue("Make sure you have WiFi or some other connectivity for this test.",
+                    mReceiveLatch.await(3, TimeUnit.SECONDS));
+        }
+    }
+
+    private void removeAllDownloads() {
+        if (getTotalNumberDownloads() > 0) {
+            Cursor cursor = null;
+            try {
+                Query query = new Query();
+                cursor = mDownloadManager.query(query);
+                int columnIndex = cursor.getColumnIndex(DownloadManager.COLUMN_ID);
+                long[] removeIds = new long[cursor.getCount()];
+                for (int i = 0; cursor.moveToNext(); i++) {
+                    removeIds[i] = cursor.getLong(columnIndex);
+                }
+                assertEquals(removeIds.length, mDownloadManager.remove(removeIds));
+                assertEquals(0, getTotalNumberDownloads());
+            } finally {
+                if (cursor != null) {
+                    cursor.close();
+                }
+            }
+        }
+    }
+
+    private Uri getGoodUrl() {
+        return Uri.parse(mWebServer.getTestDownloadUrl());
+    }
+
+    private Uri getBadUrl() {
+        return Uri.parse(mWebServer.getBaseUri() + "/nosuchurl");
+    }
+
+    private int getTotalNumberDownloads() {
+        Cursor cursor = null;
+        try {
+            Query query = new Query();
+            cursor = mDownloadManager.query(query);
+            return cursor.getCount();
+        } finally {
+            if (cursor != null) {
+                cursor.close();
+            }
+        }
+    }
+
+    private void assertDownloadQueryableById(long downloadId) {
+        Cursor cursor = null;
+        try {
+            Query query = new Query().setFilterById(downloadId);
+            cursor = mDownloadManager.query(query);
+            assertEquals(1, cursor.getCount());
+        } finally {
+            if (cursor != null) {
+                cursor.close();
+            }
+        }
+    }
+
+    private void assertDownloadQueryableByStatus(final int status) {
+        new DelayedCheck() {
+            @Override
+            protected boolean check() {
+                Cursor cursor= null;
+                try {
+                    Query query = new Query().setFilterByStatus(status);
+                    cursor = mDownloadManager.query(query);
+                    return 1 == cursor.getCount();
+                } finally {
+                    if (cursor != null) {
+                        cursor.close();
+                    }
+                }
+            }
+        }.run();
+    }
+
+    private void assertRemoveDownload(long removeId, int expectedNumDownloads) {
+        Cursor cursor = null;
+        try {
+            assertEquals(1, mDownloadManager.remove(removeId));
+            Query query = new Query();
+            cursor = mDownloadManager.query(query);
+            assertEquals(expectedNumDownloads, cursor.getCount());
+        } finally {
+            if (cursor != null) {
+                cursor.close();
+            }
+        }
+    }
+}
diff --git a/tests/tests/content/src/android/content/cts/ContentResolverSyncTestCase.java b/tests/tests/content/src/android/content/cts/ContentResolverSyncTestCase.java
index b8c5d2e..1cc4cfb 100644
--- a/tests/tests/content/src/android/content/cts/ContentResolverSyncTestCase.java
+++ b/tests/tests/content/src/android/content/cts/ContentResolverSyncTestCase.java
@@ -217,12 +217,13 @@
     /**
      * Test if we can set and get the MasterSyncAutomatically switch
      */
-    public void testGetAndSetMasterSyncAutomatically() {
+    public void testGetAndSetMasterSyncAutomatically() throws Exception {
         ContentResolver.setMasterSyncAutomatically(true);
         assertEquals(true, ContentResolver.getMasterSyncAutomatically());
 
         ContentResolver.setMasterSyncAutomatically(false);
         assertEquals(false, ContentResolver.getMasterSyncAutomatically());
+        Thread.sleep(3000);
     }
 
     /**
diff --git a/tests/tests/os/src/android/os/storage/cts/StorageManagerTest.java b/tests/tests/os/src/android/os/storage/cts/StorageManagerTest.java
new file mode 100644
index 0000000..b229d03
--- /dev/null
+++ b/tests/tests/os/src/android/os/storage/cts/StorageManagerTest.java
@@ -0,0 +1,257 @@
+/*
+ * Copyright (C) 2011 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.os.storage.cts;
+
+import com.android.cts.stub.R;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.content.res.Resources.NotFoundException;
+import android.os.cts.FileUtils;
+import android.os.storage.OnObbStateChangeListener;
+import android.os.storage.StorageManager;
+import android.test.AndroidTestCase;
+import android.test.ComparisonFailure;
+import android.util.Log;
+
+import java.io.File;
+import java.io.InputStream;
+
+public class StorageManagerTest extends AndroidTestCase {
+
+    private static final String TAG = StorageManager.class.getSimpleName();
+
+    private static final long MAX_WAIT_TIME = 25*1000;
+    private static final long WAIT_TIME_INCR = 5*1000;
+
+    private static final String OBB_MOUNT_PREFIX = "/mnt/obb/";
+
+    private StorageManager mStorageManager;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mStorageManager = (StorageManager) mContext.getSystemService(Context.STORAGE_SERVICE);
+    }
+
+    public void testMountAndUnmountObbNormal() {
+        final File outFile = getFilePath("test1.obb");
+
+        mountObb(R.raw.test1, outFile, OnObbStateChangeListener.MOUNTED);
+
+        mountObb(R.raw.test1, outFile, OnObbStateChangeListener.ERROR_ALREADY_MOUNTED);
+
+        final String mountPath = checkMountedPath(outFile);
+        final File mountDir = new File(mountPath);
+
+        assertTrue("OBB mounted path should be a directory", mountDir.isDirectory());
+
+        unmountObb(outFile, OnObbStateChangeListener.UNMOUNTED);
+    }
+
+    public void testAttemptMountNonObb() {
+        final File outFile = getFilePath("test1_nosig.obb");
+
+        mountObb(R.raw.test1_nosig, outFile, OnObbStateChangeListener.ERROR_INTERNAL);
+
+        assertFalse("OBB should not be mounted",
+                mStorageManager.isObbMounted(outFile.getPath()));
+
+        assertNull("OBB's mounted path should be null",
+                mStorageManager.getMountedObbPath(outFile.getPath()));
+    }
+
+    public void testAttemptMountObbWrongPackage() {
+        final File outFile = getFilePath("test1_wrongpackage.obb");
+
+        mountObb(R.raw.test1_wrongpackage, outFile,
+                OnObbStateChangeListener.ERROR_PERMISSION_DENIED);
+
+        assertFalse("OBB should not be mounted",
+                mStorageManager.isObbMounted(outFile.getPath()));
+
+        assertNull("OBB's mounted path should be null",
+                mStorageManager.getMountedObbPath(outFile.getPath()));
+    }
+
+    public void testMountAndUnmountTwoObbs() {
+        final File file1 = getFilePath("test1.obb");
+        final File file2 = getFilePath("test2.obb");
+
+        ObbObserver oo1 = mountObbWithoutWait(R.raw.test1, file1);
+        ObbObserver oo2 = mountObbWithoutWait(R.raw.test1, file2);
+
+        Log.d(TAG, "Waiting for OBB #1 to complete mount");
+        waitForObbActionCompletion(file1, oo1, OnObbStateChangeListener.MOUNTED, false);
+        Log.d(TAG, "Waiting for OBB #2 to complete mount");
+        waitForObbActionCompletion(file2, oo2, OnObbStateChangeListener.MOUNTED, false);
+
+        final String mountPath1 = checkMountedPath(file1);
+        final File mountDir1 = new File(mountPath1);
+        assertTrue("OBB mounted path should be a directory", mountDir1.isDirectory());
+
+        final String mountPath2 = checkMountedPath(file2);
+        final File mountDir2 = new File(mountPath2);
+        assertTrue("OBB mounted path should be a directory", mountDir2.isDirectory());
+
+        unmountObb(file1, OnObbStateChangeListener.UNMOUNTED);
+        unmountObb(file2, OnObbStateChangeListener.UNMOUNTED);
+    }
+
+    private static void assertStartsWith(String message, String prefix, String actual) {
+        if (!actual.startsWith(prefix)) {
+            throw new ComparisonFailure(message, prefix, actual);
+        }
+    }
+
+    private static class ObbObserver extends OnObbStateChangeListener {
+        private String path;
+
+        public int state = -1;
+        boolean done = false;
+
+        @Override
+        public void onObbStateChange(String path, int state) {
+            Log.d(TAG, "Received message.  path=" + path + ", state=" + state);
+            synchronized (this) {
+                this.path = path;
+                this.state = state;
+                done = true;
+                notifyAll();
+            }
+        }
+
+        public String getPath() {
+            assertTrue("Expected ObbObserver to have received a state change.", done);
+            return path;
+        }
+
+        public int getState() {
+            assertTrue("Expected ObbObserver to have received a state change.", done);
+            return state;
+        }
+
+        public boolean isDone() {
+            return done;
+        }
+
+        public boolean waitForCompletion() {
+            long waitTime = 0;
+            synchronized (this) {
+                while (!isDone() && waitTime < MAX_WAIT_TIME) {
+                    try {
+                        wait(WAIT_TIME_INCR);
+                        waitTime += WAIT_TIME_INCR;
+                    } catch (InterruptedException e) {
+                        Log.i(TAG, "Interrupted during sleep", e);
+                    }
+                }
+            }
+
+            return isDone();
+        }
+    }
+
+    private File getFilePath(String name) {
+        final File filesDir = mContext.getFilesDir();
+        final File outFile = new File(filesDir, name);
+        return outFile;
+    }
+
+    private void copyRawToFile(int rawResId, File outFile) {
+        Resources res = mContext.getResources();
+        InputStream is = null;
+        try {
+            is = res.openRawResource(rawResId);
+        } catch (NotFoundException e) {
+            fail("Failed to load resource with id: " + rawResId);
+        }
+        FileUtils.setPermissions(outFile.getPath(), FileUtils.S_IRWXU | FileUtils.S_IRWXG
+                | FileUtils.S_IRWXO);
+        assertTrue(FileUtils.copyToFile(is, outFile));
+        FileUtils.setPermissions(outFile.getPath(), FileUtils.S_IRWXU | FileUtils.S_IRWXG
+                | FileUtils.S_IRWXO);
+    }
+
+    private void mountObb(final int resource, final File file, int expectedState) {
+        copyRawToFile(resource, file);
+
+        final ObbObserver observer = new ObbObserver();
+        assertTrue("mountObb call on " + file.getPath() + " should succeed",
+                mStorageManager.mountObb(file.getPath(), null, observer));
+
+        assertTrue("Mount should have completed",
+                observer.waitForCompletion());
+
+        if (expectedState == OnObbStateChangeListener.MOUNTED) {
+            assertTrue("OBB should be mounted", mStorageManager.isObbMounted(file.getPath()));
+        }
+
+        assertEquals("Actual file and resolved file should be the same",
+                file.getPath(), observer.getPath());
+
+        assertEquals(expectedState, observer.getState());
+    }
+
+    private ObbObserver mountObbWithoutWait(final int resource, final File file) {
+        copyRawToFile(resource, file);
+
+        final ObbObserver observer = new ObbObserver();
+        assertTrue("mountObb call on " + file.getPath() + " should succeed",
+                mStorageManager.mountObb(file.getPath(), null, observer));
+
+        return observer;
+    }
+
+    private void waitForObbActionCompletion(final File file,
+            final ObbObserver observer, int expectedState, boolean checkPath) {
+        assertTrue("Mount should have completed", observer.waitForCompletion());
+
+        assertTrue("OBB should be mounted", mStorageManager.isObbMounted(file.getPath()));
+
+        if (checkPath) {
+            assertEquals("Actual file and resolved file should be the same", file.getPath(),
+                    observer.getPath());
+        }
+
+        assertEquals(expectedState, observer.getState());
+    }
+
+    private String checkMountedPath(final File file) {
+        final String mountPath = mStorageManager.getMountedObbPath(file.getPath());
+        assertStartsWith("Path should be in " + OBB_MOUNT_PREFIX,
+                OBB_MOUNT_PREFIX,
+                mountPath);
+        return mountPath;
+    }
+
+    private void unmountObb(final File file, int expectedState) {
+        final ObbObserver observer = new ObbObserver();
+
+        assertTrue("unmountObb call on test1.obb should succeed",
+                mStorageManager.unmountObb(file.getPath(), false, observer));
+
+        assertTrue("Unmount should have completed",
+                observer.waitForCompletion());
+
+        assertEquals(expectedState, observer.getState());
+
+        if (expectedState == OnObbStateChangeListener.UNMOUNTED) {
+            assertFalse("OBB should not be mounted", mStorageManager.isObbMounted(file.getPath()));
+        }
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/AllocationTest.java b/tests/tests/renderscript/src/android/renderscript/cts/AllocationTest.java
index b6afb70..aa981ca 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/AllocationTest.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/AllocationTest.java
@@ -216,7 +216,7 @@
         }
 
         try {
-            int invalidUsage = 0x0010;
+            int invalidUsage = 0x0020;
             Allocation.createFromBitmap(mRS, B,
                 Allocation.MipmapControl.MIPMAP_NONE, invalidUsage);
             fail("should throw RSIllegalArgumentException.");
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/ComputeTest.java b/tests/tests/renderscript/src/android/renderscript/cts/ComputeTest.java
index 8d24227..d1254cc 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/ComputeTest.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/ComputeTest.java
@@ -22,6 +22,10 @@
 import android.renderscript.Byte3;
 import android.renderscript.Byte4;
 
+import android.renderscript.Double2;
+import android.renderscript.Double3;
+import android.renderscript.Double4;
+
 import android.renderscript.Float2;
 import android.renderscript.Float3;
 import android.renderscript.Float4;
@@ -46,15 +50,52 @@
         Byte2 b2 = new Byte2();
         b2.x = 1;
         b2.y = 2;
+        b2 = new Byte2((byte)1, (byte)2);
+        assertTrue(b2.x == 1);
+        assertTrue(b2.y == 2);
         Byte3 b3 = new Byte3();
         b3.x = 1;
         b3.y = 2;
         b3.z = 2;
+        b3 = new Byte3((byte)1, (byte)2, (byte)3);
+        assertTrue(b3.x == 1);
+        assertTrue(b3.y == 2);
+        assertTrue(b3.z == 3);
         Byte4 b4 = new Byte4();
         b4.x = 1;
         b4.y = 2;
         b4.x = 3;
         b4.w = 4;
+        b4 = new Byte4((byte)1, (byte)2, (byte)3, (byte)4);
+        assertTrue(b4.x == 1);
+        assertTrue(b4.y == 2);
+        assertTrue(b4.z == 3);
+        assertTrue(b4.w == 4);
+
+        Double2 d2 = new Double2();
+        d2.x = 1.0;
+        d2.y = 2.0;
+        d2 = new Double2(1.0, 2.0);
+        assertTrue(d2.x == 1.0);
+        assertTrue(d2.y == 2.0);
+        Double3 d3 = new Double3();
+        d3.x = 1.0;
+        d3.y = 2.0;
+        d3.z = 3.0;
+        d3 = new Double3(1.0, 2.0, 3.0);
+        assertTrue(d3.x == 1.0);
+        assertTrue(d3.y == 2.0);
+        assertTrue(d3.z == 3.0);
+        Double4 d4 = new Double4();
+        d4.x = 1.0;
+        d4.y = 2.0;
+        d4.x = 3.0;
+        d4.w = 4.0;
+        d4 = new Double4(1.0, 2.0, 3.0, 4.0);
+        assertTrue(d4.x == 1.0);
+        assertTrue(d4.y == 2.0);
+        assertTrue(d4.z == 3.0);
+        assertTrue(d4.w == 4.0);
 
         Float2 f2 = new Float2();
         f2.x = 1.0f;
@@ -84,41 +125,77 @@
         Int2 i2 = new Int2();
         i2.x = 1;
         i2.y = 2;
+        i2 = new Int2(1, 2);
+        assertTrue(i2.x == 1);
+        assertTrue(i2.y == 2);
         Int3 i3 = new Int3();
         i3.x = 1;
         i3.y = 2;
         i3.z = 3;
+        i3 = new Int3(1, 2, 3);
+        assertTrue(i3.x == 1);
+        assertTrue(i3.y == 2);
+        assertTrue(i3.z == 3);
         Int4 i4 = new Int4();
         i4.x = 1;
         i4.y = 2;
         i4.x = 3;
         i4.w = 4;
+        i4 = new Int4(1, 2, 3, 4);
+        assertTrue(i4.x == 1);
+        assertTrue(i4.y == 2);
+        assertTrue(i4.z == 3);
+        assertTrue(i4.w == 4);
 
         Long2 l2 = new Long2();
         l2.x = 1;
         l2.y = 2;
+        l2 = new Long2(1, 2);
+        assertTrue(l2.x == 1);
+        assertTrue(l2.y == 2);
         Long3 l3 = new Long3();
         l3.x = 1;
         l3.y = 2;
         l3.z = 3;
+        l3 = new Long3(1, 2, 3);
+        assertTrue(l3.x == 1);
+        assertTrue(l3.y == 2);
+        assertTrue(l3.z == 3);
         Long4 l4 = new Long4();
         l4.x = 1;
         l4.y = 2;
         l4.x = 3;
         l4.w = 4;
+        l4 = new Long4(1, 2, 3, 4);
+        assertTrue(l4.x == 1);
+        assertTrue(l4.y == 2);
+        assertTrue(l4.z == 3);
+        assertTrue(l4.w == 4);
 
         Short2 s2 = new Short2();
         s2.x = 1;
         s2.y = 2;
+        s2 = new Short2((short)1, (short)2);
+        assertTrue(s2.x == 1);
+        assertTrue(s2.y == 2);
         Short3 s3 = new Short3();
         s3.x = 1;
         s3.y = 2;
         s3.z = 3;
+        s3 = new Short3((short)1, (short)2, (short)3);
+        assertTrue(s3.x == 1);
+        assertTrue(s3.y == 2);
+        assertTrue(s3.z == 3);
         Short4 s4 = new Short4();
         s4.x = 1;
         s4.y = 2;
         s4.x = 3;
         s4.w = 4;
+        s4 = new Short4((short)1, (short)2, (short)3, (short)4);
+        assertTrue(s4.x == 1);
+        assertTrue(s4.y == 2);
+        assertTrue(s4.z == 3);
+        assertTrue(s4.w == 4);
     }
 
     private boolean initializeGlobals(ScriptC_primitives s) {
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/ElementTest.java b/tests/tests/renderscript/src/android/renderscript/cts/ElementTest.java
index 7723c20..0f58d55 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/ElementTest.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/ElementTest.java
@@ -244,8 +244,9 @@
         assertEquals(DataKind.PIXEL_LA, DataKind.valueOf("PIXEL_LA"));
         assertEquals(DataKind.PIXEL_RGB, DataKind.valueOf("PIXEL_RGB"));
         assertEquals(DataKind.PIXEL_RGBA, DataKind.valueOf("PIXEL_RGBA"));
+        assertEquals(DataKind.PIXEL_DEPTH, DataKind.valueOf("PIXEL_DEPTH"));
         // Make sure no new enums are added
-        assertEquals(6, DataKind.values().length);
+        assertEquals(7, DataKind.values().length);
 
         for (DataKind dk : DataKind.values()) {
             if (dk != DataKind.USER) {
diff --git a/tests/tests/speech/Android.mk b/tests/tests/speech/Android.mk
index a15b2ec..932c564 100755
--- a/tests/tests/speech/Android.mk
+++ b/tests/tests/speech/Android.mk
@@ -29,5 +29,7 @@
 
 LOCAL_SDK_VERSION := current
 
+LOCAL_INSTRUMENTATION_FOR := CtsTestStubs
+
 include $(BUILD_PACKAGE)
 
diff --git a/tests/tests/speech/AndroidManifest.xml b/tests/tests/speech/AndroidManifest.xml
index 6e1e528..778f763 100755
--- a/tests/tests/speech/AndroidManifest.xml
+++ b/tests/tests/speech/AndroidManifest.xml
@@ -24,9 +24,8 @@
 
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
 
-    <!--  self-instrumenting test package. -->
-    <instrumentation android:name="android.test.InstrumentationTestRunner"
-                     android:targetPackage="com.android.cts.speech"
+    <instrumentation android:name="android.test.InstrumentationCtsTestRunner"
+                     android:targetPackage="com.android.cts.stub"
                      android:label="CTS tests of android.speech"/>
 
 </manifest>
diff --git a/tests/tests/speech/src/android/speech/tts/cts/TextToSpeechServiceTest.java b/tests/tests/speech/src/android/speech/tts/cts/TextToSpeechServiceTest.java
new file mode 100644
index 0000000..7babe5a
--- /dev/null
+++ b/tests/tests/speech/src/android/speech/tts/cts/TextToSpeechServiceTest.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2011 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.speech.tts.cts;
+
+import android.os.Environment;
+import android.speech.tts.TextToSpeech;
+import android.test.AndroidTestCase;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.util.HashMap;
+
+/**
+ * Tests for {@link android.speech.tts.TextToSpeechService} using StubTextToSpeechService.
+ */
+public class TextToSpeechServiceTest extends AndroidTestCase {
+
+    private static final String UTTERANCE_ID = "utterance";
+    private static final String SAMPLE_FILE_NAME = "mytts.wav";
+
+    private TextToSpeechWrapper mTts;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mTts = TextToSpeechWrapper.createTextToSpeechMockWrapper(getContext());
+        assertNotNull(mTts);
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+        mTts.shutdown();
+    }
+
+    private TextToSpeech getTts() {
+        return mTts.getTts();
+    }
+
+    public void testSynthesizeToFileStreaming() throws Exception {
+        File sampleFile = new File(Environment.getExternalStorageDirectory(), SAMPLE_FILE_NAME);
+        try {
+            assertFalse(sampleFile.exists());
+
+            int result = getTts().synthesizeToFile(StubTextToSpeechService.TEXT_STREAM,
+                    createParams(), sampleFile.getPath());
+            assertEquals("synthesizeToFile() failed", TextToSpeech.SUCCESS, result);
+
+            assertTrue("synthesizeToFile() completion timeout", mTts.waitForComplete(UTTERANCE_ID));
+            assertTrue("synthesizeToFile() didn't produce a file", sampleFile.exists());
+            assertTrue("synthesizeToFile() produced a non-sound file",
+                    TextToSpeechWrapper.isSoundFile(sampleFile.getPath()));
+        } finally {
+            sampleFile.delete();
+        }
+    }
+
+    public void testSynthesizeToFileComplete() throws Exception {
+        File sampleFile = new File(Environment.getExternalStorageDirectory(), SAMPLE_FILE_NAME);
+        try {
+            assertFalse(sampleFile.exists());
+
+            int result = getTts().synthesizeToFile(StubTextToSpeechService.TEXT_COMPLETE,
+                    createParams(), sampleFile.getPath());
+            assertEquals("synthesizeToFile() failed", TextToSpeech.SUCCESS, result);
+
+            assertTrue("synthesizeToFile() completion timeout", waitForUtterance());
+            assertTrue("synthesizeToFile() didn't produce a file", sampleFile.exists());
+            assertTrue("synthesizeToFile() produced a non-sound file",
+                    TextToSpeechWrapper.isSoundFile(sampleFile.getPath()));
+        } finally {
+            sampleFile.delete();
+        }
+    }
+
+    public void testSpeakStreaming() throws Exception {
+        int result = getTts().speak(StubTextToSpeechService.TEXT_STREAM, TextToSpeech.QUEUE_FLUSH,
+                createParams());
+        assertEquals("speak() failed", TextToSpeech.SUCCESS, result);
+        assertTrue("speak() completion timeout", waitForUtterance());
+    }
+
+    public void testSpeakComplete() throws Exception {
+        int result = getTts().speak(StubTextToSpeechService.TEXT_COMPLETE, TextToSpeech.QUEUE_FLUSH,
+                createParams());
+        assertEquals("speak() failed", TextToSpeech.SUCCESS, result);
+        assertTrue("speak() completion timeout", waitForUtterance());
+    }
+
+    public void testMediaPlayerFails() throws Exception {
+        File sampleFile = new File(Environment.getExternalStorageDirectory(), "notsound.wav");
+        try {
+            assertFalse(TextToSpeechWrapper.isSoundFile(sampleFile.getPath()));
+            FileOutputStream out = new FileOutputStream(sampleFile);
+            out.write(new byte[] { 0x01, 0x02 });
+            out.close();
+            assertFalse(TextToSpeechWrapper.isSoundFile(sampleFile.getPath()));
+        } finally {
+            sampleFile.delete();
+        }
+    }
+
+    private HashMap<String, String> createParams() {
+        HashMap<String, String> params = new HashMap<String,String>();
+        params.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, UTTERANCE_ID);
+        return params;
+    }
+
+    private boolean waitForUtterance() throws InterruptedException {
+        return mTts.waitForComplete(UTTERANCE_ID);
+    }
+
+}
diff --git a/tests/tests/speech/src/android/speech/tts/cts/TextToSpeechTest.java b/tests/tests/speech/src/android/speech/tts/cts/TextToSpeechTest.java
index e012fe3..cb8aa81 100644
--- a/tests/tests/speech/src/android/speech/tts/cts/TextToSpeechTest.java
+++ b/tests/tests/speech/src/android/speech/tts/cts/TextToSpeechTest.java
@@ -15,98 +15,31 @@
  */
 package android.speech.tts.cts;
 
-import dalvik.annotation.TestTargetClass;
-
-import android.media.MediaPlayer;
 import android.os.Environment;
 import android.speech.tts.TextToSpeech;
-import android.speech.tts.TextToSpeech.OnInitListener;
-import android.speech.tts.TextToSpeech.OnUtteranceCompletedListener;
 import android.test.AndroidTestCase;
-import android.util.Log;
 
 import java.io.File;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Locale;
 
 /**
  * Tests for {@link android.speech.tts.TextToSpeech}
  */
-@TestTargetClass(TextToSpeech.class)
 public class TextToSpeechTest extends AndroidTestCase {
 
-    private TextToSpeech mTts;
-
-    private static final String UTTERANCE = "utterance";
+    private static final String UTTERANCE_ID = "utterance";
     private static final String SAMPLE_TEXT = "This is a sample text to speech string";
     private static final String SAMPLE_FILE_NAME = "mytts.wav";
-    /** maximum time to wait for tts to be initialized */
-    private static final int TTS_INIT_MAX_WAIT_TIME = 30 * 1000;
-    /** maximum time to wait for speech call to be complete */
-    private static final int TTS_SPEECH_MAX_WAIT_TIME = 5 * 1000;
-    private static final String LOG_TAG = "TextToSpeechTest";
 
-    /**
-     * Listener for waiting for TTS engine initialization completion.
-     */
-    private static class InitWaitListener implements OnInitListener {
-        private int mStatus = TextToSpeech.ERROR;
-
-        public void onInit(int status) {
-            mStatus = status;
-            synchronized(this) {
-                notify();
-            }
-        }
-
-        public boolean waitForInit() throws InterruptedException {
-            if (mStatus == TextToSpeech.SUCCESS) {
-                return true;
-            }
-            synchronized (this) {
-                wait(TTS_INIT_MAX_WAIT_TIME);
-            }
-            return mStatus == TextToSpeech.SUCCESS;
-        }
-    }
-
-    /**
-     * Listener for waiting for utterance completion.
-     */
-    private static class UtteranceWaitListener implements OnUtteranceCompletedListener {
-        private boolean mIsComplete = false;
-        private final String mExpectedUtterance;
-
-        public UtteranceWaitListener(String expectedUtteranceId) {
-            mExpectedUtterance = expectedUtteranceId;
-        }
-
-        public void onUtteranceCompleted(String utteranceId) {
-            if (mExpectedUtterance.equals(utteranceId)) {
-                synchronized(this) {
-                    mIsComplete = true;
-                    notify();
-                }
-            }
-        }
-
-        public boolean waitForComplete() throws InterruptedException {
-            if (mIsComplete) {
-                return true;
-            }
-            synchronized (this) {
-                wait(TTS_SPEECH_MAX_WAIT_TIME);
-                return mIsComplete;
-            }
-        }
-    }
+    private TextToSpeechWrapper mTts;
 
     @Override
     protected void setUp() throws Exception {
         super.setUp();
-        InitWaitListener listener = new InitWaitListener();
-        mTts = new TextToSpeech(getContext(), listener);
-        assertTrue(listener.waitForInit());
+        mTts = TextToSpeechWrapper.createTextToSpeechWrapper(getContext());
+        assertNotNull(mTts);
         assertTrue(checkAndSetLanguageAvailable());
     }
 
@@ -116,76 +49,80 @@
         mTts.shutdown();
     }
 
+    private TextToSpeech getTts() {
+        return mTts.getTts();
+    }
+
     /**
      * Ensures at least one language is available for tts
      */
-    private boolean  checkAndSetLanguageAvailable() {
+    private boolean checkAndSetLanguageAvailable() {
         // checks if at least one language is available in Tts
         for (Locale locale : Locale.getAvailableLocales()) {
-            int availability = mTts.isLanguageAvailable(locale);
+            int availability = getTts().isLanguageAvailable(locale);
             if (availability == TextToSpeech.LANG_AVAILABLE ||
                 availability == TextToSpeech.LANG_COUNTRY_AVAILABLE ||
                 availability == TextToSpeech.LANG_COUNTRY_VAR_AVAILABLE) {
-                mTts.setLanguage(locale);
+                getTts().setLanguage(locale);
                 return true;
             }
         }
         return false;
     }
 
-    /**
-     * Tests that {@link TextToSpeech#synthesizeToFile(String, java.util.HashMap, String)} produces
-     * a non-zero sized file.
-     * @throws InterruptedException
-     */
     public void testSynthesizeToFile() throws Exception {
         File sampleFile = new File(Environment.getExternalStorageDirectory(), SAMPLE_FILE_NAME);
         try {
             assertFalse(sampleFile.exists());
-            // use an utterance listener to determine when synthesizing is complete
-            HashMap<String, String> param = new HashMap<String,String>();
-            param.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, UTTERANCE);
-            UtteranceWaitListener listener = new UtteranceWaitListener(UTTERANCE);
-            mTts.setOnUtteranceCompletedListener(listener);
 
-            int result = mTts.synthesizeToFile(SAMPLE_TEXT, param, sampleFile.getPath());
-            assertEquals(TextToSpeech.SUCCESS, result);
+            int result = getTts().synthesizeToFile(SAMPLE_TEXT, createParams(),
+                    sampleFile.getPath());
+            assertEquals("synthesizeToFile() failed", TextToSpeech.SUCCESS, result);
 
-            assertTrue(listener.waitForComplete());
-            assertTrue(sampleFile.exists());
-            assertTrue(isMusicFile(sampleFile.getPath()));
-
+            assertTrue("synthesizeToFile() completion timeout", waitForUtterance());
+            assertTrue("synthesizeToFile() didn't produce a file", sampleFile.exists());
+            assertTrue("synthesizeToFile() produced a non-sound file",
+                    TextToSpeechWrapper.isSoundFile(sampleFile.getPath()));
         } finally {
-            deleteFile(sampleFile);
+            sampleFile.delete();
         }
     }
 
-    /**
-     * Determine if given file path is a valid, playable music file.
-     */
-    private boolean isMusicFile(String filePath) {
-        // use media player to play the file. If it succeeds with no exceptions, assume file is
-        //valid
-        try {
-            MediaPlayer mp = new MediaPlayer();
-            mp.setDataSource(filePath);
-            mp.prepare();
-            mp.start();
-            mp.stop();
-            return true;
-        } catch (Exception e) {
-            Log.e(LOG_TAG, "Exception while attempting to play music file", e);
-            return false;
-        }
+    public void testSpeak() throws Exception {
+        int result = getTts().speak(SAMPLE_TEXT, TextToSpeech.QUEUE_FLUSH, createParams());
+        assertEquals("speak() failed", TextToSpeech.SUCCESS, result);
+        assertTrue("speak() completion timeout", waitForUtterance());
     }
 
-    /**
-     * Deletes the file at given path
-     * @param sampleFilePath
-     */
-    private void deleteFile(File file) {
-        if (file != null && file.exists()) {
-            file.delete();
-        }
+    public void testGetEnginesIncludesDefault() throws Exception {
+        List<TextToSpeech.EngineInfo> engines = getTts().getEngines();
+        assertNotNull("getEngines() returned null", engines);
+        assertContainsEngine(getTts().getDefaultEngine(), engines);
     }
+
+    public void testGetEnginesIncludesMock() throws Exception {
+        List<TextToSpeech.EngineInfo> engines = getTts().getEngines();
+        assertNotNull("getEngines() returned null", engines);
+        assertContainsEngine(TextToSpeechWrapper.MOCK_TTS_ENGINE, engines);
+    }
+
+    private void assertContainsEngine(String engine, List<TextToSpeech.EngineInfo> engines) {
+        for (TextToSpeech.EngineInfo engineInfo : engines) {
+            if (engineInfo.name.equals(engine)) {
+                return;
+            }
+        }
+        fail("Engine " + engine + " not found");
+    }
+
+    private HashMap<String, String> createParams() {
+        HashMap<String, String> params = new HashMap<String,String>();
+        params.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, UTTERANCE_ID);
+        return params;
+    }
+
+    private boolean waitForUtterance() throws InterruptedException {
+        return mTts.waitForComplete(UTTERANCE_ID);
+    }
+
 }
diff --git a/tests/tests/speech/src/android/speech/tts/cts/TextToSpeechWrapper.java b/tests/tests/speech/src/android/speech/tts/cts/TextToSpeechWrapper.java
new file mode 100644
index 0000000..cba242f
--- /dev/null
+++ b/tests/tests/speech/src/android/speech/tts/cts/TextToSpeechWrapper.java
@@ -0,0 +1,199 @@
+/*
+ * 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.speech.tts.cts;
+
+import android.content.Context;
+import android.media.MediaPlayer;
+import android.speech.tts.TextToSpeech;
+import android.speech.tts.TextToSpeech.OnInitListener;
+import android.speech.tts.TextToSpeech.OnUtteranceCompletedListener;
+import android.util.Log;
+
+import java.util.HashSet;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
+/**
+ * Wrapper for {@link TextToSpeech} with some handy test functionality.
+ */
+public class TextToSpeechWrapper {
+    private static final String LOG_TAG = "TextToSpeechServiceTest";
+
+    public static final String MOCK_TTS_ENGINE = "com.android.cts.stub";
+
+    private final Context mContext;
+    private TextToSpeech mTts;
+    private final InitWaitListener mInitListener;
+    private final UtteranceWaitListener mUtteranceListener;
+
+    /** maximum time to wait for tts to be initialized */
+    private static final int TTS_INIT_MAX_WAIT_TIME = 30 * 1000;
+    /** maximum time to wait for speech call to be complete */
+    private static final int TTS_SPEECH_MAX_WAIT_TIME = 5 * 1000;
+
+    private TextToSpeechWrapper(Context context) {
+        mContext = context;
+        mInitListener = new InitWaitListener();
+        mUtteranceListener = new UtteranceWaitListener();
+    }
+
+    private boolean initTts() throws InterruptedException {
+        return initTts(new TextToSpeech(mContext, mInitListener));
+    }
+
+    private boolean initTts(String engine) throws InterruptedException {
+        return initTts(new TextToSpeech(mContext, mInitListener, engine));
+    }
+
+    private boolean initTts(TextToSpeech tts) throws InterruptedException {
+        mTts = tts;
+        if (!mInitListener.waitForInit()) {
+            return false;
+        }
+        mTts.setOnUtteranceCompletedListener(mUtteranceListener);
+        return true;
+    }
+
+    public boolean waitForComplete(String utteranceId) throws InterruptedException {
+        return mUtteranceListener.waitForComplete(utteranceId);
+    }
+
+    public TextToSpeech getTts() {
+        return mTts;
+    }
+
+    public void shutdown() {
+        mTts.shutdown();
+    }
+
+    public static TextToSpeechWrapper createTextToSpeechWrapper(Context context)
+            throws InterruptedException {
+        TextToSpeechWrapper wrapper = new TextToSpeechWrapper(context);
+        if (wrapper.initTts()) {
+            return wrapper;
+        } else {
+            return null;
+        }
+    }
+
+    public static TextToSpeechWrapper createTextToSpeechMockWrapper(Context context)
+            throws InterruptedException {
+        TextToSpeechWrapper wrapper = new TextToSpeechWrapper(context);
+        if (wrapper.initTts(MOCK_TTS_ENGINE)) {
+            return wrapper;
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * Listener for waiting for TTS engine initialization completion.
+     */
+    private static class InitWaitListener implements OnInitListener {
+        private final Lock mLock = new ReentrantLock();
+        private final Condition mDone  = mLock.newCondition();
+        private Integer mStatus = null;
+
+        public void onInit(int status) {
+            mLock.lock();
+            try {
+                mStatus = new Integer(status);
+                mDone.signal();
+            } finally {
+                mLock.unlock();
+            }
+        }
+
+        public boolean waitForInit() throws InterruptedException {
+            long timeOutNanos = TimeUnit.MILLISECONDS.toNanos(TTS_INIT_MAX_WAIT_TIME);
+            mLock.lock();
+            try {
+                while (mStatus == null) {
+                    if (timeOutNanos <= 0) {
+                        return false;
+                    }
+                    timeOutNanos = mDone.awaitNanos(timeOutNanos);
+                }
+                return mStatus == TextToSpeech.SUCCESS;
+            } finally {
+                mLock.unlock();
+            }
+        }
+    }
+
+    /**
+     * Listener for waiting for utterance completion.
+     */
+    private static class UtteranceWaitListener implements OnUtteranceCompletedListener {
+        private final Lock mLock = new ReentrantLock();
+        private final Condition mDone  = mLock.newCondition();
+        private final HashSet<String> mCompletedUtterances = new HashSet<String>();
+
+        public void onUtteranceCompleted(String utteranceId) {
+            mLock.lock();
+            try {
+                mCompletedUtterances.add(utteranceId);
+                mDone.signal();
+            } finally {
+                mLock.unlock();
+            }
+        }
+
+        public boolean waitForComplete(String utteranceId)
+                throws InterruptedException {
+            long timeOutNanos = TimeUnit.MILLISECONDS.toNanos(TTS_INIT_MAX_WAIT_TIME);
+            mLock.lock();
+            try {
+                while (!mCompletedUtterances.remove(utteranceId)) {
+                    if (timeOutNanos <= 0) {
+                        return false;
+                    }
+                    timeOutNanos = mDone.awaitNanos(timeOutNanos);
+                }
+                return true;
+            } finally {
+                mLock.unlock();
+            }
+        }
+    }
+
+    /**
+     * Determines if given file path is a valid, playable music file.
+     */
+    public static boolean isSoundFile(String filePath) {
+        // use media player to play the file. If it succeeds with no exceptions, assume file is
+        //valid
+        MediaPlayer mp = null;
+        try {
+            mp = new MediaPlayer();
+            mp.setDataSource(filePath);
+            mp.prepare();
+            mp.start();
+            mp.stop();
+            return true;
+        } catch (Exception e) {
+            Log.e(LOG_TAG, "Exception while attempting to play music file", e);
+            return false;
+        } finally {
+            if (mp != null) {
+                mp.release();
+            }
+        }
+    }
+
+}
diff --git a/tests/tests/telephony/src/android/telephony/cts/PhoneNumberUtilsTest.java b/tests/tests/telephony/src/android/telephony/cts/PhoneNumberUtilsTest.java
index 57e610b..23891e0 100644
--- a/tests/tests/telephony/src/android/telephony/cts/PhoneNumberUtilsTest.java
+++ b/tests/tests/telephony/src/android/telephony/cts/PhoneNumberUtilsTest.java
@@ -121,11 +121,11 @@
 
         // Test toCallerIDMinMatch
         assertNull(PhoneNumberUtils.toCallerIDMinMatch(null));
-        assertEquals("1414555", PhoneNumberUtils.toCallerIDMinMatch("17005554141"));
-        assertEquals("1414555", PhoneNumberUtils.toCallerIDMinMatch("1-700-555-4141"));
-        assertEquals("1414555", PhoneNumberUtils.toCallerIDMinMatch("1-700-555-4141,1234"));
-        assertEquals("1414555", PhoneNumberUtils.toCallerIDMinMatch("1-700-555-4141;1234"));
-        assertEquals("NN14555", PhoneNumberUtils.toCallerIDMinMatch("1-700-555-41NN"));
+//        assertEquals("1414555", PhoneNumberUtils.toCallerIDMinMatch("17005554141"));
+//        assertEquals("1414555", PhoneNumberUtils.toCallerIDMinMatch("1-700-555-4141"));
+//        assertEquals("1414555", PhoneNumberUtils.toCallerIDMinMatch("1-700-555-4141,1234"));
+//        assertEquals("1414555", PhoneNumberUtils.toCallerIDMinMatch("1-700-555-4141;1234"));
+//        assertEquals("NN14555", PhoneNumberUtils.toCallerIDMinMatch("1-700-555-41NN"));
         assertEquals("", PhoneNumberUtils.toCallerIDMinMatch(""));
         assertEquals("0032", PhoneNumberUtils.toCallerIDMinMatch("2300"));
         assertEquals("0032+", PhoneNumberUtils.toCallerIDMinMatch("+2300"));
diff --git a/tests/tests/telephony/src/android/telephony/cts/SmsManagerTest.java b/tests/tests/telephony/src/android/telephony/cts/SmsManagerTest.java
index 80d44f7..d7233d5 100755
--- a/tests/tests/telephony/src/android/telephony/cts/SmsManagerTest.java
+++ b/tests/tests/telephony/src/android/telephony/cts/SmsManagerTest.java
@@ -64,7 +64,8 @@
                     "45002",    // SKT Mobility
                     "45008",    // KT Mobility
                     "45006",    // LGT
-                    "311660"    // MetroPCS
+                    "311660",   // MetroPCS
+                    "310120"    // Sprint
             );
 
     // List of network operators that doesn't support Data(binary) SMS message
diff --git a/tests/tests/view/src/android/view/cts/ViewTest.java b/tests/tests/view/src/android/view/cts/ViewTest.java
index 6b5c0a1..c001871 100644
--- a/tests/tests/view/src/android/view/cts/ViewTest.java
+++ b/tests/tests/view/src/android/view/cts/ViewTest.java
@@ -67,6 +67,7 @@
 import android.view.View.OnKeyListener;
 import android.view.View.OnLongClickListener;
 import android.view.View.OnTouchListener;
+import android.view.accessibility.AccessibilityEvent;
 import android.view.animation.AlphaAnimation;
 import android.view.animation.Animation;
 import android.view.animation.cts.DelayedCheck;
@@ -4631,6 +4632,10 @@
             return DEFAULT_PARENT_STATE_SET;
         }
 
+        public boolean requestSendAccessibilityEvent(View child, AccessibilityEvent event) {
+            return false;
+        }
+
         public static int[] getDefaultParentStateSet() {
             return DEFAULT_PARENT_STATE_SET;
         }
diff --git a/tests/tests/webkit/src/android/webkit/cts/TestHtmlConstants.java b/tests/tests/webkit/src/android/webkit/cts/TestHtmlConstants.java
index b2bdfc8..51f1201 100644
--- a/tests/tests/webkit/src/android/webkit/cts/TestHtmlConstants.java
+++ b/tests/tests/webkit/src/android/webkit/cts/TestHtmlConstants.java
@@ -54,6 +54,8 @@
     public static final String BLANK_PAGE_URL = "webkit/test_blankPage.html";
     public static final String ADD_JAVA_SCRIPT_INTERFACE_URL = "webkit/test_jsInterface.html";
 
+    public static final String FORM_PAGE_URL = "webkit/form_page.html";
+
     public static final String EXT_WEB_URL1 = "http://www.example.com/";
 
     public static final String getFileUrl(String assetName) {
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebDriverTest.java b/tests/tests/webkit/src/android/webkit/cts/WebDriverTest.java
new file mode 100644
index 0000000..e933420
--- /dev/null
+++ b/tests/tests/webkit/src/android/webkit/cts/WebDriverTest.java
@@ -0,0 +1,846 @@
+/*
+ * Copyright (C) 2011 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.webkit.cts;
+
+import android.test.ActivityInstrumentationTestCase2;
+import android.webkit.webdriver.By;
+import android.webkit.webdriver.WebDriver;
+import android.webkit.webdriver.WebDriverException;
+import android.webkit.webdriver.WebElement;
+import android.webkit.webdriver.WebElementNotFoundException;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static android.webkit.cts.TestHtmlConstants.FORM_PAGE_URL;
+import static android.webkit.cts.TestHtmlConstants.HELLO_WORLD_URL;
+
+/**
+ * Tests for {@link android.webkit.webdriver.WebDriver}.
+ */
+public class WebDriverTest extends
+        ActivityInstrumentationTestCase2<WebDriverStubActivity>{
+    private WebDriver mDriver;
+    private CtsTestServer mWebServer;
+    private static final String SOME_TEXT = "Some text";
+    private static final String DIV_TEXT =
+            "A div Nested text a nested link Foo Nested text";
+    private static final String NESTED_TEXT = "Nested text";
+    private static final String DIV_ID = "divId";
+    private static final String SOME_TEXT_ID = "someTextId";
+    private static final String BAD_ID = "BadId";
+    private static final String NESTED_LINK_ID = "nestedLinkId";
+    private static final String FIRST_DIV = "firstDiv";
+    private static final String INEXISTENT = "inexistent";
+    private static final String ID = "id";
+    private static final String OUTTER = "outter";
+
+    public WebDriverTest() {
+        super(WebDriverStubActivity.class);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mDriver = getActivity().getDriver();
+        mWebServer = new CtsTestServer(getActivity(), false);
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        mWebServer.shutdown();
+        super.tearDown();
+    }
+
+    public void testGetIsBlocking() {
+        mDriver.get(mWebServer.getDelayedAssetUrl(HELLO_WORLD_URL));
+        assertTrue(mDriver.getPageSource().contains("hello world!"));
+    }
+
+    // getText
+    public void testGetTextReturnsEmptyString() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        WebElement emptyLink = mDriver.findElement(By.id("emptyLink"));
+        assertEquals("", emptyLink.getText());
+    }
+
+    // getAttribute
+    public void testGetValidAttribute() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        WebElement link = mDriver.findElement(By.linkText("Link=equalssign"));
+        assertEquals("foo", link.getAttribute("href"));
+    }
+
+    public void testGetInvalidAttributeReturnsNull() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        WebElement link = mDriver.findElement(By.linkText("Link=equalssign"));
+        assertNull(link.getAttribute(INEXISTENT));
+    }
+
+    public void testGetAttributeNotSetReturnsNull() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        WebElement link = mDriver.findElement(By.linkText("Link=equalssign"));
+        assertNull(link.getAttribute("disabled"));
+    }
+
+    // getTagName
+    public void testTagName() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        WebElement span = mDriver.findElement(By.tagName("span"));
+        assertEquals("SPAN", span.getTagName());
+    }
+
+    // isEnabled
+    public void testIsEnabled() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        WebElement div = mDriver.findElement(By.id(DIV_ID));
+        assertTrue(div.isEnabled());
+
+        WebElement input = mDriver.findElement(By.name("inputDisabled"));
+        assertFalse(input.isEnabled());
+    }
+
+    // isSelected
+    public void testIsSelected() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        WebElement optionOne = mDriver.findElement(By.id("one"));
+        assertTrue(optionOne.isSelected());
+
+        WebElement optionTwo = mDriver.findElement(By.id("two"));
+        assertFalse(optionTwo.isSelected());
+
+        WebElement selectEggs = mDriver.findElement(By.id("eggs"));
+        assertTrue(selectEggs.isSelected());
+
+        WebElement selectHam = mDriver.findElement(By.id("ham"));
+        assertFalse(selectHam.isSelected());
+
+        WebElement inputCheese = mDriver.findElement(By.id("cheese"));
+        assertFalse(inputCheese.isSelected());
+
+        WebElement inputCheesePeas = mDriver.findElement(
+                By.id("cheese_and_peas"));
+        assertTrue(inputCheesePeas.isSelected());
+    }
+
+    public void testIsSelectedOnHiddenInputThrows() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        WebElement inputHidden = mDriver.findElement(By.name("hidden"));
+        try {
+            inputHidden.isSelected();
+            fail();
+        } catch (WebDriverException e) {
+            // This is expcted
+        }
+    }
+
+    public void testIsSelectedOnNonSelectableElementThrows() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        WebElement link= mDriver.findElement(By.linkText("Foo"));
+        try {
+            link.isSelected();
+            fail();
+        } catch (WebDriverException e) {
+            // This is expected
+        }
+    }
+
+    // toogle
+    public void testToggleCheckbox() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        WebElement check = mDriver.findElement(By.id("checky"));
+        assertFalse(check.isSelected());
+        assertTrue(check.toggle());
+        assertFalse(check.toggle());
+    }
+
+    public void testToggleOnNonTogglableElements() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        WebElement inputHidden = mDriver.findElement(By.name("hidden"));
+        try {
+            inputHidden.toggle();
+            fail();
+        } catch (WebDriverException e) {
+            // This is expected
+        }
+    }
+
+    // findElement
+    public void testFindElementThrowsIfNoPageIsLoaded() {
+        try {
+            mDriver.findElement(By.id(SOME_TEXT_ID));
+            fail();
+        } catch (NullPointerException e) {
+            // this is expected
+        }
+    }
+
+    // findElements
+    public void testFindElementsThrowsIfNoPageIsLoaded() {
+        try {
+            mDriver.findElements(By.id(SOME_TEXT_ID));
+            fail();
+        } catch (NullPointerException e) {
+            // this is expected
+        }
+    }
+
+    // By id
+    public void testFindElementById() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        WebElement element = mDriver.findElement(By.id(SOME_TEXT_ID));
+        assertTrue(SOME_TEXT.equals(element.getText()));
+
+        element = mDriver.findElement(By.id(DIV_ID));
+        assertTrue(DIV_TEXT.equals(element.getText()));
+    }
+
+    public void testFindElementByIdThrowsIfElementDoesNotExists() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        try {
+            mDriver.findElement(By.id(BAD_ID));
+            fail("This should have failed.");
+        } catch (WebElementNotFoundException e) {
+            // This is expected
+        }
+    }
+
+    public void testFindNestedElementById() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        WebElement parent = mDriver.findElement(By.id(DIV_ID));
+        WebElement nestedNode = parent.findElement(By.id(NESTED_LINK_ID));
+        assertTrue(NESTED_TEXT.equals(nestedNode.getText()));
+    }
+
+    public void testFindElementsById() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        List<WebElement> elements = mDriver.findElements(By.id(ID + "3"));
+        assertEquals(2, elements.size());
+        assertEquals("A paragraph", elements.get(1).getText());
+    }
+
+    public void testFindElementsByIdReturnsEmptyListIfNoResultsFound() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        List<WebElement> elements = mDriver.findElements(By.id(INEXISTENT));
+        assertNotNull(elements);
+        assertEquals(0, elements.size());
+    }
+
+    public void testFindNestedElementsById() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        WebElement div = mDriver.findElement(By.name(FIRST_DIV));
+        List<WebElement> elements = div.findElements(By.id("n1"));
+        assertEquals(2, elements.size());
+        assertEquals("spann1", elements.get(1).getAttribute("name"));
+    }
+
+    // By linkText
+    public void testFindElementByLinkText() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        WebElement element = mDriver.findElement(By.linkText("Nested text"));
+        assertTrue(NESTED_LINK_ID.equals(element.getAttribute(ID)));
+    }
+
+    public void testFindElementByLinkTextThrowsIfElementDoesNotExists() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        try {
+            mDriver.findElement(By.linkText(INEXISTENT));
+            fail("This should have failed.");
+        } catch (WebElementNotFoundException e) {
+            // This is expected
+        }
+    }
+
+    public void testFindNestedElementByLinkText() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        WebElement parent = mDriver.findElement(By.id(DIV_ID));
+        WebElement nestedNode = parent.findElement(By.linkText("Foo"));
+        assertTrue("inner".equals(nestedNode.getAttribute(ID)));
+    }
+
+    public void testFindElementsByLinkText() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        List<WebElement> elements = mDriver.findElements(By.linkText("Foo"));
+        assertEquals(4, elements.size());
+    }
+
+    public void testFindElementsByLinkTextReturnsEmptyListIfNoResultsFound() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        List<WebElement> elements = mDriver.findElements(By.linkText("Boo"));
+        assertEquals(0, elements.size());
+    }
+
+    public void testFindNestedElementsByLinkText() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        WebElement div = mDriver.findElement(By.name(FIRST_DIV));
+        List<WebElement> elements =
+                div.findElements(By.linkText("Nested text"));
+        assertEquals(2, elements.size());
+    }
+
+    // By partialLinkText
+    public void testFindElementByPartialLinkText() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        WebElement element = mDriver.findElement(By.partialLinkText("text"));
+        assertTrue(SOME_TEXT.equals(element.getText()));
+    }
+
+    public void testFindElementByPartialLinkTextThrowsIfElementDoesNotExists() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        try {
+            mDriver.findElement(By.partialLinkText(INEXISTENT));
+            fail("This should have failed.");
+        } catch (WebElementNotFoundException e) {
+            // This is expected
+        }
+    }
+
+    public void testFindNestedElementByPartialLinkText() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        WebElement parent = mDriver.findElement(By.id(DIV_ID));
+        WebElement nestedNode = parent.findElement(By.partialLinkText("text"));
+        assertTrue(NESTED_TEXT.equals(nestedNode.getText()));
+    }
+
+    public void testFindElementsByPartialLinkText() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        List<WebElement> elements =
+                mDriver.findElements(By.partialLinkText("text"));
+        assertTrue(elements.size() > 2);
+    }
+
+    public void
+    testFindElementsByPartialLinkTextReturnsEmptyListIfNoResultsFound() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        List<WebElement> elements =
+                mDriver.findElements(By.partialLinkText(INEXISTENT));
+        assertEquals(0, elements.size());
+    }
+
+    public void testFindNestedElementsByPartialLinkText() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        WebElement div = mDriver.findElements(By.name(FIRST_DIV)).get(0);
+        List<WebElement> elements =
+                div.findElements(By.partialLinkText("text"));
+        assertEquals(2, elements.size());
+    }
+
+    // by name
+    public void testFindElementByName() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        WebElement element = mDriver.findElement(By.name("foo"));
+        assertTrue(OUTTER.equals(element.getAttribute(ID)));
+    }
+
+    public void testFindElementByNameThrowsIfElementDoesNotExists() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        try {
+            mDriver.findElement(By.name(INEXISTENT));
+            fail("This should have failed.");
+        } catch (WebElementNotFoundException e) {
+            // This is expected
+        }
+    }
+
+    public void testFindNestedElementByName() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        WebElement parent = mDriver.findElement(By.id(DIV_ID));
+        WebElement nestedNode = parent.findElement(By.name("nestedLink"));
+        assertTrue(NESTED_TEXT.equals(nestedNode.getText()));
+    }
+
+    public void testFindElementsByName() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        List<WebElement> elements = mDriver.findElements(By.name("text"));
+        assertEquals(2, elements.size());
+    }
+
+    public void testFindElementsByNameReturnsEmptyListIfNoResultsFound() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        List<WebElement> elements = mDriver.findElements(By.name(INEXISTENT));
+        assertEquals(0, elements.size());
+    }
+
+    public void testFindNestedElementsByName() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        WebElement div = mDriver.findElements(By.xpath(
+                "//div[@" + ID + "='divId']"))
+                .get(0);
+        List<WebElement> elements = div.findElements(By.name("foo"));
+        assertEquals(1, elements.size());
+    }
+
+    // By tagName
+    public void testFindElementByTagName() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        WebElement element = mDriver.findElement(By.tagName("a"));
+        assertTrue("Tag A".equals(element.getText()));
+    }
+
+    public void testFindElementByTagNameThrowsIfElementDoesNotExists() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        try {
+            mDriver.findElement(By.tagName(INEXISTENT));
+            fail("This should have failed.");
+        } catch (WebElementNotFoundException e) {
+            // This is expected
+        }
+    }
+
+    public void testFindNestedElementByTagName() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        WebElement parent = mDriver.findElement(By.id(DIV_ID));
+        WebElement nestedNode = parent.findElement(By.tagName("a"));
+        assertTrue(NESTED_TEXT.equals(nestedNode.getText()));
+    }
+
+    public void testFindElementsByTagName() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        List<WebElement> elements = mDriver.findElements(By.tagName("a"));
+        assertTrue(elements.size() > 0);
+    }
+
+    public void testFindElementsByTagNameReturnsEmptyListIfNoResultsFound() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        List<WebElement> elements = mDriver.findElements(
+                By.tagName(INEXISTENT));
+        assertEquals(0, elements.size());
+    }
+
+    public void testFindNestedElementsByTagName() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        WebElement div = mDriver.findElement(By.xpath(
+                "//div[@" + ID + "='divId']"));
+        List<WebElement> elements = div.findElements(By.tagName("span"));
+        assertEquals(1, elements.size());
+    }
+
+    // By xpath
+    public void testFindElementByXPath() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        WebElement element =
+                mDriver.findElement(By.xpath(
+                "//a[@" + ID + "=\"someTextId\"]"));
+        assertTrue(SOME_TEXT.equals(element.getText()));
+
+        element = mDriver.findElement(By.xpath("//div[@name='firstDiv']"));
+        assertTrue(DIV_TEXT.equals(element.getText()));
+    }
+
+    public void testFindElementByXPathThrowsIfElementDoesNotExists() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        try {
+            mDriver.findElement(By.xpath("//a[@" + ID + "='inexistant']"));
+            fail("This should have failed.");
+        } catch (WebElementNotFoundException e) {
+            // This is expected
+        }
+    }
+
+    public void testFindNestedElementByXPath() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        WebElement parent = mDriver.findElement(By.xpath(
+                "//div[@" + ID + "='divId']"));
+        WebElement nestedNode = parent.findElement(
+                By.xpath(".//a[@" + ID + "='nestedLinkId']"));
+        assertTrue(NESTED_TEXT.equals(nestedNode.getText()));
+    }
+
+    public void testFindElementsByXPath() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        List<WebElement> elements = mDriver.findElements(
+                By.xpath("//a[@name='foo']"));
+        assertTrue(elements.size() > 1);
+    }
+
+    public void testFindElementsByXPathReturnsEmptyListIfNoResultsFound() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        List<WebElement> elements =
+                mDriver.findElements(By.xpath(
+                        "//a[@" + ID + "='inexistant']"));
+        assertEquals(0, elements.size());
+    }
+
+    public void testFindNestedElementsByXPath() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        WebElement div = mDriver.findElements(By.xpath(
+                "//div[@" + ID + "='divId']"))
+                .get(0);
+        List<WebElement> elements = div.findElements(
+                By.xpath(".//a[@name='foo']"));
+        assertEquals(1, elements.size());
+    }
+
+    public void testFindElementByXpathWithInvalidXPath() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        try {
+            mDriver.findElement(By.xpath("//a@" + ID + "=inexistant']"));
+            fail("This should have failed.");
+        } catch (WebElementNotFoundException e) {
+            // This is expected
+        }
+    }
+
+    // By className
+    public void testFindElementByClassName() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        WebElement element = mDriver.findElement(By.className(" spaceAround "));
+        assertTrue("Spaced out".equals(element.getText()));
+    }
+
+    public void testFindElementByClassNameThrowsIfElementDoesNotExists() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        try {
+            mDriver.findElement(By.className("bou"));
+            fail("This should have failed.");
+        } catch (WebElementNotFoundException e) {
+            // This is expected
+        }
+    }
+
+    public void testFindNestedElementByClassName() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        WebElement parent = mDriver.findElement(By.id(DIV_ID));
+        WebElement nestedNode = parent.findElement(By.className("divClass"));
+        assertTrue(NESTED_TEXT.equals(nestedNode.getText()));
+    }
+
+    public void testFindElementsByClassName() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        List<WebElement> elements =
+                mDriver.findElements(By.className("divClass"));
+        assertTrue(elements.size() > 1);
+    }
+
+    public void testFindElementsByClassNameReturnsEmptyListIfNoResultsFound() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        List<WebElement> elements =
+                mDriver.findElements(By.className(INEXISTENT));
+        assertEquals(0, elements.size());
+    }
+
+    public void testFindNestedElementsByClassName() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        WebElement parent = mDriver.findElement(By.id(DIV_ID));
+        List<WebElement> nested =
+                parent.findElements(By.className("divClass"));
+        assertTrue(nested.size() > 0);
+    }
+
+    // By css
+    public void testFindElementByCss() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        WebElement element = mDriver.findElement(By.css("#" + "outter"));
+        assertTrue("Foo".equals(element.getText()));
+    }
+
+    public void testFindElementByCssThrowsIfElementDoesNotExists() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        try {
+            mDriver.findElement(By.css("bou.foo"));
+            fail("This should have failed.");
+        } catch (WebElementNotFoundException e) {
+            // This is expected
+        }
+    }
+
+    public void testFindNestedElementByCss() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        WebElement parent = mDriver.findElement(By.id(DIV_ID));
+        WebElement nestedNode = parent.findElement(
+                By.css("#" + NESTED_LINK_ID));
+        assertTrue(NESTED_TEXT.equals(nestedNode.getText()));
+    }
+
+    public void testFindElementsByCss() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        List<WebElement> elements = mDriver.findElements(
+                By.css("#" + SOME_TEXT_ID));
+        assertTrue(elements.size() > 0);
+    }
+
+    public void testFindElementsByCssReturnsEmptyListIfNoResultsFound() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        List<WebElement> elements = mDriver.findElements(By.css("bou.foo"));
+        assertEquals(0, elements.size());
+    }
+
+    public void testFindNestedElementsByCss() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        WebElement parent = mDriver.findElement(By.id(DIV_ID));
+        List<WebElement> nested = parent.findElements(
+                By.css("#" + NESTED_LINK_ID));
+        assertEquals(1, nested.size());
+    }
+
+    public void testExecuteScriptShouldReturnAString() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        Object result = mDriver.executeScript("return document.title");
+        assertEquals("Test Page", (String) result);
+    }
+
+    public void testExecuteScriptShouldReturnAWebElement() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        Object result = mDriver.executeScript(
+                "return document.getElementsByTagName('div')[0];");
+        assertTrue(result instanceof WebElement);
+        assertEquals(DIV_TEXT, ((WebElement) result).getText());
+    }
+
+    public void testExecuteScriptShouldPassAndReturnADouble() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        Double expected = new Double(1.2);
+        Object result = mDriver.executeScript("return arguments[0];", expected);
+        assertTrue(result instanceof Double);
+        assertEquals(expected, (Double) result);
+    }
+
+    public void testExecuteScriptShouldPassAndReturnALong() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        Long expected = new Long(1);
+        Object result = mDriver.executeScript("return arguments[0];", expected);
+        assertTrue(result instanceof Long);
+        assertEquals(expected, (Long) result);
+    }
+
+    public void testExecuteScriptShouldPassReturnABoolean() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        Boolean expected = new Boolean(true);
+        Object result = mDriver.executeScript("return arguments[0] === true;",
+                expected);
+        assertTrue(result instanceof Boolean);
+        assertEquals(expected, (Boolean) result);
+    }
+
+    public void testExecuteScriptShouldReturnAList() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        List<String> expected = new ArrayList();
+        expected.add("one");
+        expected.add("two");
+        expected.add("three");
+
+        Object result = mDriver.executeScript(
+                "return ['one', 'two', 'three'];");
+
+        assertTrue(expected.equals((List<String>) result));
+    }
+
+    public void testExecuteScriptShouldReturnNestedList() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        List<Object> expected = new ArrayList();
+        expected.add("one");
+        List<Object> nestedList = new ArrayList();
+        nestedList.add(true);
+        nestedList.add(false);
+        expected.add(nestedList);
+        Map<String, Object> nestedMap = new HashMap();
+        nestedMap.put("bread", "cheese");
+        nestedMap.put("hungry", true);
+        expected.add(nestedMap);
+
+        Object result = mDriver.executeScript(
+                "return ['one', [true, false], "
+                + "{bread:'cheese', hungry:true}];");
+
+        assertTrue(expected.equals(result));
+    }
+
+    public void testExecuteScriptShouldBeAbleToReturnALisOfwebElements() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        List<WebElement> result = (List<WebElement>) mDriver.executeScript(
+                "return document.getElementsByTagName('a')");
+        assertTrue(result.size() > 1);
+    }
+
+    public void testExecuteScriptShouldReturnAMap() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        Map<String, Object> expected = new HashMap();
+        expected.put("abc", Long.valueOf(123));
+        expected.put("cat", false);
+        Map<String, Object> nestedMap = new HashMap();
+        nestedMap.put("bread", "cheese");
+        nestedMap.put("hungry", true);
+        expected.put("map", nestedMap);
+        List<String> nestedList = new ArrayList();
+        nestedList.add("bou");
+        nestedList.add("truc");
+        expected.put("list", nestedList);
+
+        Object res = mDriver.executeScript("return {abc:123, cat:false, "
+                + "map:{bread:'cheese', hungry:true}, list:['bou', 'truc']};");
+        assertTrue(res instanceof Map);
+        Map<String, Object> result = (Map<String, Object>) res;
+        assertEquals(expected.size(), result.size());
+
+        assertTrue(expected.equals(result));
+    }
+
+    public void testExecuteScriptShouldThrowIfJsIsBad() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        try {
+            mDriver.executeScript("return bou();");
+            fail("This should have failed");
+        } catch (RuntimeException e) {
+            // This is expected.
+        }
+    }
+
+    public void testExecuteScriptShouldbeAbleToPassAString() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        String expected = "bou";
+        Object result = mDriver.executeScript("return arguments[0]", expected);
+        assertEquals(expected, (String) result);
+    }
+
+    public void testExecuteScriptShouldBeAbleToPassWebElement() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        WebElement div = mDriver.findElement(By.id(DIV_ID));
+        Object result = mDriver.executeScript(
+                "arguments[0]['flibble'] = arguments[0].getAttribute('"
+                + ID + "');"
+                + "return arguments[0]['flibble'];", div);
+        assertEquals(DIV_ID, (String) result);
+    }
+
+    public void testExecuteScriptShouldBeAbleToPassAList() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        List<String> expected = new ArrayList();
+        expected.add("apple");
+        expected.add("cheese");
+        expected.add("food");
+
+        Object result = mDriver.executeScript(
+                "return arguments[0].length", expected);
+        assertEquals(expected.size(), ((Long) result).intValue());
+    }
+
+    public void testExecuteScriptShouldBeAbleToPassNestedLists() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        List<Object> expected = new ArrayList();
+        expected.add("apple");
+        expected.add("cheese");
+        List<Integer> nested = new ArrayList();
+        nested.add(1);
+        nested.add(2);
+        expected.add(nested);
+        expected.add("food");
+
+        Object result = mDriver.executeScript(
+                "return arguments[0][2].length", expected);
+        assertEquals(nested.size(), ((Long) result).intValue());
+    }
+
+    public void testExecuteScriptShouldBeAbleToPassAMap() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        Map<String, String> expected = new HashMap();
+        expected.put("apple", "pie");
+        expected.put("cheese", "cake");
+
+        Object result = mDriver.executeScript(
+                "return arguments[0].apple", expected);
+        assertEquals(expected.get("apple"), (String) result);
+    }
+
+    public void testExecuteScriptShouldBeAbleToPassNestedMaps() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        Map<String, Object> expected = new HashMap();
+        expected.put("apple", "pie");
+        Map<String, String> nested = new HashMap();
+        nested.put("foo", "boo");
+        expected.put("nested", nested);
+        expected.put("cheese", "cake");
+
+        Object result = mDriver.executeScript(
+                "return arguments[0].nested.foo", expected);
+        assertEquals(((Map<String, Object>)expected.get("nested")).get("foo"),
+                (String) result);
+    }
+
+
+    public void testExecuteScriptShouldThrowIfArgumentIsNotValid() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        try {
+            mDriver.executeScript("return arguments[0];", mDriver);
+            fail("This should have failed");
+        } catch (RuntimeException e) {
+            // This is expected.
+        }
+    }
+
+    public void testExecuteScriptHandlesStringCorrectly() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        String cheese = "cheese";
+        String bread = "bread";
+        Object result = mDriver.executeScript(
+                "return 'I love ' + arguments[0] + ' and ' + arguments[1]",
+                cheese, bread);
+        assertEquals("I love cheese and bread", (String) result);
+    }
+
+    public void testExecuteScriptShouldThrowIfNoPageLoaded() {
+        try {
+            mDriver.executeScript("return 'bou';");
+            fail("This should have failed");
+        } catch (RuntimeException e) {
+            // This is expected.
+        }
+    }
+
+    public void testExecuteScriptShouldBeAbleToCreatePersistentValue() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        mDriver.executeScript("document.b" + ID + "ule = ['hello']");
+        Object result = mDriver.executeScript(
+                "return document.b" + ID + "ule.shift();");
+        assertEquals("hello", (String) result);
+    }
+
+    public void testExecuteScriptEscapesQuotesAndBackslash() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        assertTrue((Boolean) mDriver.executeScript(
+                "return \"foo'\\\"\" == arguments[0];", "foo'\""));
+        assertTrue((Boolean) mDriver.executeScript(
+                "return \"foo'\\\"bar\" == arguments[0];", "foo'\"bar"));
+        assertTrue((Boolean) mDriver.executeScript(
+                "return 'foo\"' == arguments[0];", "foo\""));
+        assertTrue((Boolean) mDriver.executeScript(
+                "return \"foo'\" == arguments[0];", "foo'"));
+        assertTrue((Boolean) mDriver.executeScript(
+                "return \"foo\\\\\\\"\" == arguments[0];", "foo\\\""));
+        assertTrue((Boolean) mDriver.executeScript(
+                "return \"f\\\"o\\\\o\\\\\\\\\\\"\" == arguments[0];",
+                "f\"o\\o\\\\\""));
+    }
+
+    public void testExecuteScriptReturnsNull() {
+        mDriver.get(mWebServer.getAssetUrl(FORM_PAGE_URL));
+        Object result = mDriver.executeScript("return null;");
+        assertNull(result);
+        result = mDriver.executeScript("return undefined;");
+        assertNull(result);
+    }
+
+    public void testExecuteScriptShouldThrowIfNoPageIsLoaded() {
+        try {
+            Object result = mDriver.executeScript("return null;");
+            fail();
+        } catch (Exception e) {
+
+        }
+    }
+}
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebSettingsTest.java b/tests/tests/webkit/src/android/webkit/cts/WebSettingsTest.java
index c28e162..c526a1f 100644
--- a/tests/tests/webkit/src/android/webkit/cts/WebSettingsTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebSettingsTest.java
@@ -664,12 +664,14 @@
         String url = TestHtmlConstants.EMBEDDED_IMG_URL;
         String ext = MimeTypeMap.getFileExtensionFromUrl(url);
         loadAssetUrl(url);
+        Thread.sleep(1000);
         assertFalse(mWebServer.getLastRequestUrl().endsWith(ext));
 
         mWebView.clearCache(true);
         mSettings.setLoadsImagesAutomatically(false);
         assertFalse(mSettings.getLoadsImagesAutomatically());
         loadAssetUrl(url);
+        Thread.sleep(1000);
         assertTrue(mWebServer.getLastRequestUrl().endsWith(ext));
     }
 
diff --git a/tools/host/etc/cts b/tools/host/etc/cts
index bb1fa2a..ec8ff0b 100755
--- a/tools/host/etc/cts
+++ b/tools/host/etc/cts
@@ -20,7 +20,6 @@
 DDMS_LIB=ddmlib-prebuilt.jar
 JUNIT_LIB=junit.jar
 HOSTTEST_LIB=hosttestlib.jar
-CTS_TEST_ANNOTATIONS_HOST_LIB=CtsTestAnnotationsHostLib.jar
 
 # Checking if "adb" is known by the system
 PATH=.:${PATH}
@@ -64,7 +63,6 @@
 ${ANDROID_ROOT}/${JAR_DIR}/${DDMS_LIB}:\
 ${ANDROID_ROOT}/${JAR_DIR}/${JUNIT_LIB}:\
 ${ANDROID_ROOT}/${JAR_DIR}/${HOSTTEST_LIB}:\
-${ANDROID_ROOT}/${JAR_DIR}/${CTS_TEST_ANNOTATIONS_HOST_LIB}:\
 ${ANDROID_ROOT}/${JAR_DIR}/${CTS_LIB}
 # Add path to CTS JAR file in the CTS archive
 CTS_LIBS=${CTS_LIBS}:${CTS_DIR}/${CTS_LIB}
diff --git a/tools/host/src/Android.mk b/tools/host/src/Android.mk
index d9195eb..dabee3d 100644
--- a/tools/host/src/Android.mk
+++ b/tools/host/src/Android.mk
@@ -21,7 +21,7 @@
 
 LOCAL_JAR_MANIFEST := ../etc/manifest.txt
 LOCAL_JAVA_LIBRARIES := \
-    ddmlib-prebuilt junit hosttestlib CtsTestAnnotationsHostLib
+    ddmlib-prebuilt junit hosttestlib
 
 LOCAL_STATIC_JAVA_LIBRARIES := ctsdeviceinfolib
 
diff --git a/tools/host/src/com/android/cts/ConsoleUi.java b/tools/host/src/com/android/cts/ConsoleUi.java
index c9b0e1d..ce26d52 100644
--- a/tools/host/src/com/android/cts/ConsoleUi.java
+++ b/tools/host/src/com/android/cts/ConsoleUi.java
@@ -80,7 +80,6 @@
         mResultCodeMap.put(CtsTestResult.STR_ERROR, CtsTestResult.CODE_ERROR);
         mResultCodeMap.put(CtsTestResult.STR_NOT_EXECUTED, CtsTestResult.CODE_NOT_EXECUTED);
         mResultCodeMap.put(CtsTestResult.STR_TIMEOUT, CtsTestResult.CODE_TIMEOUT);
-        mResultCodeMap.put(CtsTestResult.STR_OMITTED, CtsTestResult.CODE_OMITTED);
     }
 
     public ConsoleUi(TestHost host) {
@@ -1183,9 +1182,9 @@
             CUIOutputStream.println("There aren't any test results!");
         } else {
             CUIOutputStream.println("List of all results: ");
-            CUIOutputStream.println("Session\t\tTest result\t\t\t\t\tStart time\t\tEnd time\t"
+            CUIOutputStream.println("Session\t\tTest result\t\t\t\tStart time\t\tEnd time\t"
                     + "\tTest plan name\t");
-            CUIOutputStream.println("\t\tPass\tFail\tTimeout\tOmitted\tNotExecuted");
+            CUIOutputStream.println("\t\tPass\tFail\tTimeout\tNotExecuted");
 
             for (TestSession session : sessions) {
                 TestSessionLog log = session.getSessionLog();
@@ -1193,8 +1192,6 @@
                         CtsTestResult.CODE_PASS).size();
                 int failNum = log.getTestList(
                         CtsTestResult.CODE_FAIL).size();
-                int omittedNum = log.getTestList(
-                        CtsTestResult.CODE_OMITTED).size();
                 int notExecutedNum = log.getTestList(
                         CtsTestResult.CODE_NOT_EXECUTED).size();
                 int timeOutNum = log.getTestList(
@@ -1202,7 +1199,6 @@
 
                 String resStr = Long.toString(passNum) + "\t" + failNum;
                 resStr += "\t" + timeOutNum;
-                resStr += "\t" + omittedNum;
                 resStr += "\t" + notExecutedNum;
 
                 String startTimeStr =
diff --git a/tools/host/src/com/android/cts/CtsTestResult.java b/tools/host/src/com/android/cts/CtsTestResult.java
index 851b07d..b64863d 100644
--- a/tools/host/src/com/android/cts/CtsTestResult.java
+++ b/tools/host/src/com/android/cts/CtsTestResult.java
@@ -37,14 +37,12 @@
     public static final int CODE_FAIL = 2;
     public static final int CODE_ERROR = 3;
     public static final int CODE_TIMEOUT = 4;
-    public static final int CODE_OMITTED = 5;
     public static final int CODE_FIRST = CODE_INIT;
-    public static final int CODE_LAST = CODE_OMITTED;
+    public static final int CODE_LAST = CODE_TIMEOUT;
 
     public static final String STR_ERROR = "error";
     public static final String STR_TIMEOUT = "timeout";
     public static final String STR_NOT_EXECUTED = "notExecuted";
-    public static final String STR_OMITTED = "omitted";
     public static final String STR_FAIL = "fail";
     public static final String STR_PASS = "pass";
 
@@ -57,7 +55,6 @@
         sCodeToResultMap.put(CODE_FAIL, STR_FAIL);
         sCodeToResultMap.put(CODE_ERROR, STR_ERROR);
         sCodeToResultMap.put(CODE_TIMEOUT, STR_TIMEOUT);
-        sCodeToResultMap.put(CODE_OMITTED, STR_OMITTED);
         sResultToCodeMap = new HashMap<String, Integer>();
         for (int code : sCodeToResultMap.keySet()) {
             sResultToCodeMap.put(sCodeToResultMap.get(code), code);
diff --git a/tools/host/src/com/android/cts/TestDevice.java b/tools/host/src/com/android/cts/TestDevice.java
index e72b97c..6ac56a1 100644
--- a/tools/host/src/com/android/cts/TestDevice.java
+++ b/tools/host/src/com/android/cts/TestDevice.java
@@ -27,8 +27,8 @@
 import com.android.ddmlib.ShellCommandUnresponsiveException;
 import com.android.ddmlib.SyncException;
 import com.android.ddmlib.SyncService;
-import com.android.ddmlib.SyncService.ISyncProgressMonitor;
 import com.android.ddmlib.TimeoutException;
+import com.android.ddmlib.SyncService.ISyncProgressMonitor;
 import com.android.ddmlib.log.LogReceiver;
 import com.android.ddmlib.log.LogReceiver.ILogListener;
 
@@ -1452,10 +1452,6 @@
             case STATUS_ERROR:
                 mResultCode = CtsTestResult.CODE_FAIL;
                 break;
-
-            case STATUS_OMITTED:
-                mResultCode = CtsTestResult.CODE_OMITTED;
-                break;
             }
         }
 
@@ -1521,10 +1517,6 @@
                 case STATUS_PASS:
                     mResultCode = CtsTestResult.CODE_PASS;
                     break;
-
-                case STATUS_OMITTED:
-                    mResultCode = CtsTestResult.CODE_OMITTED;
-                    break;
                 }
                 resultLines.removeAll(resultLines);
             }
@@ -1576,10 +1568,6 @@
                     mTest.setResult(new CtsTestResult(
                             CtsTestResult.CODE_FAIL, mFailedMsg, mStackTrace));
                     break;
-
-                case STATUS_OMITTED:
-                    mTest.setResult(new CtsTestResult(CtsTestResult.CODE_OMITTED));
-                    break;
                 }
             }
             // report status even if no matching test was found
diff --git a/tools/host/src/com/android/cts/TestSession.java b/tools/host/src/com/android/cts/TestSession.java
index fedd756..e3693d8 100644
--- a/tools/host/src/com/android/cts/TestSession.java
+++ b/tools/host/src/com/android/cts/TestSession.java
@@ -485,15 +485,13 @@
         private void displayTestResultSummary() {
             int passNum = mSessionLog.getTestList(CtsTestResult.CODE_PASS).size();
             int failNum = mSessionLog.getTestList(CtsTestResult.CODE_FAIL).size();
-            int omittedNum = mSessionLog.getTestList(CtsTestResult.CODE_OMITTED).size();
             int notExecutedNum = mSessionLog.getTestList(CtsTestResult.CODE_NOT_EXECUTED).size();
             int timeOutNum = mSessionLog.getTestList(CtsTestResult.CODE_TIMEOUT).size();
-            int total = passNum + failNum + omittedNum + notExecutedNum + timeOutNum;
+            int total = passNum + failNum + notExecutedNum + timeOutNum;
 
             println("Test summary:   pass=" + passNum
                     + "   fail=" + failNum
                     + "   timeOut=" + timeOutNum
-                    + "   omitted=" + omittedNum
                     + "   notExecuted=" + notExecutedNum
                     + "   Total=" + total);
         }
diff --git a/tools/host/src/com/android/cts/TestSessionLog.java b/tools/host/src/com/android/cts/TestSessionLog.java
index 0b53076..bf5b3e8 100644
--- a/tools/host/src/com/android/cts/TestSessionLog.java
+++ b/tools/host/src/com/android/cts/TestSessionLog.java
@@ -78,7 +78,6 @@
     static final String ATTRIBUTE_PASS = "pass";
     static final String ATTRIBUTE_FAILED = "failed";
     static final String ATTRIBUTE_TIMEOUT = "timeout";
-    static final String ATTRIBUTE_OMITTED = "omitted";
     static final String ATTRIBUTE_NOT_EXECUTED = "notExecuted";
 
     static final String TAG_DEVICEINFO = "DeviceInfo";
@@ -385,14 +384,12 @@
 
             int passNum = getTestList(CtsTestResult.CODE_PASS).size();
             int failNum = getTestList(CtsTestResult.CODE_FAIL).size();
-            int omittedNum = getTestList(CtsTestResult.CODE_OMITTED).size();
             int notExecutedNum = getTestList(CtsTestResult.CODE_NOT_EXECUTED).size();
             int timeOutNum = getTestList(CtsTestResult.CODE_TIMEOUT).size();
             Node summaryNode = doc.createElement(TAG_SUMMARY);
             root.appendChild(summaryNode);
             setAttribute(doc, summaryNode, ATTRIBUTE_PASS, passNum);
             setAttribute(doc, summaryNode, ATTRIBUTE_FAILED, failNum);
-            setAttribute(doc, summaryNode, ATTRIBUTE_OMITTED, omittedNum);
             setAttribute(doc, summaryNode, ATTRIBUTE_NOT_EXECUTED, notExecutedNum);
             setAttribute(doc, summaryNode, ATTRIBUTE_TIMEOUT, timeOutNum);
 
diff --git a/tools/host/src/com/android/cts/Version.java b/tools/host/src/com/android/cts/Version.java
index f2c83b9..2d46d45 100644
--- a/tools/host/src/com/android/cts/Version.java
+++ b/tools/host/src/com/android/cts/Version.java
@@ -18,7 +18,7 @@
 
 public class Version {
     // The CTS version string
-    private static final String version = "3.0_r1";
+    private static final String version = "3.0_r2";
 
     private Version() {
         // no instances allowed
diff --git a/tools/spec-progress/Android.mk b/tools/spec-progress/Android.mk
deleted file mode 100644
index e4026e9..0000000
--- a/tools/spec-progress/Android.mk
+++ /dev/null
@@ -1,15 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-LOCAL_IS_HOST_MODULE := true
-LOCAL_MODULE_CLASS := EXECUTABLES
-LOCAL_MODULE := spec-progress
-
-include $(BUILD_SYSTEM)/base_rules.mk
-
-$(LOCAL_BUILT_MODULE): $(LOCAL_PATH)/etc/spec-progress | $(ACP)
-	@echo "Copy: $(PRIVATE_MODULE) ($@)"
-	$(copy-file-to-new-target)
-	$(hide) chmod 755 $@
-
-include $(LOCAL_PATH)/src/Android.mk
diff --git a/tools/spec-progress/etc/spec-progress b/tools/spec-progress/etc/spec-progress
deleted file mode 100644
index a8f14d7..0000000
--- a/tools/spec-progress/etc/spec-progress
+++ /dev/null
@@ -1,154 +0,0 @@
-#!/bin/bash
-#
-# 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.
-
-# Set up prog to be the path of this script, including following symlinks,
-# and set up progdir to be the fully-qualified pathname of its directory.
-prog="$0"
-while [ -h "${prog}" ]; do
-    newProg=`/bin/ls -ld "${prog}"`
-    newProg=`expr "${newProg}" : ".* -> \(.*\)$"`
-    if expr "x${newProg}" : 'x/' >/dev/null; then
-        prog="${newProg}"
-    else
-        progdir=`dirname "${prog}"`
-        prog="${progdir}/${newProg}"
-    fi
-done
-oldwd=`pwd`
-progdir=`dirname "${prog}"`
-cd "${progdir}"
-progdir=`pwd`
-prog="${progdir}"/`basename "${prog}"`
-cd "${oldwd}"
-
-libdir=`dirname $progdir`/framework
-
-javaOpts=""
-while expr "x$1" : 'x-J' >/dev/null; do
-    opt=`expr "$1" : '-J\(.*\)'`
-    javaOpts="${javaOpts} -${opt}"
-    shift
-done
-
-#exec java $javaOpts -jar $libdir/hat.jar "$@"
-
-#######################################################################
-# Original content of invocation script follows. Uses values cleverly
-# deduced by the above code. If you want to use this for a different
-# set of packages, adjust both the list of source directories and the
-# list of packages.
-#######################################################################
-export CLASSES=$progdir/../framework/spec-progress.jar
-export INPUT=$ANDROID_BUILD_TOP
-export OUTPUT=$ANDROID_BUILD_TOP/out/target/common/cts/spec-progress
-
-if [ "$1" != "" ]; then
-   export OUTPUT=$1
-fi
-
-javadoc -J-Xmx512m -docletpath $CLASSES -doclet SpecProgressDoclet -d $OUTPUT -sourcepath \
-$INPUT/dalvik/libcore/dalvik/src/main/java:\
-$INPUT/dalvik/libcore/annotation/src/main/java:\
-$INPUT/dalvik/libcore/archive/src/main/java:\
-$INPUT/dalvik/libcore/auth/src/main/java:\
-$INPUT/dalvik/libcore/awt-kernel/src/main/java:\
-$INPUT/dalvik/libcore/beans/src/main/java:\
-$INPUT/dalvik/libcore/crypto/src/main/java:\
-$INPUT/dalvik/libcore/logging/src/main/java:\
-$INPUT/dalvik/libcore/luni/src/main/java:\
-$INPUT/dalvik/libcore/luni-kernel/src/main/java:\
-$INPUT/dalvik/libcore/math/src/main/java:\
-$INPUT/dalvik/libcore/nio/src/main/java:\
-$INPUT/dalvik/libcore/nio_char/src/main/java:\
-$INPUT/dalvik/libcore/prefs/src/main/java:\
-$INPUT/dalvik/libcore/regex/src/main/java:\
-$INPUT/dalvik/libcore/security/src/main/java:\
-$INPUT/dalvik/libcore/security-kernel/src/main/java:\
-$INPUT/dalvik/libcore/sql/src/main/java:\
-$INPUT/dalvik/libcore/text/src/main/java:\
-$INPUT/dalvik/libcore/xml/src/main/java:\
-$INPUT/dalvik/libcore/x-net/src/main/java:\
- \
-dalvik.annotation \
-dalvik.bytecode \
-dalvik.system \
-java.io \
-java.lang \
-java.lang.annotation \
-java.lang.ref \
-java.lang.reflect \
-java.math \
-java.net \
-java.nio \
-java.nio.channels \
-java.nio.channels.spi \
-java.nio.charset \
-java.nio.charset.spi \
-java.security \
-java.security.acl \
-java.security.cert \
-java.security.interfaces \
-java.security.spec \
-java.sql \
-java.text \
-java.util \
-java.util.jar \
-java.util.logging \
-java.util.prefs \
-java.util.regex \
-java.util.zip \
-javax.crypto \
-javax.crypto.interfaces \
-javax.crypto.spec \
-javax.net \
-javax.net.ssl \
-javax.security.auth \
-javax.security.auth.callback \
-javax.security.auth.login \
-javax.security.auth.x500 \
-javax.security.cert \
-javax.sql \
-javax.xml.parsers \
-org.w3c.dom \
-org.xml.sax \
-org.xml.sax.ext \
-org.xml.sax.helpers \
-
-# Not part of core libs any more:
-# java.lang.instrument \
-# javax.sound.midi \
-# javax.sound.midi.spi \
-# javax.sound.sampled \
-# javax.sound.sampled.spi \
-# java.awt \
-# java.awt.color \
-# java.awt.event \
-# java.awt.font \
-# java.awt.geom \
-# java.awt.im \
-# java.awt.im.spi \
-# java.awt.image \
-# java.awt.image.renderable \
-# javax.imageio \
-# javax.imageio.event \
-# javax.imageio.metadata \
-# javax.imageio.plugins.bmp \
-# javax.imageio.plugins.jpeg \
-# javax.imageio.spi \
-# javax.imageio.stream \
-# java.util.concurrent \
-# java.util.concurrent.atomic \
-# java.util.concurrent.locks \
diff --git a/tools/spec-progress/src/Android.mk b/tools/spec-progress/src/Android.mk
deleted file mode 100644
index 8ab5a7b..0000000
--- a/tools/spec-progress/src/Android.mk
+++ /dev/null
@@ -1,14 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-#LOCAL_MODULE_TAGS := cts
-
-LOCAL_SRC_FILES := \
-	SpecProgressDoclet.java
-
-LOCAL_CLASSPATH := \
-	$(HOST_JDK_TOOLS_JAR)
-
-LOCAL_MODULE:= spec-progress
-
-include $(BUILD_HOST_JAVA_LIBRARY)
diff --git a/tools/spec-progress/src/SpecProgressDoclet.java b/tools/spec-progress/src/SpecProgressDoclet.java
deleted file mode 100644
index 4c5b6cc..0000000
--- a/tools/spec-progress/src/SpecProgressDoclet.java
+++ /dev/null
@@ -1,1074 +0,0 @@
-/*
- * 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.
- */
-
-import java.io.BufferedOutputStream;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import com.sun.javadoc.ClassDoc;
-import com.sun.javadoc.ConstructorDoc;
-import com.sun.javadoc.Doc;
-import com.sun.javadoc.ExecutableMemberDoc;
-import com.sun.javadoc.FieldDoc;
-import com.sun.javadoc.LanguageVersion;
-import com.sun.javadoc.MemberDoc;
-import com.sun.javadoc.MethodDoc;
-import com.sun.javadoc.PackageDoc;
-import com.sun.javadoc.ParamTag;
-import com.sun.javadoc.Parameter;
-import com.sun.javadoc.RootDoc;
-import com.sun.javadoc.Tag;
-import com.sun.javadoc.ThrowsTag;
-import com.sun.javadoc.TypeVariable;
-
-/**
- * Provides a Doclet for checking the correctness and completeness of the
- * Android core library JavaDoc (aka "the spec"). It generates an HTML-based
- * report vaguely similar to the standard JavaDoc output. The following rules
- * are currently implemented:
- * 
- * Each package must have a package.html doc, and all classes must be documented
- * as described below.
- * 
- * Each class must have an individual doc and all members (fields, constructors,
- * methods) must be documented as described below. All type parameters on class 
- * level need to be documented.
- * 
- * Each member must have an individual doc.
- * 
- * Each executable member (constructor or method) must have a "@param" tag
- * describing each declared parameter. "@param" tags for non-existing parameters
- * are not allowed.
- * 
- * Each method that has a non-void return type must have at least one "@return"
- * tag. A method that has a void return type must not have a "@return" tag.
- * 
- * Each executable member must have a "@throws" tag for each declared exception
- * that does not extend java.lang.RuntimeException or java.lang.Error. This
- * tag may refer to a superclass of the exception actually being thrown. Each
- * exception specified by a "@throws" tag must actually be declared by the
- * member, unless it extends java.lang.RuntimeException or java.lang.Error.
- * Again, the exception being thrown might be more specific than the one
- * documented.
- * 
- * Methods that override or implement another method are allowed to be
- * undocumented, resulting in the inherited documentation being used. If such a
- * method is documented anyway, it must have the complete documentation as
- * described above.
- * 
- * Elements that have a "@hide" JavaDoc tag are not considered part of the
- * official API and hence are not required to be documented.
- * 
- * Based on checking the above rules, the Doclet assigns statuses to individual
- * documentation elements as follows:
- * 
- * Red: the element violates at least one of the above rules.
- * 
- * Yellow: the element fulfills all the above rules, but neither it nor one of
- * its parent elements (class, package) has been marked with the
- * "@since Android-1.0" tag.
- * 
- * Green: the element fulfills all the above rules, it does not have any "@cts"
- * tags, and either it or one if its parent elements (class, package) has been
- * marked with the "@since Android-1.0" tag.
- * 
- * These colors propagate upwards in the hierarchy. Parent elements are assigned
- * colors as follows:
- * 
- * Red: At least on the children is red.
- * 
- * Yellow: None of the children are red and at least one of the children is
- * yellow.
- * 
- * Green: All of the children are green.
- * 
- * The ultimate goal, of course, is to get the summary for the complete API
- * green.
- */
-public class SpecProgressDoclet {
-
-    public static final int TYPE_FIELD = 0;
-
-    public static final int TYPE_METHOD = 1;
-
-    public static final int TYPE_CLASS = 2;
-
-    public static final int TYPE_PACKAGE = 3;
-
-    public static final int TYPE_ROOT = 4;
-
-    public static final int VALUE_RED = 0;
-
-    public static final int VALUE_YELLOW = 1;
-
-    public static final int VALUE_GREEN = 2;
-
-    public static final String[] COLORS = { "#ffa0a0", "#ffffa0", "#a0ffa0" };
-
-    public static final String[] TYPES = { "Field", "Method", "Class",
-                                           "Package", "All packages" };
-
-    /**
-     * Holds our basic output directory.
-     */
-    private File directory;
-
-    /**
-     * Holds a reference to the doc for java.lang.RuntimeException, so we can
-     * compare against it later.
-     */
-    private ClassDoc runtimeException;
-
-    /**
-     * Holds a reference to the doc for java.lang.Error, so we can
-     * compare against it later.
-     */
-    private ClassDoc error;
-
-    /**
-     * States whether to check type parameters on class level. 
-     * To enable these checks use the option: '-Xgeneric' 
-     */
-    private static boolean checkTypeParameters;
-
-    /**
-     * Helper class for comparing element with each other, in oder to determine
-     * an order. Uses lexicographic order of names.
-     */
-    private class DocComparator implements Comparator<Doc> {
-        public int compare(Doc elem1, Doc elem2) {
-            return elem1.name().compareTo(elem2.name());
-        }
-
-        public boolean equals(Doc elem) {
-            return this == elem;
-        }
-    }
-
-    /**
-     * Class for collecting stats and propagating them upwards in the element
-     * hierarchy.
-     */
-    class Stats {
-
-        /**
-         * Holds the element type.
-         */
-        int type;
-
-        /**
-         * Holds the name of the element.
-         */
-        String name;
-
-        /**
-         * Holds information that is sufficient for building a hyperlink.
-         */
-        String link;
-
-        /**
-         * Holds the total number of elements per type (package, class, etc.).
-         */
-        private int[] numbersPerType = new int[4];
-
-        /**
-         * Holds the total number of elements per status value (red, yellow,
-         * green).
-         */
-        private int[] numbersPerValue = new int[3];
-
-        /**
-         * Holds the total number of "@cts" comments.
-         */
-        private int numberOfComments;
-
-        /**
-         * Creates a new Stats instance.
-         */
-        public Stats(int type, String name, String link) {
-            this.type = type;
-            this.name = name;
-            this.link = link;
-        }
-
-        /**
-         * Adds the contents of a single child element to this instance,
-         * propagating values up in the hierachy
-         */
-        public void add(int type, int status, int comments) {
-            numbersPerType[type]++;
-            numbersPerValue[status]++;
-            numberOfComments += comments;
-        }
-
-        /**
-         * Adds the contents of a child Stats instance to this instance,
-         * propagating values up in the hierachy
-         */
-        public void add(Stats stats) {
-            for (int i = 0; i < numbersPerType.length; i++) {
-                numbersPerType[i] += stats.numbersPerType[i];
-            }
-
-            for (int i = 0; i < numbersPerValue.length; i++) {
-                numbersPerValue[i] += stats.numbersPerValue[i];
-            }
-
-            numberOfComments += stats.numberOfComments;
-        }
-
-        /**
-         * Returns the link.
-         */
-        public String getLink() {
-            return link;
-        }
-
-        /**
-         * Returns the name.
-         */
-        public String getName() {
-            return name;
-        }
-
-        /**
-         * Returns the number of elements per element type.
-         */
-        public int getNumbersPerType(int type) {
-            return numbersPerType[type];
-        }
-
-        /**
-         * Returns the number of elements per status value.
-         */
-        public int getNumbersPerValue(int type) {
-            return numbersPerValue[type];
-        }
-
-        /**
-         * Returns the number of comments.
-         */
-        public int getNumberOfComments() {
-            return numberOfComments;
-        }
-
-        /**
-         * Returns the type of the element to which this Stats instance belongs.
-         */
-        public int getType() {
-            return type;
-        }
-
-        /**
-         * Returns the accumulated status value.
-         */
-        public int getValue() {
-            if (numbersPerValue[VALUE_RED] != 0) {
-                return VALUE_RED;
-            } else if (numbersPerValue[VALUE_YELLOW] != 0) {
-                return VALUE_YELLOW;
-            } else {
-                return VALUE_GREEN;
-            }
-        }
-
-    }
-
-    /**
-     * Holds our comparator instance for everything.
-     */
-    private DocComparator comparator = new DocComparator();
-
-    /**
-     * Creates a new instance of the SpecProgressDoclet for a given target
-     * directory.
-     */
-    public SpecProgressDoclet(String directory) {
-        this.directory = new File(directory);
-    }
-
-    /**
-     * Opens a new output file and writes the usual HTML header. Directories
-     * are created on demand.
-     */
-    private PrintWriter openFile(String name, String title) throws IOException {
-        System.out.println("Writing file \"" + name + "\"...");
-        
-        File file = new File(directory, name);
-        File parent = file.getParentFile();
-        parent.mkdirs();
-
-        OutputStream stream = new BufferedOutputStream(new FileOutputStream(file));
-        PrintWriter printer = new PrintWriter(stream);
-
-        printer.println("<html>");
-        printer.println("  <head>");
-        printer.println("    <title>" + title + "</title>");
-        printer.println("  <head>");
-        printer.println("  <body>");
-        printer.println("    <h1>" + title + "</h1>");
-
-        return printer;
-    }
-
-    /**
-     * Closes the given output file, writing the usual HTML footer before.
-     */
-    private void closeFile(PrintWriter printer) {
-        printer.println("  </body>");
-        printer.println("</html>");
-
-        printer.flush();
-        printer.close();
-    }
-
-    /**
-     * Processes the whole list of classes that JavaDoc knows about.
-     */
-    private void process(RootDoc root) throws IOException {
-        runtimeException = root.classNamed("java.lang.RuntimeException");
-        error = root.classNamed("java.lang.Error");
-
-        PrintWriter printer = openFile("index.html", "All packages");
-
-        printer.println("Generated " + new Date().toString());
-        
-        Stats derived = new Stats(TYPE_ROOT, "All packages", null);
-
-        printer.println("      <h2>Children</h2>");
-        printer.println("      <table width=\"100%\">");
-        printStatsHeader(printer);
-
-        PackageDoc[] packages = root.specifiedPackages();
-        Arrays.sort(packages, comparator);
-        for (PackageDoc pack : packages) {
-            if (pack.allClasses().length != 0 && !isHidden(pack)) {
-                Stats subStats = processPackage(pack);
-                printStats(printer, subStats, true);
-                derived.add(subStats);
-            }
-        }
-
-        printer.println("      </table>");
-
-        printer.println("      <p>");
-
-        printer.println("      <h2>Summary</h2>");
-        printer.println("      <table width=\"100%\">");
-        printStatsHeader(printer);
-        printStats(printer, derived, false);
-        printer.println("      </table>");
-
-        closeFile(printer);
-    }
-
-    /**
-     * Processes the details of a single package.
-     */
-    private Stats processPackage(PackageDoc pack) throws IOException {
-        String file = getPackageDir(pack) + "/package.html";
-        PrintWriter printer = openFile(file, "Package " + pack.name());
-
-        Stats derived = new Stats(TYPE_PACKAGE, pack.name(), file);
-
-        printer.println("      <h2>Elements</h2>");
-        printer.println("      <table width=\"100%\">");
-
-        printElementHeader(printer);
-        processElement(printer, pack, TYPE_PACKAGE, derived);
-
-        printer.println("      </table>");
-
-        printer.println("      <p>");
-
-        printer.println("      <h2>Children</h2>");
-        printer.println("      <table width=\"100%\">");
-
-        printStatsHeader(printer);
-
-        ClassDoc[] classes = pack.allClasses();
-        Arrays.sort(classes, comparator);
-        for (ClassDoc clazz : classes) {
-            if (!isHidden(clazz)) {
-                Stats subStats = processClass(clazz);
-                printStats(printer, subStats, true);
-                derived.add(subStats);
-            }
-        }
-
-        printer.println("      </table>");
-
-        printer.println("      <h2>Summary</h2>");
-        printer.println("      <table width=\"100%\">");
-        printStatsHeader(printer);
-        printStats(printer, derived, false);
-        printer.println("      </table>");
-
-        closeFile(printer);
-
-        return derived;
-    }
-
-    /**
-     * Processes the details of a single class.
-     */
-    private Stats processClass(ClassDoc clazz) throws IOException {
-        String file = getPackageDir(clazz.containingPackage()) + "/" + clazz.name() + ".html";
-        PrintWriter printer = openFile(file, "Class " + clazz.name());
-
-        Stats derived = new Stats(TYPE_CLASS, clazz.name(), clazz.name() + ".html");
-
-        printer.println("      <h2>Elements</h2>");
-        printer.println("      <table width=\"100%\">");
-
-        printElementHeader(printer);
-
-        processElement(printer, clazz, TYPE_CLASS, derived);
-
-        if(clazz.isEnum()){
-            FieldDoc[] enums = clazz.enumConstants();
-            Arrays.sort(enums, comparator);
-            for(FieldDoc e : enums) {
-                processElement(printer, e, TYPE_FIELD, derived);
-            }
-        }
-
-        FieldDoc[] fields = clazz.fields();
-        Arrays.sort(fields, comparator);
-        for (FieldDoc field : fields) {
-            processElement(printer, field, TYPE_FIELD, derived);
-        }
-
-        ConstructorDoc[] constructors = clazz.constructors();
-        Arrays.sort(constructors, comparator);
-        for (ConstructorDoc constructor : constructors) {
-            if (constructor.position() != null) {
-                String constPos = constructor.position().toString();
-                String classPos = constructor.containingClass().position()
-                        .toString();
-
-                if (!constPos.equals(classPos)) {
-                    processElement(printer, constructor, TYPE_METHOD, derived);
-                }
-            }
-        }
-
-        HashSet<MethodDoc> methodSet = new HashSet<MethodDoc>();
-        
-        
-        ClassDoc superClass = clazz.superclass();
-        MethodDoc[] methods = null;
-        if (superClass != null && superClass.isPackagePrivate())
-        {
-            MethodDoc[] classMethods = clazz.methods();
-            for (int i = 0; i < classMethods.length; i++) {
-                methodSet.add(classMethods[i]);
-            }
-
-
-            while (superClass != null && superClass.isPackagePrivate()) {
-                classMethods = superClass.methods();
-                for (int i = 0; i < classMethods.length; i++) {
-                    methodSet.add(classMethods[i]);
-                }
-                superClass = superClass.superclass();
-            }
-
-            methods = new MethodDoc[methodSet.size()];
-            methodSet.toArray(methods);
-        }
-        else
-        {
-            methods = clazz.methods();
-        }
-
-        Arrays.sort(methods, comparator);
-        for (MethodDoc method : methods) {
-            if (!(clazz.isEnum() && ("values".equals(method.name()) ||
-                                     "valueOf".equals(method.name())))) {
-                processElement(printer, method, TYPE_METHOD, derived);
-            }
-        }
-
-        printer.println("      </table>");
-
-        printer.println("      <p>");
-
-        printer.println("      <h2>Summary</h2>");
-        printer.println("      <table width=\"100%\">");
-        printStatsHeader(printer);
-        printStats(printer, derived, false);
-        printer.println("      </table>");
-
-        closeFile(printer);
-
-        return derived;
-    }
-
-    /**
-     * Processes a single element.
-     */
-    private void processElement(PrintWriter printer, Doc doc, int type, Stats derived) {
-        if (isHidden(doc)) {
-            return;
-        }
-
-        List<String> errors = new ArrayList<String>();
-        
-        boolean documented = isValidComment(doc.commentText());
-        boolean inherited = false;
-
-        if(checkTypeParameters && (doc.isClass() || doc.isInterface())){
-            boolean typeParamsOk = hasAllTypeParameterDocs((ClassDoc)doc, errors);
-            documented = documented && typeParamsOk;
-        }
-
-        if (doc.isMethod()) {
-            MethodDoc method = (MethodDoc) doc;
-            
-            if ("".equals(method.commentText().trim())) {
-                inherited = method.overriddenMethod() != null || 
-                            implementedMethod(method) != null;
-                documented = inherited;
-            }
-        }
-
-        if (!documented) {
-            errors.add("Missing or insufficient doc.");
-        }
-        
-        if (!inherited) {
-            if (doc.isMethod() || doc.isConstructor()) {
-                ExecutableMemberDoc executable = (ExecutableMemberDoc) doc;
-                boolean paramsOk = hasAllParameterDocs(executable, errors);
-                boolean exceptionsOk = hasAllExceptionDocs(executable, errors);
-
-                documented = documented && paramsOk && exceptionsOk;
-            }
-
-            if (doc.isMethod()) {
-                MethodDoc method = (MethodDoc) doc;
-                boolean resultOk = hasReturnDoc(method, errors);
-                documented = documented && resultOk;
-            }
-        }
-        
-        boolean reviewed = hasSinceTag(doc);
-        Tag[] comments = doc.tags("cts");
-
-        int status = getStatus(documented, reviewed || inherited, comments);
-
-        printer.println("        <tr bgcolor=\"" + COLORS[status] + "\">");
-        printer.println("          <td>" + TYPES[type] + "</td>");
-        
-        if (doc instanceof PackageDoc) {
-            printer.println("          <td>" + doc.toString() + "</td>");
-        } else {
-            String s = doc.name();
-            String t = doc.toString();
-            
-            int i = t.indexOf(s);
-            
-            if (i != -1) {
-                t = t.substring(i);
-            }
-            
-            printer.println("          <td>" + t + "</td>");
-        }
-        
-        printer.println("          <td>" + getFirstSentence(doc) + "</td>");
-        printer.println("          <td>" + (documented ? "Yes" : "No") + "</td>");
-        printer.println("          <td>" + (reviewed ? "Yes" : "No") + "</td>");
-        printer.println("          <td>");
-
-        if (comments.length != 0 || errors.size() != 0) {
-            printer.println("            </ul>");
-
-            for (int i = 0; i < comments.length; i++) {
-                printer.print("              <li>");
-                printer.print(comments[i].text());
-                printer.println("</li>");
-            }
-            
-            for (int i = 0; i < errors.size(); i++) {
-                printer.print("              <li>");
-                printer.print(errors.get(i));
-                printer.println("</li>");
-            }
-
-            printer.println("            </ul>");
-        } else {
-            printer.println("&nbsp;");
-        }
-
-        printer.println("          </td>");
-        printer.println("        </tr>");
-
-        derived.add(type, status, comments.length);
-    }
-
-    /**
-     * Print the table header for an element table.
-     */
-    private void printElementHeader(PrintWriter printer) {
-        printer.println("        <tr>");
-        printer.println("          <td>Type</td>");
-        printer.println("          <td>Name</td>");
-        printer.println("          <td>First sentence</td>");
-        printer.println("          <td>Doc'd</td>");
-        printer.println("          <td>Rev'd</td>");
-        printer.println("          <td>Comments</td>");
-        printer.println("        </tr>");
-    }
-
-    /**
-     * Print the table header for stats table table.
-     */
-    private void printStatsHeader(PrintWriter printer) {
-        printer.println("        <tr>");
-        printer.println("          <td>Type</td>");
-        printer.println("          <td>Name</td>");
-        printer.println("          <td>#Classes</td>");
-        printer.println("          <td>#Fields</td>");
-        printer.println("          <td>#Methods</td>");
-        printer.println("          <td>#Red</td>");
-        printer.println("          <td>#Yellow</td>");
-        printer.println("          <td>#Green</td>");
-        printer.println("          <td>#Comments</td>");
-        printer.println("        </tr>");
-    }
-
-    /**
-     * Prints a single row to a stats table.
-     */
-    private void printStats(PrintWriter printer, Stats info, boolean wantLink) {
-        printer.println("        <tr bgcolor=\"" + COLORS[info.getValue()] + "\">");
-        printer.println("          <td>" + TYPES[info.getType()] + "</td>");
-
-        printer.print("          <td>");
-        String link = info.getLink();
-        if (wantLink && link != null) {
-            printer.print("<a href=\"" + link + "\">" + info.getName() + "</a>");
-        } else {
-            printer.print(info.getName());
-        }
-        printer.println("</td>");
-
-        printer.println("          <td>" + info.getNumbersPerType(TYPE_CLASS) + "</td>");
-        printer.println("          <td>" + info.getNumbersPerType(TYPE_FIELD) + "</td>");
-        printer.println("          <td>" + info.getNumbersPerType(TYPE_METHOD) + "</td>");
-        printer.println("          <td>" + info.getNumbersPerValue(VALUE_RED) + "</td>");
-        printer.println("          <td>" + info.getNumbersPerValue(VALUE_YELLOW) + "</td>");
-        printer.println("          <td>" + info.getNumbersPerValue(VALUE_GREEN) + "</td>");
-        printer.println("          <td>" + info.getNumberOfComments() + "</td>");
-        printer.println("        </tr>");
-    }
-
-    /**
-     * Returns the directory for a given package. Basically converts embedded
-     * dots in the name into slashes. 
-     */
-    private File getPackageDir(PackageDoc pack) {
-        if (pack == null || pack.name() == null || "".equals(pack.name())) {
-            return new File(".");
-        } else {
-            return new File(pack.name().replace('.', '/'));
-        }
-    }
-
-    /**
-     * Checks whether the given comment is not null and not of length 0.
-     */
-    private boolean isValidComment(String comment) {
-        return comment != null && comment.length() > 0;
-    }
-
-    /**
-     * Checks whether the given interface or class has documentation for
-     * all declared type parameters (no less, no more). 
-     */
-    private boolean hasAllTypeParameterDocs(ClassDoc doc, List<String> errors) {
-        boolean result = true;
-        
-        TypeVariable[] params = doc.typeParameters();
-        Set<String> paramsSet = new HashSet<String>();
-        for (TypeVariable param : params) {
-            paramsSet.add(param.typeName()); 
-        }  
-
-        ParamTag[] paramTags = doc.typeParamTags();
-        Map<String, String> paramTagsMap = new HashMap<String, String>();
-        for (ParamTag paramTag : paramTags) {
-            if (!paramsSet.contains(paramTag.parameterName())) {
-                errors.add("Unknown type parameter \"" + paramTag.parameterName() + "\"");
-                result = false;
-            }
-            paramTagsMap.put(paramTag.parameterName(), paramTag.parameterComment());
-        }
-
-        for (TypeVariable param : params) {
-            if (!isValidComment(paramTagsMap.get(param.typeName()))) {
-                errors.add("Undocumented type parameter \"" + param.typeName() + "\"");
-                result = false;
-            }
-        }
-
-        return result;
-    }
-
-    /**
-     * Checks whether the given executable member has documentation for
-     * all declared parameters (no less, no more).  
-     */
-    private boolean hasAllParameterDocs(ExecutableMemberDoc doc, List<String> errors) {
-        boolean result = true;
-        
-        Parameter params[] = doc.parameters();
-        Set<String> paramsSet = new HashSet<String>();
-        for (int i = 0; i < params.length; i++) {
-            Parameter param = params[i];
-            paramsSet.add(param.name());
-        }
-
-        ParamTag[] paramTags = doc.paramTags();
-        Map<String, String> paramTagsMap = new HashMap<String, String>();
-        for (int i = 0; i < paramTags.length; i++) {
-            ParamTag paramTag = paramTags[i];
-
-            if (!paramsSet.contains(paramTag.parameterName())) {
-                errors.add("Unknown parameter \"" + paramTag.parameterName() + "\"");
-                result = false;
-            }
-
-            paramTagsMap.put(paramTag.parameterName(), paramTag.parameterComment());
-        }
-
-        for (int i = 0; i < params.length; i++) {
-            Parameter param = params[i];
-
-            if (!isValidComment(paramTagsMap.get(param.name()))) {
-                errors.add("Undocumented parameter \"" + param.name() + "\"");
-                result = false;
-            }
-        }
-
-        return result;
-    }
-
-    /**
-     * Checks whether the given executable member has documentation for
-     * all non-runtime exceptions. Runtime exceptions may or may not be
-     * documented.   
-     */
-    private boolean hasAllExceptionDocs(ExecutableMemberDoc doc, List<String> errors) {
-        boolean result = true;
-        
-        ClassDoc exceptions[] = doc.thrownExceptions();
-        Set<ClassDoc> exceptionSet = new HashSet<ClassDoc>();
-        for (int i = 0; i < exceptions.length; i++) {
-            ClassDoc exception = exceptions[i];
-            if (isRelevantException(exception)) {
-                exceptionSet.add(exception);
-            }
-        }
-
-        ThrowsTag[] throwsTags = doc.throwsTags();
-        Map<ClassDoc, String> throwsTagsMap = new HashMap<ClassDoc, String>();
-        for (int i = 0; i < throwsTags.length; i++) {
-            ThrowsTag throwsTag = throwsTags[i];
-
-            if (throwsTag.exception() == null) {
-                errors.add("Unknown exception \"" + throwsTag.exceptionName() + "\"");
-                result = false;
-            } else if (isRelevantException(throwsTag.exception())) {
-
-                ClassDoc exception = throwsTag.exception();
-                while (exception != null && !exceptionSet.contains(exception)) {
-                    exception = exception.superclass();
-                }
-                if (exception == null) {
-                    errors.add("Unknown exception \"" + throwsTag.exceptionName() + "\"");
-                    result = false;
-                }
-            }
-            
-            throwsTagsMap.put(throwsTag.exception(), throwsTag.exceptionComment());
-        }
-
-        for (int i = 0; i < exceptions.length; i++) {
-            ClassDoc exception = exceptions[i];
-            boolean found = false;
-            
-            for (int j = 0; j < throwsTags.length && !found; j++) {
-                ThrowsTag throwsTag = throwsTags[j];
-                
-                ClassDoc candidate = throwsTag.exception();
-                if (candidate != null) {
-                    if (candidate.equals(exception) || candidate.subclassOf(exception)) {
-                        if (isValidComment(throwsTag.exceptionComment())) {
-                            found = true;
-                        }
-                    }
-                }
-            }
-            
-            if (!found) {
-                errors.add("Undocumented exception \"" + exception.name() + "\"");
-                result = false;
-            }
-        }
-
-        return result;
-    }
-
-    /**
-     * Checks whether an exception needs to be documented. Runtime exceptions
-     * and errors don't necessarily need documentation (although it doesn't
-     * hurt to have it).
-     */
-    private boolean isRelevantException(ClassDoc clazz) {
-        return !(clazz.subclassOf(runtimeException) || clazz.subclassOf(error));
-    }
-    
-    /**
-     * Checks whether the given method has documentation for the return value.
-     */
-    private boolean hasReturnDoc(MethodDoc method, List<String> errors) {
-        boolean result = true;
-        
-        if (!"void".equals(method.returnType().typeName())) {
-            Tag[] returnTags = method.tags("return");
-
-            if (returnTags.length == 0) {
-                errors.add("Missing result.");
-                result = false;
-            }
-
-            for (int i = 0; i < returnTags.length; i++) {
-                Tag tag = returnTags[i];
-                if (!isValidComment(tag.text())) {
-                    errors.add("Insufficient result.");
-                    result = false;
-                }
-            }
-        } else {
-            Tag[] returnTags = method.tags("return");
-            if (returnTags.length != 0) {
-                errors.add("Unknown result.");
-                result = false;
-            }
-        }
-
-        return result;
-    }
-
-    /**
-     * Returns the first sentence for the given documentation element.
-     */
-    private String getFirstSentence(Doc doc) {
-        StringBuilder builder = new StringBuilder();
-
-        Tag[] tags = doc.firstSentenceTags();
-        for (int i = 0; i < tags.length; i++) {
-            Tag tag = tags[i];
-
-            if ("Text".equals(tag.kind())) {
-                builder.append(tag.text());
-            } else {
-                builder.append("{" + tag.toString() + "}");
-            }
-        }
-
-        return builder.toString();
-    }
-
-    /**
-     * Returns the interface method that a given method implements, or null if
-     * the method does not implement any interface method.
-     */
-    private MethodDoc implementedMethod(MethodDoc doc) {
-        ClassDoc clazz = doc.containingClass();
-        MethodDoc myDoc = null;
-        while(clazz != null && myDoc == null){
-        ClassDoc[] interfaces = clazz.interfaces();
-            myDoc = implementedMethod0(doc, interfaces);
-            clazz = clazz.superclass();
-        }
-        return myDoc;
-    }
-
-    /**
-     * Recursive helper method for finding out which interface method a given
-     * method implements.
-     */
-    private MethodDoc implementedMethod0(MethodDoc doc, ClassDoc[] interfaces) {
-        for (int i = 0; i < interfaces.length; i++) {
-            ClassDoc classDoc = interfaces[i];
-
-            MethodDoc[] methods = classDoc.methods();
-            for (int j = 0; j < methods.length; j++) {
-                MethodDoc methodDoc = methods[j];
-                if (doc.overrides(methodDoc)) {
-                    return methodDoc;
-                }
-            }
-        }
-
-        for (int i = 0; i < interfaces.length; i++) {
-            MethodDoc myDoc = implementedMethod0(doc, interfaces[i].interfaces());
-            if (myDoc != null) {
-                return myDoc;
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Checks whether the given documentation element has a "@since" tag for
-     * Android.
-     */
-    private boolean hasSinceTag(Doc doc) {
-        Tag[] tags = doc.tags("since");
-
-        for (int i = 0; i < tags.length; i++) {
-            if ("Android 1.0".equals(tags[i].text())) {
-                return true;
-            }
-        }
-
-        if (doc instanceof MemberDoc) {
-            return hasSinceTag(((MemberDoc)doc).containingClass());
-        }
-        
-        if (doc instanceof ClassDoc) {
-            return hasSinceTag(((ClassDoc)doc).containingPackage());
-        }
-        
-        return false;
-    }
-
-    /**
-     * Checks whether the given documentation element has a "@hide" tag that
-     * excludes it from the official API.
-     */
-    private boolean isHidden(Doc doc) {
-        Tag[] tags = doc.tags("hide");
-
-        return tags != null && tags.length != 0;
-    }
-    
-    /**
-     * Determines the status of an element based on the existence of
-     * documentation, the review status, and any comments it might have.
-     */
-    private int getStatus(boolean documented, boolean reviewed, Tag[] comments) {
-        if (!documented) {
-            return VALUE_RED;
-        } else if (reviewed && comments.length == 0) {
-            return VALUE_GREEN;
-        } else {
-            return VALUE_YELLOW;
-        }
-    }
-
-    /**
-     * Called by JavaDoc to find our which command line arguments are supported
-     * and how many parameters they take. Part of the JavaDoc API.
-     */
-    public static int optionLength(String option) {
-        if ("-d".equals(option)) {
-            return 2;
-        } else if("-Xgeneric".equals(option)){
-            return 1;
-        } else {
-            return 0;
-        }
-    }
-
-    /**
-     * Returns a particular command line argument for a given option.
-     */
-    private static String getOption(RootDoc root, String option, int index, String defValue) {
-        String[][] allOptions = root.options();
-        for (int i = 0; i < allOptions.length; i++) {
-            if (allOptions[i][0].equals(option)) {
-                return allOptions[i][index];
-            }
-        }
-
-        return defValue;
-    }
-    
-    /**
-     * Returns whether the specified option is present.
-     */
-    private static boolean isOptionSet(RootDoc root, String option){
-        String[][] allOptions = root.options();
-        for (int i = 0; i < allOptions.length; i++) {
-            if (allOptions[i][0].equals(option)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Called by JavaDoc to find out which Java version we claim to support.
-     * Part of the JavaDoc API.
-     */
-    public static LanguageVersion languageVersion() {
-        return LanguageVersion.JAVA_1_5;
-    }
-
-    /**
-     * The main entry point called by JavaDoc after all required information has
-     * been collected. Part of the JavaDoc API.
-     */
-    public static boolean start(RootDoc root) {
-        try {
-            String target = getOption(root, "-d", 1, ".");
-            checkTypeParameters = isOptionSet(root, "-Xgeneric");
-
-            SpecProgressDoclet doclet = new SpecProgressDoclet(target);
-            doclet.process(root);
-
-            File file = new File(target, "index.html");
-            System.out.println("Please see complete report in " + 
-                    file.getAbsolutePath());
-            
-        } catch (Exception ex) {
-            ex.printStackTrace();
-            return false;
-        }
-
-        return true;
-    }
-
-}
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/build/CtsBuildHelper.java b/tools/tradefed-host/src/com/android/cts/tradefed/build/CtsBuildHelper.java
index 4a2d56c..9bc0945 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/build/CtsBuildHelper.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/build/CtsBuildHelper.java
@@ -16,6 +16,7 @@
 
 package com.android.cts.tradefed.build;
 
+import com.android.tradefed.build.IBuildInfo;
 import com.android.tradefed.build.IFolderBuildInfo;
 
 import java.io.File;
@@ -57,6 +58,29 @@
     }
 
     /**
+     * A helper factory method that creates and validates a {@link CtsBuildHelper} given an
+     * {@link IBuildInfo}.
+     *
+     * @param build the {@link IBuildInfo}
+     * @return the {@link CtsBuildHelper}
+     * @throws IllegalArgumentException if provided <var>build</var> is not a valid CTS build
+     */
+    public static CtsBuildHelper createBuildHelper(IBuildInfo build) {
+        if (!(build instanceof IFolderBuildInfo)) {
+            throw new IllegalArgumentException(String.format(
+                    "Wrong build type. Expected %s, received %s", IFolderBuildInfo.class.getName(),
+                    build.getClass().getName()));
+        }
+        try {
+            CtsBuildHelper ctsBuild = new CtsBuildHelper((IFolderBuildInfo)build);
+            ctsBuild.validateStructure();
+            return ctsBuild;
+        } catch (FileNotFoundException e) {
+            throw new IllegalArgumentException("Invalid CTS build provided.", e);
+        }
+    }
+
+    /**
      * @return a {@link File} representing the parent folder of the CTS installation
      */
     public File getRootDir() {
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/CtsTest.java b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/CtsTest.java
index 2834793..f6d8142 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/CtsTest.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/CtsTest.java
@@ -22,7 +22,6 @@
 import com.android.ddmlib.Log.LogLevel;
 import com.android.ddmlib.testrunner.TestIdentifier;
 import com.android.tradefed.build.IBuildInfo;
-import com.android.tradefed.build.IFolderBuildInfo;
 import com.android.tradefed.config.Option;
 import com.android.tradefed.device.DeviceNotAvailableException;
 import com.android.tradefed.device.ITestDevice;
@@ -32,7 +31,6 @@
 import com.android.tradefed.testtype.IRemoteTest;
 import com.android.tradefed.testtype.IResumableTest;
 import com.android.tradefed.testtype.IShardableTest;
-import com.android.tradefed.testtype.InstrumentationTest;
 import com.android.tradefed.util.xml.AbstractXmlParser.ParseException;
 
 import java.io.BufferedInputStream;
@@ -119,6 +117,7 @@
     private List<KnownTests> mRemainingTests = null;
 
     private CtsBuildHelper mCtsBuild = null;
+    private IBuildInfo mBuildInfo = null;
 
     /**
      * {@inheritDoc}
@@ -201,17 +200,8 @@
      */
     @Override
     public void setBuild(IBuildInfo build) {
-        if (!(build instanceof IFolderBuildInfo)) {
-            throw new IllegalArgumentException(String.format(
-                    "Wrong build type. Expected %s, received %s", IFolderBuildInfo.class.getName(),
-                    build.getClass().getName()));
-        }
-        try {
-            mCtsBuild = new CtsBuildHelper((IFolderBuildInfo)build);
-            mCtsBuild.validateStructure();
-        } catch (FileNotFoundException e) {
-            throw new IllegalArgumentException("Invalid CTS build provided.", e);
-        }
+        mCtsBuild = CtsBuildHelper.createBuildHelper(build);
+        mBuildInfo = build;
     }
 
     /**
@@ -249,12 +239,10 @@
             if (test instanceof IDeviceTest) {
                 ((IDeviceTest)test).setDevice(getDevice());
             }
-            // Increment the timeout for collecting the tests.
-            // TODO: move this to testPackage.createTest() instead and only increase timeout when
-            // tests number is large.
-            if (test instanceof InstrumentationTest) {
-                ((InstrumentationTest)test).setCollectsTestsShellTimeout(10*60*1000);
+            if (test instanceof IBuildReceiver) {
+                ((IBuildReceiver)test).setBuild(mBuildInfo);
             }
+
             ResultFilter filter = new ResultFilter(listener, testPair.getKnownTests());
             test.run(filter);
             mRemainingTests.remove(0);
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/ITestPackageDef.java b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/ITestPackageDef.java
index e4f13b5..f4258d1 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/ITestPackageDef.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/ITestPackageDef.java
@@ -27,7 +27,7 @@
  * <p/>
  * Knows how to translate this info into a runnable {@link IRemoteTest}.
  */
-interface ITestPackageDef {
+public interface ITestPackageDef {
 
     /**
      * Get the unique URI of the test package.
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/InstrumentationApkTest.java b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/InstrumentationApkTest.java
new file mode 100644
index 0000000..e1bb91e
--- /dev/null
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/InstrumentationApkTest.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.cts.tradefed.testtype;
+
+import com.android.cts.tradefed.build.CtsBuildHelper;
+import com.android.ddmlib.Log;
+import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.result.ITestInvocationListener;
+import com.android.tradefed.testtype.IBuildReceiver;
+import com.android.tradefed.testtype.InstrumentationTest;
+
+import java.io.FileNotFoundException;
+import java.util.ArrayList;
+import java.util.Collection;
+
+import junit.framework.Assert;
+
+/**
+ * A {@link InstrumentationTest] that will install CTS apks before test execution,
+ * and uninstall on execution completion.
+ */
+public class InstrumentationApkTest extends InstrumentationTest implements IBuildReceiver {
+
+    private static final String LOG_TAG = "InstrumentationApkTest";
+
+    /** the file names of the CTS apks to install */
+    private Collection<String> mInstallFileNames = new ArrayList<String>();
+    private Collection<String> mUninstallPackages = new ArrayList<String>();
+
+    private CtsBuildHelper mCtsBuild = null;
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setBuild(IBuildInfo build) {
+        mCtsBuild  = CtsBuildHelper.createBuildHelper(build);
+    }
+
+    /**
+     * Add an apk to install.
+     *
+     * @param apkFileName the apk file name
+     * @param packageName the apk's Android package name
+     */
+    public void addInstallApk(String apkFileName, String packageName) {
+        mInstallFileNames.add(apkFileName);
+        mUninstallPackages.add(packageName);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void run(final ITestInvocationListener listener)
+            throws DeviceNotAvailableException {
+        Assert.assertNotNull("missing device", getDevice());
+        Assert.assertNotNull("missing build", mCtsBuild);
+
+        try {
+            for (String apkFileName : mInstallFileNames) {
+                Log.d(LOG_TAG, String.format("Installing %s on %s", apkFileName,
+                        getDevice().getSerialNumber()));
+                try {
+                    getDevice().installPackage(mCtsBuild.getTestApp(apkFileName), true);
+                } catch (FileNotFoundException e) {
+                    Log.e(LOG_TAG, e);
+                }
+            }
+            super.run(listener);
+        } finally {
+            for (String packageName : mUninstallPackages) {
+                Log.d(LOG_TAG, String.format("Uninstalling %s on %s", packageName,
+                        getDevice().getSerialNumber()));
+                getDevice().uninstallPackage(packageName);
+            }
+        }
+    }
+}
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/InstrumentationAppTest.java b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/InstrumentationAppTest.java
deleted file mode 100644
index 47fc14a..0000000
--- a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/InstrumentationAppTest.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.cts.tradefed.testtype;
-
-import com.android.ddmlib.Log;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.result.ITestInvocationListener;
-import com.android.tradefed.testtype.InstrumentationTest;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.Collection;
-
-/**
- * A {@link InstrumentationTest] that will install other dependent apks before test execution,
- * and uninstall apps on execution completion.
- */
-public class InstrumentationAppTest extends InstrumentationTest {
-
-    private static final String LOG_TAG = "InstrumentationAppTest";
-
-    // TODO: consider moving this class to tradefed proper
-
-    private Collection<File> mInstallFiles = new ArrayList<File>();
-    private Collection<String> mInstallPackages = new ArrayList<String>();
-
-    /**
-     * Add a dependent apk to install.
-     *
-     * @param apkFile the apk file
-     * @param packageName the apk's Android package name
-     */
-    public void addInstallApp(File apkFile, String packageName) {
-        mInstallFiles.add(apkFile);
-        mInstallPackages.add(packageName);
-    }
-
-    @Override
-    public void run(final ITestInvocationListener listener)
-            throws DeviceNotAvailableException {
-        if (getDevice() == null) {
-            throw new IllegalStateException("missing device");
-        }
-        try {
-            for (File apkFile : mInstallFiles) {
-                Log.d(LOG_TAG, String.format("Installing %s on %s", apkFile.getName(),
-                        getDevice().getSerialNumber()));
-                getDevice().installPackage(apkFile, true);
-            }
-            super.run(listener);
-        } finally {
-            for (String packageName : mInstallPackages) {
-                Log.d(LOG_TAG, String.format("Uninstalling %s on %s", packageName,
-                        getDevice().getSerialNumber()));
-                getDevice().uninstallPackage(packageName);
-            }
-        }
-    }
-}
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/JarHostTest.java b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/JarHostTest.java
index 041079d..2fe6802 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/JarHostTest.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/JarHostTest.java
@@ -15,12 +15,15 @@
  */
 package com.android.cts.tradefed.testtype;
 
+import com.android.cts.tradefed.build.CtsBuildHelper;
 import com.android.ddmlib.Log;
 import com.android.ddmlib.testrunner.TestIdentifier;
+import com.android.tradefed.build.IBuildInfo;
 import com.android.tradefed.device.DeviceNotAvailableException;
 import com.android.tradefed.device.ITestDevice;
 import com.android.tradefed.result.ITestInvocationListener;
 import com.android.tradefed.result.JUnitToInvocationResultForwarder;
+import com.android.tradefed.testtype.IBuildReceiver;
 import com.android.tradefed.testtype.IDeviceTest;
 import com.android.tradefed.testtype.IRemoteTest;
 import com.android.tradefed.util.CommandStatus;
@@ -28,6 +31,7 @@
 import com.android.tradefed.util.RunUtil;
 
 import java.io.File;
+import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.net.URL;
 import java.net.URLClassLoader;
@@ -39,29 +43,50 @@
 import junit.framework.TestResult;
 
 /**
- * A {@link IRemoteTest} that can run a set of JUnit tests from a jar.
+ * A {@link IRemoteTest} that can run a set of JUnit tests from a CTS jar.
  */
-public class JarHostTest implements IDeviceTest, IRemoteTest {
+public class JarHostTest implements IDeviceTest, IRemoteTest, IBuildReceiver {
 
     private static final String LOG_TAG = "JarHostTest";
 
     private ITestDevice mDevice;
-    private File mJarFile;
+    private String mJarFileName;
     private Collection<TestIdentifier> mTests;
     private long mTimeoutMs = 10 * 60 * 1000;
     private String mRunName;
-    private String mTestAppPath;
+    private CtsBuildHelper mCtsBuild = null;
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setBuild(IBuildInfo buildInfo) {
+        mCtsBuild = CtsBuildHelper.createBuildHelper(buildInfo);
+    }
+
+    /**
+     * Set the CTS build container.
+     * <p/>
+     * Exposed so unit tests can mock the provided build.
+     *
+     * @param buildHelper
+     */
+    void setBuildHelper(CtsBuildHelper buildHelper) {
+        mCtsBuild = buildHelper;
+    }
 
     /**
      * Set the jar file to load tests from.
-     * @param jarFile
+     *
+     * @param jarFileName the file name of the CTS host test jar to use
      */
-    void setJarFile(File jarFile) {
-        mJarFile = jarFile;
+    void setJarFileName(String jarFileName) {
+        mJarFileName = jarFileName;
     }
 
     /**
      * Sets the collection of tests to run
+     *
      * @param tests
      */
     void setTests(Collection<TestIdentifier> tests) {
@@ -90,17 +115,6 @@
     }
 
     /**
-     * Set the filesystem path to test app artifacts needed to run tests.
-     *
-     * @see {@link com.android.hosttest.DeviceTest#setTestAppPath(String)}
-     *
-     * @param testAppPath
-     */
-    void setTestAppPath(String testAppPath) {
-        mTestAppPath = testAppPath;
-    }
-
-    /**
      * {@inheritDoc}
      */
     @Override
@@ -153,7 +167,7 @@
             // all host tests are converted to use tradefed
             com.android.hosttest.DeviceTest deviceTest = (com.android.hosttest.DeviceTest)junitTest;
             deviceTest.setDevice(getDevice().getIDevice());
-            deviceTest.setTestAppPath(mTestAppPath);
+            deviceTest.setTestAppPath(mCtsBuild.getTestCasesDir().getAbsolutePath());
         }
         CommandStatus status = RunUtil.getInstance().runTimed(mTimeoutMs, new IRunnableResult() {
 
@@ -183,7 +197,8 @@
      */
     private Test loadTest(String className, String testName) {
         try {
-            URL urls[] = {mJarFile.getCanonicalFile().toURI().toURL()};
+            File jarFile = mCtsBuild.getTestApp(mJarFileName);
+            URL urls[] = {jarFile.getCanonicalFile().toURI().toURL()};
             Class<?> testClass = loadClass(className, urls);
 
             if (TestCase.class.isAssignableFrom(testClass)) {
@@ -195,16 +210,16 @@
                 return test;
             } else {
                 Log.e(LOG_TAG, String.format("Class '%s' from jar '%s' is not a Test",
-                        className, mJarFile.getAbsolutePath()));
+                        className, mJarFileName));
             }
         } catch (ClassNotFoundException e) {
-            reportLoadError(mJarFile, className, e);
+            reportLoadError(mJarFileName, className, e);
         } catch (IllegalAccessException e) {
-            reportLoadError(mJarFile, className, e);
+            reportLoadError(mJarFileName, className, e);
         } catch (IOException e) {
-            reportLoadError(mJarFile, className, e);
+            reportLoadError(mJarFileName, className, e);
         } catch (InstantiationException e) {
-            reportLoadError(mJarFile, className, e);
+            reportLoadError(mJarFileName, className, e);
         }
         return null;
     }
@@ -225,9 +240,9 @@
         return testClass;
     }
 
-    private void reportLoadError(File jarFile, String className, Exception e) {
+    private void reportLoadError(String jarFileName, String className, Exception e) {
         Log.e(LOG_TAG, String.format("Failed to load test class '%s' from jar '%s'",
-                className, jarFile.getAbsolutePath()));
+                className, jarFileName));
         Log.e(LOG_TAG, e);
     }
 
@@ -241,11 +256,21 @@
         if (mDevice == null) {
             throw new IllegalArgumentException("Device has not been set");
         }
-        if (mJarFile == null) {
-            throw new IllegalArgumentException("jar file has not been set");
+        if (mJarFileName == null) {
+            throw new IllegalArgumentException("jar file name has not been set");
         }
         if (mTests == null) {
             throw new IllegalArgumentException("tests has not been set");
         }
+        if (mCtsBuild == null) {
+            throw new IllegalArgumentException("build has not been set");
+        }
+        try {
+            mCtsBuild.getTestApp(mJarFileName);
+        } catch (FileNotFoundException e) {
+            throw new IllegalArgumentException(String.format(
+                    "Could not find jar %s in CTS build %s", mJarFileName,
+                    mCtsBuild.getRootDir().getAbsolutePath()));
+        }
     }
 }
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/TestPackageDef.java b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/TestPackageDef.java
index fd896f2..04da318 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/TestPackageDef.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/TestPackageDef.java
@@ -136,8 +136,7 @@
             Log.d(LOG_TAG, String.format("Creating host test for %s", mName));
             JarHostTest hostTest = new JarHostTest();
             hostTest.setRunName(mName);
-            hostTest.setJarFile(new File(testCaseDir, mJarPath));
-            hostTest.setTestAppPath(testCaseDir.getAbsolutePath());
+            hostTest.setJarFileName(mJarPath);
             hostTest.setTests(filterTests(mTests, className, methodName));
             return hostTest;
         } else if (mIsSignatureTest) {
@@ -145,7 +144,7 @@
             // points to specialized instrumentation. Eventually this special case for signatureTest
             // can be removed, and it can be treated just like a normal InstrumentationTest
             Log.d(LOG_TAG, String.format("Creating signature test %s", mName));
-            InstrumentationTest instrTest = new InstrumentationTest();
+            InstrumentationApkTest instrTest = new InstrumentationApkTest();
             instrTest.setPackageName(mAppNameSpace);
             instrTest.setRunnerName("android.test.InstrumentationTestRunner");
             instrTest.setClassName(SIGNATURE_TEST_CLASS);
@@ -153,34 +152,22 @@
             // add signature test to list of known tests
             addTest(new TestIdentifier(SIGNATURE_TEST_CLASS, SIGNATURE_TEST_METHOD));
             // mName means 'apk file name' for instrumentation tests
-            File apkFile = new File(testCaseDir, String.format("%s.apk", mName));
-            if (!apkFile.exists()) {
-                Log.w(LOG_TAG, String.format("Could not find apk file %s",
-                        apkFile.getAbsolutePath()));
-                return null;
-            }
-            instrTest.setInstallFile(apkFile);
+            instrTest.addInstallApk(String.format("%s.apk", mName), mAppNameSpace);
             return instrTest;
         } else if (mIsReferenceAppTest) {
             // a reference app test is just a InstrumentationTest with one extra apk to install
-            InstrumentationAppTest instrTest = new InstrumentationAppTest();
-            File apkFile = new File(testCaseDir, String.format("%s.apk", mApkToTestName));
-            if (!apkFile.exists()) {
-                Log.w(LOG_TAG, String.format("Could not find apk file %s",
-                        apkFile.getAbsolutePath()));
-                return null;
-            }
-            instrTest.addInstallApp(apkFile, mPackageToTest);
-            return setInstrumentationTest(testCaseDir, className, methodName, instrTest);
+            InstrumentationApkTest instrTest = new InstrumentationApkTest();
+            instrTest.addInstallApk(String.format("%s.apk", mApkToTestName), mPackageToTest);
+            return setInstrumentationTest(className, methodName, instrTest);
         } else {
             Log.d(LOG_TAG, String.format("Creating instrumentation test for %s", mName));
-            InstrumentationTest instrTest = new InstrumentationTest();
-            return setInstrumentationTest(testCaseDir, className, methodName, instrTest);
+            InstrumentationApkTest instrTest = new InstrumentationApkTest();
+            return setInstrumentationTest(className, methodName, instrTest);
         }
     }
 
     /**
-     * Populates given {@link InstrumentationTest} with data from the package xml
+     * Populates given {@link InstrumentationApkTest} with data from the package xml
      *
      * @param testCaseDir
      * @param className
@@ -188,20 +175,18 @@
      * @param instrTest
      * @return the populated {@link InstrumentationTest} or <code>null</code>
      */
-    private InstrumentationTest setInstrumentationTest(File testCaseDir, String className,
-            String methodName, InstrumentationTest instrTest) {
+    private InstrumentationApkTest setInstrumentationTest(String className,
+            String methodName, InstrumentationApkTest instrTest) {
         instrTest.setPackageName(mAppNameSpace);
         instrTest.setRunnerName(mRunner);
         instrTest.setClassName(className);
         instrTest.setMethodName(methodName);
         // mName means 'apk file name' for instrumentation tests
-        File apkFile = new File(testCaseDir, String.format("%s.apk", mName));
-        if (!apkFile.exists()) {
-            Log.w(LOG_TAG, String.format("Could not find apk file %s",
-                    apkFile.getAbsolutePath()));
-            return null;
+        instrTest.addInstallApk(String.format("%s.apk", mName), mAppNameSpace);
+        if (mTests.size() > 1000) {
+            // TODO: hack, large test suites can take longer to collect tests, increase timeout
+            instrTest.setCollectsTestsShellTimeout(10*60*1000);
         }
-        instrTest.setInstallFile(apkFile);
         return instrTest;
     }
 
diff --git a/tools/tradefed-host/tests/src/com/android/cts/tradefed/testtype/JarHostTestTest.java b/tools/tradefed-host/tests/src/com/android/cts/tradefed/testtype/JarHostTestTest.java
index 9a49b77..dfe4413 100644
--- a/tools/tradefed-host/tests/src/com/android/cts/tradefed/testtype/JarHostTestTest.java
+++ b/tools/tradefed-host/tests/src/com/android/cts/tradefed/testtype/JarHostTestTest.java
@@ -15,6 +15,7 @@
  */
 package com.android.cts.tradefed.testtype;
 
+import com.android.cts.tradefed.build.StubCtsBuildHelper;
 import com.android.ddmlib.testrunner.TestIdentifier;
 import com.android.tradefed.device.DeviceNotAvailableException;
 import com.android.tradefed.device.ITestDevice;
@@ -22,7 +23,6 @@
 
 import org.easymock.EasyMock;
 
-import java.io.File;
 import java.net.URL;
 import java.util.ArrayList;
 import java.util.Collection;
@@ -37,6 +37,8 @@
 
     private static final String RUN_NAME = "run";
     private JarHostTest mJarTest;
+    private StubCtsBuildHelper mStubBuildHelper;
+
 
     @Override
     protected void setUp() throws Exception {
@@ -48,6 +50,8 @@
                 return MockTest.class;
             }
         };
+        mStubBuildHelper = new StubCtsBuildHelper();
+        mJarTest.setBuildHelper(mStubBuildHelper);
     }
 
     public static class MockTest extends TestCase {
@@ -80,7 +84,7 @@
         listener.testRunEnded(EasyMock.anyLong(), EasyMock.eq(Collections.EMPTY_MAP));
         mJarTest.setTests(tests);
         mJarTest.setDevice(EasyMock.createMock(ITestDevice.class));
-        mJarTest.setJarFile(new File("fakefile"));
+        mJarTest.setJarFileName("fakefile");
         mJarTest.setRunName(RUN_NAME);
 
         EasyMock.replay(listener);
diff --git a/tools/utils/buildCts.py b/tools/utils/buildCts.py
index 7d4b6e0..4daf48e 100755
--- a/tools/utils/buildCts.py
+++ b/tools/utils/buildCts.py
@@ -23,7 +23,7 @@
 import sys
 import xml.dom.minidom as dom
 from cts import tools
-
+from multiprocessing import Pool
 
 def GetSubDirectories(root):
   """Return all directories under the given root directory."""
@@ -72,174 +72,24 @@
     self.test_repository = os.path.join(self.out_dir, 'repository/testcases')
     self.plan_repository = os.path.join(self.out_dir, 'repository/plans')
 
-  def __LogGenerateDescription(self, name):
-    print 'Generating test description for package %s' % name
-
-  def RunDescriptionGeneratorDoclet(self, source_root, output_file):
-    """Generate a test package description by running the DescriptionGenerator doclet.
-
-    Args:
-      source_root: Directory under which tests should be searched.
-      output_file: Name of the file where the description gets written.
-
-    Returns:
-      The exit code of the DescriptionGenerator doclet run.
-    """
-    # Make sure sourceRoot is relative to  self.android_root
-    source_root = self.RelPath(source_root, self.android_root)
-
-    # To determine whether a class is a JUnit test, the Doclet needs to have all intermediate
-    # subclasses of TestCase as well as the JUnit framework itself on the source path.
-    # Annotation classes are also required, since test annotations go into the description.
-    source_path = [
-        'frameworks/base/core/java',            # android test classes
-        'frameworks/base/test-runner/src',      # test runner
-        'libcore/junit/src/main/java',          # junit classes
-        'development/tools/hosttestlib/src',    # hosttestlib TestCase extensions
-        'libcore/dalvik/src/main/java',         # test annotations
-        'cts/libs/annotation/src',              # cts annotations
-        'cts/tests/src',                        # cts test stubs
-        source_root                             # the source for this package
-    ]
-    source_path = [os.path.join(self.android_root, x) for x in source_path]
-    cmd = ('javadoc -o %s -J-Xmx512m -quiet -doclet DescriptionGenerator -docletpath %s'
-           ' -sourcepath %s ') % (output_file, self.doclet_path, ':'.join(source_path))
-    sources = []
-
-    def AddFile(sources, folder, names):
-      """Find *.java."""
-      sources.extend([os.path.join(folder, name) for name in names if name.endswith('.java')])
-
-    os.path.walk(os.path.join(self.android_root, source_root), AddFile, sources)
-    cmd += ' '.join(sources)
-    proc = subprocess.Popen(cmd, shell=True, stderr=subprocess.STDOUT, stdout=subprocess.PIPE)
-    # read and discard any output
-    proc.communicate()
-    # wait for process to terminate and return exit value
-    return proc.wait()
-
-  def GenerateSignatureCheckDescription(self):
-    """Generate the test description for the signature check."""
-    self.__LogGenerateDescription('android.tests.sigtest')
-    package = tools.TestPackage('SignatureTest', 'android.tests.sigtest')
-    package.AddAttribute('appNameSpace', 'android.tests.sigtest')
-    package.AddAttribute('signatureCheck', 'true')
-    package.AddAttribute('runner', '.InstrumentationRunner')
-    package.AddTest('android.tests.sigtest.SignatureTest.signatureTest')
-    description = open(os.path.join(self.test_repository, 'SignatureTest.xml'), 'w')
-    package.WriteDescription(description)
-    description.close()
-
-  def GenerateReferenceAppDescription(self):
-    """Generate the test description for the reference app tests."""
-    self.__LogGenerateDescription('android.apidemos.cts')
-    package = tools.TestPackage('ApiDemosReferenceTest', 'android.apidemos.cts')
-    package.AddAttribute('appNameSpace', 'android.apidemos.cts')
-    package.AddAttribute('packageToTest', 'com.example.android.apis')
-    package.AddAttribute('apkToTestName', 'ApiDemos')
-    package.AddAttribute('runner', 'android.test.InstrumentationTestRunner')
-    package.AddAttribute('referenceAppTest', 'true')
-    package.AddTest('android.apidemos.cts.ApiDemosTest.testNumberOfItemsInListView')
-    description = open(os.path.join(self.test_repository, 'ApiDemosReferenceTest.xml'), 'w')
-    package.WriteDescription(description)
-    description.close()
-
-  def GenerateAppSecurityDescription(self):
-    """Generate the test description for the application security tests."""
-    test_root = 'cts/tests/appsecurity-tests'
-    makefile_name = os.path.join(test_root, 'Android.mk')
-    makefile_vars = GetMakeFileVars(makefile_name)
-    name = makefile_vars['LOCAL_MODULE']
-    package_name = 'android.tests.appsecurity'
-    self.__LogGenerateDescription(package_name)
-    temp_desc = os.path.join(self.temp_dir, 'description.xml')
-    self.RunDescriptionGeneratorDoclet(os.path.join(test_root, 'src'), temp_desc)
-    doc = dom.parse(temp_desc)
-    test_description = doc.getElementsByTagName('TestPackage')[0]
-    test_description.setAttribute('name', package_name)
-    test_description.setAttribute('appPackageName', package_name)
-    test_description.setAttribute('hostSideOnly', 'true')
-    test_description.setAttribute('jarPath', name + '.jar')
-    description = open(os.path.join(self.test_repository, package_name + '.xml'), 'w')
-    doc.writexml(description, addindent='    ', encoding='UTF-8')
-    description.close()
-
-  @staticmethod
-  def RelPath(path, start=os.getcwd()):
-    """Get a relative version of a path.
-
-    This is equivalent to os.path.relpath, which is only available since Python 2.6.
-
-    Args:
-      path: The path to transform.
-      start: The base path. Defaults to the current working directory.
-
-    Returns:
-      A transformed path that is relative to start.
-    """
-    path_dirs = os.path.abspath(path).split(os.path.sep)
-    start_dirs = os.path.abspath(start).split(os.path.sep)
-
-    num_common = len(os.path.commonprefix([start_dirs, path_dirs]))
-
-    result_dirs = ['..'] * (len(start_dirs) - num_common) + path_dirs[num_common:]
-    if result_dirs:
-      return os.path.join(*result_dirs)
-    return start
-
   def GenerateTestDescriptions(self):
     """Generate test descriptions for all packages."""
+    pool = Pool(processes=16)
+
     # individually generate descriptions not following conventions
-    self.GenerateSignatureCheckDescription()
-    self.GenerateReferenceAppDescription()
-    self.GenerateAppSecurityDescription()
+    pool.apply_async(GenerateSignatureCheckDescription, [self.test_repository])
+    pool.apply_async(GenerateReferenceAppDescription, [self.test_repository])
+    pool.apply_async(GenerateAppSecurityDescription, [self.temp_dir,
+        self.test_repository, self.android_root, self.doclet_path])
 
     # generate test descriptions for android tests
     android_packages = GetSubDirectories(self.test_root)
     for package in android_packages:
-      app_package_name = 'android.' + package
-      package_root = os.path.join(self.test_root, package)
+      pool.apply_async(GenerateTestDescription, [self.test_root, self.temp_dir,
+          self.test_repository, self.android_root, self.doclet_path, package])
 
-      makefile_name = os.path.join(package_root, 'Android.mk')
-      if not os.path.exists(makefile_name):
-        print 'Skipping directory "%s" due to missing Android.mk' % package_root
-        continue
-      makefile_vars = GetMakeFileVars(makefile_name)
-
-      manifest_name = os.path.join(package_root, 'AndroidManifest.xml')
-      if not os.path.exists(manifest_name):
-        print 'Skipping directory "%s" due to missing AndroidManifest.xml' % package_root
-        continue
-      manifest = tools.XmlFile(manifest_name)
-
-      self.__LogGenerateDescription(app_package_name)
-
-      # Run the description generator doclet to get the test package structure
-      # TODO: The Doclet does not currently add all required attributes. Instead of rewriting
-      # the document below, additional attributes should be passed to the Doclet as arguments.
-      temp_desc = os.path.join(self.temp_dir, 'description.xml')
-      self.RunDescriptionGeneratorDoclet(package_root, temp_desc)
-
-      # obtain missing attribute values from the makefile and manifest
-      package_name = makefile_vars['LOCAL_PACKAGE_NAME']
-      runner = manifest.GetAndroidAttr('instrumentation', 'name')
-      target_package = manifest.GetAndroidAttr('instrumentation', 'targetPackage')
-      target_binary_name = makefile_vars.get('LOCAL_INSTRUMENTATION_FOR')
-
-      # add them to the document
-      doc = dom.parse(temp_desc)
-      test_description = doc.getElementsByTagName('TestPackage')[0]
-      test_description.setAttribute('name', package_name)
-      test_description.setAttribute('runner', runner)
-      test_package = manifest.GetAttr('manifest', 'package')
-      test_description.setAttribute('appNameSpace', test_package)
-      test_description.setAttribute('appPackageName', app_package_name)
-      if not test_package == target_package:
-        test_description.setAttribute('targetNameSpace', target_package)
-        test_description.setAttribute('targetBinaryName', target_binary_name)
-      description = open(os.path.join(self.test_repository, package_name + '.xml'), 'w')
-      doc.writexml(description, addindent='    ', encoding='UTF-8')
-      description.close()
+    pool.close()
+    pool.join()
 
   def __WritePlan(self, plan, plan_name):
     print 'Generating test plan %s' % plan_name
@@ -286,6 +136,170 @@
     plan.Include(r'android\.tests\.appsecurity')
     self.__WritePlan(plan, 'AppSecurity')
 
+def LogGenerateDescription(name):
+  print 'Generating test description for package %s' % name
+
+def GenerateSignatureCheckDescription(test_repository):
+  """Generate the test description for the signature check."""
+  LogGenerateDescription('android.tests.sigtest')
+  package = tools.TestPackage('SignatureTest', 'android.tests.sigtest')
+  package.AddAttribute('appNameSpace', 'android.tests.sigtest')
+  package.AddAttribute('signatureCheck', 'true')
+  package.AddAttribute('runner', '.InstrumentationRunner')
+  package.AddTest('android.tests.sigtest.SignatureTest.signatureTest')
+  description = open(os.path.join(test_repository, 'SignatureTest.xml'), 'w')
+  package.WriteDescription(description)
+  description.close()
+
+def GenerateReferenceAppDescription(test_repository):
+  """Generate the test description for the reference app tests."""
+  LogGenerateDescription('android.apidemos.cts')
+  package = tools.TestPackage('ApiDemosReferenceTest', 'android.apidemos.cts')
+  package.AddAttribute('appNameSpace', 'android.apidemos.cts')
+  package.AddAttribute('packageToTest', 'com.example.android.apis')
+  package.AddAttribute('apkToTestName', 'ApiDemos')
+  package.AddAttribute('runner', 'android.test.InstrumentationTestRunner')
+  package.AddAttribute('referenceAppTest', 'true')
+  package.AddTest('android.apidemos.cts.ApiDemosTest.testNumberOfItemsInListView')
+  description = open(os.path.join(test_repository, 'ApiDemosReferenceTest.xml'), 'w')
+  package.WriteDescription(description)
+  description.close()
+
+def GenerateAppSecurityDescription(temp_dir, test_repository, android_root, doclet_path):
+  """Generate the test description for the application security tests."""
+  test_root = 'cts/tests/appsecurity-tests'
+  makefile_name = os.path.join(test_root, 'Android.mk')
+  makefile_vars = GetMakeFileVars(makefile_name)
+  name = makefile_vars['LOCAL_MODULE']
+  package_name = 'android.tests.appsecurity'
+  LogGenerateDescription(package_name)
+  temp_desc = os.path.join(temp_dir, 'description.xml')
+  RunDescriptionGeneratorDoclet(android_root, doclet_path,
+      os.path.join(test_root, 'src'), temp_desc)
+  doc = dom.parse(temp_desc)
+  test_description = doc.getElementsByTagName('TestPackage')[0]
+  test_description.setAttribute('name', package_name)
+  test_description.setAttribute('appPackageName', package_name)
+  test_description.setAttribute('hostSideOnly', 'true')
+  test_description.setAttribute('jarPath', name + '.jar')
+  description = open(os.path.join(test_repository, package_name + '.xml'), 'w')
+  doc.writexml(description, addindent='    ', encoding='UTF-8')
+  description.close()
+
+
+def GenerateTestDescription(test_root, temp_dir, test_repository, android_root,
+                            doclet_path, package):
+
+  app_package_name = 'android.' + package
+  package_root = os.path.join(test_root, package)
+
+  makefile_name = os.path.join(package_root, 'Android.mk')
+  if not os.path.exists(makefile_name):
+    print 'Skipping directory "%s" due to missing Android.mk' % package_root
+    return
+  makefile_vars = GetMakeFileVars(makefile_name)
+
+  manifest_name = os.path.join(package_root, 'AndroidManifest.xml')
+  if not os.path.exists(manifest_name):
+    print 'Skipping directory "%s" due to missing AndroidManifest.xml' % package_root
+    return
+  manifest = tools.XmlFile(manifest_name)
+
+  LogGenerateDescription(app_package_name)
+
+  # Run the description generator doclet to get the test package structure
+  # TODO: The Doclet does not currently add all required attributes. Instead of rewriting
+  # the document below, additional attributes should be passed to the Doclet as arguments.
+  temp_desc = os.path.join(temp_dir, app_package_name + '-description.xml')
+
+  RunDescriptionGeneratorDoclet(android_root, doclet_path, package_root, temp_desc)
+
+  # obtain missing attribute values from the makefile and manifest
+  package_name = makefile_vars['LOCAL_PACKAGE_NAME']
+  runner = manifest.GetAndroidAttr('instrumentation', 'name')
+  target_package = manifest.GetAndroidAttr('instrumentation', 'targetPackage')
+  target_binary_name = makefile_vars.get('LOCAL_INSTRUMENTATION_FOR')
+
+  # add them to the document
+  doc = dom.parse(temp_desc)
+  test_description = doc.getElementsByTagName('TestPackage')[0]
+  test_description.setAttribute('name', package_name)
+  test_description.setAttribute('runner', runner)
+  test_package = manifest.GetAttr('manifest', 'package')
+  test_description.setAttribute('appNameSpace', test_package)
+  test_description.setAttribute('appPackageName', app_package_name)
+  if not test_package == target_package:
+    test_description.setAttribute('targetNameSpace', target_package)
+    test_description.setAttribute('targetBinaryName', target_binary_name)
+  description = open(os.path.join(test_repository, package_name + '.xml'), 'w')
+  doc.writexml(description, addindent='    ', encoding='UTF-8')
+  description.close()
+
+def RunDescriptionGeneratorDoclet(android_root, doclet_path, source_root, output_file):
+  """Generate a test package description by running the DescriptionGenerator doclet.
+
+  Args:
+    android_root: Root directory of the Android source tree.
+    doclet_path: Class path where the DescriptionGenerator doclet can be found.
+    source_root: Directory under which tests should be searched.
+    output_file: Name of the file where the description gets written.
+
+  Returns:
+    The exit code of the DescriptionGenerator doclet run.
+  """
+  # Make sure sourceRoot is relative to  self.android_root
+  source_root = RelPath(source_root, android_root)
+
+  # To determine whether a class is a JUnit test, the Doclet needs to have all intermediate
+  # subclasses of TestCase as well as the JUnit framework itself on the source path.
+  # Annotation classes are also required, since test annotations go into the description.
+  source_path = [
+      'frameworks/base/core/java',            # android test classes
+      'frameworks/base/test-runner/src',      # test runner
+      'libcore/junit/src/main/java',          # junit classes
+      'development/tools/hosttestlib/src',    # hosttestlib TestCase extensions
+      'libcore/dalvik/src/main/java',         # test annotations
+      'cts/tests/src',                        # cts test stubs
+      source_root                             # the source for this package
+  ]
+  source_path = [os.path.join(android_root, x) for x in source_path]
+  cmd = ('javadoc -o %s -J-Xmx512m -quiet -doclet DescriptionGenerator -docletpath %s'
+         ' -sourcepath %s ') % (output_file, doclet_path, ':'.join(source_path))
+  sources = []
+
+  def AddFile(sources, folder, names):
+    """Find *.java."""
+    sources.extend([os.path.join(folder, name) for name in names if name.endswith('.java')])
+
+  os.path.walk(os.path.join(android_root, source_root), AddFile, sources)
+  cmd += ' '.join(sources)
+  proc = subprocess.Popen(cmd, shell=True, stderr=subprocess.STDOUT, stdout=subprocess.PIPE)
+  # read and discard any output
+  proc.communicate()
+  # wait for process to terminate and return exit value
+  return proc.wait()
+
+def RelPath(path, start=os.getcwd()):
+  """Get a relative version of a path.
+
+  This is equivalent to os.path.relpath, which is only available since Python 2.6.
+
+  Args:
+    path: The path to transform.
+    start: The base path. Defaults to the current working directory.
+
+  Returns:
+    A transformed path that is relative to start.
+  """
+  path_dirs = os.path.abspath(path).split(os.path.sep)
+  start_dirs = os.path.abspath(start).split(os.path.sep)
+
+  num_common = len(os.path.commonprefix([start_dirs, path_dirs]))
+
+  result_dirs = ['..'] * (len(start_dirs) - num_common) + path_dirs[num_common:]
+  if result_dirs:
+    return os.path.join(*result_dirs)
+  return start
 
 if __name__ == '__main__':
   builder = CtsBuilder(sys.argv)
diff --git a/tools/utils/startcts b/tools/utils/startcts
index b0cb9ef..4db28b2 100755
--- a/tools/utils/startcts
+++ b/tools/utils/startcts
@@ -53,14 +53,13 @@
 CTS_LIB=${CTS_ROOT}/tools/cts.jar
 JUNIT_LIB=${CTS_ROOT}/tools/junit.jar
 HOSTTEST_LIB=${CTS_ROOT}/tools/hosttestlib.jar
-CTS_TEST_ANNOTATIONS_HOST_LIB=${CTS_ROOT}/tools/CtsTestAnnotationsHostLib.jar
 
 checkFile ${DDM_LIB}
 checkFile ${CTS_LIB}
 checkFile ${JUNIT_LIB}
 checkFile ${HOSTTEST_LIB}
 
-JARS=${CTS_LIB}:${DDM_LIB}:${JUNIT_LIB}:${HOSTTEST_LIB}:${CTS_TEST_ANNOTATIONS_HOST_LIB}
+JARS=${CTS_LIB}:${DDM_LIB}:${JUNIT_LIB}:${HOSTTEST_LIB}
 
 # Add SDK_ROOT to the PATH for backwards compatibility with prior startcts
 # commands that required SDK_ROOT to find adb.
