am c4fb4472: am 23cfdd20: Merge "Expect "jpg", not "jpeg", in testGuessFileName" into lmp-mr1-dev

* commit 'c4fb447213634dd386075d7caa510d503fda5789':
  Expect "jpg", not "jpeg", in testGuessFileName
diff --git a/CtsTestCaseList.mk b/CtsTestCaseList.mk
index 16f9ec1..0581a5d 100644
--- a/CtsTestCaseList.mk
+++ b/CtsTestCaseList.mk
@@ -109,6 +109,7 @@
     CtsAdminTestCases \
     CtsAnimationTestCases \
     CtsAppTestCases \
+    CtsAppWidgetTestCases \
     CtsBluetoothTestCases \
     CtsCalendarcommon2TestCases \
     CtsContentTestCases \
diff --git a/apps/CtsVerifier/AndroidManifest.xml b/apps/CtsVerifier/AndroidManifest.xml
index 50edde6..c64a71d 100644
--- a/apps/CtsVerifier/AndroidManifest.xml
+++ b/apps/CtsVerifier/AndroidManifest.xml
@@ -18,7 +18,7 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
       package="com.android.cts.verifier"
       android:versionCode="5"
-      android:versionName="5.0_r1.93">
+      android:versionName="5.0_r1.91">
 
     <uses-sdk android:minSdkVersion="19" android:targetSdkVersion="21"/>
 
diff --git a/apps/CtsVerifier/proguard.flags b/apps/CtsVerifier/proguard.flags
index ca4680f..fe7eed8 100644
--- a/apps/CtsVerifier/proguard.flags
+++ b/apps/CtsVerifier/proguard.flags
@@ -19,3 +19,5 @@
 -dontwarn android.hardware.Sensor
 -dontwarn android.test.AndroidTestRunner
 -dontwarn java.util.concurrent.ConcurrentLinkedDeque
+-dontwarn android.cts.util.**
+-dontwarn junit.**
diff --git a/libs/deviceutil/src/android/cts/util/MediaUtils.java b/libs/deviceutil/src/android/cts/util/MediaUtils.java
index 2b76c99..eab4808 100644
--- a/libs/deviceutil/src/android/cts/util/MediaUtils.java
+++ b/libs/deviceutil/src/android/cts/util/MediaUtils.java
@@ -18,8 +18,6 @@
 import android.content.Context;
 import android.content.res.AssetFileDescriptor;
 import android.media.MediaCodecInfo;
-import android.media.MediaCodecInfo.CodecCapabilities;
-import android.media.MediaCodecInfo.VideoCapabilities;
 import android.media.MediaCodecList;
 import android.media.MediaExtractor;
 import android.media.MediaFormat;
@@ -321,44 +319,11 @@
 
     public static boolean canDecodeVideo(String mime, int width, int height, float rate) {
         MediaFormat format = MediaFormat.createVideoFormat(mime, width, height);
-
-        // WORKAROUND for MediaCodecList.findDecoderForFormat() that does not
-        // work if frame rate is specified.
-        return findCodecForFormat(format, (double)rate, false /* encoder */) != null;
+        format.setFloat(MediaFormat.KEY_FRAME_RATE, rate);
+        return canDecode(format);
     }
 
     public static boolean checkDecoderForFormat(MediaFormat format) {
         return check(canDecode(format), "no decoder for " + format);
     }
-
-    // WORKAROUND for MediaCodecList.findEncoderForFormat() that does not
-    // work if frame rate is specified.
-    public static String findEncoderForFormat(MediaFormat format, double rate) {
-        return findCodecForFormat(format, rate, true /* encoder */);
-    }
-
-    private static String findCodecForFormat(MediaFormat format, double rate, boolean encoder) {
-        String mime = format.getString(MediaFormat.KEY_MIME);
-        for (MediaCodecInfo info : sMCL.getCodecInfos()) {
-            if (info.isEncoder() != encoder) {
-                continue;
-            }
-            CodecCapabilities codecCaps = null;
-            try {
-                codecCaps = info.getCapabilitiesForType(mime);
-            } catch (IllegalArgumentException | NullPointerException e) {
-                continue;
-            }
-            if (codecCaps != null && codecCaps.isFormatSupported(format)) {
-                int width = format.getInteger(MediaFormat.KEY_WIDTH);
-                int height = format.getInteger(MediaFormat.KEY_HEIGHT);
-                VideoCapabilities caps = codecCaps.getVideoCapabilities();
-                if (caps != null && caps.areSizeAndRateSupported(width, height, rate)) {
-                    return info.getName();
-                }
-            }
-        }
-        return null;
-    }
-
 }
diff --git a/suite/cts/deviceTests/videoperf/src/com/android/cts/videoperf/VideoEncoderDecoderTest.java b/suite/cts/deviceTests/videoperf/src/com/android/cts/videoperf/VideoEncoderDecoderTest.java
index 6747acf..aacb7a5 100644
--- a/suite/cts/deviceTests/videoperf/src/com/android/cts/videoperf/VideoEncoderDecoderTest.java
+++ b/suite/cts/deviceTests/videoperf/src/com/android/cts/videoperf/VideoEncoderDecoderTest.java
@@ -16,7 +16,6 @@
 
 package com.android.cts.videoperf;
 
-import android.cts.util.MediaUtils;
 import android.graphics.Point;
 import android.media.MediaCodec;
 import android.media.MediaCodecList;
@@ -158,9 +157,10 @@
             format.setInteger(MediaFormat.KEY_COLOR_FORMAT,
                     infoEnc.mSupportSemiPlanar ? CodecCapabilities.COLOR_FormatYUV420SemiPlanar :
                         CodecCapabilities.COLOR_FormatYUV420Planar);
+            format.setInteger(MediaFormat.KEY_FRAME_RATE, infoEnc.mFps);
             mFrameRate = infoEnc.mFps;
             format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, KEY_I_FRAME_INTERVAL);
-            double encodingTime = runEncoder(VIDEO_AVC, format, TOTAL_FRAMES, mFrameRate);
+            double encodingTime = runEncoder(VIDEO_AVC, format, TOTAL_FRAMES);
             // re-initialize format for decoder
             format = new MediaFormat();
             format.setString(MediaFormat.KEY_MIME, mimeType);
@@ -208,12 +208,11 @@
      * @param totalFrames total number of frames to encode
      * @return time taken in ms to encode the frames. This does not include initialization time.
      */
-    private double runEncoder(String mimeType, MediaFormat format, int totalFrames, int frameRate) {
+    private double runEncoder(String mimeType, MediaFormat format, int totalFrames) {
         MediaCodec codec = null;
         try {
             MediaCodecList mcl = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
-            String encoderName = MediaUtils.findEncoderForFormat(format, frameRate);
-            format.setInteger(MediaFormat.KEY_FRAME_RATE, frameRate);
+            String encoderName = mcl.findEncoderForFormat(format);
             codec = MediaCodec.createByCodecName(encoderName);
             codec.configure(
                     format,
diff --git a/tests/expectations/knownfailures.txt b/tests/expectations/knownfailures.txt
index d81ce35..391bec3 100644
--- a/tests/expectations/knownfailures.txt
+++ b/tests/expectations/knownfailures.txt
@@ -7,13 +7,6 @@
   bug: 17536113
 },
 {
-  description: "the ConnectivityConstraintTest are not yet stable",
-  names: [
-    "android.jobscheduler.cts.ConnectivityConstraintTest"
-  ],
-  bug: 18117279
-},
-{
   description: "tests a fragile by nature as they rely on hardcoded behavior",
   names: [
     "android.accessibilityservice.cts.AccessibilityTextTraversalTest#testActionNextAndPreviousAtGranularityPageOverText",
@@ -59,6 +52,26 @@
   bug: 16720689
 },
 {
+  description: "test can only run properly on a user build device when the bug is resolved",
+  names: [
+    "android.appwidget.cts.AppWidgetTest#testAppWidgetProviderCallbacks",
+    "android.appwidget.cts.AppWidgetTest#testBindAppWidget",
+    "android.appwidget.cts.AppWidgetTest#testCollectionWidgets",
+    "android.appwidget.cts.AppWidgetTest#testDeleteHost",
+    "android.appwidget.cts.AppWidgetTest#testDeleteHosts",
+    "android.appwidget.cts.AppWidgetTest#testGetAppWidgetIds",
+    "android.appwidget.cts.AppWidgetTest#testGetAppWidgetInfo",
+    "android.appwidget.cts.AppWidgetTest#testGetAppWidgetOptions",
+    "android.appwidget.cts.AppWidgetTest#testPartiallyUpdateAppWidgetViaWidgetId",
+    "android.appwidget.cts.AppWidgetTest#testPartiallyUpdateAppWidgetViaWidgetIds",
+    "android.appwidget.cts.AppWidgetTest#testTwoAppWidgetProviderCallbacks",
+    "android.appwidget.cts.AppWidgetTest#testUpdateAppWidgetViaComponentName",
+    "android.appwidget.cts.AppWidgetTest#testUpdateAppWidgetViaWidgetId",
+    "android.appwidget.cts.AppWidgetTest#testUpdateAppWidgetViaWidgetIds"
+  ],
+  bug: 17993121
+},
+{
   description: "A few WebGL tests are known to fail in WebView",
   names: [
     "android.webgl.cts.WebGLTest#test_conformance_extensions_oes_texture_float_with_video_html",
diff --git a/tests/tests/graphics/res/drawable/vector_icon_delete.xml b/tests/tests/graphics/res/drawable/vector_icon_delete.xml
index 8d9c21c..7b8f2aa 100644
--- a/tests/tests/graphics/res/drawable/vector_icon_delete.xml
+++ b/tests/tests/graphics/res/drawable/vector_icon_delete.xml
@@ -24,6 +24,6 @@
 
     <path
         android:fillColor="#FF000000"
-        android:pathData="M6.0,19.0c0.0,1.104 0.896,2.0 2.0,2.0l8.0,0.0c1.104,0.0 2.0-0.896 2.0-2.0l0.0-12.0L6.0,7.0L6.0,19.0zM18.0,4.0l-2.5,0.0l-1.0-1.0l-5.0,0.0l-1.0,1.0L6.0,4.0C5.4469986,4.0 5.0,4.4469986 5.0,5.0l0.0,1.0l14.0,0.0l0.0-1.0C19.0,4.4469986 18.552002,4.0 18.0,4.0z" />
+        android:pathData="M6.0,19.0c0.0,1.104 896e-3,2.0 2.0,2.0l8.0,0.0c1.104,0.0 2.0-896e-3 2.0-2.0l0.0-12.0L6.0,7.0L6.0,19.0zM18.0,4.0l-2.5,0.0l-1.0-1.0l-5.0,0.0l-1.0,1.0L6.0,4.0C5.4469986,4.0 5.0,4.4469986 5.0,5.0l0.0,1.0l14.0,0.0l0.0-1.0C19.0,4.4469986 18.552002,4.0 18.0,4.0z" />
 
 </vector>
\ No newline at end of file
diff --git a/tests/tests/graphics/res/drawable/vector_icon_heart.xml b/tests/tests/graphics/res/drawable/vector_icon_heart.xml
index ff55fe5..ad991c9 100644
--- a/tests/tests/graphics/res/drawable/vector_icon_heart.xml
+++ b/tests/tests/graphics/res/drawable/vector_icon_heart.xml
@@ -24,6 +24,6 @@
 
     <path
         android:fillColor="#FF000000"
-        android:pathData="M16.0,5.0c-1.955,0.0 -3.83,1.268 -4.5,3.0c-0.67-1.732 -2.547-3.0 -4.5-3.0C4.4570007,5.0 2.5,6.931999 2.5,9.5c0.0,3.529 3.793,6.258 9.0,11.5c5.207-5.242 9.0-7.971 9.0-11.5C20.5,6.931999 18.543,5.0 16.0,5.0z" />
+        android:pathData="M16.0,5.0c-1.955.0 -3.83,1.268 -4.5,3.0c-0.67-1.732 -2.547-3.0 -4.5-3.0C4.4570007,5.0 2.5,6.931999 2.5,9.5c0.0,3.529 3.793,6.258 9.0,11.5c5.207-5.242 9.0-7.971 9.0-11.5C20.5,6.931999 18.543,5.0 16.0,5.0z" />
 
 </vector>
\ No newline at end of file
diff --git a/tests/tests/graphics/src/android/graphics/cts/PaintTest.java b/tests/tests/graphics/src/android/graphics/cts/PaintTest.java
index 1f709d3..bac72b2 100644
--- a/tests/tests/graphics/src/android/graphics/cts/PaintTest.java
+++ b/tests/tests/graphics/src/android/graphics/cts/PaintTest.java
@@ -19,6 +19,7 @@
 
 import android.graphics.ColorFilter;
 import android.graphics.MaskFilter;
+import android.graphics.Matrix;
 import android.graphics.Paint;
 import android.graphics.Paint.Align;
 import android.graphics.Paint.Cap;
@@ -28,6 +29,8 @@
 import android.graphics.PathEffect;
 import android.graphics.Rasterizer;
 import android.graphics.Shader;
+import android.graphics.Bitmap;
+import android.graphics.BitmapShader;
 import android.graphics.Typeface;
 import android.graphics.Xfermode;
 import android.os.Build;
@@ -190,7 +193,7 @@
         assertEquals(m, p2.getMaskFilter());
         assertEquals(e, p2.getPathEffect());
         assertEquals(r, p2.getRasterizer());
-        assertNotSame(s, p2.getShader());
+        assertEquals(s, p2.getShader());
         assertEquals(t, p2.getTypeface());
         assertEquals(x, p2.getXfermode());
 
@@ -199,7 +202,7 @@
         assertEquals(m, p2.getMaskFilter());
         assertEquals(e, p2.getPathEffect());
         assertEquals(r, p2.getRasterizer());
-        assertNotSame(s, p2.getShader());
+        assertEquals(s, p2.getShader());
         assertEquals(t, p2.getTypeface());
         assertEquals(x, p2.getXfermode());
 
@@ -271,6 +274,35 @@
         assertNull(p.getShader());
     }
 
+    public void testShaderLocalMatrix() {
+        int width = 80;
+        int height = 120;
+        int[] color = new int[width * height];
+        Bitmap bitmap = Bitmap.createBitmap(color, width, height, Bitmap.Config.RGB_565);
+
+        Paint p = new Paint();
+        Matrix m = new Matrix();
+        Shader s = new BitmapShader(bitmap, Shader.TileMode.REPEAT, Shader.TileMode.REPEAT);
+
+        // set the shaders matrix to a non identity value and attach to paint
+        m.setScale(10, 0);
+        s.setLocalMatrix(m);
+        p.setShader(s);
+
+        Matrix m2 = new Matrix();
+        assertTrue(p.getShader().getLocalMatrix(m2));
+        assertEquals(m, m2);
+
+        // updated the matrix again and set it on the shader but NOT the paint
+        m.setScale(0, 10);
+        s.setLocalMatrix(m);
+
+        // assert that the matrix on the paint's shader also changed
+        Matrix m3 = new Matrix();
+        assertTrue(p.getShader().getLocalMatrix(m3));
+        assertEquals(m, m3);
+    }
+
     public void testSetAntiAlias() {
         Paint p = new Paint();
 
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/BurstCaptureRawTest.java b/tests/tests/hardware/src/android/hardware/camera2/cts/BurstCaptureRawTest.java
new file mode 100644
index 0000000..c82d442
--- /dev/null
+++ b/tests/tests/hardware/src/android/hardware/camera2/cts/BurstCaptureRawTest.java
@@ -0,0 +1,309 @@
+/*
+ * Copyright (C) 2014 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.hardware.camera2.cts;
+
+import static android.hardware.camera2.cts.helpers.AssertHelpers.assertArrayContains;
+import static android.hardware.camera2.cts.CameraTestUtils.*;
+
+import android.graphics.ImageFormat;
+import android.graphics.Rect;
+import android.hardware.camera2.CameraCharacteristics;
+import android.hardware.camera2.CameraDevice;
+import android.hardware.camera2.CaptureRequest;
+import android.hardware.camera2.CaptureResult;
+import android.hardware.camera2.cts.CameraTestUtils.SimpleCaptureCallback;
+import android.hardware.camera2.cts.CameraTestUtils.SimpleImageReaderListener;
+import android.hardware.camera2.cts.testcases.Camera2SurfaceViewTestCase;
+import android.hardware.camera2.params.StreamConfigurationMap;
+import android.util.Log;
+import android.util.Range;
+import android.util.Size;
+
+import java.util.ArrayList;
+
+/**
+ * Basic tests for burst capture in RAW10/16.
+ */
+public class BurstCaptureRawTest extends Camera2SurfaceViewTestCase {
+    private static final String TAG = "BurstCaptureRawTest";
+    private static final int RAW_FORMATS[] = {
+            ImageFormat.RAW10, ImageFormat.RAW_SENSOR };
+    private static final long EXPOSURE_MULTIPLIERS[] = {
+            1, 2, 3 };
+    private static final int SENSITIVITY_MLTIPLIERS[] = {
+            1, 2, 3 };
+    private static final int MAX_FRAMES_BURST =
+            EXPOSURE_MULTIPLIERS.length * SENSITIVITY_MLTIPLIERS.length;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+    }
+
+    /**
+     * Verify raw sensor size information is correctly configured.
+     */
+    public void testRawSensorSize() throws Exception {
+        Log.i(TAG, "Begin testRawSensorSize");
+        for (String id : mCameraIds) {
+            try {
+                openDevice(id);
+
+                ArrayList<Integer> supportedRawList = new ArrayList<Integer>(RAW_FORMATS.length);
+                if (!checkCapability(supportedRawList)) {
+                    Log.i(TAG, "Capability is not supported on camera " + id
+                            + ". Skip the test.");
+                    continue;
+                }
+
+                Size[] rawSizes = mStaticInfo.getRawOutputSizesChecked();
+                assertTrue("No capture sizes available for RAW format!", rawSizes.length != 0);
+
+                Rect activeArray = mStaticInfo.getActiveArraySizeChecked();
+                Size size = new Size(activeArray.width(), activeArray.height());
+                mCollector.expectTrue("Missing ActiveArraySize",
+                        activeArray.width() > 0 && activeArray.height() > 0);
+                mCollector.expectContains(
+                        "Available sizes for RAW format must include ActiveArraySize",
+                        rawSizes, size);
+
+            } finally {
+                closeDevice();
+            }
+        }
+        Log.i(TAG, "End testRawSensorSize");
+    }
+
+    /**
+     * Verify the value of metadata (exposure and sensitivity) is rounded down if the request cannot
+     * be honored.
+     */
+    public void testMetadataRoundDown() throws Exception {
+        Log.i(TAG, "Begin testMetadataRoundDown");
+        for (String id : mCameraIds) {
+            try {
+                openDevice(id);
+
+                ArrayList<Integer> supportedRawList = new ArrayList<Integer>(RAW_FORMATS.length);
+                if (!checkCapability(supportedRawList)) {
+                    Log.i(TAG, "Capability is not supported on camera " + id
+                            + ". Skip the test.");
+                    continue;
+                }
+
+                // prepare preview and still RAW capture
+                Size maxPreviewSize = mOrderedPreviewSizes.get(0);
+                Rect activeArray = mStaticInfo.getActiveArraySizeChecked();
+                Size rawCaptureSize = new Size(activeArray.width(), activeArray.height());
+
+                CaptureRequest.Builder previewBuilder =
+                        mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
+
+                CaptureRequest.Builder rawBurstBuilder =
+                        mCamera.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
+
+                SimpleCaptureCallback previewCaptureCallback = new SimpleCaptureCallback();
+                SimpleCaptureCallback rawCaptureCallback = new SimpleCaptureCallback();
+                SimpleImageReaderListener rawReaderListener = new SimpleImageReaderListener();
+
+                // test each supported RAW format
+                for (int rawFormat : supportedRawList) {
+                    Log.i(TAG, "Testing format " + imageFormatToString(rawFormat) + ".");
+
+                    // start preview and prepare RAW capture
+                    prepareCaptureAndStartPreview(previewBuilder, rawBurstBuilder,
+                            maxPreviewSize, rawCaptureSize, rawFormat, previewCaptureCallback,
+                            MAX_FRAMES_BURST, rawReaderListener);
+
+                    // build burst capture
+                    ArrayList<CaptureRequest> rawRequestList = createBurstRequest(rawBurstBuilder);
+
+                    // submit captrue
+                    Log.i(TAG, "Submitting Burst Request.");
+                    mSession.captureBurst(rawRequestList, rawCaptureCallback, mHandler);
+
+                    // verify metadata
+                    for (int i = 0; i < MAX_FRAMES_BURST; i++) {
+                        CaptureResult result = rawCaptureCallback.getCaptureResult(
+                                CAPTURE_IMAGE_TIMEOUT_MS);
+
+                        long resultExposure = result.get(CaptureResult.SENSOR_EXPOSURE_TIME);
+                        int resultSensitivity = result.get(CaptureResult.SENSOR_SENSITIVITY);
+                        long desiredExposure = rawRequestList.get(i).get(
+                                CaptureRequest.SENSOR_EXPOSURE_TIME);
+                        int desiredSensitivity = rawRequestList.get(i).get(
+                                CaptureRequest.SENSOR_SENSITIVITY);
+
+                        Log.i(TAG, String.format(
+                                "Received capture result, exposure = %d, sensitivity = %d. "
+                                        + "Requested exposure = %d, sensitivity = %d.",
+                                resultExposure,
+                                resultSensitivity, desiredExposure, desiredSensitivity));
+
+                        mCollector.expectTrue(
+                                String.format("Exposure value is greater than requested: "
+                                        + "requested = %d, result = %d.",
+                                        desiredExposure, resultExposure),
+                                        resultExposure <= desiredExposure);
+
+                        mCollector.expectTrue(
+                                String.format("Sensitivity value is greater than requested: "
+                                        + "requested = %d, result = %d.",
+                                        desiredSensitivity, resultSensitivity),
+                                        resultSensitivity <= desiredSensitivity);
+                    }
+
+                    // clear out the surface and camera session
+                    stopPreviewAndClearSurface(previewBuilder, rawBurstBuilder);
+                }
+            } finally {
+                closeDevice();
+                closeImageReader();
+            }
+        }
+        Log.i(TAG, "End testMetadataRoundDown");
+    }
+
+    /**
+     * Check sensor capability prior to the test.
+     *
+     * @return true if the it is has the capability to execute the test.
+     */
+    private boolean checkCapability(ArrayList<Integer> supportedRawList) {
+        // make sure the sensor has manual support
+        if (!mStaticInfo.isCapabilitySupported(
+                CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_FULL)) {
+            Log.w(TAG, "Full hardware level is not supported");
+            return false;
+        }
+
+        // get the list of supported RAW format
+        StreamConfigurationMap config = mStaticInfo.getValueFromKeyNonNull(
+                CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
+
+        // check for the RAW support
+        supportedRawList.clear();
+        for (int rawFormat : RAW_FORMATS) {
+            if (!config.isOutputSupportedFor(rawFormat)) {
+                continue;
+            }
+            supportedRawList.add(rawFormat);
+        }
+
+        if (supportedRawList.size() == 0)
+        {
+            Log.w(TAG, "RAW output is not supported!");
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * Return the sensor format to human readable string.
+     * @param format Sensor image format.
+     * @return Human readable string.
+     */
+    private String imageFormatToString(int format) {
+        switch (format) {
+            case ImageFormat.RAW10:
+                return "RAW10";
+            case ImageFormat.RAW_SENSOR:
+                return "RAW_SENSOR";
+        }
+
+        return "Unknown";
+    }
+
+    /**
+     * Construct an array of burst request for the test case.
+     * <p>
+     * For each capture request, 3A and post processing (noise reduction, sharpening, etc) will be turned off.
+     * Then exposure and sensitivity value will be configured,
+     * which are determined by EXPOSURE_MULIPLIERS and SENSITIVITY_MULTIPLIERS.
+     * </p>
+     * @param rawBurstBuilder The builder needs to have targets setup.
+     * @return An array list capture request for burst.
+     */
+    private ArrayList<CaptureRequest> createBurstRequest(CaptureRequest.Builder rawBurstBuilder) {
+        // set manual mode
+        rawBurstBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_OFF);
+        rawBurstBuilder.set(CaptureRequest.CONTROL_AWB_MODE, CaptureRequest.CONTROL_AWB_MODE_OFF);
+        rawBurstBuilder.set(CaptureRequest.NOISE_REDUCTION_MODE,
+                CaptureRequest.NOISE_REDUCTION_MODE_OFF);
+        rawBurstBuilder.set(CaptureRequest.EDGE_MODE, CaptureRequest.EDGE_MODE_OFF);
+        // exposure has higher priority over frame duration; therefore the frame readout time:
+        // exposure time + overhead
+        rawBurstBuilder.set(CaptureRequest.SENSOR_FRAME_DURATION, 0L);
+
+        // get the exposure and sensitivity range
+        Range<Long> exposureRangeNs = new Range<Long>(mStaticInfo.getExposureMinimumOrDefault(),
+                mStaticInfo.getExposureMaximumOrDefault());
+
+        Range<Integer> isoRange = new Range<Integer>(mStaticInfo.getSensitivityMinimumOrDefault(),
+                mStaticInfo.getSensitivityMaximumOrDefault());
+
+        Log.i(TAG, String.format("Exposure time - max: %d, min: %d.", exposureRangeNs.getUpper(),
+                exposureRangeNs.getLower()));
+        Log.i(TAG, String.format("Sensitivity - max: %d, min: %d.", isoRange.getUpper(),
+                isoRange.getLower()));
+
+        // building burst request
+        Log.i(TAG, String.format("Setting up burst = %d frames.", MAX_FRAMES_BURST));
+        ArrayList<CaptureRequest> rawRequestList = new ArrayList<CaptureRequest>(MAX_FRAMES_BURST);
+
+        for (int i = 0; i < EXPOSURE_MULTIPLIERS.length; i++) {
+            for (int j = 0; j < SENSITIVITY_MLTIPLIERS.length; j++) {
+                long desiredExposure = Math.min(
+                        exposureRangeNs.getLower() * EXPOSURE_MULTIPLIERS[i],
+                        exposureRangeNs.getUpper());
+
+                int desiredSensitivity =
+                        Math.min(isoRange.getLower() * SENSITIVITY_MLTIPLIERS[j],
+                                isoRange.getUpper());
+
+                rawBurstBuilder.set(CaptureRequest.SENSOR_EXPOSURE_TIME, desiredExposure);
+                rawBurstBuilder.set(CaptureRequest.SENSOR_SENSITIVITY, desiredSensitivity);
+
+                rawRequestList.add(rawBurstBuilder.build());
+            }
+        }
+        return rawRequestList;
+    }
+
+    /**
+     * Stop preview and remove the target surfaces inside the CaptureRequest.Builder.
+     *
+     * @param previewBuilder Configured builder for preview.
+     * @param rawBurstBuilder Configured builder for RAW.
+     * @throws Exception Exceptions from stopPreview
+     */
+    private void stopPreviewAndClearSurface(CaptureRequest.Builder previewBuilder,
+            CaptureRequest.Builder rawBurstBuilder) throws Exception
+    {
+        previewBuilder.removeTarget(mPreviewSurface);
+        rawBurstBuilder.removeTarget(mPreviewSurface);
+        rawBurstBuilder.removeTarget(mReaderSurface);
+
+        stopPreview();
+    }
+}
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/RecordingTest.java b/tests/tests/hardware/src/android/hardware/camera2/cts/RecordingTest.java
index add8e5d..386696c 100644
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/RecordingTest.java
+++ b/tests/tests/hardware/src/android/hardware/camera2/cts/RecordingTest.java
@@ -14,7 +14,6 @@
 import static android.hardware.camera2.cts.CameraTestUtils.*;
 import static com.android.ex.camera2.blocking.BlockingSessionCallback.*;
 
-import android.cts.util.MediaUtils;
 import android.graphics.ImageFormat;
 import android.hardware.camera2.CameraCharacteristics;
 import android.hardware.camera2.CameraCaptureSession;
@@ -1063,7 +1062,8 @@
     private static boolean isSupportedByAVCEncoder(Size sz, int frameRate) {
         MediaFormat format = MediaFormat.createVideoFormat(
                 MediaFormat.MIMETYPE_VIDEO_AVC, sz.getWidth(), sz.getHeight());
+        format.setInteger(MediaFormat.KEY_FRAME_RATE, frameRate);
         MediaCodecList mcl = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
-        return MediaUtils.findEncoderForFormat(format, frameRate) != null;
+        return mcl.findEncoderForFormat(format) != null;
     }
 }
diff --git a/tests/tests/media/src/android/media/cts/AdaptivePlaybackTest.java b/tests/tests/media/src/android/media/cts/AdaptivePlaybackTest.java
index 2ef223e..3b46360 100644
--- a/tests/tests/media/src/android/media/cts/AdaptivePlaybackTest.java
+++ b/tests/tests/media/src/android/media/cts/AdaptivePlaybackTest.java
@@ -1348,7 +1348,7 @@
 
 class CodecFactory {
     protected boolean hasCodec(String codecName) {
-        MediaCodecList list = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
+        MediaCodecList list = new MediaCodecList(MediaCodecList.ALL_CODECS);
         for (MediaCodecInfo info : list.getCodecInfos()) {
             if (codecName.equals(info.getName())) {
                 return true;
diff --git a/tests/tests/media/src/android/media/cts/EncodeVirtualDisplayTest.java b/tests/tests/media/src/android/media/cts/EncodeVirtualDisplayTest.java
index 12fcd30..ba67a42ca 100755
--- a/tests/tests/media/src/android/media/cts/EncodeVirtualDisplayTest.java
+++ b/tests/tests/media/src/android/media/cts/EncodeVirtualDisplayTest.java
@@ -22,7 +22,6 @@
 import android.media.MediaCodecList;
 import android.media.MediaFormat;
 import android.content.Context;
-import android.cts.util.MediaUtils;
 import android.graphics.drawable.ColorDrawable;
 import android.hardware.display.DisplayManager;
 import android.hardware.display.VirtualDisplay;
@@ -166,10 +165,12 @@
      * Returns true if the encoder level, specified in the ENCODER_PARAM_TABLE, can be supported.
      */
     private static boolean verifySupportForEncoderLevel(int i) {
+        MediaCodecList mcl = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
         MediaFormat format = MediaFormat.createVideoFormat(
                 MIME_TYPE, ENCODER_PARAM_TABLE[i][0], ENCODER_PARAM_TABLE[i][1]);
         format.setInteger(MediaFormat.KEY_BIT_RATE, ENCODER_PARAM_TABLE[i][2]);
-        return MediaUtils.findEncoderForFormat(format, ENCODER_PARAM_TABLE[i][3]) != null;
+        format.setInteger(MediaFormat.KEY_FRAME_RATE, ENCODER_PARAM_TABLE[i][3]);
+        return mcl.findEncoderForFormat(format) != null;
     }
 
     /**
@@ -210,10 +211,11 @@
             encoderFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT,
                     MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface);
             encoderFormat.setInteger(MediaFormat.KEY_BIT_RATE, sBitRate);
+            encoderFormat.setInteger(MediaFormat.KEY_FRAME_RATE, sFrameRate);
             encoderFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, IFRAME_INTERVAL);
 
-            String codec = MediaUtils.findEncoderForFormat(encoderFormat, sFrameRate);
-            encoderFormat.setInteger(MediaFormat.KEY_FRAME_RATE, sFrameRate);
+            MediaCodecList mcl = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
+            String codec = mcl.findEncoderForFormat(encoderFormat);
             if (codec == null) {
                 // Don't run the test if the codec isn't present.
                 Log.i(TAG, "SKIPPING test: no support for " + encoderFormat);
diff --git a/tests/tests/media/src/android/media/cts/EncodeVirtualDisplayWithCompositionTest.java b/tests/tests/media/src/android/media/cts/EncodeVirtualDisplayWithCompositionTest.java
index dd5b238..014c1a5 100644
--- a/tests/tests/media/src/android/media/cts/EncodeVirtualDisplayWithCompositionTest.java
+++ b/tests/tests/media/src/android/media/cts/EncodeVirtualDisplayWithCompositionTest.java
@@ -22,7 +22,6 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.ServiceConnection;
-import android.cts.util.MediaUtils;
 import android.graphics.SurfaceTexture;
 import android.graphics.Typeface;
 import android.graphics.drawable.ColorDrawable;
@@ -1328,11 +1327,12 @@
             new Size(352, 576)
         };
 
+        MediaCodecList mcl = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
         for (Size sz : standardSizes) {
             MediaFormat format = MediaFormat.createVideoFormat(
                 MIME_TYPE, sz.getWidth(), sz.getHeight());
-            // require at least 15fps
-            if (MediaUtils.findEncoderForFormat(format, 15) != null) {
+            format.setInteger(MediaFormat.KEY_FRAME_RATE, 15); // require at least 15fps
+            if (mcl.findEncoderForFormat(format) != null) {
                 return sz;
             }
         }
diff --git a/tests/tests/media/src/android/media/cts/ExtractDecodeEditEncodeMuxTest.java b/tests/tests/media/src/android/media/cts/ExtractDecodeEditEncodeMuxTest.java
index acd179e..9da229c 100644
--- a/tests/tests/media/src/android/media/cts/ExtractDecodeEditEncodeMuxTest.java
+++ b/tests/tests/media/src/android/media/cts/ExtractDecodeEditEncodeMuxTest.java
@@ -18,7 +18,6 @@
 
 import android.annotation.TargetApi;
 import android.content.res.AssetFileDescriptor;
-import android.cts.util.MediaUtils;
 import android.media.MediaCodec;
 import android.media.MediaCodecInfo;
 import android.media.MediaCodecList;
@@ -285,12 +284,12 @@
         outputVideoFormat.setInteger(
                 MediaFormat.KEY_COLOR_FORMAT, OUTPUT_VIDEO_COLOR_FORMAT);
         outputVideoFormat.setInteger(MediaFormat.KEY_BIT_RATE, OUTPUT_VIDEO_BIT_RATE);
+        outputVideoFormat.setInteger(MediaFormat.KEY_FRAME_RATE, OUTPUT_VIDEO_FRAME_RATE);
         outputVideoFormat.setInteger(
                 MediaFormat.KEY_I_FRAME_INTERVAL, OUTPUT_VIDEO_IFRAME_INTERVAL);
+        if (VERBOSE) Log.d(TAG, "video format: " + outputVideoFormat);
 
         String videoEncoderName = mcl.findEncoderForFormat(outputVideoFormat);
-        outputVideoFormat.setInteger(MediaFormat.KEY_FRAME_RATE, OUTPUT_VIDEO_FRAME_RATE);
-        if (VERBOSE) Log.d(TAG, "video format: " + outputVideoFormat);
         if (videoEncoderName == null) {
             // Don't fail CTS if they don't have an AVC codec (not here, anyway).
             Log.e(TAG, "Unable to find an appropriate codec for " + outputVideoFormat);
diff --git a/tests/tests/media/src/android/media/cts/MediaCodecCapabilitiesTest.java b/tests/tests/media/src/android/media/cts/MediaCodecCapabilitiesTest.java
index cbb0a3d..afed27b 100644
--- a/tests/tests/media/src/android/media/cts/MediaCodecCapabilitiesTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaCodecCapabilitiesTest.java
@@ -96,13 +96,11 @@
                     hasDecoder(MIMETYPE_VIDEO_HEVC, HEVCProfileMain, HEVCMainTierLevel41));
         }
 
-        /* this check is not yet working
         if (MediaUtils.canDecodeVideo(MIMETYPE_VIDEO_HEVC, 3840, 2160, 30)) {
             assertTrue(
                     "H.265 must support Main10 Profile Main Tier Level 5 if UHD is supported",
                     hasDecoder(MIMETYPE_VIDEO_HEVC, HEVCProfileMain10, HEVCMainTierLevel5));
         }
-        */
     }
 
     public void testAvcBaseline1() throws Exception {
diff --git a/tests/tests/media/src/android/media/cts/MediaCodecTest.java b/tests/tests/media/src/android/media/cts/MediaCodecTest.java
index df5eb06..0aff8ed 100644
--- a/tests/tests/media/src/android/media/cts/MediaCodecTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaCodecTest.java
@@ -1073,7 +1073,7 @@
     }
 
     private static boolean supportsCodec(String mimeType, boolean encoder) {
-        MediaCodecList list = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
+        MediaCodecList list = new MediaCodecList(MediaCodecList.ALL_CODECS);
         for (MediaCodecInfo info : list.getCodecInfos()) {
             if (encoder && !info.isEncoder()) {
                 continue;
diff --git a/tests/tests/os/src/android/os/cts/BuildVersionTest.java b/tests/tests/os/src/android/os/cts/BuildVersionTest.java
index 4c92da7..6069ee6 100644
--- a/tests/tests/os/src/android/os/cts/BuildVersionTest.java
+++ b/tests/tests/os/src/android/os/cts/BuildVersionTest.java
@@ -28,7 +28,7 @@
 public class BuildVersionTest extends TestCase {
 
     private static final String LOG_TAG = "BuildVersionTest";
-    private static final Set<String> EXPECTED_RELEASES = new HashSet<String>(Arrays.asList("5.0.1"));
+    private static final Set<String> EXPECTED_RELEASES = new HashSet<String>(Arrays.asList("5.0"));
     private static final int EXPECTED_SDK = 21;
     private static final String EXPECTED_BUILD_VARIANT = "user";
     private static final String EXPECTED_TAG = "release-keys";
diff --git a/tests/tests/webkit/src/android/webkit/cts/CookieManagerTest.java b/tests/tests/webkit/src/android/webkit/cts/CookieManagerTest.java
index c612886..856b4aa 100644
--- a/tests/tests/webkit/src/android/webkit/cts/CookieManagerTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/CookieManagerTest.java
@@ -319,8 +319,6 @@
         assertFalse(anyDeleted.get());
     }
 
-    /*
-    TODO: uncomment when acceptThirdPartyCookies implementation lands
     public void testThirdPartyCookie() throws Throwable {
         if (!NullWebViewUtils.isWebViewAvailable()) {
             return;
@@ -377,7 +375,6 @@
             mOnUiThread.getSettings().setJavaScriptEnabled(false);
         }
     }
-    */
 
     public void testb3167208() throws Exception {
         if (!NullWebViewUtils.isWebViewAvailable()) {
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebViewTest.java b/tests/tests/webkit/src/android/webkit/cts/WebViewTest.java
index 1e22acc..f72a70d 100755
--- a/tests/tests/webkit/src/android/webkit/cts/WebViewTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebViewTest.java
@@ -122,6 +122,11 @@
      */
     private static final long SCROLL_WAIT_INTERVAL_MS = 200;
 
+    /**
+     * Epsilon used in page scale value comparisons.
+     */
+    private static final float PAGE_SCALE_EPSILON = 0.0001f;
+
     private WebView mWebView;
     private CtsTestServer mWebServer;
     private WebViewOnUiThread mOnUiThread;
@@ -330,7 +335,7 @@
         // that a scale change does *not* happen.
         Thread.sleep(500);
         currScale = mOnUiThread.getScale();
-        assertEquals(currScale, previousScale);
+        assertEquals(currScale, previousScale, PAGE_SCALE_EPSILON);
 
         assertTrue(mOnUiThread.zoomOut());
         previousScale = currScale;
@@ -354,7 +359,7 @@
         // that a scale change does *not* happen.
         Thread.sleep(500);
         currScale = mOnUiThread.getScale();
-        assertEquals(currScale, previousScale);
+        assertEquals(currScale, previousScale, PAGE_SCALE_EPSILON);
 
         mOnUiThread.zoomBy(1.25f);
         previousScale = currScale;
@@ -378,7 +383,7 @@
         // that a scale change does *not* happen.
         Thread.sleep(500);
         currScale = mOnUiThread.getScale();
-        assertEquals(currScale, previousScale);
+        assertEquals(currScale, previousScale, PAGE_SCALE_EPSILON);
 
         mOnUiThread.zoomBy(0.8f);
         previousScale = currScale;
@@ -402,7 +407,7 @@
         // that a scale change does *not* happen.
         Thread.sleep(500);
         currScale = mOnUiThread.getScale();
-        assertEquals(currScale, previousScale);
+        assertEquals(currScale, previousScale, PAGE_SCALE_EPSILON);
     }
 
     @UiThreadTest
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/build/CtsBuildProvider.java b/tools/tradefed-host/src/com/android/cts/tradefed/build/CtsBuildProvider.java
index 42724e5..2ee649d 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/build/CtsBuildProvider.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/build/CtsBuildProvider.java
@@ -31,7 +31,7 @@
     @Option(name="cts-install-path", description="the path to the cts installation to use")
     private String mCtsRootDirPath = System.getProperty("CTS_ROOT");
 
-    public static final String CTS_BUILD_VERSION = "5.0_r1.93";
+    public static final String CTS_BUILD_VERSION = "5.0_r1.91";
 
     /**
      * {@inheritDoc}
diff --git a/tools/utils/buildCts.py b/tools/utils/buildCts.py
index 4d04e1a..b2ab4d6 100755
--- a/tools/utils/buildCts.py
+++ b/tools/utils/buildCts.py
@@ -158,6 +158,7 @@
     # CTS Stable plan
     plan = tools.TestPlan(packages)
     plan.Exclude(r'com\.android\.cts\.browserbench')
+    plan.Exclude(r'com\.android\.cts\.filesystemperf\.RandomRWTest$')
     for package, test_list in flaky_tests.iteritems():
       plan.ExcludeTests(package, test_list)
     self.__WritePlan(plan, 'CTS-stable')
@@ -166,6 +167,7 @@
     plan = tools.TestPlan(packages)
     plan.Exclude('.*')
     plan.Include(r'com\.android\.cts\.browserbench')
+    plan.Include(r'com\.android\.cts\.filesystemperf\.RandomRWTest$')
     for package, test_list in flaky_tests.iteritems():
       plan.Include(package+'$')
       plan.IncludeTests(package, test_list)
@@ -173,7 +175,6 @@
 
     small_tests = BuildAospSmallSizeTestList()
     medium_tests = BuildAospMediumSizeTestList()
-    new_test_packages = BuildCtsVettedNewPackagesList()
 
     # CTS - sub plan for public, small size tests
     plan = tools.TestPlan(packages)
@@ -181,6 +182,7 @@
     for package, test_list in small_tests.iteritems():
       plan.Include(package+'$')
     plan.Exclude(r'com\.android\.cts\.browserbench')
+    plan.Exclude(r'com\.android\.cts\.filesystemperf\.RandomRWTest$')
     for package, test_list in flaky_tests.iteritems():
       plan.ExcludeTests(package, test_list)
     self.__WritePlan(plan, 'CTS-kitkat-small')
@@ -191,6 +193,7 @@
     for package, test_list in medium_tests.iteritems():
       plan.Include(package+'$')
     plan.Exclude(r'com\.android\.cts\.browserbench')
+    plan.Exclude(r'com\.android\.cts\.filesystemperf\.RandomRWTest$')
     for package, test_list in flaky_tests.iteritems():
       plan.ExcludeTests(package, test_list)
     self.__WritePlan(plan, 'CTS-kitkat-medium')
@@ -200,6 +203,7 @@
     plan.Exclude('.*')
     plan.Include(r'android\.hardware$')
     plan.Exclude(r'com\.android\.cts\.browserbench')
+    plan.Exclude(r'com\.android\.cts\.filesystemperf\.RandomRWTest$')
     for package, test_list in flaky_tests.iteritems():
       plan.ExcludeTests(package, test_list)
     self.__WritePlan(plan, 'CTS-hardware')
@@ -210,6 +214,7 @@
     plan.Include(r'android\.media$')
     plan.Include(r'android\.view$')
     plan.Exclude(r'com\.android\.cts\.browserbench')
+    plan.Exclude(r'com\.android\.cts\.filesystemperf\.RandomRWTest$')
     for package, test_list in flaky_tests.iteritems():
       plan.ExcludeTests(package, test_list)
     self.__WritePlan(plan, 'CTS-media')
@@ -219,48 +224,27 @@
     plan.Exclude('.*')
     plan.Include(r'android\.mediastress$')
     plan.Exclude(r'com\.android\.cts\.browserbench')
+    plan.Exclude(r'com\.android\.cts\.filesystemperf\.RandomRWTest$')
     for package, test_list in flaky_tests.iteritems():
       plan.ExcludeTests(package, test_list)
     self.__WritePlan(plan, 'CTS-mediastress')
 
-    # CTS - sub plan for new tests that is vetted for L launch
-    plan = tools.TestPlan(packages)
-    plan.Exclude('.*')
-    for package, test_list in new_test_packages.iteritems():
-      plan.Include(package+'$')
-    plan.Exclude(r'com\.android\.cts\.browserbench')
-    for package, test_list in flaky_tests.iteritems():
-      plan.ExcludeTests(package, test_list)
-    self.__WritePlan(plan, 'CTS-l-tests')
-
-    #CTS - sub plan for new test packages added for staging
+    # CTS - sub plan for new test packages added for staging
     plan = tools.TestPlan(packages)
     for package, test_list in small_tests.iteritems():
       plan.Exclude(package+'$')
     for package, test_list in medium_tests.iteritems():
       plan.Exclude(package+'$')
-    for package, tests_list in new_test_packages.iteritems():
-      plan.Exclude(package+'$')
     plan.Exclude(r'android\.hardware$')
     plan.Exclude(r'android\.media$')
     plan.Exclude(r'android\.view$')
     plan.Exclude(r'android\.mediastress$')
     plan.Exclude(r'com\.android\.cts\.browserbench')
+    plan.Exclude(r'com\.android\.cts\.filesystemperf\.RandomRWTest$')
     for package, test_list in flaky_tests.iteritems():
       plan.ExcludeTests(package, test_list)
     self.__WritePlan(plan, 'CTS-staging')
 
-    plan = tools.TestPlan(packages)
-    plan.Exclude('.*')
-    plan.Include(r'com\.drawelements\.')
-    self.__WritePlan(plan, 'CTS-DEQP')
-
-    plan = tools.TestPlan(packages)
-    plan.Exclude('.*')
-    plan.Include(r'android\.webgl')
-    self.__WritePlan(plan, 'CTS-webview')
-
-
 def BuildAospMediumSizeTestList():
   """ Construct a defaultdic that lists package names of medium tests
       already published to aosp. """
@@ -342,42 +326,9 @@
       'com.android.cts.videoperf' : [],
       'zzz.android.monkey' : []}
 
-def BuildCtsVettedNewPackagesList():
-  """ Construct a defaultdict that maps package names that is vetted for L. """
-  return {
-      'android.JobScheduler' : [],
-      'android.core.tests.libcore.package.harmony_annotation' : [],
-      'android.core.tests.libcore.package.harmony_beans' : [],
-      'android.core.tests.libcore.package.harmony_java_io' : [],
-      'android.core.tests.libcore.package.harmony_java_lang' : [],
-      'android.core.tests.libcore.package.harmony_java_math' : [],
-      'android.core.tests.libcore.package.harmony_java_net' : [],
-      'android.core.tests.libcore.package.harmony_java_nio' : [],
-      'android.core.tests.libcore.package.harmony_java_util' : [],
-      'android.core.tests.libcore.package.harmony_java_text' : [],
-      'android.core.tests.libcore.package.harmony_javax_security' : [],
-      'android.core.tests.libcore.package.harmony_logging' : [],
-      'android.core.tests.libcore.package.harmony_prefs' : [],
-      'android.core.tests.libcore.package.harmony_sql' : [],
-      'android.core.tests.libcore.package.jsr166' : [],
-      'android.core.tests.libcore.package.okhttp' : [],
-      'android.display' : [],
-      'android.host.theme' : [],
-      'android.jdwp' : [],
-      'android.location2' : [],
-      'android.print' : [],
-      'android.renderscriptlegacy' : [],
-      'android.signature' : [],
-      'android.tv' : [],
-      'android.uiautomation' : [],
-      'android.uirendering' : [],
-      'android.webgl' : [],
-      'com.drawelements.deqp.gles3' : [],
-      'com.drawelements.deqp.gles31' : []}
-
 def BuildCtsFlakyTestList():
   """ Construct a defaultdict that maps package name to a list of tests
-      that are known to be flaky in the lab or not passing on userdebug builds. """
+      that are known to be flaky. """
   return {
       'android.app' : [
           'cts.ActivityManagerTest#testIsRunningInTestHarness',],
@@ -412,11 +363,7 @@
           'cts.SELinuxDomainTest#testSuDomain',
           'cts.SELinuxHostTest#testAllEnforcing',],
       'android.webkit' : [
-          'cts.WebViewClientTest#testOnUnhandledKeyEvent',],
-      'com.android.cts.filesystemperf' : [
-          'RandomRWTest#testRandomRead',
-          'RandomRWTest#testRandomUpdate',],
-      '' : []}
+          'cts.WebViewClientTest#testOnUnhandledKeyEvent',]}
 
 def LogGenerateDescription(name):
   print 'Generating test description for package %s' % name
diff --git a/tools/vm-tests-tf/Android.mk b/tools/vm-tests-tf/Android.mk
index 88f2a53..f96b780 100644
--- a/tools/vm-tests-tf/Android.mk
+++ b/tools/vm-tests-tf/Android.mk
@@ -14,6 +14,29 @@
 
 LOCAL_PATH := $(call my-dir)
 
+# test dex library
+# ============================================================
+include $(CLEAR_VARS)
+
+# custom variables used to generate test description. do not touch!
+LOCAL_SRC_FILES := $(call all-java-files-under, src/dot)
+
+LOCAL_MODULE := cts-tf-dalvik-lib
+LOCAL_MODULE_CLASS := JAVA_LIBRARIES
+LOCAL_MODULE_TAGS := optional
+LOCAL_JAVA_LIBRARIES := junit-hostdex
+LOCAL_CLASSPATH := $(HOST_JDK_TOOLS_JAR)
+
+include $(BUILD_HOST_DALVIK_JAVA_LIBRARY)
+
+cts-tf-dalvik-lib.jack := $(full_classes_jack)
+
+private_jill_jarjar_asm := $(addprefix $(HOST_OUT_JAVA_LIBRARIES)/,jill-jarjar-asm.jar)
+$(private_jill_jarjar_asm) : PRIVATE_JARJAR_RULES := $(LOCAL_PATH)/jill-jarjar-rules.txt
+$(private_jill_jarjar_asm) : $(addprefix $(HOST_OUT_JAVA_LIBRARIES)/,jill.jar) | $(JARJAR)
+	@echo JarJar: $@
+	$(hide) java -jar $(JARJAR) process $(PRIVATE_JARJAR_RULES) $< $@
+
 # buildutil java library
 # ============================================================
 include $(CLEAR_VARS)
@@ -29,16 +52,53 @@
 LOCAL_MODULE_TAGS := optional
 
 LOCAL_JAVA_LIBRARIES := dx dasm cfassembler junit
-LOCAL_CLASSPATH := $(HOST_JDK_TOOLS_JAR)
+LOCAL_JAVA_LIBRARIES += jack
+
+LOCAL_CLASSPATH := $(HOST_JDK_TOOLS_JAR) $(private_jill_jarjar_asm)
 
 include $(BUILD_HOST_JAVA_LIBRARY)
 
 # Buid android.core.vm-tests-tf.jar
 # ============================================================
 #
+
 intermediates := $(call intermediates-dir-for,JAVA_LIBRARIES,vm-tests-tf,HOST)
 vmteststf_jar := $(intermediates)/android.core.vm-tests-tf.jar
 vmteststf_dep_jars := $(addprefix $(HOST_OUT_JAVA_LIBRARIES)/, cts-tf-dalvik-buildutil.jar dasm.jar dx.jar cfassembler.jar junit.jar)
+vmteststf_dep_jars += $(addprefix $(HOST_OUT_JAVA_LIBRARIES)/, jack.jar)
+vmteststf_dep_jars += $(private_jill_jarjar_asm)
+
+$(vmteststf_jar): PRIVATE_JACK_VM_ARGS := $(DEFAULT_JACK_VM_ARGS)
+ifneq ($(ANDROID_JACK_VM_ARGS),)
+$(vmteststf_jar): PRIVATE_JACK_VM_ARGS := $(ANDROID_JACK_VM_ARGS)
+endif
+ifneq ($(LOCAL_JACK_VM_ARGS),)
+$(vmteststf_jar): PRIVATE_JACK_VM_ARGS := $(LOCAL_JACK_VM_ARGS)
+endif
+
+$(vmteststf_jar): PRIVATE_JACK_EXTRA_ARGS := $(DEFAULT_JACK_EXTRA_ARGS)
+ifneq ($(ANDROID_JACK_EXTRA_ARGS),)
+$(vmteststf_jar): PRIVATE_JACK_EXTRA_ARGS := $(ANDROID_JACK_EXTRA_ARGS)
+endif
+ifneq ($(LOCAL_JACK_EXTRA_ARGS),)
+$(vmteststf_jar): PRIVATE_JACK_EXTRA_ARGS := $(LOCAL_JACK_EXTRA_ARGS)
+endif
+
+$(vmteststf_jar): PRIVATE_JACK_VM := $(DEFAULT_JACK_VM)
+ifneq ($(strip $(ANDROID_JACK_VM)),)
+$(vmteststf_jar): PRIVATE_JACK_VM := $(ANDROID_JACK_VM)
+endif
+
+ifeq ($(strip $(LOCAL_USE_JACK)),true)
+    vmteststf_dep_jars += $(cts-tf-dalvik-lib.jack)
+endif
+
+$(intermediates)/junit.jack:$(LOCAL_PATH)/lib/junit.jar | $(JILL_JAR)
+	$(transform-jar-to-jack)
+
+$(intermediates)/tradefed-prebuilt.jack:$(HOST_OUT_JAVA_LIBRARIES)/tradefed-prebuilt.jar | $(JILL_JAR)
+	$(transform-jar-to-jack)
+
 $(vmteststf_jar): PRIVATE_SRC_FOLDER := $(LOCAL_PATH)/src
 $(vmteststf_jar): PRIVATE_LIB_FOLDER := $(LOCAL_PATH)/lib
 $(vmteststf_jar): PRIVATE_INTERMEDIATES_CLASSES := $(call intermediates-dir-for,JAVA_LIBRARIES,cts-tf-dalvik-buildutil,HOST)/classes
@@ -47,7 +107,8 @@
 $(vmteststf_jar): PRIVATE_INTERMEDIATES_MAIN_FILES := $(intermediates)/main_files
 $(vmteststf_jar): PRIVATE_INTERMEDIATES_HOSTJUNIT_FILES := $(intermediates)/hostjunit_files
 $(vmteststf_jar): PRIVATE_CLASS_PATH := $(subst $(space),:,$(vmteststf_dep_jars)):$(HOST_JDK_TOOLS_JAR)
-$(vmteststf_jar) : $(vmteststf_dep_jars) $(HOST_OUT_JAVA_LIBRARIES)/tradefed-prebuilt.jar
+ifneq ($(strip $(LOCAL_USE_JACK)),true)
+$(vmteststf_jar) : $(vmteststf_dep_jars) $(JACK_JAR) $(JILL_JAR) $(HOST_OUT_JAVA_LIBRARIES)/tradefed-prebuilt.jar
 	$(hide) rm -rf $(dir $@) && mkdir -p $(dir $@)
 	$(hide) mkdir -p $(PRIVATE_INTERMEDIATES_HOSTJUNIT_FILES)/dot/junit $(dir $(PRIVATE_INTERMEDIATES_DEXCORE_JAR))
 	# generated and compile the host side junit tests
@@ -62,6 +123,26 @@
 		$(if $(NO_OPTIMIZE_DX), --no-optimize) $(PRIVATE_INTERMEDIATES_DEXCORE_JAR).jar && rm -f $(PRIVATE_INTERMEDIATES_DEXCORE_JAR).jar
 	$(hide) cd $(PRIVATE_INTERMEDIATES_HOSTJUNIT_FILES)/classes && zip -q -r ../../android.core.vm-tests-tf.jar .
 	$(hide) cd $(dir $@) && zip -q -r android.core.vm-tests-tf.jar tests
+else # LOCAL_USE_JACK
+$(vmteststf_jar) : $(vmteststf_dep_jars) $(JACK_JAR) $(JILL_JAR) out/target/common/obj/JAVA_LIBRARIES/core-libart_intermediates/classes.jack $(HOST_OUT_JAVA_LIBRARIES)/tradefed-prebuilt.jar $(LOCAL_PATH)/lib/junit.jar $(intermediates)/tradefed-prebuilt.jack $(intermediates)/junit.jack
+	$(hide) rm -rf $(dir $@) && mkdir -p $(dir $@)
+	$(hide) mkdir -p $(PRIVATE_INTERMEDIATES_HOSTJUNIT_FILES)/dot/junit $(dir $(PRIVATE_INTERMEDIATES_DEXCORE_JAR))
+	# generated and compile the host side junit tests
+	@echo "Write generated Main_*.java files to $(PRIVATE_INTERMEDIATES_MAIN_FILES)"
+	$(hide) java -cp $(PRIVATE_CLASS_PATH) util.build.JackBuildDalvikSuite $(PRIVATE_SRC_FOLDER) $(PRIVATE_INTERMEDIATES) \
+		out/target/common/obj/JAVA_LIBRARIES/core-libart_intermediates/classes.jack:$(cts-tf-dalvik-lib.jack):$(HOST_OUT_JAVA_LIBRARIES)/tradefed-prebuilt.jar:$(LOCAL_PATH)/lib/junit.jar:$(PRIVATE_INTERMEDIATES)/junit.jack:$(PRIVATE_INTERMEDIATES)/tradefed-prebuilt.jack \
+		$(PRIVATE_INTERMEDIATES_MAIN_FILES) $(PRIVATE_INTERMEDIATES_CLASSES) $(PRIVATE_INTERMEDIATES_HOSTJUNIT_FILES) $$RUN_VM_TESTS_RTO
+	@echo "Generate $(PRIVATE_INTERMEDIATES_DEXCORE_JAR)"
+	$(hide) jar -cf $(PRIVATE_INTERMEDIATES_DEXCORE_JAR)-class.jar \
+		$(addprefix -C $(PRIVATE_INTERMEDIATES_CLASSES) , dot/junit/DxUtil.class dot/junit/DxAbstractMain.class)
+	$(hide) $(JILL) --output $(PRIVATE_INTERMEDIATES_DEXCORE_JAR).jack $(PRIVATE_INTERMEDIATES_DEXCORE_JAR)-class.jar
+	$(hide) mkdir -p $(PRIVATE_INTERMEDIATES_DEXCORE_JAR).tmp
+	$(hide) $(call call-jack,$(PRIVATE_JACK_VM),$(PRIVATE_JACK_VM_ARGS),$(PRIVATE_JACK_EXTRA_ARGS)) --output-dex $(PRIVATE_INTERMEDIATES_DEXCORE_JAR).tmp \
+		$(if $(NO_OPTIMIZE_DX), -D jack.dex.optimize "false") --import $(PRIVATE_INTERMEDIATES_DEXCORE_JAR).jack && rm -f $(PRIVATE_INTERMEDIATES_DEXCORE_JAR).jack
+	$(hide) cd $(PRIVATE_INTERMEDIATES_DEXCORE_JAR).tmp && zip -q -r $(abspath $(PRIVATE_INTERMEDIATES_DEXCORE_JAR)) .
+	$(hide) cd $(PRIVATE_INTERMEDIATES_HOSTJUNIT_FILES)/classes && zip -q -r ../../android.core.vm-tests-tf.jar .
+	$(hide) cd $(dir $@) && zip -q -r android.core.vm-tests-tf.jar tests
+endif # LOCAL_USE_JACK
 
 # Clean up temp vars
 intermediates :=
diff --git a/tools/vm-tests-tf/jill-jarjar-rules.txt b/tools/vm-tests-tf/jill-jarjar-rules.txt
new file mode 100644
index 0000000..ee6f403
--- /dev/null
+++ b/tools/vm-tests-tf/jill-jarjar-rules.txt
@@ -0,0 +1 @@
+rule org.objectweb.** com.android.jill.@0
\ No newline at end of file
diff --git a/tools/vm-tests-tf/src/util/build/BuildDalvikSuite.java b/tools/vm-tests-tf/src/util/build/BuildDalvikSuite.java
index c772c33..4ce8c38 100644
--- a/tools/vm-tests-tf/src/util/build/BuildDalvikSuite.java
+++ b/tools/vm-tests-tf/src/util/build/BuildDalvikSuite.java
@@ -78,6 +78,7 @@
 
     private int testClassCnt = 0;
     private int testMethodsCnt = 0;
+    private boolean useJack;
 
     /*
      * using a linked hashmap to keep the insertion order for iterators.
@@ -101,39 +102,47 @@
      */
     public static void main(String[] args) throws IOException {
 
-        if (args.length > 5) {
-            JAVASRC_FOLDER = args[0];
-            OUTPUT_FOLDER = args[1];
-            CLASS_PATH = args[2];
-            MAIN_SRC_OUTPUT_FOLDER = args[3];
-            CLASSES_OUTPUT_FOLDER = MAIN_SRC_OUTPUT_FOLDER + "/classes";
-
-            COMPILED_CLASSES_FOLDER = args[4];
-
-            HOSTJUNIT_SRC_OUTPUT_FOLDER = args[5];
-            HOSTJUNIT_CLASSES_OUTPUT_FOLDER = HOSTJUNIT_SRC_OUTPUT_FOLDER + "/classes";
-
-            if (args.length > 6) {
-                // optional: restrict to e.g. "opcodes.add_double"
-                restrictTo = args[6];
-                System.out.println("restricting build to: " + restrictTo);
-            }
-
-        } else {
-            System.out.println("usage: java-src-folder output-folder classpath " +
-                    "generated-main-files compiled_output generated-main-files " +
-            "[restrict-to-opcode]");
-            System.exit(-1);
-        }
+        parseArgs(args);
 
         long start = System.currentTimeMillis();
-        BuildDalvikSuite cat = new BuildDalvikSuite();
+        BuildDalvikSuite cat = new BuildDalvikSuite(false);
         cat.compose();
         long end = System.currentTimeMillis();
 
         System.out.println("elapsed seconds: " + (end - start) / 1000);
     }
 
+    public static void parseArgs(String[] args) {
+      if (args.length > 5) {
+          JAVASRC_FOLDER = args[0];
+          OUTPUT_FOLDER = args[1];
+          CLASS_PATH = args[2];
+          MAIN_SRC_OUTPUT_FOLDER = args[3];
+          CLASSES_OUTPUT_FOLDER = MAIN_SRC_OUTPUT_FOLDER + "/classes";
+
+          COMPILED_CLASSES_FOLDER = args[4];
+
+          HOSTJUNIT_SRC_OUTPUT_FOLDER = args[5];
+          HOSTJUNIT_CLASSES_OUTPUT_FOLDER = HOSTJUNIT_SRC_OUTPUT_FOLDER + "/classes";
+
+          if (args.length > 6) {
+              // optional: restrict to e.g. "opcodes.add_double"
+              restrictTo = args[6];
+              System.out.println("restricting build to: " + restrictTo);
+          }
+
+      } else {
+          System.out.println("usage: java-src-folder output-folder classpath " +
+                  "generated-main-files compiled_output generated-main-files " +
+          "[restrict-to-opcode]");
+          System.exit(-1);
+      }
+    }
+
+    public BuildDalvikSuite(boolean useJack) {
+      this.useJack = useJack;
+    }
+
     public void compose() throws IOException {
         System.out.println("Collecting all junit tests...");
         new TestRunner() {
@@ -182,19 +191,21 @@
         li.add(method);
     }
     private String curJunitFileName = null;
+    private String curJunitName = null;
     private String curJunitFileData = "";
 
-    private JavacBuildStep javacHostJunitBuildStep;
+    private SourceBuildStep hostJunitBuildStep;
 
     private void flushHostJunitFile() {
         if (curJunitFileName != null) {
             File toWrite = new File(curJunitFileName);
             String absPath = toWrite.getAbsolutePath();
             // add to java source files for later compilation
-            javacHostJunitBuildStep.addSourceFile(absPath);
+            hostJunitBuildStep.addSourceFile(absPath);
             // write file
             curJunitFileData += "\n}\n";
             writeToFileMkdir(toWrite, curJunitFileData);
+
             curJunitFileName = null;
             curJunitFileData = "";
         }
@@ -267,11 +278,11 @@
         String datafileContent = "";
         Set<BuildStep> targets = new TreeSet<BuildStep>();
 
-        javacHostJunitBuildStep = new JavacBuildStep(HOSTJUNIT_CLASSES_OUTPUT_FOLDER, CLASS_PATH);
+        SourceBuildStep srcBuildStep;
+        hostJunitBuildStep = new JavacBuildStep(
+            HOSTJUNIT_CLASSES_OUTPUT_FOLDER, CLASS_PATH);
 
-
-        JavacBuildStep javacBuildStep = new JavacBuildStep(
-                CLASSES_OUTPUT_FOLDER, CLASS_PATH);
+        srcBuildStep = new JavacBuildStep(CLASSES_OUTPUT_FOLDER, CLASS_PATH);
 
         for (Entry<String, List<String>> entry : map.entrySet()) {
 
@@ -334,19 +345,25 @@
                 "    public static void main(String[] args) throws Exception {" +
                 methodContent + "\n}\n";
 
-                String fileName = getFileName(pName, method, ".java");
                 File sourceFile = getFileFromPackage(pName, method);
 
-                File classFile = new File(CLASSES_OUTPUT_FOLDER + "/" +
-                        getFileName(pName, method, ".class"));
-                // if (sourceFile.lastModified() > classFile.lastModified()) {
                 writeToFile(sourceFile, content);
-                javacBuildStep.addSourceFile(sourceFile.getAbsolutePath());
+                if (useJack) {
+                    File jackFile = new File(CLASSES_OUTPUT_FOLDER + "/" +
+                            getFileName(pName, method, ".jack"));
+                    JackBuildStep step = new JackBuildStep(jackFile.getAbsolutePath(), CLASS_PATH);
+                    step.addSourceFile(sourceFile.getAbsolutePath());
+                    if (!step.build()) {
+                        System.out.println("main src dalvik-cts-buildutil build step failed");
+                        System.exit(1);
+                    }
+                } else {
+                    srcBuildStep.addSourceFile(sourceFile.getAbsolutePath());
+                }
 
                 BuildStep dexBuildStep = generateDexBuildStep(
-                        CLASSES_OUTPUT_FOLDER, getFileName(pName, method, ""));
+                        CLASSES_OUTPUT_FOLDER, getFileName(pName, method, ""), null);
                 targets.add(dexBuildStep);
-                // }
 
 
                 // prepare the entry in the data file for the bash script.
@@ -442,22 +459,23 @@
         scriptDataDir.mkdirs();
         writeToFile(new File(scriptDataDir, "scriptdata"), datafileContent);
 
-        if (!javacHostJunitBuildStep.build()) {
+        if (!hostJunitBuildStep.build()) {
             System.out.println("main javac cts-host-hostjunit-classes build step failed");
             System.exit(1);
         }
 
-        if (javacBuildStep.build()) {
-            for (BuildStep buildStep : targets) {
-                if (!buildStep.build()) {
-                    System.out.println("building failed. buildStep: " +
-                            buildStep.getClass().getName() + ", " + buildStep);
-                    System.exit(1);
-                }
+        if (!useJack) {
+            if (!srcBuildStep.build()) {
+                System.out.println("main src dalvik-cts-buildutil build step failed");
+                System.exit(1);
             }
-        } else {
-            System.out.println("main javac dalvik-cts-buildutil build step failed");
-            System.exit(1);
+        }
+        for (BuildStep buildStep : targets) {
+            if (!buildStep.build()) {
+                System.out.println("building failed. buildStep: " +
+                        buildStep.getClass().getName() + ", " + buildStep);
+                System.exit(1);
+            }
         }
     }
 
@@ -514,19 +532,37 @@
             return;
         }
 
-        if (new File(sourceFolder, fileName + ".java").exists()) {
-
+        File srcFile = new File(sourceFolder, fileName + ".java");
+        if (srcFile.exists()) {
+            JackBuildStep jackBuildStep = null;
+            if (useJack) {
+                jackBuildStep = new JackBuildStep(
+                        COMPILED_CLASSES_FOLDER + File.separator + fileName + ".jack",
+                        CLASS_PATH);
+                jackBuildStep.addSourceFile(srcFile.getAbsolutePath());
+            }
             BuildStep dexBuildStep = generateDexBuildStep(
-                    COMPILED_CLASSES_FOLDER, fileName);
+                COMPILED_CLASSES_FOLDER, fileName, jackBuildStep);
             targets.add(dexBuildStep);
             return;
         }
 
         try {
             if (Class.forName(dependentTestClassName) != null) {
+                JillBuildStep jillBuildStep = null;
+                if (useJack) {
+                    BuildStep.BuildFile classFile = new BuildStep.BuildFile(
+                        COMPILED_CLASSES_FOLDER, fileName + ".class");
 
+                    BuildStep.BuildFile jackFile = new BuildStep.BuildFile(
+                        COMPILED_CLASSES_FOLDER,
+                        fileName + ".jack");
+
+                    jillBuildStep = new JillBuildStep(classFile,
+                        jackFile);
+                }
                 BuildStep dexBuildStep = generateDexBuildStep(
-                        COMPILED_CLASSES_FOLDER, fileName);
+                    COMPILED_CLASSES_FOLDER, fileName, jillBuildStep);
                 targets.add(dexBuildStep);
                 return;
             }
@@ -539,24 +575,50 @@
     }
 
     private BuildStep generateDexBuildStep(String classFileFolder,
-            String classFileName) {
-        BuildStep.BuildFile classFile = new BuildStep.BuildFile(
-                classFileFolder, classFileName + ".class");
+            String classFileName, BuildStep dependency) {
+        if (!useJack) {
+            BuildStep.BuildFile classFile = new BuildStep.BuildFile(
+                    classFileFolder, classFileName + ".class");
 
-        BuildStep.BuildFile tmpJarFile = new BuildStep.BuildFile(OUTPUT_FOLDER,
-                classFileName + "_tmp.jar");
+            BuildStep.BuildFile tmpJarFile = new BuildStep.BuildFile(
+                    OUTPUT_FOLDER,
+                    classFileName + "_tmp.jar");
 
-        JarBuildStep jarBuildStep = new JarBuildStep(classFile, classFileName +
-                ".class", tmpJarFile, false);
+            JarBuildStep jarBuildStep = new JarBuildStep(classFile,
+                    classFileName + ".class", tmpJarFile, false);
 
-        BuildStep.BuildFile outputFile = new BuildStep.BuildFile(OUTPUT_FOLDER,
-                classFileName + ".jar");
+            if (dependency != null) {
+                jarBuildStep.addChild(dependency);
+            }
 
-        DexBuildStep dexBuildStep = new DexBuildStep(tmpJarFile, outputFile,
-                true);
+            BuildStep.BuildFile outputFile = new BuildStep.BuildFile(
+                    OUTPUT_FOLDER,
+                    classFileName + ".jar");
 
-        dexBuildStep.addChild(jarBuildStep);
-        return dexBuildStep;
+            DxBuildStep dexBuildStep = new DxBuildStep(tmpJarFile,
+                    outputFile,
+                    true);
+
+            dexBuildStep.addChild(jarBuildStep);
+            return dexBuildStep;
+        } else {
+          BuildStep.BuildFile jackFile = new BuildStep.BuildFile(
+              classFileFolder, classFileName + ".jack");
+
+          BuildStep.BuildFile outputFile = new BuildStep.BuildFile(
+                  OUTPUT_FOLDER,
+                  classFileName + ".jar");
+
+          JackDexBuildStep dexBuildStep = new JackDexBuildStep(jackFile,
+                  outputFile,
+                  true);
+
+          if (dependency != null) {
+              dexBuildStep.addChild(dependency);
+          }
+          return dexBuildStep;
+
+        }
 
     }
 
@@ -747,7 +809,7 @@
 
     private void writeToFile(File file, String content) {
         try {
-            if (file.length() == content.length()) {
+            if (file.exists() && file.length() == content.length()) {
                 FileReader reader = new FileReader(file);
                 char[] charContents = new char[(int) file.length()];
                 reader.read(charContents);
diff --git a/tools/vm-tests-tf/src/util/build/DexBuildStep.java b/tools/vm-tests-tf/src/util/build/DxBuildStep.java
similarity index 93%
rename from tools/vm-tests-tf/src/util/build/DexBuildStep.java
rename to tools/vm-tests-tf/src/util/build/DxBuildStep.java
index 6aba51c..6e347b2 100644
--- a/tools/vm-tests-tf/src/util/build/DexBuildStep.java
+++ b/tools/vm-tests-tf/src/util/build/DxBuildStep.java
@@ -19,11 +19,11 @@
 import com.android.dx.command.dexer.Main;
 import java.io.IOException;
 
-public class DexBuildStep extends BuildStep {
+public class DxBuildStep extends BuildStep {
 
     private final boolean deleteInputFileAfterBuild;
 
-    DexBuildStep(BuildFile inputFile, BuildFile outputFile,
+    DxBuildStep(BuildFile inputFile, BuildFile outputFile,
             boolean deleteInputFileAfterBuild) {
         super(inputFile, outputFile);
         this.deleteInputFileAfterBuild = deleteInputFileAfterBuild;
@@ -71,7 +71,7 @@
     @Override
     public boolean equals(Object obj) {
         if (super.equals(obj)) {
-            DexBuildStep other = (DexBuildStep) obj;
+            DxBuildStep other = (DxBuildStep) obj;
 
             return inputFile.equals(other.inputFile)
                     && outputFile.equals(other.outputFile);
diff --git a/tools/vm-tests-tf/src/util/build/JackBuildDalvikSuite.java b/tools/vm-tests-tf/src/util/build/JackBuildDalvikSuite.java
new file mode 100644
index 0000000..a508e5b
--- /dev/null
+++ b/tools/vm-tests-tf/src/util/build/JackBuildDalvikSuite.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2014 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 util.build;
+
+import java.io.IOException;
+
+public class JackBuildDalvikSuite {
+
+    public static void main(String[] args) throws IOException {
+
+        BuildDalvikSuite.parseArgs(args);
+
+        long start = System.currentTimeMillis();
+        BuildDalvikSuite cat = new BuildDalvikSuite(true);
+        cat.compose();
+        long end = System.currentTimeMillis();
+
+        System.out.println("elapsed seconds: " + (end - start) / 1000);
+    }
+}
diff --git a/tools/vm-tests-tf/src/util/build/JackBuildStep.java b/tools/vm-tests-tf/src/util/build/JackBuildStep.java
new file mode 100644
index 0000000..9e93475
--- /dev/null
+++ b/tools/vm-tests-tf/src/util/build/JackBuildStep.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2013 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 util.build;
+
+import com.android.jack.Jack;
+import com.android.jack.Main;
+import com.android.jack.Options;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+public class JackBuildStep extends SourceBuildStep {
+
+    private final String destPath;
+    private final String classPath;
+    private final Set<String> sourceFiles = new HashSet<String>();
+
+    public JackBuildStep(String destPath, String classPath) {
+        this.destPath = destPath;
+        this.classPath = classPath;
+    }
+
+    @Override
+    public void addSourceFile(String sourceFile) {
+        sourceFiles.add(sourceFile);
+    }
+
+    @Override
+    boolean build() {
+        if (super.build()) {
+            if (sourceFiles.isEmpty()) {
+                return true;
+            }
+
+            File outDir = new File(destPath).getParentFile();
+            if (!outDir.exists() && !outDir.mkdirs()) {
+                System.err.println("failed to create output dir: "
+                        + outDir.getAbsolutePath());
+                return false;
+            }
+            List<String> commandLine = new ArrayList(4 + sourceFiles.size());
+            commandLine.add("--classpath");
+            commandLine.add(classPath);
+            commandLine.add("--output-jack");
+            commandLine.add(destPath);
+            commandLine.addAll(sourceFiles);
+
+            try {
+                Options options = Main.parseCommandLine(commandLine);
+                Jack.run(options);
+            } catch (Throwable ex) {
+                ex.printStackTrace();
+                return false;
+            }
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (super.equals(obj)) {
+            JackBuildStep other = (JackBuildStep) obj;
+            return destPath.equals(other.destPath) && classPath.equals(other.classPath)
+                    && sourceFiles.equals(other.sourceFiles);
+        }
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        return destPath.hashCode() ^ classPath.hashCode() ^ sourceFiles.hashCode();
+    }
+}
diff --git a/tools/vm-tests-tf/src/util/build/JackDexBuildStep.java b/tools/vm-tests-tf/src/util/build/JackDexBuildStep.java
new file mode 100644
index 0000000..8d9771c
--- /dev/null
+++ b/tools/vm-tests-tf/src/util/build/JackDexBuildStep.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package util.build;
+
+import com.android.jack.Jack;
+import com.android.jack.Main;
+import com.android.jack.Options;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+public class JackDexBuildStep extends BuildStep {
+
+    private final boolean deleteInputFileAfterBuild;
+
+    JackDexBuildStep(BuildFile inputFile, BuildFile outputFile,
+            boolean deleteInputFileAfterBuild) {
+        super(inputFile, outputFile);
+        this.deleteInputFileAfterBuild = deleteInputFileAfterBuild;
+    }
+
+    @Override
+    boolean build() {
+
+        if (super.build()) {
+            String outputFilePath = outputFile.fileName.getAbsolutePath();
+            if (outputFilePath.endsWith(".dex")) {
+              throw new AssertionError(
+                  "DexBuildStep does not support dex output outside of an archive");
+            }
+
+            File outDir = outputFile.fileName.getParentFile();
+            if (!outDir.exists() && !outDir.mkdirs()) {
+                System.err.println("failed to create output dir: "
+                        + outDir.getAbsolutePath());
+                return false;
+            }
+
+            List<String> commandLine = new ArrayList<String>(4);
+            commandLine.add("--output-dex-zip");
+            commandLine.add(outputFilePath);
+            commandLine.add("--import");
+            commandLine.add(inputFile.fileName.getAbsolutePath());
+
+            try {
+               Options options = Main.parseCommandLine(commandLine);
+               Jack.run(options);
+                if (deleteInputFileAfterBuild) {
+                    inputFile.fileName.delete();
+                }
+                return true;
+            } catch (Throwable ex) {
+                System.err.println("exception while dexing "
+                        + inputFile.fileName.getAbsolutePath() + " to "
+                        + outputFile.fileName.getAbsolutePath());
+                ex.printStackTrace();
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        return inputFile.hashCode() ^ outputFile.hashCode();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (super.equals(obj)) {
+            JackDexBuildStep other = (JackDexBuildStep) obj;
+
+            return inputFile.equals(other.inputFile)
+                    && outputFile.equals(other.outputFile);
+        }
+        return false;
+    }
+
+
+}
diff --git a/tools/vm-tests-tf/src/util/build/JavacBuildStep.java b/tools/vm-tests-tf/src/util/build/JavacBuildStep.java
index 7d7033f..d08a2c6 100644
--- a/tools/vm-tests-tf/src/util/build/JavacBuildStep.java
+++ b/tools/vm-tests-tf/src/util/build/JavacBuildStep.java
@@ -23,7 +23,7 @@
 import java.util.HashSet;
 import java.util.Set;
 
-public class JavacBuildStep extends BuildStep {
+public class JavacBuildStep extends SourceBuildStep {
 
     private final String destPath;
     private final String classPath;
@@ -32,12 +32,13 @@
         this.destPath = destPath;
         this.classPath = classPath;
     }
-    
+
+    @Override
     public void addSourceFile(String sourceFile)
     {
         sourceFiles.add(sourceFile);
     }
-    
+
     @Override
     boolean build() {
         if (super.build())
@@ -46,7 +47,7 @@
             {
                 return true;
             }
-            
+
             File destFile = new File(destPath);
             if (!destFile.exists() && !destFile.mkdirs())
             {
@@ -59,13 +60,12 @@
             commandLine[1] = classPath;
             commandLine[2] = "-d";
             commandLine[3] = destPath;
-             
+
             String[] files = new String[sourceFiles.size()];
             sourceFiles.toArray(files);
-            
+
             System.arraycopy(files, 0, commandLine, args, files.length);
-            
-            
+
             return Main.compile(commandLine, new PrintWriter(System.err)) == 0;
         }
         return false;
@@ -73,17 +73,16 @@
 
     @Override
     public boolean equals(Object obj) {
-        // TODO Auto-generated method stub
         if (super.equals(obj))
         {
             JavacBuildStep other = (JavacBuildStep) obj;
-            return destPath.equals(other.destPath) 
+            return destPath.equals(other.destPath)
                 && classPath.equals(other.classPath)
                 && sourceFiles.equals(other.sourceFiles);
         }
         return false;
     }
-    
+
     @Override
     public int hashCode() {
         return destPath.hashCode() ^ classPath.hashCode() ^ sourceFiles.hashCode();
diff --git a/tools/vm-tests-tf/src/util/build/JillBuildStep.java b/tools/vm-tests-tf/src/util/build/JillBuildStep.java
new file mode 100644
index 0000000..aff3bb0
--- /dev/null
+++ b/tools/vm-tests-tf/src/util/build/JillBuildStep.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2013 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 util.build;
+
+import com.android.jill.Main;
+import com.android.jill.Options;
+
+import java.io.File;
+
+public class JillBuildStep extends BuildStep {
+
+    JillBuildStep(BuildFile inputFile, BuildFile outputFile) {
+        super(inputFile, outputFile);
+    }
+
+    @Override
+    boolean build() {
+        if (super.build()) {
+
+            File outDir = outputFile.fileName.getParentFile();
+            if (!outDir.exists() && !outDir.mkdirs()) {
+                System.err.println("failed to create output dir: "
+                        + outDir.getAbsolutePath());
+                return false;
+            }
+
+            int args = 3;
+            String[] commandLine = new String[args];
+            commandLine[0] = "--output";
+            commandLine[1] = outputFile.fileName.getAbsolutePath();
+            commandLine[2] = inputFile.fileName.getAbsolutePath();
+
+            try {
+                Options options = Main.getOptions(commandLine);
+                Main.run(options);
+            } catch (Throwable ex) {
+                ex.printStackTrace();
+                return false;
+            }
+
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (super.equals(obj)) {
+            JillBuildStep other = (JillBuildStep) obj;
+
+            return inputFile.equals(other.inputFile) && outputFile.equals(other.outputFile);
+        }
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        return inputFile.hashCode() ^ outputFile.hashCode();
+    }
+}
diff --git a/tools/vm-tests-tf/src/util/build/SourceBuildStep.java b/tools/vm-tests-tf/src/util/build/SourceBuildStep.java
new file mode 100644
index 0000000..4a68a05
--- /dev/null
+++ b/tools/vm-tests-tf/src/util/build/SourceBuildStep.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package util.build;
+
+public abstract class SourceBuildStep extends BuildStep {
+
+  public abstract void addSourceFile(String sourceFile);
+
+}