diff --git a/api/16.txt b/api/16.txt
index 8ff7675..aa23b4d 100644
--- a/api/16.txt
+++ b/api/16.txt
@@ -25204,7 +25204,6 @@
     method public java.lang.String getTitle();
     method public java.lang.String getUrl();
     method public deprecated int getVisibleTitleHeight();
-    method public deprecated android.view.View getZoomControls();
     method public void goBack();
     method public void goBackOrForward(int);
     method public void goForward();
@@ -41832,7 +41831,7 @@
     method public static void fail();
   }
 
-  public class AssertionFailedError extends java.lang.Error {
+  public class AssertionFailedError extends java.lang.AssertionError {
     ctor public AssertionFailedError();
     ctor public AssertionFailedError(java.lang.String);
   }
@@ -41890,9 +41889,9 @@
     method public synchronized void addListener(junit.framework.TestListener);
     method public void endTest(junit.framework.Test);
     method public synchronized int errorCount();
-    method public synchronized java.util.Enumeration errors();
+    method public synchronized java.util.Enumeration<junit.framework.TestFailure> errors();
     method public synchronized int failureCount();
-    method public synchronized java.util.Enumeration failures();
+    method public synchronized java.util.Enumeration<junit.framework.TestFailure> failures();
     method public synchronized void removeListener(junit.framework.TestListener);
     method protected void run(junit.framework.TestCase);
     method public synchronized int runCount();
@@ -41909,21 +41908,21 @@
 
   public class TestSuite implements junit.framework.Test {
     ctor public TestSuite();
-    ctor public TestSuite(java.lang.Class, java.lang.String);
-    ctor public TestSuite(java.lang.Class);
+    ctor public TestSuite(java.lang.Class<?>);
+    ctor public TestSuite(java.lang.Class<? extends junit.framework.TestCase>, java.lang.String);
     ctor public TestSuite(java.lang.String);
     method public void addTest(junit.framework.Test);
-    method public void addTestSuite(java.lang.Class);
+    method public void addTestSuite(java.lang.Class<? extends junit.framework.TestCase>);
     method public int countTestCases();
-    method public static junit.framework.Test createTest(java.lang.Class, java.lang.String);
+    method public static junit.framework.Test createTest(java.lang.Class<?>, java.lang.String);
     method public java.lang.String getName();
-    method public static java.lang.reflect.Constructor getTestConstructor(java.lang.Class) throws java.lang.NoSuchMethodException;
+    method public static java.lang.reflect.Constructor<?> getTestConstructor(java.lang.Class) throws java.lang.NoSuchMethodException;
     method public void run(junit.framework.TestResult);
     method public void runTest(junit.framework.Test, junit.framework.TestResult);
     method public void setName(java.lang.String);
     method public junit.framework.Test testAt(int);
     method public int testCount();
-    method public java.util.Enumeration tests();
+    method public java.util.Enumeration<junit.framework.Test> tests();
   }
 
 }
@@ -41946,7 +41945,7 @@
     method protected static java.util.Properties getPreferences();
     method public junit.framework.Test getTest(java.lang.String);
     method public static boolean inVAJava();
-    method protected java.lang.Class loadSuiteClass(java.lang.String) throws java.lang.ClassNotFoundException;
+    method protected java.lang.Class<?> loadSuiteClass(java.lang.String) throws java.lang.ClassNotFoundException;
     method protected java.lang.String processArguments(java.lang.String[]);
     method protected abstract void runFailed(java.lang.String);
     method public static void savePreferences() throws java.io.IOException;
diff --git a/api/current.txt b/api/current.txt
index ee964f7..bb313cd 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -19697,12 +19697,12 @@
     method public final void testApplicationTestCaseSetUpProperly() throws java.lang.Exception;
   }
 
-  public class AssertionFailedError extends java.lang.Error {
+  public deprecated class AssertionFailedError extends java.lang.Error {
     ctor public AssertionFailedError();
     ctor public AssertionFailedError(java.lang.String);
   }
 
-  public class ComparisonFailure extends android.test.AssertionFailedError {
+  public deprecated class ComparisonFailure extends android.test.AssertionFailedError {
     ctor public ComparisonFailure(java.lang.String, java.lang.String, java.lang.String);
   }
 
@@ -19744,6 +19744,7 @@
     ctor public InstrumentationTestSuite(android.app.Instrumentation);
     ctor public InstrumentationTestSuite(java.lang.String, android.app.Instrumentation);
     ctor public InstrumentationTestSuite(java.lang.Class, android.app.Instrumentation);
+    method public void addTestSuite(java.lang.Class);
   }
 
   public class IsolatedContext extends android.content.ContextWrapper {
@@ -25795,7 +25796,6 @@
     method public java.lang.String getTitle();
     method public java.lang.String getUrl();
     method public deprecated int getVisibleTitleHeight();
-    method public deprecated android.view.View getZoomControls();
     method public void goBack();
     method public void goBackOrForward(int);
     method public void goForward();
@@ -42498,15 +42498,21 @@
     method public static void assertTrue(boolean);
     method public static void fail(java.lang.String);
     method public static void fail();
+    method public static void failNotEquals(java.lang.String, java.lang.Object, java.lang.Object);
+    method public static void failNotSame(java.lang.String, java.lang.Object, java.lang.Object);
+    method public static void failSame(java.lang.String);
+    method public static java.lang.String format(java.lang.String, java.lang.Object, java.lang.Object);
   }
 
-  public class AssertionFailedError extends java.lang.Error {
+  public class AssertionFailedError extends java.lang.AssertionError {
     ctor public AssertionFailedError();
     ctor public AssertionFailedError(java.lang.String);
   }
 
   public class ComparisonFailure extends junit.framework.AssertionFailedError {
     ctor public ComparisonFailure(java.lang.String, java.lang.String, java.lang.String);
+    method public java.lang.String getActual();
+    method public java.lang.String getExpected();
   }
 
   public abstract interface Protectable {
@@ -42558,9 +42564,9 @@
     method public synchronized void addListener(junit.framework.TestListener);
     method public void endTest(junit.framework.Test);
     method public synchronized int errorCount();
-    method public synchronized java.util.Enumeration errors();
+    method public synchronized java.util.Enumeration<junit.framework.TestFailure> errors();
     method public synchronized int failureCount();
-    method public synchronized java.util.Enumeration failures();
+    method public synchronized java.util.Enumeration<junit.framework.TestFailure> failures();
     method public synchronized void removeListener(junit.framework.TestListener);
     method protected void run(junit.framework.TestCase);
     method public synchronized int runCount();
@@ -42577,21 +42583,24 @@
 
   public class TestSuite implements junit.framework.Test {
     ctor public TestSuite();
-    ctor public TestSuite(java.lang.Class, java.lang.String);
-    ctor public TestSuite(java.lang.Class);
+    ctor public TestSuite(java.lang.Class<?>);
+    ctor public TestSuite(java.lang.Class<? extends junit.framework.TestCase>, java.lang.String);
     ctor public TestSuite(java.lang.String);
+    ctor public TestSuite(java.lang.Class<?>...);
+    ctor public TestSuite(java.lang.Class<? extends junit.framework.TestCase>[], java.lang.String);
     method public void addTest(junit.framework.Test);
-    method public void addTestSuite(java.lang.Class);
+    method public void addTestSuite(java.lang.Class<? extends junit.framework.TestCase>);
     method public int countTestCases();
-    method public static junit.framework.Test createTest(java.lang.Class, java.lang.String);
+    method public static junit.framework.Test createTest(java.lang.Class<?>, java.lang.String);
     method public java.lang.String getName();
-    method public static java.lang.reflect.Constructor getTestConstructor(java.lang.Class) throws java.lang.NoSuchMethodException;
+    method public static java.lang.reflect.Constructor<?> getTestConstructor(java.lang.Class<?>) throws java.lang.NoSuchMethodException;
     method public void run(junit.framework.TestResult);
     method public void runTest(junit.framework.Test, junit.framework.TestResult);
     method public void setName(java.lang.String);
     method public junit.framework.Test testAt(int);
     method public int testCount();
-    method public java.util.Enumeration tests();
+    method public java.util.Enumeration<junit.framework.Test> tests();
+    method public static junit.framework.Test warning(java.lang.String);
   }
 
 }
@@ -42608,13 +42617,13 @@
     method public java.lang.String extractClassName(java.lang.String);
     method public static java.lang.String getFilteredTrace(java.lang.Throwable);
     method public static java.lang.String getFilteredTrace(java.lang.String);
-    method public junit.runner.TestSuiteLoader getLoader();
+    method public deprecated junit.runner.TestSuiteLoader getLoader();
     method public static java.lang.String getPreference(java.lang.String);
     method public static int getPreference(java.lang.String, int);
     method protected static java.util.Properties getPreferences();
     method public junit.framework.Test getTest(java.lang.String);
-    method public static boolean inVAJava();
-    method protected java.lang.Class loadSuiteClass(java.lang.String) throws java.lang.ClassNotFoundException;
+    method public static deprecated boolean inVAJava();
+    method protected java.lang.Class<?> loadSuiteClass(java.lang.String) throws java.lang.ClassNotFoundException;
     method protected java.lang.String processArguments(java.lang.String[]);
     method protected abstract void runFailed(java.lang.String);
     method public static void savePreferences() throws java.io.IOException;
diff --git a/core/java/android/accounts/AccountManagerService.java b/core/java/android/accounts/AccountManagerService.java
index 241fecb..2b643c2 100644
--- a/core/java/android/accounts/AccountManagerService.java
+++ b/core/java/android/accounts/AccountManagerService.java
@@ -1869,9 +1869,12 @@
         File systemDir = Environment.getSystemSecureDirectory();
         File databaseFile = new File(systemDir, "users/" + userId + "/" + DATABASE_NAME);
         if (userId == 0) {
-            // Migrate old file, if it exists, to the new location
+            // Migrate old file, if it exists, to the new location.
+            // Make sure the new file doesn't already exist. A dummy file could have been
+            // accidentally created in the old location, causing the new one to become corrupted
+            // as well.
             File oldFile = new File(systemDir, DATABASE_NAME);
-            if (oldFile.exists()) {
+            if (oldFile.exists() && !databaseFile.exists()) {
                 // Check for use directory; create if it doesn't exist, else renameTo will fail
                 File userDir = new File(systemDir, "users/" + userId);
                 if (!userDir.exists()) {
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 227900e..1c820dc 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -4656,7 +4656,7 @@
 
     /**
      * Print the Activity's state into the given stream.  This gets invoked if
-     * you run "adb shell dumpsys activity <activity_component_name>".
+     * you run "adb shell dumpsys activity &lt;activity_component_name&gt;".
      *
      * @param prefix Desired prefix to prepend at each line of output.
      * @param fd The raw file descriptor that the dump is being sent to.
diff --git a/core/java/android/app/Fragment.java b/core/java/android/app/Fragment.java
index c493f0f..d3ba497 100644
--- a/core/java/android/app/Fragment.java
+++ b/core/java/android/app/Fragment.java
@@ -203,7 +203,7 @@
  * <li> {@link #onCreateView} creates and returns the view hierarchy associated
  * with the fragment.
  * <li> {@link #onActivityCreated} tells the fragment that its activity has
- * completed its own {@link Activity#onCreate Activity.onCreaate}.
+ * completed its own {@link Activity#onCreate Activity.onCreate()}.
  * <li> {@link #onStart} makes the fragment visible to the user (based on its
  * containing activity being started).
  * <li> {@link #onResume} makes the fragment interacting with the user (based on its
diff --git a/core/java/android/app/Service.java b/core/java/android/app/Service.java
index 207ae76..cb43d4c 100644
--- a/core/java/android/app/Service.java
+++ b/core/java/android/app/Service.java
@@ -666,8 +666,8 @@
     
     /**
      * Print the Service's state into the given stream.  This gets invoked if
-     * you run "adb shell dumpsys activity service <yourservicename>".
-     * This is distinct from "dumpsys <servicename>", which only works for
+     * you run "adb shell dumpsys activity service &lt;yourservicename&gt;".
+     * This is distinct from "dumpsys &lt;servicename&gt;", which only works for
      * named system services and which invokes the {@link IBinder#dump} method
      * on the {@link IBinder} interface registered with ServiceManager.
      *
diff --git a/core/java/android/content/ContentProvider.java b/core/java/android/content/ContentProvider.java
index 05ef194..1206056 100644
--- a/core/java/android/content/ContentProvider.java
+++ b/core/java/android/content/ContentProvider.java
@@ -1127,7 +1127,7 @@
 
     /**
      * Print the Provider's state into the given stream.  This gets invoked if
-     * you run "adb shell dumpsys activity provider <provider_component_name>".
+     * you run "adb shell dumpsys activity provider &lt;provider_component_name&gt;".
      *
      * @param prefix Desired prefix to prepend at each line of output.
      * @param fd The raw file descriptor that the dump is being sent to.
diff --git a/core/java/android/content/SyncManager.java b/core/java/android/content/SyncManager.java
index 6219de7..34c40a0 100644
--- a/core/java/android/content/SyncManager.java
+++ b/core/java/android/content/SyncManager.java
@@ -205,6 +205,9 @@
 
     private final PowerManager mPowerManager;
 
+    // Use this as a random offset to seed all periodic syncs
+    private int mSyncRandomOffsetMillis;
+
     private static final long SYNC_ALARM_TIMEOUT_MIN = 30 * 1000; // 30 seconds
     private static final long SYNC_ALARM_TIMEOUT_MAX = 2 * 60 * 60 * 1000; // two hours
 
@@ -438,6 +441,9 @@
             // do this synchronously to ensure we have the accounts before this call returns
             onAccountsUpdated(null);
         }
+
+        // Pick a random second in a day to seed all periodic syncs
+        mSyncRandomOffsetMillis = mSyncStorageEngine.getSyncRandomOffset() * 1000;
     }
 
     /**
@@ -666,6 +672,7 @@
 
     private void sendCheckAlarmsMessage() {
         if (Log.isLoggable(TAG, Log.VERBOSE)) Log.v(TAG, "sending MESSAGE_CHECK_ALARMS");
+        mSyncHandler.removeMessages(SyncHandler.MESSAGE_CHECK_ALARMS);
         mSyncHandler.sendEmptyMessage(SyncHandler.MESSAGE_CHECK_ALARMS);
     }
 
@@ -714,6 +721,8 @@
     }
 
     private void increaseBackoffSetting(SyncOperation op) {
+        // TODO: Use this function to align it to an already scheduled sync
+        //       operation in the specified window
         final long now = SystemClock.elapsedRealtime();
 
         final Pair<Long, Long> previousSettings =
@@ -1060,6 +1069,8 @@
         final long now = SystemClock.elapsedRealtime();
         pw.print("now: "); pw.print(now);
         pw.println(" (" + formatTime(System.currentTimeMillis()) + ")");
+        pw.print("offset: "); pw.print(DateUtils.formatElapsedTime(mSyncRandomOffsetMillis/1000));
+        pw.println(" (HH:MM:SS)");
         pw.print("uptime: "); pw.print(DateUtils.formatElapsedTime(now/1000));
                 pw.println(" (HH:MM:SS)");
         pw.print("time spent syncing: ");
@@ -1771,6 +1782,9 @@
             AccountAndUser[] accounts = mAccounts;
 
             final long nowAbsolute = System.currentTimeMillis();
+            final long shiftedNowAbsolute = (0 < nowAbsolute - mSyncRandomOffsetMillis)
+                                               ? (nowAbsolute  - mSyncRandomOffsetMillis) : 0;
+
             ArrayList<SyncStorageEngine.AuthorityInfo> infos = mSyncStorageEngine.getAuthorities();
             for (SyncStorageEngine.AuthorityInfo info : infos) {
                 // skip the sync if the account of this operation no longer exists
@@ -1792,16 +1806,32 @@
                 SyncStatusInfo status = mSyncStorageEngine.getOrCreateSyncStatus(info);
                 for (int i = 0, N = info.periodicSyncs.size(); i < N; i++) {
                     final Bundle extras = info.periodicSyncs.get(i).first;
-                    final Long periodInSeconds = info.periodicSyncs.get(i).second;
+                    final Long periodInMillis = info.periodicSyncs.get(i).second * 1000;
                     // find when this periodic sync was last scheduled to run
                     final long lastPollTimeAbsolute = status.getPeriodicSyncTime(i);
-                    // compute when this periodic sync should next run - this can be in the future
-                    // for example if the user changed the time, synced and changed back.
-                    final long nextPollTimeAbsolute = lastPollTimeAbsolute > nowAbsolute
-                            ? nowAbsolute
-                            : lastPollTimeAbsolute + periodInSeconds * 1000;
-                    // if it is ready to run then schedule it and mark it as having been scheduled
-                    if (nextPollTimeAbsolute <= nowAbsolute) {
+
+                    long remainingMillis
+                            = periodInMillis - (shiftedNowAbsolute % periodInMillis);
+
+                    /*
+                     * Sync scheduling strategy:
+                     *    Set the next periodic sync based on a random offset (in seconds).
+                     *
+                     *    Also sync right now if any of the following cases hold
+                     *    and mark it as having been scheduled
+                     *
+                     * Case 1:  This sync is ready to run now.
+                     * Case 2:  If the lastPollTimeAbsolute is in the future,
+                     *          sync now and reinitialize. This can happen for
+                     *          example if the user changed the time, synced and
+                     *          changed back.
+                     * Case 3:  If we failed to sync at the last scheduled time
+                     */
+                    if (remainingMillis == periodInMillis  // Case 1
+                            || lastPollTimeAbsolute > nowAbsolute // Case 2
+                            || (nowAbsolute - lastPollTimeAbsolute
+                                    >= periodInMillis)) { // Case 3
+                        // Sync now
                         final Pair<Long, Long> backoff = mSyncStorageEngine.getBackoff(
                                 info.account, info.userId, info.authority);
                         final RegisteredServicesCache.ServiceInfo<SyncAdapterType> syncAdapterInfo =
@@ -1819,12 +1849,13 @@
                                                 info.account, info.userId, info.authority),
                                         syncAdapterInfo.type.allowParallelSyncs()));
                         status.setPeriodicSyncTime(i, nowAbsolute);
-                    } else {
-                        // it isn't ready to run, remember this time if it is earlier than
-                        // earliestFuturePollTime
-                        if (nextPollTimeAbsolute < earliestFuturePollTime) {
-                            earliestFuturePollTime = nextPollTimeAbsolute;
-                        }
+                    }
+                    // Compute when this periodic sync should next run
+                    final long nextPollTimeAbsolute = nowAbsolute + remainingMillis;
+
+                    // remember this time if it is earlier than earliestFuturePollTime
+                    if (nextPollTimeAbsolute < earliestFuturePollTime) {
+                        earliestFuturePollTime = nextPollTimeAbsolute;
                     }
                 }
             }
diff --git a/core/java/android/content/SyncStorageEngine.java b/core/java/android/content/SyncStorageEngine.java
index d3baf70..d821918 100644
--- a/core/java/android/content/SyncStorageEngine.java
+++ b/core/java/android/content/SyncStorageEngine.java
@@ -37,6 +37,7 @@
 import android.os.Parcel;
 import android.os.RemoteCallbackList;
 import android.os.RemoteException;
+import android.os.SystemClock;
 import android.util.Log;
 import android.util.SparseArray;
 import android.util.Xml;
@@ -49,6 +50,7 @@
 import java.util.Calendar;
 import java.util.HashMap;
 import java.util.Iterator;
+import java.util.Random;
 import java.util.TimeZone;
 import java.util.List;
 
@@ -65,6 +67,7 @@
 
     private static final String XML_ATTR_NEXT_AUTHORITY_ID = "nextAuthorityId";
     private static final String XML_ATTR_LISTEN_FOR_TICKLES = "listen-for-tickles";
+    private static final String XML_ATTR_SYNC_RANDOM_OFFSET = "offsetInSeconds";
     private static final String XML_ATTR_ENABLED = "enabled";
     private static final String XML_ATTR_USER = "user";
     private static final String XML_TAG_LISTEN_FOR_TICKLES = "listenForTickles";
@@ -277,6 +280,8 @@
 
     private static volatile SyncStorageEngine sSyncStorageEngine = null;
 
+    private int mSyncRandomOffset;
+
     /**
      * This file contains the core engine state: all accounts and the
      * settings for them.  It must never be lost, and should be changed
@@ -375,6 +380,10 @@
         }
     }
 
+    public int getSyncRandomOffset() {
+        return mSyncRandomOffset;
+    }
+
     public void addStatusChangeListener(int mask, ISyncStatusObserver callback) {
         synchronized (mAuthorities) {
             mChangeListeners.register(callback, mask);
@@ -1465,6 +1474,16 @@
                 } catch (NumberFormatException e) {
                     // don't care
                 }
+                String offsetString = parser.getAttributeValue(null, XML_ATTR_SYNC_RANDOM_OFFSET);
+                try {
+                    mSyncRandomOffset = (offsetString == null) ? 0 : Integer.parseInt(offsetString);
+                } catch (NumberFormatException e) {
+                    mSyncRandomOffset = 0;
+                }
+                if (mSyncRandomOffset == 0) {
+                    Random random = new Random(System.currentTimeMillis());
+                    mSyncRandomOffset = random.nextInt(86400);
+                }
                 mMasterSyncAutomatically.put(0, listen == null || Boolean.parseBoolean(listen));
                 eventType = parser.next();
                 AuthorityInfo authority = null;
@@ -1705,6 +1724,7 @@
             out.startTag(null, "accounts");
             out.attribute(null, "version", Integer.toString(ACCOUNTS_VERSION));
             out.attribute(null, XML_ATTR_NEXT_AUTHORITY_ID, Integer.toString(mNextAuthorityId));
+            out.attribute(null, XML_ATTR_SYNC_RANDOM_OFFSET, Integer.toString(mSyncRandomOffset));
 
             // Write the Sync Automatically flags for each user
             final int M = mMasterSyncAutomatically.size();
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index b06b4a5..5d890d4 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -1095,6 +1095,18 @@
     /** {@hide} */
     public static final int ENFORCEMENT_YES = 1;
 
+    /** {@hide} */
+    public static String enforcementToString(int enforcement) {
+        switch (enforcement) {
+            case ENFORCEMENT_DEFAULT:
+                return "DEFAULT";
+            case ENFORCEMENT_YES:
+                return "YES";
+            default:
+                return Integer.toString(enforcement);
+        }
+    }
+
     /**
      * Retrieve overall information about an application package that is
      * installed on the system.
diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java
index aa0ac74..8bc36b7 100644
--- a/core/java/android/view/HardwareRenderer.java
+++ b/core/java/android/view/HardwareRenderer.java
@@ -237,6 +237,17 @@
     abstract boolean validate();
 
     /**
+     * This method ensures the hardware renderer is in a valid state
+     * before executing the specified action.
+     * 
+     * This method will attempt to set a valid state even if the window
+     * the renderer is attached to was destroyed.
+     *
+     * @return true if the action was run
+     */
+    abstract boolean safelyRun(Runnable action);
+
+    /**
      * Setup the hardware renderer for drawing. This is called whenever the
      * size of the target surface changes or when the surface is first created.
      * 
@@ -1380,26 +1391,40 @@
         }
 
         @Override
-        void destroyHardwareResources(View view) {
-            if (view != null) {
-                boolean needsContext = true;
-                if (isEnabled() && checkCurrent() != SURFACE_STATE_ERROR) needsContext = false;
+        boolean safelyRun(Runnable action) {
+            boolean needsContext = true;
+            if (isEnabled() && checkCurrent() != SURFACE_STATE_ERROR) needsContext = false;
 
-                if (needsContext) {
-                    Gl20RendererEglContext managedContext =
-                            (Gl20RendererEglContext) sEglContextStorage.get();
-                    if (managedContext == null) return;
-                    usePbufferSurface(managedContext.getContext());
-                }
+            if (needsContext) {
+                Gl20RendererEglContext managedContext =
+                        (Gl20RendererEglContext) sEglContextStorage.get();
+                if (managedContext == null) return false;
+                usePbufferSurface(managedContext.getContext());
+            }
 
-                destroyResources(view);
-                GLES20Canvas.flushCaches(GLES20Canvas.FLUSH_CACHES_LAYERS);
-
+            try {
+                action.run();
+            } finally {
                 if (needsContext) {
                     sEgl.eglMakeCurrent(sEglDisplay, EGL_NO_SURFACE,
                             EGL_NO_SURFACE, EGL_NO_CONTEXT);
                 }
             }
+
+            return true;
+        }
+
+        @Override
+        void destroyHardwareResources(final View view) {
+            if (view != null) {
+                safelyRun(new Runnable() {
+                    @Override
+                    public void run() {
+                        destroyResources(view);
+                        GLES20Canvas.flushCaches(GLES20Canvas.FLUSH_CACHES_LAYERS);
+                    }
+                });
+            }
         }
 
         private static void destroyResources(View view) {
diff --git a/core/java/android/view/MotionEvent.java b/core/java/android/view/MotionEvent.java
index 77fd8d2..e51ba3d 100644
--- a/core/java/android/view/MotionEvent.java
+++ b/core/java/android/view/MotionEvent.java
@@ -2715,6 +2715,67 @@
     }
 
     /**
+     * Adds all of the movement samples of the specified event to this one if
+     * it is compatible.  To be compatible, the event must have the same device id,
+     * source, action, flags, pointer count, pointer properties.
+     *
+     * Only applies to {@link #ACTION_MOVE} or {@link #ACTION_HOVER_MOVE} events.
+     *
+     * @param event The event whose movements samples should be added to this one
+     * if possible.
+     * @return True if batching was performed or false if batching was not possible.
+     * @hide
+     */
+    public final boolean addBatch(MotionEvent event) {
+        final int action = nativeGetAction(mNativePtr);
+        if (action != ACTION_MOVE && action != ACTION_HOVER_MOVE) {
+            return false;
+        }
+        if (action != nativeGetAction(event.mNativePtr)) {
+            return false;
+        }
+
+        if (nativeGetDeviceId(mNativePtr) != nativeGetDeviceId(event.mNativePtr)
+                || nativeGetSource(mNativePtr) != nativeGetSource(event.mNativePtr)
+                || nativeGetFlags(mNativePtr) != nativeGetFlags(event.mNativePtr)) {
+            return false;
+        }
+
+        final int pointerCount = nativeGetPointerCount(mNativePtr);
+        if (pointerCount != nativeGetPointerCount(event.mNativePtr)) {
+            return false;
+        }
+
+        synchronized (gSharedTempLock) {
+            ensureSharedTempPointerCapacity(Math.max(pointerCount, 2));
+            final PointerProperties[] pp = gSharedTempPointerProperties;
+            final PointerCoords[] pc = gSharedTempPointerCoords;
+
+            for (int i = 0; i < pointerCount; i++) {
+                nativeGetPointerProperties(mNativePtr, i, pp[0]);
+                nativeGetPointerProperties(event.mNativePtr, i, pp[1]);
+                if (!pp[0].equals(pp[1])) {
+                    return false;
+                }
+            }
+
+            final int metaState = nativeGetMetaState(event.mNativePtr);
+            final int historySize = nativeGetHistorySize(event.mNativePtr);
+            for (int h = 0; h <= historySize; h++) {
+                final int historyPos = (h == historySize ? HISTORY_CURRENT : h);
+
+                for (int i = 0; i < pointerCount; i++) {
+                    nativeGetPointerCoords(event.mNativePtr, i, historyPos, pc[i]);
+                }
+
+                final long eventTimeNanos = nativeGetEventTimeNanos(event.mNativePtr, historyPos);
+                nativeAddBatch(mNativePtr, eventTimeNanos, pc, metaState);
+            }
+        }
+        return true;
+    }
+
+    /**
      * Returns true if all points in the motion event are completely within the specified bounds.
      * @hide
      */
@@ -3416,5 +3477,22 @@
             id = other.id;
             toolType = other.toolType;
         }
+
+        @Override
+        public boolean equals(Object other) {
+            if (other instanceof PointerProperties) {
+                return equals((PointerProperties)other);
+            }
+            return false;
+        }
+
+        private boolean equals(PointerProperties other) {
+            return other != null && id == other.id && toolType == other.toolType;
+        }
+
+        @Override
+        public int hashCode() {
+            return id | (toolType << 8);
+        }
     }
 }
diff --git a/core/java/android/view/TextureView.java b/core/java/android/view/TextureView.java
index 3cd8b71..ba62e65 100644
--- a/core/java/android/view/TextureView.java
+++ b/core/java/android/view/TextureView.java
@@ -204,7 +204,18 @@
     @Override
     protected void onDetachedFromWindow() {
         super.onDetachedFromWindow();
-        destroySurface();
+        if (mLayer != null && mAttachInfo != null && mAttachInfo.mHardwareRenderer != null) {
+            boolean success = mAttachInfo.mHardwareRenderer.safelyRun(new Runnable() {
+                @Override
+                public void run() {
+                    destroySurface();
+                }
+            });
+
+            if (!success) {
+                Log.w(LOG_TAG, "TextureView was not able to destroy its surface: " + this);
+            }
+        }
     }
 
     private void destroySurface() {
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 84632c6..d1cfc6b 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -1539,6 +1539,7 @@
      *
      * @deprecated The built-in zoom mechanism is preferred, see
      *             {@link WebSettings#setBuiltInZoomControls(boolean)}.
+     * @hide since API version 16.
      */
     @Deprecated
     public View getZoomControls() {
diff --git a/core/java/android/webkit/WebViewClassic.java b/core/java/android/webkit/WebViewClassic.java
index d7ebf5c..5dc2681 100644
--- a/core/java/android/webkit/WebViewClassic.java
+++ b/core/java/android/webkit/WebViewClassic.java
@@ -57,6 +57,7 @@
 import android.os.AsyncTask;
 import android.os.Bundle;
 import android.os.Handler;
+import android.os.Looper;
 import android.os.Message;
 import android.os.SystemClock;
 import android.provider.Settings;
@@ -100,7 +101,6 @@
 import android.webkit.WebViewCore.DrawData;
 import android.webkit.WebViewCore.EventHub;
 import android.webkit.WebViewCore.TextFieldInitData;
-import android.webkit.WebViewCore.TouchEventData;
 import android.webkit.WebViewCore.TouchHighlightData;
 import android.webkit.WebViewCore.WebKitHitTest;
 import android.widget.AbsoluteLayout;
@@ -981,6 +981,8 @@
 
     /**
      * Touch mode
+     * TODO: Some of this is now unnecessary as it is handled by
+     * WebInputTouchDispatcher (such as click, long press, and double tap).
      */
     private int mTouchMode = TOUCH_DONE_MODE;
     private static final int TOUCH_INIT_MODE = 1;
@@ -994,35 +996,10 @@
     private static final int TOUCH_DRAG_LAYER_MODE = 9;
     private static final int TOUCH_DRAG_TEXT_MODE = 10;
 
-    // Whether to forward the touch events to WebCore
-    // Can only be set by WebKit via JNI.
-    private boolean mForwardTouchEvents = false;
-
-    // Whether to prevent default during touch. The initial value depends on
-    // mForwardTouchEvents. If WebCore wants all the touch events, it says yes
-    // for touch down. Otherwise UI will wait for the answer of the first
-    // confirmed move before taking over the control.
-    private static final int PREVENT_DEFAULT_NO = 0;
-    private static final int PREVENT_DEFAULT_MAYBE_YES = 1;
-    private static final int PREVENT_DEFAULT_NO_FROM_TOUCH_DOWN = 2;
-    private static final int PREVENT_DEFAULT_YES = 3;
-    private static final int PREVENT_DEFAULT_IGNORE = 4;
-    private int mPreventDefault = PREVENT_DEFAULT_IGNORE;
-
     // true when the touch movement exceeds the slop
     private boolean mConfirmMove;
     private boolean mTouchInEditText;
 
-    // if true, touch events will be first processed by WebCore, if prevent
-    // default is not set, the UI will continue handle them.
-    private boolean mDeferTouchProcess;
-
-    // to avoid interfering with the current touch events, track them
-    // separately. Currently no snapping or fling in the deferred process mode
-    private int mDeferTouchMode = TOUCH_DONE_MODE;
-    private float mLastDeferTouchX;
-    private float mLastDeferTouchY;
-
     // Whether or not to draw the cursor ring.
     private boolean mDrawCursorRing = true;
 
@@ -1410,7 +1387,7 @@
     private boolean mSentAutoScrollMessage = false;
 
     // used for serializing asynchronously handled touch events.
-    private final TouchEventQueue mTouchEventQueue = new TouchEventQueue();
+    private WebViewInputDispatcher mInputDispatcher;
 
     // Used to track whether picture updating was paused due to a window focus change.
     private boolean mPictureUpdatePausedForFocusChange = false;
@@ -1500,6 +1477,68 @@
 
     }
 
+    private void onHandleUiEvent(MotionEvent event, int eventType, int flags) {
+        switch (eventType) {
+        case WebViewInputDispatcher.EVENT_TYPE_LONG_PRESS:
+            HitTestResult hitTest = getHitTestResult();
+            if (hitTest != null
+                    && hitTest.getType() != HitTestResult.UNKNOWN_TYPE) {
+                performLongClick();
+            }
+            break;
+        case WebViewInputDispatcher.EVENT_TYPE_DOUBLE_TAP:
+            mZoomManager.handleDoubleTap(event.getX(), event.getY());
+            break;
+        case WebViewInputDispatcher.EVENT_TYPE_TOUCH:
+            onHandleUiTouchEvent(event);
+            break;
+        }
+    }
+
+    private void onHandleUiTouchEvent(MotionEvent ev) {
+        final ScaleGestureDetector detector =
+                mZoomManager.getMultiTouchGestureDetector();
+
+        float x = ev.getX();
+        float y = ev.getY();
+
+        if (detector != null) {
+            detector.onTouchEvent(ev);
+            if (detector.isInProgress()) {
+                mLastTouchTime = ev.getEventTime();
+                x = detector.getFocusX();
+                y = detector.getFocusY();
+
+                mWebView.cancelLongPress();
+                mPrivateHandler.removeMessages(SWITCH_TO_LONGPRESS);
+                if (!mZoomManager.supportsPanDuringZoom()) {
+                    return;
+                }
+                mTouchMode = TOUCH_DRAG_MODE;
+                if (mVelocityTracker == null) {
+                    mVelocityTracker = VelocityTracker.obtain();
+                }
+            }
+        }
+
+        int action = ev.getActionMasked();
+        if (action == MotionEvent.ACTION_POINTER_DOWN) {
+            cancelTouch();
+            action = MotionEvent.ACTION_DOWN;
+        } else if (action == MotionEvent.ACTION_POINTER_UP && ev.getPointerCount() >= 2) {
+            // set mLastTouchX/Y to the remaining points for multi-touch.
+            mLastTouchX = Math.round(x);
+            mLastTouchY = Math.round(y);
+        } else if (action == MotionEvent.ACTION_MOVE) {
+            // negative x or y indicate it is on the edge, skip it.
+            if (x < 0 || y < 0) {
+                return;
+            }
+        }
+
+        handleTouchEventCommon(ev, action, Math.round(x), Math.round(y));
+    }
+
     // The webview that is bound to this WebViewClassic instance. Primarily needed for supplying
     // as the first param in the WebViewClient and WebChromeClient callbacks.
     final private WebView mWebView;
@@ -4372,8 +4411,7 @@
         boolean animateScroll = ((!mScroller.isFinished()
                 || mVelocityTracker != null)
                 && (mTouchMode != TOUCH_DRAG_MODE ||
-                mHeldMotionless != MOTIONLESS_TRUE))
-                || mDeferTouchMode == TOUCH_DRAG_MODE;
+                mHeldMotionless != MOTIONLESS_TRUE));
         if (mTouchMode == TOUCH_DRAG_MODE) {
             if (mHeldMotionless == MOTIONLESS_PENDING) {
                 mPrivateHandler.removeMessages(DRAG_HELD_MOTIONLESS);
@@ -5573,7 +5611,6 @@
 
         addAccessibilityApisToJavaScript();
 
-        mTouchEventQueue.reset();
         updateHwAccelerated();
     }
 
@@ -5822,20 +5859,6 @@
      */
     private static final float MMA_WEIGHT_N = 5;
 
-    private boolean hitFocusedPlugin(int contentX, int contentY) {
-        // TODO: Figure out what to do with this (b/6111517)
-        return false;
-    }
-
-    private boolean shouldForwardTouchEvent() {
-        if (mFullScreenHolder != null) return true;
-        if (mBlockWebkitViewMessages) return false;
-        return mForwardTouchEvents
-                && !mSelectingText
-                && mPreventDefault != PREVENT_DEFAULT_IGNORE
-                && mPreventDefault != PREVENT_DEFAULT_NO;
-    }
-
     private boolean inFullScreenMode() {
         return mFullScreenHolder != null;
     }
@@ -5905,23 +5928,17 @@
             mWebView.requestFocus();
         }
 
-        if (DebugFlags.WEB_VIEW) {
-            Log.v(LOGTAG, ev + " at " + ev.getEventTime()
-                + " mTouchMode=" + mTouchMode
-                + " numPointers=" + ev.getPointerCount());
+        if (mInputDispatcher == null) {
+            return false;
         }
 
-        // If WebKit wasn't interested in this multitouch gesture, enqueue
-        // the event for handling directly rather than making the round trip
-        // to WebKit and back.
-        if (ev.getPointerCount() > 1 && mPreventDefault != PREVENT_DEFAULT_NO) {
-            passMultiTouchToWebKit(ev, mTouchEventQueue.nextTouchSequence());
+        if (mInputDispatcher.postPointerEvent(ev, getScrollX(),
+                getScrollY() - getTitleHeight(), mZoomManager.getInvScale())) {
+            return true;
         } else {
-            mTouchEventQueue.enqueueTouchEvent(ev);
+            Log.w(LOGTAG, "mInputDispatcher rejected the event!");
+            return false;
         }
-
-        // Since all events are handled asynchronously, we always want the gesture stream.
-        return true;
     }
 
     private float calculateDragAngle(int dx, int dy) {
@@ -5931,12 +5948,14 @@
     }
 
     /*
-     * Common code for single touch and multi-touch.
-     * (x, y) denotes current focus point, which is the touch point for single touch
-     * and the middle point for multi-touch.
-     */
-    private boolean handleTouchEventCommon(MotionEvent ev, int action, int x, int y) {
-        long eventTime = ev.getEventTime();
+    * Common code for single touch and multi-touch.
+    * (x, y) denotes current focus point, which is the touch point for single touch
+    * and the middle point for multi-touch.
+    */
+    private void handleTouchEventCommon(MotionEvent event, int action, int x, int y) {
+        ScaleGestureDetector detector = mZoomManager.getMultiTouchGestureDetector();
+
+        long eventTime = event.getEventTime();
 
         // Due to the touch screen edge effect, a touch closer to the edge
         // always snapped to the edge. As getViewWidth() can be different from
@@ -5952,7 +5971,6 @@
 
         switch (action) {
             case MotionEvent.ACTION_DOWN: {
-                mPreventDefault = PREVENT_DEFAULT_NO;
                 mConfirmMove = false;
                 mInitialHitTestResult = null;
                 if (!mEditTextScroller.isFinished()) {
@@ -5972,20 +5990,11 @@
                     if (deltaX * deltaX + deltaY * deltaY < mDoubleTapSlopSquare) {
                         mTouchMode = TOUCH_DOUBLE_TAP_MODE;
                     } else {
-                        // commit the short press action for the previous tap
-                        doShortPress();
                         mTouchMode = TOUCH_INIT_MODE;
-                        mDeferTouchProcess = !mBlockWebkitViewMessages
-                                && (!inFullScreenMode() && mForwardTouchEvents)
-                                ? hitFocusedPlugin(contentX, contentY)
-                                : false;
                     }
                 } else { // the normal case
                     mTouchMode = TOUCH_INIT_MODE;
-                    mDeferTouchProcess = !mBlockWebkitViewMessages
-                            && (!inFullScreenMode() && mForwardTouchEvents)
-                            ? hitFocusedPlugin(contentX, contentY)
-                            : false;
+                    // TODO: Have WebViewInputDispatch handle this
                     TouchHighlightData data = new TouchHighlightData();
                     data.mX = contentX;
                     data.mY = contentY;
@@ -5999,19 +6008,6 @@
                         mWebViewCore.sendMessageAtFrontOfQueue(
                                 EventHub.HIT_TEST, data);
                     }
-                    if (DEBUG_TOUCH_HIGHLIGHT) {
-                        if (getSettings().getNavDump()) {
-                            mTouchHighlightX = x + getScrollX();
-                            mTouchHighlightY = y + getScrollY();
-                            mPrivateHandler.postDelayed(new Runnable() {
-                                @Override
-                                public void run() {
-                                    mTouchHighlightX = mTouchHighlightY = 0;
-                                    invalidate();
-                                }
-                            }, TOUCH_HIGHLIGHT_ELAPSE_TIME);
-                        }
-                    }
                     if (mLogEvent && eventTime - mLastTouchUpTime < 1000) {
                         EventLog.writeEvent(EventLogTags.BROWSER_DOUBLE_TAP_DURATION,
                                 (eventTime - mLastTouchUpTime), eventTime);
@@ -6058,43 +6054,6 @@
                             SWITCH_TO_SHORTPRESS, TAP_TIMEOUT);
                     mPrivateHandler.sendEmptyMessageDelayed(
                             SWITCH_TO_LONGPRESS, LONG_PRESS_TIMEOUT);
-                    if (inFullScreenMode() || mDeferTouchProcess) {
-                        mPreventDefault = PREVENT_DEFAULT_YES;
-                    } else if (!mBlockWebkitViewMessages && mForwardTouchEvents) {
-                        mPreventDefault = PREVENT_DEFAULT_MAYBE_YES;
-                    } else {
-                        mPreventDefault = PREVENT_DEFAULT_NO;
-                    }
-                    // pass the touch events from UI thread to WebCore thread
-                    if (shouldForwardTouchEvent()) {
-                        TouchEventData ted = new TouchEventData();
-                        ted.mAction = action;
-                        ted.mIds = new int[1];
-                        ted.mIds[0] = ev.getPointerId(0);
-                        ted.mPoints = new Point[1];
-                        ted.mPoints[0] = new Point(contentX, contentY);
-                        ted.mPointsInView = new Point[1];
-                        ted.mPointsInView[0] = new Point(x, y);
-                        ted.mMetaState = ev.getMetaState();
-                        ted.mReprocess = mDeferTouchProcess;
-                        ted.mNativeLayer = nativeScrollableLayer(
-                                contentX, contentY, ted.mNativeLayerRect, null);
-                        ted.mSequence = mTouchEventQueue.nextTouchSequence();
-                        mTouchEventQueue.preQueueTouchEventData(ted);
-                        mWebViewCore.sendMessage(EventHub.TOUCH_EVENT, ted);
-                        if (mDeferTouchProcess) {
-                            // still needs to set them for compute deltaX/Y
-                            mLastTouchX = x;
-                            mLastTouchY = y;
-                            break;
-                        }
-                        if (!inFullScreenMode()) {
-                            mPrivateHandler.removeMessages(PREVENT_DEFAULT_TIMEOUT);
-                            mPrivateHandler.sendMessageDelayed(mPrivateHandler
-                                    .obtainMessage(PREVENT_DEFAULT_TIMEOUT,
-                                            action, 0), TAP_TIMEOUT);
-                        }
-                    }
                 }
                 startTouch(x, y, eventTime);
                 if (mIsEditingText) {
@@ -6104,13 +6063,11 @@
                 break;
             }
             case MotionEvent.ACTION_MOVE: {
-                boolean firstMove = false;
                 if (!mConfirmMove && (deltaX * deltaX + deltaY * deltaY)
                         >= mTouchSlopSquare) {
                     mPrivateHandler.removeMessages(SWITCH_TO_SHORTPRESS);
                     mPrivateHandler.removeMessages(SWITCH_TO_LONGPRESS);
                     mConfirmMove = true;
-                    firstMove = true;
                     if (mTouchMode == TOUCH_DOUBLE_TAP_MODE) {
                         mTouchMode = TOUCH_INIT_MODE;
                     }
@@ -6149,48 +6106,16 @@
                     break;
                 }
 
-                // pass the touch events from UI thread to WebCore thread
-                if (shouldForwardTouchEvent() && mConfirmMove && (firstMove
-                        || eventTime - mLastSentTouchTime > mCurrentTouchInterval)) {
-                    TouchEventData ted = new TouchEventData();
-                    ted.mAction = action;
-                    ted.mIds = new int[1];
-                    ted.mIds[0] = ev.getPointerId(0);
-                    ted.mPoints = new Point[1];
-                    ted.mPoints[0] = new Point(contentX, contentY);
-                    ted.mPointsInView = new Point[1];
-                    ted.mPointsInView[0] = new Point(x, y);
-                    ted.mMetaState = ev.getMetaState();
-                    ted.mReprocess = mDeferTouchProcess;
-                    ted.mNativeLayer = mCurrentScrollingLayerId;
-                    ted.mNativeLayerRect.set(mScrollingLayerRect);
-                    ted.mMotionEvent = MotionEvent.obtain(ev);
-                    ted.mSequence = mTouchEventQueue.nextTouchSequence();
-                    mTouchEventQueue.preQueueTouchEventData(ted);
-                    mWebViewCore.sendMessage(EventHub.TOUCH_EVENT, ted);
-                    mLastSentTouchTime = eventTime;
-                    if (mDeferTouchProcess) {
-                        break;
-                    }
-                    if (firstMove && !inFullScreenMode()) {
-                        mPrivateHandler.sendMessageDelayed(mPrivateHandler
-                                .obtainMessage(PREVENT_DEFAULT_TIMEOUT,
-                                        action, 0), TAP_TIMEOUT);
-                    }
-                }
-                if (mTouchMode == TOUCH_DONE_MODE
-                        || mPreventDefault == PREVENT_DEFAULT_YES) {
+                if (mTouchMode == TOUCH_DONE_MODE) {
                     // no dragging during scroll zoom animation, or when prevent
                     // default is yes
                     break;
                 }
                 if (mVelocityTracker == null) {
                     Log.e(LOGTAG, "Got null mVelocityTracker when "
-                            + "mPreventDefault = " + mPreventDefault
-                            + " mDeferTouchProcess = " + mDeferTouchProcess
                             + " mTouchMode = " + mTouchMode);
                 } else {
-                    mVelocityTracker.addMovement(ev);
+                    mVelocityTracker.addMovement(event);
                 }
 
                 if (mTouchMode != TOUCH_DRAG_MODE &&
@@ -6201,19 +6126,9 @@
                         break;
                     }
 
-                    if (mPreventDefault == PREVENT_DEFAULT_MAYBE_YES
-                            || mPreventDefault == PREVENT_DEFAULT_NO_FROM_TOUCH_DOWN) {
-                        // track mLastTouchTime as we may need to do fling at
-                        // ACTION_UP
-                        mLastTouchTime = eventTime;
-                        break;
-                    }
-
                     // Only lock dragging to one axis if we don't have a scale in progress.
                     // Scaling implies free-roaming movement. Note this is only ever a question
                     // if mZoomManager.supportsPanDuringZoom() is true.
-                    final ScaleGestureDetector detector =
-                      mZoomManager.getMultiTouchGestureDetector();
                     mAverageAngle = calculateDragAngle(deltaX, deltaY);
                     if (detector == null || !detector.isInProgress()) {
                         // if it starts nearly horizontal or vertical, enforce it
@@ -6239,10 +6154,9 @@
                 }
 
                 // do pan
-                boolean done = false;
                 boolean keepScrollBarsVisible = false;
                 if (deltaX == 0 && deltaY == 0) {
-                    keepScrollBarsVisible = done = true;
+                    keepScrollBarsVisible = true;
                 } else {
                     mAverageAngle +=
                         (calculateDragAngle(deltaX, deltaY) - mAverageAngle)
@@ -6319,7 +6233,7 @@
                             ViewConfiguration.getScrollDefaultDelay());
                     // return false to indicate that we can't pan out of the
                     // view space
-                    return !done;
+                    return;
                 } else {
                     mPrivateHandler.removeMessages(AWAKEN_SCROLL_BARS);
                 }
@@ -6332,24 +6246,6 @@
                     stopTouch();
                     break;
                 }
-                // pass the touch events from UI thread to WebCore thread
-                if (shouldForwardTouchEvent()) {
-                    TouchEventData ted = new TouchEventData();
-                    ted.mIds = new int[1];
-                    ted.mIds[0] = ev.getPointerId(0);
-                    ted.mAction = action;
-                    ted.mPoints = new Point[1];
-                    ted.mPoints[0] = new Point(contentX, contentY);
-                    ted.mPointsInView = new Point[1];
-                    ted.mPointsInView[0] = new Point(x, y);
-                    ted.mMetaState = ev.getMetaState();
-                    ted.mReprocess = mDeferTouchProcess;
-                    ted.mNativeLayer = mCurrentScrollingLayerId;
-                    ted.mNativeLayerRect.set(mScrollingLayerRect);
-                    ted.mSequence = mTouchEventQueue.nextTouchSequence();
-                    mTouchEventQueue.preQueueTouchEventData(ted);
-                    mWebViewCore.sendMessage(EventHub.TOUCH_EVENT, ted);
-                }
                 mLastTouchUpTime = eventTime;
                 if (mSentAutoScrollMessage) {
                     mAutoScrollX = mAutoScrollY = 0;
@@ -6358,66 +6254,14 @@
                     case TOUCH_DOUBLE_TAP_MODE: // double tap
                         mPrivateHandler.removeMessages(SWITCH_TO_SHORTPRESS);
                         mPrivateHandler.removeMessages(SWITCH_TO_LONGPRESS);
-                        if (inFullScreenMode() || mDeferTouchProcess) {
-                            TouchEventData ted = new TouchEventData();
-                            ted.mIds = new int[1];
-                            ted.mIds[0] = ev.getPointerId(0);
-                            ted.mAction = WebViewCore.ACTION_DOUBLETAP;
-                            ted.mPoints = new Point[1];
-                            ted.mPoints[0] = new Point(contentX, contentY);
-                            ted.mPointsInView = new Point[1];
-                            ted.mPointsInView[0] = new Point(x, y);
-                            ted.mMetaState = ev.getMetaState();
-                            ted.mReprocess = mDeferTouchProcess;
-                            ted.mNativeLayer = nativeScrollableLayer(
-                                    contentX, contentY,
-                                    ted.mNativeLayerRect, null);
-                            ted.mSequence = mTouchEventQueue.nextTouchSequence();
-                            mTouchEventQueue.preQueueTouchEventData(ted);
-                            mWebViewCore.sendMessage(EventHub.TOUCH_EVENT, ted);
-                        } else if (mPreventDefault != PREVENT_DEFAULT_YES){
-                            mZoomManager.handleDoubleTap(mLastTouchX, mLastTouchY);
-                            mTouchMode = TOUCH_DONE_MODE;
-                        }
+                        mTouchMode = TOUCH_DONE_MODE;
                         break;
                     case TOUCH_INIT_MODE: // tap
                     case TOUCH_SHORTPRESS_START_MODE:
                     case TOUCH_SHORTPRESS_MODE:
                         mPrivateHandler.removeMessages(SWITCH_TO_SHORTPRESS);
                         mPrivateHandler.removeMessages(SWITCH_TO_LONGPRESS);
-                        if (mConfirmMove) {
-                            Log.w(LOGTAG, "Miss a drag as we are waiting for" +
-                                    " WebCore's response for touch down.");
-                            if (mPreventDefault != PREVENT_DEFAULT_YES
-                                    && (computeMaxScrollX() > 0
-                                            || computeMaxScrollY() > 0)) {
-                                // If the user has performed a very quick touch
-                                // sequence it is possible that we may get here
-                                // before WebCore has had a chance to process the events.
-                                // In this case, any call to preventDefault in the
-                                // JS touch handler will not have been executed yet.
-                                // Hence we will see both the UI (now) and WebCore
-                                // (when context switches) handling the event,
-                                // regardless of whether the web developer actually
-                                // doeses preventDefault in their touch handler. This
-                                // is the nature of our asynchronous touch model.
-
-                                // we will not rewrite drag code here, but we
-                                // will try fling if it applies.
-                                WebViewCore.reducePriority();
-                                // to get better performance, pause updating the
-                                // picture
-                                WebViewCore.pauseUpdatePicture(mWebViewCore);
-                                // fall through to TOUCH_DRAG_MODE
-                            } else {
-                                // WebKit may consume the touch event and modify
-                                // DOM. drawContentPicture() will be called with
-                                // animateSroll as true for better performance.
-                                // Force redraw in high-quality.
-                                invalidate();
-                                break;
-                            }
-                        } else {
+                        if (!mConfirmMove) {
                             if (mSelectingText) {
                                 // tapping on selection or controls does nothing
                                 if (!mSelectionStarted) {
@@ -6432,8 +6276,6 @@
                                 mPrivateHandler.sendEmptyMessageDelayed(
                                         RELEASE_SINGLE_TAP, ViewConfiguration
                                                 .getDoubleTapTimeout());
-                            } else {
-                                doShortPress();
                             }
                             break;
                         }
@@ -6446,13 +6288,9 @@
                         // up, we don't want to do a fling
                         if (eventTime - mLastTouchTime <= MIN_FLING_TIME) {
                             if (mVelocityTracker == null) {
-                                Log.e(LOGTAG, "Got null mVelocityTracker when "
-                                        + "mPreventDefault = "
-                                        + mPreventDefault
-                                        + " mDeferTouchProcess = "
-                                        + mDeferTouchProcess);
+                                Log.e(LOGTAG, "Got null mVelocityTracker");
                             } else {
-                                mVelocityTracker.addMovement(ev);
+                                mVelocityTracker.addMovement(event);
                             }
                             // set to MOTIONLESS_IGNORE so that it won't keep
                             // removing and sending message in
@@ -6491,128 +6329,10 @@
                             computeMaxScrollX(), 0, computeMaxScrollY());
                     invalidate();
                 }
-                cancelWebCoreTouchEvent(contentX, contentY, false);
                 cancelTouch();
                 break;
             }
         }
-        return true;
-    }
-
-    private void passMultiTouchToWebKit(MotionEvent ev, long sequence) {
-        TouchEventData ted = new TouchEventData();
-        ted.mAction = ev.getActionMasked();
-        final int count = ev.getPointerCount();
-        ted.mIds = new int[count];
-        ted.mPoints = new Point[count];
-        ted.mPointsInView = new Point[count];
-        for (int c = 0; c < count; c++) {
-            ted.mIds[c] = ev.getPointerId(c);
-            int x = viewToContentX((int) ev.getX(c) + getScrollX());
-            int y = viewToContentY((int) ev.getY(c) + getScrollY());
-            ted.mPoints[c] = new Point(x, y);
-            ted.mPointsInView[c] = new Point((int) ev.getX(c), (int) ev.getY(c));
-        }
-        if (ted.mAction == MotionEvent.ACTION_POINTER_DOWN
-            || ted.mAction == MotionEvent.ACTION_POINTER_UP) {
-            ted.mActionIndex = ev.getActionIndex();
-        }
-        ted.mMetaState = ev.getMetaState();
-        ted.mReprocess = true;
-        ted.mMotionEvent = MotionEvent.obtain(ev);
-        ted.mSequence = sequence;
-        mTouchEventQueue.preQueueTouchEventData(ted);
-        mWebViewCore.sendMessage(EventHub.TOUCH_EVENT, ted);
-        mWebView.cancelLongPress();
-        mPrivateHandler.removeMessages(SWITCH_TO_LONGPRESS);
-    }
-
-    void handleMultiTouchInWebView(MotionEvent ev) {
-        if (DebugFlags.WEB_VIEW) {
-            Log.v(LOGTAG, "multi-touch: " + ev + " at " + ev.getEventTime()
-                + " mTouchMode=" + mTouchMode
-                + " numPointers=" + ev.getPointerCount()
-                + " scrolloffset=(" + getScrollX() + "," + getScrollY() + ")");
-        }
-
-        final ScaleGestureDetector detector =
-            mZoomManager.getMultiTouchGestureDetector();
-
-        // A few apps use WebView but don't instantiate gesture detector.
-        // We don't need to support multi touch for them.
-        if (detector == null) return;
-
-        float x = ev.getX();
-        float y = ev.getY();
-
-        if (mPreventDefault != PREVENT_DEFAULT_YES) {
-            detector.onTouchEvent(ev);
-
-            if (detector.isInProgress()) {
-                if (DebugFlags.WEB_VIEW) {
-                    Log.v(LOGTAG, "detector is in progress");
-                }
-                mLastTouchTime = ev.getEventTime();
-                x = detector.getFocusX();
-                y = detector.getFocusY();
-
-                mWebView.cancelLongPress();
-                mPrivateHandler.removeMessages(SWITCH_TO_LONGPRESS);
-                if (!mZoomManager.supportsPanDuringZoom()) {
-                    return;
-                }
-                mTouchMode = TOUCH_DRAG_MODE;
-                if (mVelocityTracker == null) {
-                    mVelocityTracker = VelocityTracker.obtain();
-                }
-            }
-        }
-
-        int action = ev.getActionMasked();
-        if (action == MotionEvent.ACTION_POINTER_DOWN) {
-            cancelTouch();
-            action = MotionEvent.ACTION_DOWN;
-        } else if (action == MotionEvent.ACTION_POINTER_UP && ev.getPointerCount() >= 2) {
-            // set mLastTouchX/Y to the remaining points for multi-touch.
-            mLastTouchX = Math.round(x);
-            mLastTouchY = Math.round(y);
-        } else if (action == MotionEvent.ACTION_MOVE) {
-            // negative x or y indicate it is on the edge, skip it.
-            if (x < 0 || y < 0) {
-                return;
-            }
-        }
-
-        handleTouchEventCommon(ev, action, Math.round(x), Math.round(y));
-    }
-
-    private void cancelWebCoreTouchEvent(int x, int y, boolean removeEvents) {
-        if (shouldForwardTouchEvent()) {
-            if (removeEvents) {
-                mWebViewCore.removeMessages(EventHub.TOUCH_EVENT);
-            }
-            TouchEventData ted = new TouchEventData();
-            ted.mIds = new int[1];
-            ted.mIds[0] = 0;
-            ted.mPoints = new Point[1];
-            ted.mPoints[0] = new Point(x, y);
-            ted.mPointsInView = new Point[1];
-            int viewX = contentToViewX(x) - getScrollX();
-            int viewY = contentToViewY(y) - getScrollY();
-            ted.mPointsInView[0] = new Point(viewX, viewY);
-            ted.mAction = MotionEvent.ACTION_CANCEL;
-            ted.mNativeLayer = nativeScrollableLayer(
-                    x, y, ted.mNativeLayerRect, null);
-            ted.mSequence = mTouchEventQueue.nextTouchSequence();
-            mWebViewCore.sendMessage(EventHub.TOUCH_EVENT, ted);
-            mPreventDefault = PREVENT_DEFAULT_IGNORE;
-
-            if (removeEvents) {
-                // Mark this after sending the message above; we should
-                // be willing to ignore the cancel event that we just sent.
-                mTouchEventQueue.ignoreCurrentlyMissingEvents();
-            }
-        }
     }
 
     private void startTouch(float x, float y, long eventTime) {
@@ -7249,39 +6969,6 @@
         return mZoomManager.zoomOut();
     }
 
-    private void doShortPress() {
-        if (mNativeClass == 0) {
-            return;
-        }
-        if (mPreventDefault == PREVENT_DEFAULT_YES) {
-            return;
-        }
-        mTouchMode = TOUCH_DONE_MODE;
-        switchOutDrawHistory();
-        if (!mTouchHighlightRegion.isEmpty()) {
-            // set mTouchHighlightRequested to 0 to cause an immediate
-            // drawing of the touch rings
-            mTouchHighlightRequested = 0;
-            mWebView.invalidate(mTouchHighlightRegion.getBounds());
-            mPrivateHandler.postDelayed(new Runnable() {
-                @Override
-                public void run() {
-                    removeTouchHighlight();
-                }
-            }, ViewConfiguration.getPressedStateDuration());
-        }
-        if (mFocusedNode != null && mFocusedNode.mIntentUrl != null) {
-            mWebView.playSoundEffect(SoundEffectConstants.CLICK);
-            overrideLoading(mFocusedNode.mIntentUrl);
-        } else {
-            WebViewCore.TouchUpData touchUpData = new WebViewCore.TouchUpData();
-            // use "0" as generation id to inform WebKit to use the same x/y as
-            // it used when processing GET_TOUCH_HIGHLIGHT_RECTS
-            touchUpData.mMoveGeneration = 0;
-            mWebViewCore.sendMessage(EventHub.TOUCH_UP, touchUpData);
-        }
-    }
-
     /*
      * Return true if the rect (e.g. plugin) is fully visible and maximized
      * inside the WebView.
@@ -7569,485 +7256,6 @@
         return Math.max(0, mEditTextContent.height() - mEditTextContentBounds.height());
     }
 
-    /**
-     * Used only by TouchEventQueue to store pending touch events.
-     */
-    private static class QueuedTouch {
-        long mSequence;
-        MotionEvent mEvent; // Optional
-        TouchEventData mTed; // Optional
-
-        QueuedTouch mNext;
-
-        public QueuedTouch set(TouchEventData ted) {
-            mSequence = ted.mSequence;
-            mTed = ted;
-            mEvent = null;
-            mNext = null;
-            return this;
-        }
-
-        public QueuedTouch set(MotionEvent ev, long sequence) {
-            mEvent = MotionEvent.obtain(ev);
-            mSequence = sequence;
-            mTed = null;
-            mNext = null;
-            return this;
-        }
-
-        public QueuedTouch add(QueuedTouch other) {
-            if (other.mSequence < mSequence) {
-                other.mNext = this;
-                return other;
-            }
-
-            QueuedTouch insertAt = this;
-            while (insertAt.mNext != null && insertAt.mNext.mSequence < other.mSequence) {
-                insertAt = insertAt.mNext;
-            }
-            other.mNext = insertAt.mNext;
-            insertAt.mNext = other;
-            return this;
-        }
-    }
-
-    /**
-     * WebView handles touch events asynchronously since some events must be passed to WebKit
-     * for potentially slower processing. TouchEventQueue serializes touch events regardless
-     * of which path they take to ensure that no events are ever processed out of order
-     * by WebView.
-     */
-    private class TouchEventQueue {
-        private long mNextTouchSequence = Long.MIN_VALUE + 1;
-        private long mLastHandledTouchSequence = Long.MIN_VALUE;
-        private long mIgnoreUntilSequence = Long.MIN_VALUE + 1;
-
-        // Events waiting to be processed.
-        private QueuedTouch mTouchEventQueue;
-
-        // Known events that are waiting on a response before being enqueued.
-        private QueuedTouch mPreQueue;
-
-        // Pool of QueuedTouch objects saved for later use.
-        private QueuedTouch mQueuedTouchRecycleBin;
-        private int mQueuedTouchRecycleCount;
-
-        private long mLastEventTime = Long.MAX_VALUE;
-        private static final int MAX_RECYCLED_QUEUED_TOUCH = 15;
-
-        // milliseconds until we abandon hope of getting all of a previous gesture
-        private static final int QUEUED_GESTURE_TIMEOUT = 1000;
-
-        private QueuedTouch obtainQueuedTouch() {
-            if (mQueuedTouchRecycleBin != null) {
-                QueuedTouch result = mQueuedTouchRecycleBin;
-                mQueuedTouchRecycleBin = result.mNext;
-                mQueuedTouchRecycleCount--;
-                return result;
-            }
-            return new QueuedTouch();
-        }
-
-        /**
-         * Allow events with any currently missing sequence numbers to be skipped in processing.
-         */
-        public void ignoreCurrentlyMissingEvents() {
-            mIgnoreUntilSequence = mNextTouchSequence;
-
-            // Run any events we have available and complete, pre-queued or otherwise.
-            runQueuedAndPreQueuedEvents();
-        }
-
-        private void runQueuedAndPreQueuedEvents() {
-            QueuedTouch qd = mPreQueue;
-            boolean fromPreQueue = true;
-            while (qd != null && qd.mSequence == mLastHandledTouchSequence + 1) {
-                handleQueuedTouch(qd);
-                QueuedTouch recycleMe = qd;
-                if (fromPreQueue) {
-                    mPreQueue = qd.mNext;
-                } else {
-                    mTouchEventQueue = qd.mNext;
-                }
-                recycleQueuedTouch(recycleMe);
-                mLastHandledTouchSequence++;
-
-                long nextPre = mPreQueue != null ? mPreQueue.mSequence : Long.MAX_VALUE;
-                long nextQueued = mTouchEventQueue != null ?
-                        mTouchEventQueue.mSequence : Long.MAX_VALUE;
-                fromPreQueue = nextPre < nextQueued;
-                qd = fromPreQueue ? mPreQueue : mTouchEventQueue;
-            }
-        }
-
-        /**
-         * Add a TouchEventData to the pre-queue.
-         *
-         * An event in the pre-queue is an event that we know about that
-         * has been sent to webkit, but that we haven't received back and
-         * enqueued into the normal touch queue yet. If webkit ever times
-         * out and we need to ignore currently missing events, we'll run
-         * events from the pre-queue to patch the holes.
-         *
-         * @param ted TouchEventData to pre-queue
-         */
-        public void preQueueTouchEventData(TouchEventData ted) {
-            QueuedTouch newTouch = obtainQueuedTouch().set(ted);
-            if (mPreQueue == null) {
-                mPreQueue = newTouch;
-            } else {
-                QueuedTouch insertionPoint = mPreQueue;
-                while (insertionPoint.mNext != null &&
-                        insertionPoint.mNext.mSequence < newTouch.mSequence) {
-                    insertionPoint = insertionPoint.mNext;
-                }
-                newTouch.mNext = insertionPoint.mNext;
-                insertionPoint.mNext = newTouch;
-            }
-        }
-
-        private void recycleQueuedTouch(QueuedTouch qd) {
-            if (mQueuedTouchRecycleCount < MAX_RECYCLED_QUEUED_TOUCH) {
-                qd.mNext = mQueuedTouchRecycleBin;
-                mQueuedTouchRecycleBin = qd;
-                mQueuedTouchRecycleCount++;
-            }
-        }
-
-        /**
-         * Reset the touch event queue. This will dump any pending events
-         * and reset the sequence numbering.
-         */
-        public void reset() {
-            mNextTouchSequence = Long.MIN_VALUE + 1;
-            mLastHandledTouchSequence = Long.MIN_VALUE;
-            mIgnoreUntilSequence = Long.MIN_VALUE + 1;
-            while (mTouchEventQueue != null) {
-                QueuedTouch recycleMe = mTouchEventQueue;
-                mTouchEventQueue = mTouchEventQueue.mNext;
-                recycleQueuedTouch(recycleMe);
-            }
-            while (mPreQueue != null) {
-                QueuedTouch recycleMe = mPreQueue;
-                mPreQueue = mPreQueue.mNext;
-                recycleQueuedTouch(recycleMe);
-            }
-        }
-
-        /**
-         * Return the next valid sequence number for tagging incoming touch events.
-         * @return The next touch event sequence number
-         */
-        public long nextTouchSequence() {
-            return mNextTouchSequence++;
-        }
-
-        /**
-         * Enqueue a touch event in the form of TouchEventData.
-         * The sequence number will be read from the mSequence field of the argument.
-         *
-         * If the touch event's sequence number is the next in line to be processed, it will
-         * be handled before this method returns. Any subsequent events that have already
-         * been queued will also be processed in their proper order.
-         *
-         * @param ted Touch data to be processed in order.
-         * @return true if the event was processed before returning, false if it was just enqueued.
-         */
-        public boolean enqueueTouchEvent(TouchEventData ted) {
-            // Remove from the pre-queue if present
-            QueuedTouch preQueue = mPreQueue;
-            if (preQueue != null) {
-                // On exiting this block, preQueue is set to the pre-queued QueuedTouch object
-                // if it was present in the pre-queue, and removed from the pre-queue itself.
-                if (preQueue.mSequence == ted.mSequence) {
-                    mPreQueue = preQueue.mNext;
-                } else {
-                    QueuedTouch prev = preQueue;
-                    preQueue = null;
-                    while (prev.mNext != null) {
-                        if (prev.mNext.mSequence == ted.mSequence) {
-                            preQueue = prev.mNext;
-                            prev.mNext = preQueue.mNext;
-                            break;
-                        } else {
-                            prev = prev.mNext;
-                        }
-                    }
-                }
-            }
-
-            if (ted.mSequence < mLastHandledTouchSequence) {
-                // Stale event and we already moved on; drop it. (Should not be common.)
-                Log.w(LOGTAG, "Stale touch event " + MotionEvent.actionToString(ted.mAction) +
-                        " received from webcore; ignoring");
-                return false;
-            }
-
-            if (dropStaleGestures(ted.mMotionEvent, ted.mSequence)) {
-                return false;
-            }
-
-            // dropStaleGestures above might have fast-forwarded us to
-            // an event we have already.
-            runNextQueuedEvents();
-
-            if (mLastHandledTouchSequence + 1 == ted.mSequence) {
-                if (preQueue != null) {
-                    recycleQueuedTouch(preQueue);
-                    preQueue = null;
-                }
-                handleQueuedTouchEventData(ted);
-
-                mLastHandledTouchSequence++;
-
-                // Do we have any more? Run them if so.
-                runNextQueuedEvents();
-            } else {
-                // Reuse the pre-queued object if we had it.
-                QueuedTouch qd = preQueue != null ? preQueue : obtainQueuedTouch().set(ted);
-                mTouchEventQueue = mTouchEventQueue == null ? qd : mTouchEventQueue.add(qd);
-            }
-            return true;
-        }
-
-        /**
-         * Enqueue a touch event in the form of a MotionEvent from the framework.
-         *
-         * If the touch event's sequence number is the next in line to be processed, it will
-         * be handled before this method returns. Any subsequent events that have already
-         * been queued will also be processed in their proper order.
-         *
-         * @param ev MotionEvent to be processed in order
-         */
-        public void enqueueTouchEvent(MotionEvent ev) {
-            final long sequence = nextTouchSequence();
-
-            if (dropStaleGestures(ev, sequence)) {
-                return;
-            }
-
-            // dropStaleGestures above might have fast-forwarded us to
-            // an event we have already.
-            runNextQueuedEvents();
-
-            if (mLastHandledTouchSequence + 1 == sequence) {
-                handleQueuedMotionEvent(ev);
-
-                mLastHandledTouchSequence++;
-
-                // Do we have any more? Run them if so.
-                runNextQueuedEvents();
-            } else {
-                QueuedTouch qd = obtainQueuedTouch().set(ev, sequence);
-                mTouchEventQueue = mTouchEventQueue == null ? qd : mTouchEventQueue.add(qd);
-            }
-        }
-
-        private void runNextQueuedEvents() {
-            QueuedTouch qd = mTouchEventQueue;
-            while (qd != null && qd.mSequence == mLastHandledTouchSequence + 1) {
-                handleQueuedTouch(qd);
-                QueuedTouch recycleMe = qd;
-                qd = qd.mNext;
-                recycleQueuedTouch(recycleMe);
-                mLastHandledTouchSequence++;
-            }
-            mTouchEventQueue = qd;
-        }
-
-        private boolean dropStaleGestures(MotionEvent ev, long sequence) {
-            if (ev != null && ev.getAction() == MotionEvent.ACTION_MOVE && !mConfirmMove) {
-                // This is to make sure that we don't attempt to process a tap
-                // or long press when webkit takes too long to get back to us.
-                // The movement will be properly confirmed when we process the
-                // enqueued event later.
-                final int dx = Math.round(ev.getX()) - mLastTouchX;
-                final int dy = Math.round(ev.getY()) - mLastTouchY;
-                if (dx * dx + dy * dy > mTouchSlopSquare) {
-                    mPrivateHandler.removeMessages(SWITCH_TO_SHORTPRESS);
-                    mPrivateHandler.removeMessages(SWITCH_TO_LONGPRESS);
-                }
-            }
-
-            if (mTouchEventQueue == null) {
-                return sequence <= mLastHandledTouchSequence;
-            }
-
-            // If we have a new down event and it's been a while since the last event
-            // we saw, catch up as best we can and keep going.
-            if (ev != null && ev.getAction() == MotionEvent.ACTION_DOWN) {
-                long eventTime = ev.getEventTime();
-                long lastHandledEventTime = mLastEventTime;
-                if (eventTime > lastHandledEventTime + QUEUED_GESTURE_TIMEOUT) {
-                    Log.w(LOGTAG, "Got ACTION_DOWN but still waiting on stale event. " +
-                            "Catching up.");
-                    runQueuedAndPreQueuedEvents();
-
-                    // Drop leftovers that we truly don't have.
-                    QueuedTouch qd = mTouchEventQueue;
-                    while (qd != null && qd.mSequence < sequence) {
-                        QueuedTouch recycleMe = qd;
-                        qd = qd.mNext;
-                        recycleQueuedTouch(recycleMe);
-                    }
-                    mTouchEventQueue = qd;
-                    mLastHandledTouchSequence = sequence - 1;
-                }
-            }
-
-            if (mIgnoreUntilSequence - 1 > mLastHandledTouchSequence) {
-                QueuedTouch qd = mTouchEventQueue;
-                while (qd != null && qd.mSequence < mIgnoreUntilSequence) {
-                    QueuedTouch recycleMe = qd;
-                    qd = qd.mNext;
-                    recycleQueuedTouch(recycleMe);
-                }
-                mTouchEventQueue = qd;
-                mLastHandledTouchSequence = mIgnoreUntilSequence - 1;
-            }
-
-            if (mPreQueue != null) {
-                // Drop stale prequeued events
-                QueuedTouch qd = mPreQueue;
-                while (qd != null && qd.mSequence < mIgnoreUntilSequence) {
-                    QueuedTouch recycleMe = qd;
-                    qd = qd.mNext;
-                    recycleQueuedTouch(recycleMe);
-                }
-                mPreQueue = qd;
-            }
-
-            return sequence <= mLastHandledTouchSequence;
-        }
-
-        private void handleQueuedTouch(QueuedTouch qt) {
-            if (qt.mTed != null) {
-                handleQueuedTouchEventData(qt.mTed);
-            } else {
-                handleQueuedMotionEvent(qt.mEvent);
-                qt.mEvent.recycle();
-            }
-        }
-
-        private void handleQueuedMotionEvent(MotionEvent ev) {
-            mLastEventTime = ev.getEventTime();
-            int action = ev.getActionMasked();
-            if (ev.getPointerCount() > 1) {  // Multi-touch
-                handleMultiTouchInWebView(ev);
-            } else {
-                final ScaleGestureDetector detector = mZoomManager.getMultiTouchGestureDetector();
-                if (detector != null && mPreventDefault != PREVENT_DEFAULT_YES) {
-                    // ScaleGestureDetector needs a consistent event stream to operate properly.
-                    // It won't take any action with fewer than two pointers, but it needs to
-                    // update internal bookkeeping state.
-                    detector.onTouchEvent(ev);
-                }
-
-                handleTouchEventCommon(ev, action, Math.round(ev.getX()), Math.round(ev.getY()));
-            }
-        }
-
-        private void handleQueuedTouchEventData(TouchEventData ted) {
-            if (ted.mMotionEvent != null) {
-                mLastEventTime = ted.mMotionEvent.getEventTime();
-            }
-            if (!ted.mReprocess) {
-                if (ted.mAction == MotionEvent.ACTION_DOWN
-                        && mPreventDefault == PREVENT_DEFAULT_MAYBE_YES) {
-                    // if prevent default is called from WebCore, UI
-                    // will not handle the rest of the touch events any
-                    // more.
-                    mPreventDefault = ted.mNativeResult ? PREVENT_DEFAULT_YES
-                            : PREVENT_DEFAULT_NO_FROM_TOUCH_DOWN;
-                } else if (ted.mAction == MotionEvent.ACTION_MOVE
-                        && mPreventDefault == PREVENT_DEFAULT_NO_FROM_TOUCH_DOWN) {
-                    // the return for the first ACTION_MOVE will decide
-                    // whether UI will handle touch or not. Currently no
-                    // support for alternating prevent default
-                    mPreventDefault = ted.mNativeResult ? PREVENT_DEFAULT_YES
-                            : PREVENT_DEFAULT_NO;
-                }
-                if (mPreventDefault == PREVENT_DEFAULT_YES) {
-                    mTouchHighlightRegion.setEmpty();
-                }
-            } else {
-                if (ted.mPoints.length > 1) {  // multi-touch
-                    if (!ted.mNativeResult && mPreventDefault != PREVENT_DEFAULT_YES) {
-                        mPreventDefault = PREVENT_DEFAULT_NO;
-                        handleMultiTouchInWebView(ted.mMotionEvent);
-                    } else {
-                        mPreventDefault = PREVENT_DEFAULT_YES;
-                    }
-                    return;
-                }
-
-                // prevent default is not called in WebCore, so the
-                // message needs to be reprocessed in UI
-                if (!ted.mNativeResult) {
-                    // Following is for single touch.
-                    switch (ted.mAction) {
-                        case MotionEvent.ACTION_DOWN:
-                            mLastDeferTouchX = ted.mPointsInView[0].x;
-                            mLastDeferTouchY = ted.mPointsInView[0].y;
-                            mDeferTouchMode = TOUCH_INIT_MODE;
-                            break;
-                        case MotionEvent.ACTION_MOVE: {
-                            // no snapping in defer process
-                            int x = ted.mPointsInView[0].x;
-                            int y = ted.mPointsInView[0].y;
-
-                            if (mDeferTouchMode != TOUCH_DRAG_MODE) {
-                                mDeferTouchMode = TOUCH_DRAG_MODE;
-                                mLastDeferTouchX = x;
-                                mLastDeferTouchY = y;
-                                startScrollingLayer(x, y);
-                                startDrag();
-                            }
-                            int deltaX = pinLocX((int) (getScrollX()
-                                    + mLastDeferTouchX - x))
-                                    - getScrollX();
-                            int deltaY = pinLocY((int) (getScrollY()
-                                    + mLastDeferTouchY - y))
-                                    - getScrollY();
-                            doDrag(deltaX, deltaY);
-                            if (deltaX != 0) mLastDeferTouchX = x;
-                            if (deltaY != 0) mLastDeferTouchY = y;
-                            break;
-                        }
-                        case MotionEvent.ACTION_UP:
-                        case MotionEvent.ACTION_CANCEL:
-                            if (mDeferTouchMode == TOUCH_DRAG_MODE) {
-                                // no fling in defer process
-                                mScroller.springBack(getScrollX(), getScrollY(), 0,
-                                        computeMaxScrollX(), 0,
-                                        computeMaxScrollY());
-                                invalidate();
-                                WebViewCore.resumePriority();
-                                WebViewCore.resumeUpdatePicture(mWebViewCore);
-                            }
-                            mDeferTouchMode = TOUCH_DONE_MODE;
-                            break;
-                        case WebViewCore.ACTION_DOUBLETAP:
-                            // doDoubleTap() needs mLastTouchX/Y as anchor
-                            mLastDeferTouchX = ted.mPointsInView[0].x;
-                            mLastDeferTouchY = ted.mPointsInView[0].y;
-                            mZoomManager.handleDoubleTap(mLastTouchX, mLastTouchY);
-                            mDeferTouchMode = TOUCH_DONE_MODE;
-                            break;
-                        case WebViewCore.ACTION_LONGPRESS:
-                            HitTestResult hitTest = getHitTestResult();
-                            if (hitTest != null && hitTest.getType()
-                                    != HitTestResult.UNKNOWN_TYPE) {
-                                performLongClick();
-                            }
-                            mDeferTouchMode = TOUCH_DONE_MODE;
-                            break;
-                    }
-                }
-            }
-        }
-    }
-
     //-------------------------------------------------------------------------
     // Methods can be called from a separate thread, like WebViewCore
     // If it needs to call the View system, it has to send message.
@@ -8056,7 +7264,7 @@
     /**
      * General handler to receive message coming from webkit thread
      */
-    class PrivateHandler extends Handler {
+    class PrivateHandler extends Handler implements WebViewInputDispatcher.UiCallbacks {
         @Override
         public void handleMessage(Message msg) {
             // exclude INVAL_RECT_MSG_ID since it is frequently output
@@ -8097,20 +7305,6 @@
                     ((Message) msg.obj).sendToTarget();
                     break;
                 }
-                case PREVENT_DEFAULT_TIMEOUT: {
-                    // if timeout happens, cancel it so that it won't block UI
-                    // to continue handling touch events
-                    if ((msg.arg1 == MotionEvent.ACTION_DOWN
-                            && mPreventDefault == PREVENT_DEFAULT_MAYBE_YES)
-                            || (msg.arg1 == MotionEvent.ACTION_MOVE
-                            && mPreventDefault == PREVENT_DEFAULT_NO_FROM_TOUCH_DOWN)) {
-                        cancelWebCoreTouchEvent(
-                                viewToContentX(mLastTouchX + getScrollX()),
-                                viewToContentY(mLastTouchY + getScrollY()),
-                                true);
-                    }
-                    break;
-                }
                 case SCROLL_SELECT_TEXT: {
                     if (mAutoScrollX == 0 && mAutoScrollY == 0) {
                         mSentAutoScrollMessage = false;
@@ -8126,48 +7320,6 @@
                             SCROLL_SELECT_TEXT, SELECT_SCROLL_INTERVAL);
                     break;
                 }
-                case SWITCH_TO_SHORTPRESS: {
-                    if (mTouchMode == TOUCH_INIT_MODE) {
-                        mTouchMode = TOUCH_SHORTPRESS_MODE;
-                    } else if (mTouchMode == TOUCH_DOUBLE_TAP_MODE) {
-                        mTouchMode = TOUCH_DONE_MODE;
-                    }
-                    break;
-                }
-                case SWITCH_TO_LONGPRESS: {
-                    removeTouchHighlight();
-                    if (inFullScreenMode() || mDeferTouchProcess) {
-                        TouchEventData ted = new TouchEventData();
-                        ted.mAction = WebViewCore.ACTION_LONGPRESS;
-                        ted.mIds = new int[1];
-                        ted.mIds[0] = 0;
-                        ted.mPoints = new Point[1];
-                        ted.mPoints[0] = new Point(viewToContentX(mLastTouchX + getScrollX()),
-                                                   viewToContentY(mLastTouchY + getScrollY()));
-                        ted.mPointsInView = new Point[1];
-                        ted.mPointsInView[0] = new Point(mLastTouchX, mLastTouchY);
-                        // metaState for long press is tricky. Should it be the
-                        // state when the press started or when the press was
-                        // released? Or some intermediary key state? For
-                        // simplicity for now, we don't set it.
-                        ted.mMetaState = 0;
-                        ted.mReprocess = mDeferTouchProcess;
-                        ted.mNativeLayer = nativeScrollableLayer(
-                                ted.mPoints[0].x, ted.mPoints[0].y,
-                                ted.mNativeLayerRect, null);
-                        ted.mSequence = mTouchEventQueue.nextTouchSequence();
-                        mTouchEventQueue.preQueueTouchEventData(ted);
-                        mWebViewCore.sendMessage(EventHub.TOUCH_EVENT, ted);
-                    } else if (mPreventDefault != PREVENT_DEFAULT_YES) {
-                        mTouchMode = TOUCH_DONE_MODE;
-                        performLongClick();
-                    }
-                    break;
-                }
-                case RELEASE_SINGLE_TAP: {
-                    doShortPress();
-                    break;
-                }
                 case SCROLL_TO_MSG_ID: {
                     // arg1 = animate, arg2 = onlyIfImeIsShowing
                     // obj = Point(x, y)
@@ -8225,6 +7377,8 @@
                     if (mIsPaused) {
                         nativeSetPauseDrawing(mNativeClass, true);
                     }
+                    mInputDispatcher = new WebViewInputDispatcher(this,
+                            mWebViewCore.getInputDispatcherCallbacks());
                     break;
                 case UPDATE_TEXTFIELD_TEXT_MSG_ID:
                     // Make sure that the textfield is currently focused
@@ -8281,20 +7435,7 @@
                     break;
 
                 case WEBCORE_NEED_TOUCH_EVENTS:
-                    mForwardTouchEvents = (msg.arg1 != 0);
-                    break;
-
-                case PREVENT_TOUCH_ID:
-                    if (inFullScreenMode()) {
-                        break;
-                    }
-                    TouchEventData ted = (TouchEventData) msg.obj;
-
-                    if (mTouchEventQueue.enqueueTouchEvent(ted)) {
-                        // WebCore is responding to us; remove pending timeout.
-                        // It will be re-posted when needed.
-                        removeMessages(PREVENT_DEFAULT_TIMEOUT);
-                    }
+                    mInputDispatcher.setWebKitWantsTouchEvents(msg.arg1 != 0);
                     break;
 
                 case REQUEST_KEYBOARD:
@@ -8559,6 +7700,21 @@
                     break;
             }
         }
+
+        @Override
+        public Looper getUiLooper() {
+            return getLooper();
+        }
+
+        @Override
+        public void dispatchUiEvent(MotionEvent event, int eventType, int flags) {
+            onHandleUiEvent(event, eventType, flags);
+        }
+
+        @Override
+        public Context getContext() {
+            return WebViewClassic.this.getContext();
+        }
     }
 
     private void setHitTestTypeFromUrl(String url) {
diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java
index 2caec01..dd05e8c 100644
--- a/core/java/android/webkit/WebViewCore.java
+++ b/core/java/android/webkit/WebViewCore.java
@@ -40,6 +40,7 @@
 import android.view.SurfaceView;
 import android.view.View;
 import android.webkit.WebViewClassic.FocusNodeHref;
+import android.webkit.WebViewInputDispatcher.WebKitCallbacks;
 
 import junit.framework.Assert;
 
@@ -259,6 +260,10 @@
         return mBrowserFrame;
     }
 
+    public WebKitCallbacks getInputDispatcherCallbacks() {
+        return mEventHub;
+    }
+
     //-------------------------------------------------------------------------
     // Common methods
     //-------------------------------------------------------------------------
@@ -611,9 +616,6 @@
             int unichar, int repeatCount, boolean isShift, boolean isAlt,
             boolean isSym, boolean isDown);
 
-    private native void nativeClick(int nativeClass, int framePtr, int nodePtr,
-            boolean fake);
-
     private native void nativeSendListBoxChoices(int nativeClass,
             boolean[] choices, int size);
 
@@ -656,8 +658,7 @@
             int x, int y);
     private native String nativeRetrieveImageSource(int nativeClass,
             int x, int y);
-    private native void nativeTouchUp(int nativeClass,
-            int touchGeneration, int framePtr, int nodePtr, int x, int y);
+    private native boolean nativeMouseClick(int nativeClass);
 
     private native boolean nativeHandleTouchEvent(int nativeClass, int action,
             int[] idArray, int[] xArray, int[] yArray, int count,
@@ -1020,8 +1021,8 @@
             "REQUEST_CURSOR_HREF", // = 137;
             "ADD_JS_INTERFACE", // = 138;
             "LOAD_DATA", // = 139;
-            "TOUCH_UP", // = 140;
-            "TOUCH_EVENT", // = 141;
+            "", // = 140;
+            "", // = 141;
             "SET_ACTIVE", // = 142;
             "ON_PAUSE",     // = 143
             "ON_RESUME",    // = 144
@@ -1046,7 +1047,7 @@
     /**
      * @hide
      */
-    public class EventHub {
+    public class EventHub implements WebViewInputDispatcher.WebKitCallbacks {
         // Message Ids
         static final int REVEAL_SELECTION = 96;
         static final int SCROLL_TEXT_INPUT = 99;
@@ -1067,10 +1068,8 @@
         static final int REPLACE_TEXT = 114;
         static final int PASS_TO_JS = 115;
         static final int SET_GLOBAL_BOUNDS = 116;
-        static final int CLICK = 118;
         static final int SET_NETWORK_STATE = 119;
         static final int DOC_HAS_IMAGES = 120;
-        static final int FAKE_CLICK = 121;
         static final int DELETE_SELECTION = 122;
         static final int LISTBOX_CHOICES = 123;
         static final int SINGLE_LISTBOX_CHOICE = 124;
@@ -1091,11 +1090,6 @@
         static final int ADD_JS_INTERFACE = 138;
         static final int LOAD_DATA = 139;
 
-        // motion
-        static final int TOUCH_UP = 140;
-        // message used to pass UI touch events to WebCore
-        static final int TOUCH_EVENT = 141;
-
         // Used to tell the focus controller not to draw the blinking cursor,
         // based on whether the WebView has focus and whether the WebView's
         // cursor matches the webpage's focus.
@@ -1370,14 +1364,6 @@
                             keyPress(msg.arg1);
                             break;
 
-                        case FAKE_CLICK:
-                            nativeClick(mNativeClass, msg.arg1, msg.arg2, true);
-                            break;
-
-                        case CLICK:
-                            nativeClick(mNativeClass, msg.arg1, msg.arg2, false);
-                            break;
-
                         case VIEW_SIZE_CHANGED: {
                             viewSizeChanged((WebViewClassic.ViewSizeData) msg.obj);
                             break;
@@ -1490,45 +1476,6 @@
                             nativeCloseIdleConnections(mNativeClass);
                             break;
 
-                        case TOUCH_UP:
-                            TouchUpData touchUpData = (TouchUpData) msg.obj;
-                            if (touchUpData.mNativeLayer != 0) {
-                                nativeScrollLayer(mNativeClass,
-                                        touchUpData.mNativeLayer,
-                                        touchUpData.mNativeLayerRect);
-                            }
-                            nativeTouchUp(mNativeClass,
-                                    touchUpData.mMoveGeneration,
-                                    touchUpData.mFrame, touchUpData.mNode,
-                                    touchUpData.mX, touchUpData.mY);
-                            break;
-
-                        case TOUCH_EVENT: {
-                            TouchEventData ted = (TouchEventData) msg.obj;
-                            final int count = ted.mPoints.length;
-                            int[] xArray = new int[count];
-                            int[] yArray = new int[count];
-                            for (int c = 0; c < count; c++) {
-                                xArray[c] = ted.mPoints[c].x;
-                                yArray[c] = ted.mPoints[c].y;
-                            }
-                            if (ted.mNativeLayer != 0) {
-                                nativeScrollLayer(mNativeClass,
-                                        ted.mNativeLayer, ted.mNativeLayerRect);
-                            }
-                            ted.mNativeResult = nativeHandleTouchEvent(
-                                    mNativeClass, ted.mAction, ted.mIds, xArray,
-                                    yArray, count, ted.mActionIndex,
-                                    ted.mMetaState);
-                            Message.obtain(
-                                    mWebViewClassic.mPrivateHandler,
-                                    WebViewClassic.PREVENT_TOUCH_ID,
-                                    ted.mAction,
-                                    ted.mNativeResult ? 1 : 0,
-                                    ted).sendToTarget();
-                            break;
-                        }
-
                         case SET_ACTIVE:
                             nativeSetFocusControllerActive(mNativeClass, msg.arg1 == 1);
                             break;
@@ -1812,6 +1759,38 @@
             }
         }
 
+        @Override
+        public Looper getWebKitLooper() {
+            return mHandler.getLooper();
+        }
+
+        @Override
+        public boolean dispatchWebKitEvent(MotionEvent event, int eventType, int flags) {
+            switch (eventType) {
+                case WebViewInputDispatcher.EVENT_TYPE_CLICK:
+                    return nativeMouseClick(mNativeClass);
+
+                case WebViewInputDispatcher.EVENT_TYPE_TOUCH: {
+                    int count = event.getPointerCount();
+                    int[] idArray = new int[count];
+                    int[] xArray = new int[count];
+                    int[] yArray = new int[count];
+                    for (int i = 0; i < count; i++) {
+                        idArray[i] = event.getPointerId(i);
+                        xArray[i] = (int) event.getX(i);
+                        yArray[i] = (int) event.getY(i);
+                    }
+                    return nativeHandleTouchEvent(mNativeClass,
+                            event.getActionMasked(),
+                            idArray, xArray, yArray, count,
+                            event.getActionIndex(), event.getMetaState());
+                }
+
+                default:
+                    return false;
+            }
+        }
+
         /**
          * Send a message internally to the queue or to the handler
          */
diff --git a/core/java/android/webkit/WebViewInputDispatcher.java b/core/java/android/webkit/WebViewInputDispatcher.java
new file mode 100644
index 0000000..e7024d9
--- /dev/null
+++ b/core/java/android/webkit/WebViewInputDispatcher.java
@@ -0,0 +1,1151 @@
+/*
+ * Copyright (C) 2012 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;
+
+import android.content.Context;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.os.SystemClock;
+import android.util.Log;
+import android.view.InputDevice;
+import android.view.MotionEvent;
+import android.view.ViewConfiguration;
+
+/**
+ * Perform asynchronous dispatch of input events in a {@link WebView}.
+ *
+ * This dispatcher is shared by the UI thread ({@link WebViewClassic}) and web kit
+ * thread ({@link WebViewCore}).  The UI thread enqueues events for
+ * processing, waits for the web kit thread to handle them, and then performs
+ * additional processing depending on the outcome.
+ *
+ * How it works:
+ *
+ * 1. The web view thread receives an input event from the input system on the UI
+ * thread in its {@link WebViewClassic#onTouchEvent} handler.  It sends the input event
+ * to the dispatcher, then immediately returns true to the input system to indicate that
+ * it will handle the event.
+ *
+ * 2. The web kit thread is notified that an event has been enqueued.  Meanwhile additional
+ * events may be enqueued from the UI thread.  In some cases, the dispatcher may decide to
+ * coalesce motion events into larger batches or to cancel events that have been
+ * sitting in the queue for too long.
+ *
+ * 3. The web kit thread wakes up and handles all input events that are waiting for it.
+ * After processing each input event, it informs the dispatcher whether the web application
+ * has decided to handle the event itself and to prevent default event handling.
+ *
+ * 4. If web kit indicates that it wants to prevent default event handling, then web kit
+ * consumes the remainder of the gesture and web view receives a cancel event if
+ * needed.  Otherwise, the web view handles the gesture on the UI thread normally.
+ *
+ * 5. If the web kit thread takes too long to handle an input event, then it loses the
+ * right to handle it.  The dispatcher synthesizes a cancellation event for web kit and
+ * then tells the web view on the UI thread to handle the event that timed out along
+ * with the rest of the gesture.
+ *
+ * One thing to keep in mind about the dispatcher is that what goes into the dispatcher
+ * is not necessarily what the web kit or UI thread will see.  As mentioned above, the
+ * dispatcher may tweak the input event stream to improve responsiveness.  Both web view and
+ * web kit are guaranteed to perceive a consistent stream of input events but
+ * they might not always see the same events (especially if one decides
+ * to prevent the other from handling a particular gesture).
+ *
+ * This implementation very deliberately does not refer to the {@link WebViewClassic}
+ * or {@link WebViewCore} classes, preferring to communicate with them only via
+ * interfaces to avoid unintentional coupling to their implementation details.
+ *
+ * Currently, the input dispatcher only handles pointer events (includes touch,
+ * hover and scroll events).  In principle, it could be extended to handle trackball
+ * and key events if needed.
+ *
+ * @hide
+ */
+final class WebViewInputDispatcher {
+    private static final String TAG = "WebViewInputDispatcher";
+    private static final boolean DEBUG = false;
+    // This enables batching of MotionEvents. It will combine multiple MotionEvents
+    // together into a single MotionEvent if more events come in while we are
+    // still waiting on the processing of a previous event.
+    // If this is set to false, we will instead opt to drop ACTION_MOVE
+    // events we cannot keep up with.
+    // TODO: If batching proves to be working well, remove this
+    private static final boolean ENABLE_EVENT_BATCHING = true;
+
+    private final Object mLock = new Object();
+
+    // Pool of queued input events.  (guarded by mLock)
+    private static final int MAX_DISPATCH_EVENT_POOL_SIZE = 10;
+    private DispatchEvent mDispatchEventPool;
+    private int mDispatchEventPoolSize;
+
+    // Posted state, tracks events posted to the dispatcher.  (guarded by mLock)
+    private final TouchStream mPostTouchStream = new TouchStream();
+    private boolean mPostSendTouchEventsToWebKit;
+    private boolean mPostDoNotSendTouchEventsToWebKitUntilNextGesture;
+    private boolean mPostLongPressScheduled;
+    private boolean mPostClickScheduled;
+    private int mPostLastWebKitXOffset;
+    private int mPostLastWebKitYOffset;
+    private float mPostLastWebKitScale;
+
+    // State for event tracking (click, longpress, double tap, etc..)
+    private boolean mIsDoubleTapCandidate;
+    private boolean mIsTapCandidate;
+    private float mInitialDownX;
+    private float mInitialDownY;
+    private float mTouchSlopSquared;
+    private float mDoubleTapSlopSquared;
+
+    // Web kit state, tracks events observed by web kit.  (guarded by mLock)
+    private final DispatchEventQueue mWebKitDispatchEventQueue = new DispatchEventQueue();
+    private final TouchStream mWebKitTouchStream = new TouchStream();
+    private final WebKitCallbacks mWebKitCallbacks;
+    private final WebKitHandler mWebKitHandler;
+    private boolean mWebKitDispatchScheduled;
+    private boolean mWebKitTimeoutScheduled;
+    private long mWebKitTimeoutTime;
+
+    // UI state, tracks events observed by the UI.  (guarded by mLock)
+    private final DispatchEventQueue mUiDispatchEventQueue = new DispatchEventQueue();
+    private final TouchStream mUiTouchStream = new TouchStream();
+    private final UiCallbacks mUiCallbacks;
+    private final UiHandler mUiHandler;
+    private boolean mUiDispatchScheduled;
+
+    // Give up on web kit handling of input events when this timeout expires.
+    private static final long WEBKIT_TIMEOUT_MILLIS = 200;
+    private static final int TAP_TIMEOUT = ViewConfiguration.getTapTimeout();
+    private static final int LONG_PRESS_TIMEOUT =
+            ViewConfiguration.getLongPressTimeout() + TAP_TIMEOUT;
+    private static final int DOUBLE_TAP_TIMEOUT = ViewConfiguration.getDoubleTapTimeout();
+
+    /**
+     * Event type: Indicates a touch event type.
+     *
+     * This event is delivered together with a {@link MotionEvent} with one of the
+     * following actions: {@link MotionEvent#ACTION_DOWN}, {@link MotionEvent#ACTION_MOVE},
+     * {@link MotionEvent#ACTION_UP}, {@link MotionEvent#ACTION_POINTER_DOWN},
+     * {@link MotionEvent#ACTION_POINTER_UP}, {@link MotionEvent#ACTION_CANCEL}.
+     */
+    public static final int EVENT_TYPE_TOUCH = 0;
+
+    /**
+     * Event type: Indicates a hover event type.
+     *
+     * This event is delivered together with a {@link MotionEvent} with one of the
+     * following actions: {@link MotionEvent#ACTION_HOVER_ENTER},
+     * {@link MotionEvent#ACTION_HOVER_MOVE}, {@link MotionEvent#ACTION_HOVER_MOVE}.
+     */
+    public static final int EVENT_TYPE_HOVER = 1;
+
+    /**
+     * Event type: Indicates a scroll event type.
+     *
+     * This event is delivered together with a {@link MotionEvent} with action
+     * {@link MotionEvent#ACTION_SCROLL}.
+     */
+    public static final int EVENT_TYPE_SCROLL = 2;
+
+    /**
+     * Event type: Indicates a long-press event type.
+     *
+     * This event is delivered in the middle of a sequence of {@link #EVENT_TYPE_TOUCH} events.
+     * It includes a {@link MotionEvent} with action {@link MotionEvent#ACTION_MOVE}
+     * that indicates the current touch coordinates of the long-press.
+     *
+     * This event is sent when the current touch gesture has been held longer than
+     * the long-press interval.
+     */
+    public static final int EVENT_TYPE_LONG_PRESS = 3;
+
+    /**
+     * Event type: Indicates a click event type.
+     *
+     * This event is delivered after a sequence of {@link #EVENT_TYPE_TOUCH} events that
+     * comprise a complete gesture ending with {@link MotionEvent#ACTION_UP}.
+     * It includes a {@link MotionEvent} with action {@link MotionEvent#ACTION_UP}
+     * that indicates the location of the click.
+     *
+     * This event is sent shortly after the end of a touch after the double-tap
+     * interval has expired to indicate a click.
+     */
+    public static final int EVENT_TYPE_CLICK = 4;
+
+    /**
+     * Event type: Indicates a double-tap event type.
+     *
+     * This event is delivered after a sequence of {@link #EVENT_TYPE_TOUCH} events that
+     * comprise a complete gesture ending with {@link MotionEvent#ACTION_UP}.
+     * It includes a {@link MotionEvent} with action {@link MotionEvent#ACTION_UP}
+     * that indicates the location of the double-tap.
+     *
+     * This event is sent immediately after a sequence of two touches separated
+     * in time by no more than the double-tap interval and separated in space
+     * by no more than the double-tap slop.
+     */
+    public static final int EVENT_TYPE_DOUBLE_TAP = 5;
+
+    /**
+     * Flag: This event is private to this queue.  Do not forward it.
+     */
+    public static final int FLAG_PRIVATE = 1 << 0;
+
+    /**
+     * Flag: This event is currently being processed by web kit.
+     * If a timeout occurs, make a copy of it before forwarding the event to another queue.
+     */
+    public static final int FLAG_WEBKIT_IN_PROGRESS = 1 << 1;
+
+    /**
+     * Flag: A timeout occurred while waiting for web kit to process this input event.
+     */
+    public static final int FLAG_WEBKIT_TIMEOUT = 1 << 2;
+
+    /**
+     * Flag: Indicates that the event was transformed for delivery to web kit.
+     * The event must be transformed back before being delivered to the UI.
+     */
+    public static final int FLAG_WEBKIT_TRANSFORMED_EVENT = 1 << 3;
+
+    public WebViewInputDispatcher(UiCallbacks uiCallbacks, WebKitCallbacks webKitCallbacks) {
+        this.mUiCallbacks = uiCallbacks;
+        mUiHandler = new UiHandler(uiCallbacks.getUiLooper());
+
+        this.mWebKitCallbacks = webKitCallbacks;
+        mWebKitHandler = new WebKitHandler(webKitCallbacks.getWebKitLooper());
+
+        ViewConfiguration config = ViewConfiguration.get(mUiCallbacks.getContext());
+        mDoubleTapSlopSquared = config.getScaledDoubleTapSlop();
+        mDoubleTapSlopSquared = (mDoubleTapSlopSquared * mDoubleTapSlopSquared);
+        mTouchSlopSquared = config.getScaledTouchSlop();
+        mTouchSlopSquared = (mTouchSlopSquared * mTouchSlopSquared);
+    }
+
+    /**
+     * Sets whether web kit wants to receive touch events.
+     *
+     * @param enable True to enable dispatching of touch events to web kit, otherwise
+     * web kit will be skipped.
+     */
+    public void setWebKitWantsTouchEvents(boolean enable) {
+        if (DEBUG) {
+            Log.d(TAG, "webkitWantsTouchEvents: " + enable);
+        }
+        synchronized (mLock) {
+            if (mPostSendTouchEventsToWebKit != enable) {
+                if (!enable) {
+                    enqueueWebKitCancelTouchEventIfNeededLocked();
+                }
+                mPostSendTouchEventsToWebKit = enable;
+            }
+        }
+    }
+
+    /**
+     * Posts a pointer event to the dispatch queue.
+     *
+     * @param event The event to post.
+     * @param webKitXOffset X offset to apply to events before dispatching them to web kit.
+     * @param webKitYOffset Y offset to apply to events before dispatching them to web kit.
+     * @param webKitScale The scale factor to apply to translated events before dispatching
+     * them to web kit.
+     * @return True if the dispatcher will handle the event, false if the event is unsupported.
+     */
+    public boolean postPointerEvent(MotionEvent event,
+            int webKitXOffset, int webKitYOffset, float webKitScale) {
+        if (event == null
+                || (event.getSource() & InputDevice.SOURCE_CLASS_POINTER) == 0) {
+            throw new IllegalArgumentException("event must be a pointer event");
+        }
+
+        if (DEBUG) {
+            Log.d(TAG, "postPointerEvent: " + event);
+        }
+
+        final int action = event.getActionMasked();
+        final int eventType;
+        switch (action) {
+            case MotionEvent.ACTION_DOWN:
+            case MotionEvent.ACTION_MOVE:
+            case MotionEvent.ACTION_UP:
+            case MotionEvent.ACTION_POINTER_DOWN:
+            case MotionEvent.ACTION_POINTER_UP:
+            case MotionEvent.ACTION_CANCEL:
+                eventType = EVENT_TYPE_TOUCH;
+                break;
+            case MotionEvent.ACTION_SCROLL:
+                eventType = EVENT_TYPE_SCROLL;
+                break;
+            case MotionEvent.ACTION_HOVER_ENTER:
+            case MotionEvent.ACTION_HOVER_MOVE:
+            case MotionEvent.ACTION_HOVER_EXIT:
+                eventType = EVENT_TYPE_HOVER;
+                break;
+            default:
+                return false; // currently unsupported event type
+        }
+
+        synchronized (mLock) {
+            // Ensure that the event is consistent and should be delivered.
+            MotionEvent eventToEnqueue = event;
+            if (eventType == EVENT_TYPE_TOUCH) {
+                eventToEnqueue = mPostTouchStream.update(event);
+                if (eventToEnqueue == null) {
+                    if (DEBUG) {
+                        Log.d(TAG, "postPointerEvent: dropped event " + event);
+                    }
+                    unscheduleLongPressLocked();
+                    unscheduleClickLocked();
+                    return false;
+                }
+
+                if (mPostSendTouchEventsToWebKit
+                        && mPostDoNotSendTouchEventsToWebKitUntilNextGesture
+                        && action == MotionEvent.ACTION_DOWN) {
+                    // Recover from a previous web kit timeout.
+                    mPostDoNotSendTouchEventsToWebKitUntilNextGesture = false;
+                }
+            }
+
+            // Copy the event because we need to retain ownership.
+            if (eventToEnqueue == event) {
+                eventToEnqueue = event.copy();
+            }
+
+            DispatchEvent d = obtainDispatchEventLocked(eventToEnqueue, eventType, 0,
+                    webKitXOffset, webKitYOffset, webKitScale);
+            enqueueEventLocked(d);
+        }
+        return true;
+    }
+
+    private void scheduleLongPressLocked() {
+        unscheduleLongPressLocked();
+        mPostLongPressScheduled = true;
+        mUiHandler.sendEmptyMessageDelayed(UiHandler.MSG_LONG_PRESS,
+                LONG_PRESS_TIMEOUT);
+    }
+
+    private void unscheduleLongPressLocked() {
+        if (mPostLongPressScheduled) {
+            mPostLongPressScheduled = false;
+            mUiHandler.removeMessages(UiHandler.MSG_LONG_PRESS);
+        }
+    }
+
+    private void postLongPress() {
+        synchronized (mLock) {
+            if (!mPostLongPressScheduled) {
+                return;
+            }
+            mPostLongPressScheduled = false;
+
+            MotionEvent event = mPostTouchStream.getLastEvent();
+            if (event == null) {
+                return;
+            }
+
+            switch (event.getActionMasked()) {
+                case MotionEvent.ACTION_DOWN:
+                case MotionEvent.ACTION_MOVE:
+                case MotionEvent.ACTION_POINTER_DOWN:
+                case MotionEvent.ACTION_POINTER_UP:
+                    break;
+                default:
+                    return;
+            }
+
+            MotionEvent eventToEnqueue = MotionEvent.obtainNoHistory(event);
+            eventToEnqueue.setAction(MotionEvent.ACTION_MOVE);
+            DispatchEvent d = obtainDispatchEventLocked(eventToEnqueue, EVENT_TYPE_LONG_PRESS, 0,
+                    mPostLastWebKitXOffset, mPostLastWebKitYOffset, mPostLastWebKitScale);
+            enqueueEventLocked(d);
+        }
+    }
+
+    private void scheduleClickLocked() {
+        unscheduleClickLocked();
+        mPostClickScheduled = true;
+        mUiHandler.sendEmptyMessageDelayed(UiHandler.MSG_CLICK, DOUBLE_TAP_TIMEOUT);
+    }
+
+    private void unscheduleClickLocked() {
+        if (mPostClickScheduled) {
+            mPostClickScheduled = false;
+            mUiHandler.removeMessages(UiHandler.MSG_CLICK);
+        }
+    }
+
+    private void postClick() {
+        synchronized (mLock) {
+            if (!mPostClickScheduled) {
+                return;
+            }
+            mPostClickScheduled = false;
+
+            MotionEvent event = mPostTouchStream.getLastEvent();
+            if (event == null || event.getAction() != MotionEvent.ACTION_UP) {
+                return;
+            }
+
+            MotionEvent eventToEnqueue = MotionEvent.obtainNoHistory(event);
+            DispatchEvent d = obtainDispatchEventLocked(eventToEnqueue, EVENT_TYPE_CLICK, 0,
+                    mPostLastWebKitXOffset, mPostLastWebKitYOffset, mPostLastWebKitScale);
+            enqueueEventLocked(d);
+        }
+    }
+
+    private void checkForDoubleTapOnDownLocked(MotionEvent event) {
+        mIsDoubleTapCandidate = false;
+        if (!mPostClickScheduled) {
+            return;
+        }
+        int deltaX = (int) mInitialDownX - (int) event.getX();
+        int deltaY = (int) mInitialDownY - (int) event.getY();
+        if ((deltaX * deltaX + deltaY * deltaY) < mDoubleTapSlopSquared) {
+            unscheduleClickLocked();
+            mIsDoubleTapCandidate = true;
+        }
+    }
+
+    private boolean isClickCandidateLocked(MotionEvent event) {
+        if (event == null
+                || event.getActionMasked() != MotionEvent.ACTION_UP
+                || !mIsTapCandidate) {
+            return false;
+        }
+        long downDuration = event.getEventTime() - event.getDownTime();
+        return downDuration < TAP_TIMEOUT;
+    }
+
+    private void enqueueDoubleTapLocked(MotionEvent event) {
+        unscheduleClickLocked();
+        MotionEvent eventToEnqueue = MotionEvent.obtainNoHistory(event);
+        DispatchEvent d = obtainDispatchEventLocked(eventToEnqueue, EVENT_TYPE_DOUBLE_TAP, 0,
+                mPostLastWebKitXOffset, mPostLastWebKitYOffset, mPostLastWebKitScale);
+        enqueueEventLocked(d);
+        mIsDoubleTapCandidate = false;
+    }
+
+    private void checkForSlopLocked(MotionEvent event) {
+        if (!mIsTapCandidate) {
+            return;
+        }
+        int deltaX = (int) mInitialDownX - (int) event.getX();
+        int deltaY = (int) mInitialDownY - (int) event.getY();
+        if ((deltaX * deltaX + deltaY * deltaY) > mTouchSlopSquared) {
+            unscheduleLongPressLocked();
+            mIsTapCandidate = false;
+        }
+    }
+
+    private void updateStateTrackersLocked(DispatchEvent d, MotionEvent event) {
+        mPostLastWebKitXOffset = d.mWebKitXOffset;
+        mPostLastWebKitYOffset = d.mWebKitYOffset;
+        mPostLastWebKitScale = d.mWebKitScale;
+        int action = event != null ? event.getAction() : MotionEvent.ACTION_CANCEL;
+        if (d.mEventType != EVENT_TYPE_TOUCH) {
+            return;
+        }
+
+        if (action == MotionEvent.ACTION_CANCEL
+                || event.getPointerCount() > 1) {
+            unscheduleLongPressLocked();
+            unscheduleClickLocked();
+            mIsDoubleTapCandidate = false;
+            mIsTapCandidate = false;
+        } else if (action == MotionEvent.ACTION_DOWN) {
+            checkForDoubleTapOnDownLocked(event);
+            scheduleLongPressLocked();
+            mIsTapCandidate = true;
+            mInitialDownX = event.getX();
+            mInitialDownY = event.getY();
+        } else if (action == MotionEvent.ACTION_UP) {
+            unscheduleLongPressLocked();
+            if (isClickCandidateLocked(event)) {
+                if (mIsDoubleTapCandidate) {
+                    enqueueDoubleTapLocked(event);
+                } else {
+                    scheduleClickLocked();
+                }
+            }
+        } else if (action == MotionEvent.ACTION_MOVE) {
+            checkForSlopLocked(event);
+        }
+    }
+
+    /**
+     * Dispatches pending web kit events.
+     * Must only be called from the web kit thread.
+     *
+     * This method may be used to flush the queue of pending input events
+     * immediately.  This method may help to reduce input dispatch latency
+     * if called before certain expensive operations such as drawing.
+     */
+    public void dispatchWebKitEvents() {
+        dispatchWebKitEvents(false);
+    }
+
+    private void dispatchWebKitEvents(boolean calledFromHandler) {
+        for (;;) {
+            // Get the next event, but leave it in the queue so we can move it to the UI
+            // queue if a timeout occurs.
+            DispatchEvent d;
+            MotionEvent event;
+            final int eventType;
+            int flags;
+            synchronized (mLock) {
+                if (!ENABLE_EVENT_BATCHING) {
+                    drainStaleWebKitEventsLocked();
+                }
+                d = mWebKitDispatchEventQueue.mHead;
+                if (d == null) {
+                    if (mWebKitDispatchScheduled) {
+                        mWebKitDispatchScheduled = false;
+                        if (!calledFromHandler) {
+                            mWebKitHandler.removeMessages(
+                                    WebKitHandler.MSG_DISPATCH_WEBKIT_EVENTS);
+                        }
+                    }
+                    return;
+                }
+
+                event = d.mEvent;
+                if (event != null) {
+                    event.offsetLocation(d.mWebKitXOffset, d.mWebKitYOffset);
+                    event.scale(d.mWebKitScale);
+                    d.mFlags |= FLAG_WEBKIT_TRANSFORMED_EVENT;
+                }
+
+                eventType = d.mEventType;
+                if (eventType == EVENT_TYPE_TOUCH) {
+                    event = mWebKitTouchStream.update(event);
+                    if (DEBUG && event == null && d.mEvent != null) {
+                        Log.d(TAG, "dispatchWebKitEvents: dropped event " + d.mEvent);
+                    }
+                }
+
+                d.mFlags |= FLAG_WEBKIT_IN_PROGRESS;
+                flags = d.mFlags;
+            }
+
+            // Handle the event.
+            final boolean preventDefault;
+            if (event == null) {
+                preventDefault = false;
+            } else {
+                preventDefault = dispatchWebKitEvent(event, eventType, flags);
+            }
+
+            synchronized (mLock) {
+                flags = d.mFlags;
+                d.mFlags = flags & ~FLAG_WEBKIT_IN_PROGRESS;
+                boolean recycleEvent = event != d.mEvent;
+
+                if ((flags & FLAG_WEBKIT_TIMEOUT) != 0) {
+                    // A timeout occurred!
+                    recycleDispatchEventLocked(d);
+                } else {
+                    // Web kit finished in a timely manner.  Dequeue the event.
+                    assert mWebKitDispatchEventQueue.mHead == d;
+                    mWebKitDispatchEventQueue.dequeue();
+
+                    updateWebKitTimeoutLocked();
+
+                    if ((flags & FLAG_PRIVATE) != 0) {
+                        // Event was intended for web kit only.  All done.
+                        recycleDispatchEventLocked(d);
+                    } else if (preventDefault) {
+                        // Web kit has decided to consume the event!
+                        if (d.mEventType == EVENT_TYPE_TOUCH) {
+                            enqueueUiCancelTouchEventIfNeededLocked();
+                        }
+                    } else {
+                        // Web kit is being friendly.  Pass the event to the UI.
+                        enqueueUiEventUnbatchedLocked(d);
+                    }
+                }
+
+                if (event != null && recycleEvent) {
+                    event.recycle();
+                }
+            }
+        }
+    }
+
+    // Runs on web kit thread.
+    private boolean dispatchWebKitEvent(MotionEvent event, int eventType, int flags) {
+        if (DEBUG) {
+            Log.d(TAG, "dispatchWebKitEvent: event=" + event
+                    + ", eventType=" + eventType + ", flags=" + flags);
+        }
+        boolean preventDefault = mWebKitCallbacks.dispatchWebKitEvent(
+                event, eventType, flags);
+        if (DEBUG) {
+            Log.d(TAG, "dispatchWebKitEvent: preventDefault=" + preventDefault);
+        }
+        return preventDefault;
+    }
+
+    private boolean isMoveEventLocked(DispatchEvent d) {
+        return d.mEvent != null
+                && d.mEvent.getActionMasked() == MotionEvent.ACTION_MOVE;
+    }
+
+    private void drainStaleWebKitEventsLocked() {
+        DispatchEvent d = mWebKitDispatchEventQueue.mHead;
+        while (d != null && d.mNext != null
+                && isMoveEventLocked(d)
+                && isMoveEventLocked(d.mNext)) {
+            DispatchEvent next = d.mNext;
+            skipWebKitEventLocked(d);
+            d = next;
+        }
+        mWebKitDispatchEventQueue.mHead = d;
+    }
+
+    // Runs on UI thread in response to the web kit thread appearing to be unresponsive.
+    private void handleWebKitTimeout() {
+        synchronized (mLock) {
+            if (!mWebKitTimeoutScheduled) {
+                return;
+            }
+            mWebKitTimeoutScheduled = false;
+
+            if (DEBUG) {
+                Log.d(TAG, "handleWebKitTimeout: timeout occurred!");
+            }
+
+            // Drain the web kit event queue.
+            DispatchEvent d = mWebKitDispatchEventQueue.dequeueList();
+
+            // If web kit was processing an event (must be at the head of the list because
+            // it can only do one at a time), then clone it or ignore it.
+            if ((d.mFlags & FLAG_WEBKIT_IN_PROGRESS) != 0) {
+                d.mFlags |= FLAG_WEBKIT_TIMEOUT;
+                if ((d.mFlags & FLAG_PRIVATE) != 0) {
+                    d = d.mNext; // the event is private to web kit, ignore it
+                } else {
+                    d = copyDispatchEventLocked(d);
+                    d.mFlags &= ~FLAG_WEBKIT_IN_PROGRESS;
+                }
+            }
+
+            // Enqueue all non-private events for handling by the UI thread.
+            while (d != null) {
+                DispatchEvent next = d.mNext;
+                skipWebKitEventLocked(d);
+                d = next;
+            }
+
+            // Tell web kit to cancel all pending touches.
+            // This also prevents us from sending web kit any more touches until the
+            // next gesture begins.  (As required to ensure touch event stream consistency.)
+            enqueueWebKitCancelTouchEventIfNeededLocked();
+        }
+    }
+
+    private void skipWebKitEventLocked(DispatchEvent d) {
+        d.mNext = null;
+        if ((d.mFlags & FLAG_PRIVATE) != 0) {
+            recycleDispatchEventLocked(d);
+        } else {
+            d.mFlags |= FLAG_WEBKIT_TIMEOUT;
+            enqueueUiEventUnbatchedLocked(d);
+        }
+    }
+
+    /**
+     * Dispatches pending UI events.
+     * Must only be called from the UI thread.
+     *
+     * This method may be used to flush the queue of pending input events
+     * immediately.  This method may help to reduce input dispatch latency
+     * if called before certain expensive operations such as drawing.
+     */
+    public void dispatchUiEvents() {
+        dispatchUiEvents(false);
+    }
+
+    private void dispatchUiEvents(boolean calledFromHandler) {
+        for (;;) {
+            MotionEvent event;
+            final int eventType;
+            final int flags;
+            synchronized (mLock) {
+                DispatchEvent d = mUiDispatchEventQueue.dequeue();
+                if (d == null) {
+                    if (mUiDispatchScheduled) {
+                        mUiDispatchScheduled = false;
+                        if (!calledFromHandler) {
+                            mUiHandler.removeMessages(UiHandler.MSG_DISPATCH_UI_EVENTS);
+                        }
+                    }
+                    return;
+                }
+
+                event = d.mEvent;
+                if (event != null && (d.mFlags & FLAG_WEBKIT_TRANSFORMED_EVENT) != 0) {
+                    event.scale(1.0f / d.mWebKitScale);
+                    event.offsetLocation(-d.mWebKitXOffset, -d.mWebKitYOffset);
+                    d.mFlags &= ~FLAG_WEBKIT_TRANSFORMED_EVENT;
+                }
+
+                eventType = d.mEventType;
+                if (eventType == EVENT_TYPE_TOUCH) {
+                    event = mUiTouchStream.update(event);
+                    if (DEBUG && event == null && d.mEvent != null) {
+                        Log.d(TAG, "dispatchUiEvents: dropped event " + d.mEvent);
+                    }
+                }
+
+                flags = d.mFlags;
+
+                updateStateTrackersLocked(d, event);
+                if (event == d.mEvent) {
+                    d.mEvent = null; // retain ownership of event, don't recycle it yet
+                }
+                recycleDispatchEventLocked(d);
+            }
+
+            // Handle the event.
+            if (event != null) {
+                dispatchUiEvent(event, eventType, flags);
+                event.recycle();
+            }
+        }
+    }
+
+    // Runs on UI thread.
+    private void dispatchUiEvent(MotionEvent event, int eventType, int flags) {
+        if (DEBUG) {
+            Log.d(TAG, "dispatchUiEvent: event=" + event
+                    + ", eventType=" + eventType + ", flags=" + flags);
+        }
+        mUiCallbacks.dispatchUiEvent(event, eventType, flags);
+    }
+
+    private void enqueueEventLocked(DispatchEvent d) {
+        if (!shouldSkipWebKit(d.mEventType)) {
+            enqueueWebKitEventLocked(d);
+        } else {
+            enqueueUiEventLocked(d);
+        }
+    }
+
+    private boolean shouldSkipWebKit(int eventType) {
+        switch (eventType) {
+            case EVENT_TYPE_CLICK:
+            case EVENT_TYPE_HOVER:
+            case EVENT_TYPE_SCROLL:
+                return false;
+            case EVENT_TYPE_TOUCH:
+                return !mPostSendTouchEventsToWebKit
+                        || mPostDoNotSendTouchEventsToWebKitUntilNextGesture;
+        }
+        return true;
+    }
+
+    private void enqueueWebKitCancelTouchEventIfNeededLocked() {
+        // We want to cancel touch events that were delivered to web kit.
+        // Enqueue a null event at the end of the queue if needed.
+        if (mWebKitTouchStream.isCancelNeeded() || !mWebKitDispatchEventQueue.isEmpty()) {
+            DispatchEvent d = obtainDispatchEventLocked(null, EVENT_TYPE_TOUCH, FLAG_PRIVATE,
+                    0, 0, 1.0f);
+            enqueueWebKitEventUnbatchedLocked(d);
+            mPostDoNotSendTouchEventsToWebKitUntilNextGesture = true;
+        }
+    }
+
+    private void enqueueWebKitEventLocked(DispatchEvent d) {
+        if (batchEventLocked(d, mWebKitDispatchEventQueue.mTail)) {
+            if (DEBUG) {
+                Log.d(TAG, "enqueueWebKitEventLocked: batched event " + d.mEvent);
+            }
+            recycleDispatchEventLocked(d);
+        } else {
+            enqueueWebKitEventUnbatchedLocked(d);
+        }
+    }
+
+    private void enqueueWebKitEventUnbatchedLocked(DispatchEvent d) {
+        if (DEBUG) {
+            Log.d(TAG, "enqueueWebKitEventUnbatchedLocked: enqueued event " + d.mEvent);
+        }
+        mWebKitDispatchEventQueue.enqueue(d);
+        scheduleWebKitDispatchLocked();
+        updateWebKitTimeoutLocked();
+    }
+
+    private void scheduleWebKitDispatchLocked() {
+        if (!mWebKitDispatchScheduled) {
+            mWebKitHandler.sendEmptyMessage(WebKitHandler.MSG_DISPATCH_WEBKIT_EVENTS);
+            mWebKitDispatchScheduled = true;
+        }
+    }
+
+    private void updateWebKitTimeoutLocked() {
+        DispatchEvent d = mWebKitDispatchEventQueue.mHead;
+        if (d != null && mWebKitTimeoutScheduled && mWebKitTimeoutTime == d.mTimeoutTime) {
+            return;
+        }
+        if (mWebKitTimeoutScheduled) {
+            mUiHandler.removeMessages(UiHandler.MSG_WEBKIT_TIMEOUT);
+            mWebKitTimeoutScheduled = false;
+        }
+        if (d != null) {
+            mUiHandler.sendEmptyMessageAtTime(UiHandler.MSG_WEBKIT_TIMEOUT, d.mTimeoutTime);
+            mWebKitTimeoutScheduled = true;
+            mWebKitTimeoutTime = d.mTimeoutTime;
+        }
+    }
+
+    private void enqueueUiCancelTouchEventIfNeededLocked() {
+        // We want to cancel touch events that were delivered to the UI.
+        // Enqueue a null event at the end of the queue if needed.
+        if (mUiTouchStream.isCancelNeeded() || !mUiDispatchEventQueue.isEmpty()) {
+            DispatchEvent d = obtainDispatchEventLocked(null, EVENT_TYPE_TOUCH, FLAG_PRIVATE,
+                    0, 0, 1.0f);
+            enqueueUiEventUnbatchedLocked(d);
+        }
+    }
+
+    private void enqueueUiEventLocked(DispatchEvent d) {
+        if (batchEventLocked(d, mUiDispatchEventQueue.mTail)) {
+            if (DEBUG) {
+                Log.d(TAG, "enqueueUiEventLocked: batched event " + d.mEvent);
+            }
+            recycleDispatchEventLocked(d);
+        } else {
+            enqueueUiEventUnbatchedLocked(d);
+        }
+    }
+
+    private void enqueueUiEventUnbatchedLocked(DispatchEvent d) {
+        if (DEBUG) {
+            Log.d(TAG, "enqueueUiEventUnbatchedLocked: enqueued event " + d.mEvent);
+        }
+        mUiDispatchEventQueue.enqueue(d);
+        scheduleUiDispatchLocked();
+    }
+
+    private void scheduleUiDispatchLocked() {
+        if (!mUiDispatchScheduled) {
+            mUiHandler.sendEmptyMessage(UiHandler.MSG_DISPATCH_UI_EVENTS);
+            mUiDispatchScheduled = true;
+        }
+    }
+
+    private boolean batchEventLocked(DispatchEvent in, DispatchEvent tail) {
+        if (!ENABLE_EVENT_BATCHING) {
+            return false;
+        }
+        if (tail != null && tail.mEvent != null && in.mEvent != null
+                && in.mEventType == tail.mEventType
+                && in.mFlags == tail.mFlags
+                && in.mWebKitXOffset == tail.mWebKitXOffset
+                && in.mWebKitYOffset == tail.mWebKitYOffset
+                && in.mWebKitScale == tail.mWebKitScale) {
+            return tail.mEvent.addBatch(in.mEvent);
+        }
+        return false;
+    }
+
+    private DispatchEvent obtainDispatchEventLocked(MotionEvent event,
+            int eventType, int flags, int webKitXOffset, int webKitYOffset, float webKitScale) {
+        DispatchEvent d = obtainUninitializedDispatchEventLocked();
+        d.mEvent = event;
+        d.mEventType = eventType;
+        d.mFlags = flags;
+        d.mTimeoutTime = SystemClock.uptimeMillis() + WEBKIT_TIMEOUT_MILLIS;
+        d.mWebKitXOffset = webKitXOffset;
+        d.mWebKitYOffset = webKitYOffset;
+        d.mWebKitScale = webKitScale;
+        if (DEBUG) {
+            Log.d(TAG, "Timeout time: " + (d.mTimeoutTime - SystemClock.uptimeMillis()));
+        }
+        return d;
+    }
+
+    private DispatchEvent copyDispatchEventLocked(DispatchEvent d) {
+        DispatchEvent copy = obtainUninitializedDispatchEventLocked();
+        if (d.mEvent != null) {
+            copy.mEvent = d.mEvent.copy();
+        }
+        copy.mEventType = d.mEventType;
+        copy.mFlags = d.mFlags;
+        copy.mTimeoutTime = d.mTimeoutTime;
+        copy.mWebKitXOffset = d.mWebKitXOffset;
+        copy.mWebKitYOffset = d.mWebKitYOffset;
+        copy.mWebKitScale = d.mWebKitScale;
+        copy.mNext = d.mNext;
+        return copy;
+    }
+
+    private DispatchEvent obtainUninitializedDispatchEventLocked() {
+        DispatchEvent d = mDispatchEventPool;
+        if (d != null) {
+            mDispatchEventPoolSize -= 1;
+            mDispatchEventPool = d.mNext;
+            d.mNext = null;
+        } else {
+            d = new DispatchEvent();
+        }
+        return d;
+    }
+
+    private void recycleDispatchEventLocked(DispatchEvent d) {
+        if (d.mEvent != null) {
+            d.mEvent.recycle();
+            d.mEvent = null;
+        }
+
+        if (mDispatchEventPoolSize < MAX_DISPATCH_EVENT_POOL_SIZE) {
+            mDispatchEventPoolSize += 1;
+            d.mNext = mDispatchEventPool;
+            mDispatchEventPool = d;
+        }
+    }
+
+    /* Implemented by {@link WebViewClassic} to perform operations on the UI thread. */
+    public static interface UiCallbacks {
+        /**
+         * Gets the UI thread's looper.
+         * @return The looper.
+         */
+        public Looper getUiLooper();
+
+        /**
+         * Gets the UI's context
+         * @return The context
+         */
+        public Context getContext();
+
+        /**
+         * Dispatches an event to the UI.
+         * @param event The event.
+         * @param eventType The event type.
+         * @param flags The event's dispatch flags.
+         */
+        public void dispatchUiEvent(MotionEvent event, int eventType, int flags);
+    }
+
+    /* Implemented by {@link WebViewCore} to perform operations on the web kit thread. */
+    public static interface WebKitCallbacks {
+        /**
+         * Gets the web kit thread's looper.
+         * @return The looper.
+         */
+        public Looper getWebKitLooper();
+
+        /**
+         * Dispatches an event to web kit.
+         * @param event The event.
+         * @param eventType The event type.
+         * @param flags The event's dispatch flags.
+         * @return True if web kit wants to prevent default event handling.
+         */
+        public boolean dispatchWebKitEvent(MotionEvent event, int eventType, int flags);
+    }
+
+    // Runs on UI thread.
+    private final class UiHandler extends Handler {
+        public static final int MSG_DISPATCH_UI_EVENTS = 1;
+        public static final int MSG_WEBKIT_TIMEOUT = 2;
+        public static final int MSG_LONG_PRESS = 3;
+        public static final int MSG_CLICK = 4;
+
+        public UiHandler(Looper looper) {
+            super(looper);
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case MSG_DISPATCH_UI_EVENTS:
+                    dispatchUiEvents(true);
+                    break;
+                case MSG_WEBKIT_TIMEOUT:
+                    handleWebKitTimeout();
+                    break;
+                case MSG_LONG_PRESS:
+                    postLongPress();
+                    break;
+                case MSG_CLICK:
+                    postClick();
+                    break;
+                default:
+                    throw new IllegalStateException("Unknown message type: " + msg.what);
+            }
+        }
+    }
+
+    // Runs on web kit thread.
+    private final class WebKitHandler extends Handler {
+        public static final int MSG_DISPATCH_WEBKIT_EVENTS = 1;
+
+        public WebKitHandler(Looper looper) {
+            super(looper);
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case MSG_DISPATCH_WEBKIT_EVENTS:
+                    dispatchWebKitEvents(true);
+                    break;
+                default:
+                    throw new IllegalStateException("Unknown message type: " + msg.what);
+            }
+        }
+    }
+
+    private static final class DispatchEvent {
+        public DispatchEvent mNext;
+
+        public MotionEvent mEvent;
+        public int mEventType;
+        public int mFlags;
+        public long mTimeoutTime;
+        public int mWebKitXOffset;
+        public int mWebKitYOffset;
+        public float mWebKitScale;
+    }
+
+    private static final class DispatchEventQueue {
+        public DispatchEvent mHead;
+        public DispatchEvent mTail;
+
+        public boolean isEmpty() {
+            return mHead != null;
+        }
+
+        public void enqueue(DispatchEvent d) {
+            if (mHead == null) {
+                mHead = d;
+                mTail = d;
+            } else {
+                mTail.mNext = d;
+                mTail = d;
+            }
+        }
+
+        public DispatchEvent dequeue() {
+            DispatchEvent d = mHead;
+            if (d != null) {
+                DispatchEvent next = d.mNext;
+                if (next == null) {
+                    mHead = null;
+                    mTail = null;
+                } else {
+                    mHead = next;
+                    d.mNext = null;
+                }
+            }
+            return d;
+        }
+
+        public DispatchEvent dequeueList() {
+            DispatchEvent d = mHead;
+            if (d != null) {
+                mHead = null;
+                mTail = null;
+            }
+            return d;
+        }
+    }
+
+    /**
+     * Keeps track of a stream of touch events so that we can discard touch
+     * events that would make the stream inconsistent.
+     */
+    private static final class TouchStream {
+        private MotionEvent mLastEvent;
+
+        /**
+         * Gets the last touch event that was delivered.
+         * @return The last touch event, or null if none.
+         */
+        public MotionEvent getLastEvent() {
+            return mLastEvent;
+        }
+
+        /**
+         * Updates the touch event stream.
+         * @param event The event that we intend to send, or null to cancel the
+         * touch event stream.
+         * @return The event that we should actually send, or null if no event should
+         * be sent because the proposed event would make the stream inconsistent.
+         */
+        public MotionEvent update(MotionEvent event) {
+            if (event == null) {
+                if (isCancelNeeded()) {
+                    event = mLastEvent;
+                    if (event != null) {
+                        event.setAction(MotionEvent.ACTION_CANCEL);
+                        mLastEvent = null;
+                    }
+                }
+                return event;
+            }
+
+            switch (event.getActionMasked()) {
+                case MotionEvent.ACTION_MOVE:
+                case MotionEvent.ACTION_UP:
+                case MotionEvent.ACTION_POINTER_DOWN:
+                case MotionEvent.ACTION_POINTER_UP:
+                    if (mLastEvent == null
+                            || mLastEvent.getAction() == MotionEvent.ACTION_UP) {
+                        return null;
+                    }
+                    updateLastEvent(event);
+                    return event;
+
+                case MotionEvent.ACTION_DOWN:
+                    updateLastEvent(event);
+                    return event;
+
+                case MotionEvent.ACTION_CANCEL:
+                    if (mLastEvent == null) {
+                        return null;
+                    }
+                    updateLastEvent(null);
+                    return event;
+
+                default:
+                    return null;
+            }
+        }
+
+        /**
+         * Returns true if there is a gesture in progress that may need to be canceled.
+         * @return True if cancel is needed.
+         */
+        public boolean isCancelNeeded() {
+            return mLastEvent != null && mLastEvent.getAction() != MotionEvent.ACTION_UP;
+        }
+
+        private void updateLastEvent(MotionEvent event) {
+            if (mLastEvent != null) {
+                mLastEvent.recycle();
+            }
+            mLastEvent = event != null ? MotionEvent.obtainNoHistory(event) : null;
+        }
+    }
+}
\ No newline at end of file
diff --git a/media/java/android/media/MediaMetadataRetriever.java b/media/java/android/media/MediaMetadataRetriever.java
index 11ecd1f..aef631f 100644
--- a/media/java/android/media/MediaMetadataRetriever.java
+++ b/media/java/android/media/MediaMetadataRetriever.java
@@ -23,6 +23,7 @@
 import android.net.Uri;
 
 import java.io.FileDescriptor;
+import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.IOException;
 
@@ -57,7 +58,24 @@
      * @param path The path of the input media file.
      * @throws IllegalArgumentException If the path is invalid.
      */
-    public native void setDataSource(String path) throws IllegalArgumentException;
+    public void setDataSource(String path) throws IllegalArgumentException {
+        FileInputStream is = null;
+        try {
+            is = new FileInputStream(path);
+            FileDescriptor fd = is.getFD();
+            setDataSource(fd, 0, 0x7ffffffffffffffL);
+        } catch (FileNotFoundException fileEx) {
+            throw new IllegalArgumentException();
+        } catch (IOException ioEx) {
+            throw new IllegalArgumentException();
+        }
+
+        try {
+            if (is != null) {
+                is.close();
+            }
+        } catch (Exception e) {}
+    }
 
     /**
      * Sets the data source (URI) to use. Call this
diff --git a/media/jni/android_media_MediaMetadataRetriever.cpp b/media/jni/android_media_MediaMetadataRetriever.cpp
index 0dc3b65..297dadf 100644
--- a/media/jni/android_media_MediaMetadataRetriever.cpp
+++ b/media/jni/android_media_MediaMetadataRetriever.cpp
@@ -131,13 +131,6 @@
             "setDataSource failed");
 }
 
-
-static void android_media_MediaMetadataRetriever_setDataSource(
-        JNIEnv *env, jobject thiz, jstring path) {
-    android_media_MediaMetadataRetriever_setDataSourceAndHeaders(
-            env, thiz, path, NULL, NULL);
-}
-
 static void android_media_MediaMetadataRetriever_setDataSourceFD(JNIEnv *env, jobject thiz, jobject fileDescriptor, jlong offset, jlong length)
 {
     ALOGV("setDataSource");
@@ -447,8 +440,6 @@
 
 // JNI mapping between Java methods and native methods
 static JNINativeMethod nativeMethods[] = {
-        {"setDataSource",   "(Ljava/lang/String;)V", (void *)android_media_MediaMetadataRetriever_setDataSource},
-
         {
             "_setDataSource",
             "(Ljava/lang/String;[Ljava/lang/String;[Ljava/lang/String;)V",
diff --git a/native/android/native_window.cpp b/native/android/native_window.cpp
index c58ee00..99c0fd3 100644
--- a/native/android/native_window.cpp
+++ b/native/android/native_window.cpp
@@ -60,13 +60,16 @@
 
 int32_t ANativeWindow_setBuffersGeometry(ANativeWindow* window, int32_t width,
         int32_t height, int32_t format) {
-    int32_t err = native_window_set_buffers_geometry(window, width, height, format);
+    int32_t err = native_window_set_buffers_format(window, format);
     if (!err) {
-        int mode = NATIVE_WINDOW_SCALING_MODE_FREEZE;
-        if (width && height) {
-            mode = NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW;
-        }
-        err = native_window_set_scaling_mode(window, mode);
+        err = native_window_set_buffers_user_dimensions(window, width, height);
+        if (!err) {
+            int mode = NATIVE_WINDOW_SCALING_MODE_FREEZE;
+            if (width && height) {
+                mode = NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW;
+            }
+            err = native_window_set_scaling_mode(window, mode);
+         }
     }
     return err;
 }
diff --git a/policy/src/com/android/internal/policy/impl/BiometricSensorUnlock.java b/policy/src/com/android/internal/policy/impl/BiometricSensorUnlock.java
new file mode 100644
index 0000000..d445d5c
--- /dev/null
+++ b/policy/src/com/android/internal/policy/impl/BiometricSensorUnlock.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2012 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.internal.policy.impl;
+
+import android.view.View;
+
+interface BiometricSensorUnlock {
+    // Returns 'true' if the biometric sensor is available and is selected by user.
+    public boolean installedAndSelected();
+
+    // Returns 'true' if the biometric sensor has started its unlock procedure but has not yet
+    // accepted or rejected the user.
+    public boolean isRunning();
+
+    // Show the interface, but don't start the unlock procedure.  The interface should disappear
+    // after the specified timeout.  If the timeout is 0, the interface shows until another event,
+    // such as calling hide(), causes it to disappear.
+    public void show(long timeoutMilliseconds);
+
+    // Hide the interface, if any, exposing the lockscreen.
+    public void hide();
+
+    // Stop the unlock procedure if running.  Returns 'true' if it was in fact running.
+    public boolean stop();
+
+    // Start the unlock procedure.  Returns ‘false’ if it can’t be started or if the backup should
+    // be used.
+    public boolean start(boolean suppressBiometricUnlock);
+
+    // Provide a view to work within.
+    public void initializeAreaView(View topView);
+
+    // Clean up any resources used by the biometric unlock.
+    public void cleanUp();
+
+    // Returns the Device Policy Manager quality (e.g. PASSWORD_QUALITY_BIOMETRIC_WEAK).
+    public int getQuality();
+}
diff --git a/policy/src/com/android/internal/policy/impl/FaceUnlock.java b/policy/src/com/android/internal/policy/impl/FaceUnlock.java
index 31fbaafd..7b0a086 100644
--- a/policy/src/com/android/internal/policy/impl/FaceUnlock.java
+++ b/policy/src/com/android/internal/policy/impl/FaceUnlock.java
@@ -21,6 +21,7 @@
 import com.android.internal.policy.IFaceLockInterface;
 import com.android.internal.widget.LockPatternUtils;
 
+import android.app.admin.DevicePolicyManager;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
@@ -33,7 +34,7 @@
 import android.util.Log;
 import android.view.View;
 
-public class FaceUnlock implements Handler.Callback {
+public class FaceUnlock implements BiometricSensorUnlock, Handler.Callback {
 
     private static final boolean DEBUG = false;
     private static final String TAG = "FULLockscreen";
@@ -52,10 +53,6 @@
     private boolean mServiceRunning = false;
     private final Object mServiceRunningLock = new Object();
 
-    // Long enough to stay visible while dialer comes up
-    // Short enough to not be visible if the user goes back immediately
-    private final int VIEW_AREA_EMERGENCY_DIALER_TIMEOUT = 1000;
-
     // Long enough to stay visible while the service starts
     // Short enough to not have to wait long for backup if service fails to start or crashes
     // The service can take a couple of seconds to start on the first try after boot
@@ -80,22 +77,65 @@
         mHandler = new Handler(this);
     }
 
-    public void cleanUp() {
-        if (mService != null) {
-            try {
-                mService.unregisterCallback(mFaceLockCallback);
-            } catch (RemoteException e) {
-                // Not much we can do
-            }
-            stop();
-            mService = null;
-        }
+    // Indicates whether FaceLock is in use
+    public boolean installedAndSelected() {
+        return (mLockPatternUtils.usingBiometricWeak() &&
+                mLockPatternUtils.isBiometricWeakInstalled());
     }
 
-    /** When screen is turned on and focused, need to bind to FaceLock service if we are using
-     *  FaceLock, but only if we're not dealing with a call
-    */
-    public void activateIfAble(boolean hasOverlay) {
+    public boolean isRunning() {
+        return mServiceRunning;
+    }
+
+    // Shows the FaceLock area for a period of time
+    public void show(long timeoutMillis) {
+        showArea();
+        if (timeoutMillis > 0)
+            mHandler.sendEmptyMessageDelayed(MSG_HIDE_AREA_VIEW, timeoutMillis);
+    }
+
+    // Hides the FaceLock area immediately
+    public void hide() {
+        // Remove messages to prevent a delayed show message from undo-ing the hide
+        removeAreaDisplayMessages();
+        mHandler.sendEmptyMessage(MSG_HIDE_AREA_VIEW);
+    }
+
+    // Tells FaceLock to stop and then unbinds from the FaceLock service
+    public boolean stop() {
+        boolean wasRunning = false;
+        if (installedAndSelected()) {
+            stopUi();
+
+            if (mBoundToService) {
+                wasRunning = true;
+                if (DEBUG) Log.d(TAG, "before unbind from FaceLock service");
+                if (mService != null) {
+                    try {
+                        mService.unregisterCallback(mFaceLockCallback);
+                    } catch (RemoteException e) {
+                        // Not much we can do
+                    }
+                }
+                mContext.unbindService(mConnection);
+                if (DEBUG) Log.d(TAG, "after unbind from FaceLock service");
+                mBoundToService = false;
+            } else {
+                // This is usually not an error when this happens.  Sometimes we will tell it to
+                // unbind multiple times because it's called from both onWindowFocusChanged and
+                // onDetachedFromWindow.
+                if (DEBUG) Log.d(TAG, "Attempt to unbind from FaceLock when not bound");
+            }
+        }
+
+        return wasRunning;
+    }
+
+    /**
+     * When screen is turned on and focused, need to bind to FaceLock service if we are using
+     * FaceLock, but only if we're not dealing with a call
+     */
+    public boolean start(boolean suppressBiometricUnlock) {
         final boolean tooManyFaceUnlockTries = mUpdateMonitor.getMaxFaceUnlockAttemptsReached();
         final int failedBackupAttempts = mUpdateMonitor.getFailedAttempts();
         final boolean backupIsTimedOut =
@@ -103,42 +143,31 @@
         if (tooManyFaceUnlockTries) Log.i(TAG, "tooManyFaceUnlockTries: " + tooManyFaceUnlockTries);
         if (mUpdateMonitor.getPhoneState() == TelephonyManager.CALL_STATE_IDLE
                 && installedAndSelected()
-                && !hasOverlay
+                && !suppressBiometricUnlock
                 && !tooManyFaceUnlockTries
                 && !backupIsTimedOut) {
             bind();
 
             // Show FaceLock area, but only for a little bit so lockpattern will become visible if
             // FaceLock fails to start or crashes
-            showAreaWithTimeout(VIEW_AREA_SERVICE_TIMEOUT);
+            show(VIEW_AREA_SERVICE_TIMEOUT);
 
             // When switching between portrait and landscape view while FaceLock is running, the
             // screen will eventually go dark unless we poke the wakelock when FaceLock is
             // restarted
             mKeyguardScreenCallback.pokeWakelock();
         } else {
-            hideArea();
+            hide();
+            return false;
         }
-    }
 
-    public boolean isServiceRunning() {
-        return mServiceRunning;
-    }
-
-    public int viewAreaEmergencyDialerTimeout() {
-        return VIEW_AREA_EMERGENCY_DIALER_TIMEOUT;
-    }
-
-    // Indicates whether FaceLock is in use
-    public boolean installedAndSelected() {
-        return (mLockPatternUtils.usingBiometricWeak() &&
-                mLockPatternUtils.isBiometricWeakInstalled());
+        return true;
     }
 
     // Takes care of FaceLock area when layout is created
-    public void initializeAreaView(View view) {
+    public void initializeAreaView(View topView) {
         if (installedAndSelected()) {
-            mAreaView = view.findViewById(R.id.faceLockAreaView);
+            mAreaView = topView.findViewById(R.id.faceLockAreaView);
             if (mAreaView == null) {
                 Log.e(TAG, "Layout does not have areaView and FaceLock is enabled");
             }
@@ -147,13 +176,20 @@
         }
     }
 
-    // Stops FaceLock if it is running and reports back whether it was running or not
-    public boolean stopIfRunning() {
-        if (installedAndSelected() && mBoundToService) {
-            stopAndUnbind();
-            return true;
+    public void cleanUp() {
+        if (mService != null) {
+            try {
+                mService.unregisterCallback(mFaceLockCallback);
+            } catch (RemoteException e) {
+                // Not much we can do
+            }
+            stopUi();
+            mService = null;
         }
-        return false;
+    }
+
+    public int getQuality() {
+        return DevicePolicyManager.PASSWORD_QUALITY_BIOMETRIC_WEAK;
     }
 
     // Handles covering or exposing FaceLock area on the client side when FaceLock starts or stops
@@ -186,28 +222,15 @@
     }
 
     // Shows the FaceLock area immediately
-    public void showArea() {
+    private void showArea() {
         // Remove messages to prevent a delayed hide message from undo-ing the show
         removeAreaDisplayMessages();
         mHandler.sendEmptyMessage(MSG_SHOW_AREA_VIEW);
     }
 
-    // Hides the FaceLock area immediately
-    public void hideArea() {
-        // Remove messages to prevent a delayed show message from undo-ing the hide
-        removeAreaDisplayMessages();
-        mHandler.sendEmptyMessage(MSG_HIDE_AREA_VIEW);
-    }
-
-    // Shows the FaceLock area for a period of time
-    public void showAreaWithTimeout(long timeoutMillis) {
-        showArea();
-        mHandler.sendEmptyMessageDelayed(MSG_HIDE_AREA_VIEW, timeoutMillis);
-    }
-
     // Binds to FaceLock service.  This call does not tell it to start, but it causes the service
     // to call the onServiceConnected callback, which then starts FaceLock.
-    public void bind() {
+    private void bind() {
         if (installedAndSelected()) {
             if (!mBoundToService) {
                 if (DEBUG) Log.d(TAG, "before bind to FaceLock service");
@@ -223,32 +246,6 @@
         }
     }
 
-    // Tells FaceLock to stop and then unbinds from the FaceLock service
-    public void stopAndUnbind() {
-        if (installedAndSelected()) {
-            stop();
-
-            if (mBoundToService) {
-                if (DEBUG) Log.d(TAG, "before unbind from FaceLock service");
-                if (mService != null) {
-                    try {
-                        mService.unregisterCallback(mFaceLockCallback);
-                    } catch (RemoteException e) {
-                        // Not much we can do
-                    }
-                }
-                mContext.unbindService(mConnection);
-                if (DEBUG) Log.d(TAG, "after unbind from FaceLock service");
-                mBoundToService = false;
-            } else {
-                // This is usually not an error when this happens.  Sometimes we will tell it to
-                // unbind multiple times because it's called from both onWindowFocusChanged and
-                // onDetachedFromWindow.
-                if (DEBUG) Log.d(TAG, "Attempt to unbind from FaceLock when not bound");
-            }
-        }
-    }
-
     private ServiceConnection mConnection = new ServiceConnection() {
         // Completes connection, registers callback and starts FaceLock when service is bound
         @Override
@@ -268,7 +265,7 @@
                 int[] position;
                 position = new int[2];
                 mAreaView.getLocationInWindow(position);
-                start(mAreaView.getWindowToken(), position[0], position[1],
+                startUi(mAreaView.getWindowToken(), position[0], position[1],
                         mAreaView.getWidth(), mAreaView.getHeight());
             }
         }
@@ -286,7 +283,7 @@
     };
 
     // Tells the FaceLock service to start displaying its UI and perform recognition
-    public void start(IBinder windowToken, int x, int y, int w, int h) {
+    private void startUi(IBinder windowToken, int x, int y, int w, int h) {
         if (installedAndSelected()) {
             synchronized (mServiceRunningLock) {
                 if (!mServiceRunning) {
@@ -300,14 +297,14 @@
                     }
                     mServiceRunning = true;
                 } else {
-                    if (DEBUG) Log.w(TAG, "start() attempted while running");
+                    if (DEBUG) Log.w(TAG, "startUi() attempted while running");
                 }
             }
         }
     }
 
     // Tells the FaceLock service to stop displaying its UI and stop recognition
-    public void stop() {
+    private void stopUi() {
         if (installedAndSelected()) {
             // Note that attempting to stop FaceLock when it's not running is not an issue.
             // FaceLock can return, which stops it and then we try to stop it when the
@@ -333,7 +330,7 @@
         public void unlock() {
             if (DEBUG) Log.d(TAG, "FaceLock unlock()");
             showArea(); // Keep fallback covered
-            stopAndUnbind();
+            stop();
 
             mKeyguardScreenCallback.keyguardDone(true);
             mKeyguardScreenCallback.reportSuccessfulUnlockAttempt();
@@ -344,8 +341,8 @@
         @Override
         public void cancel() {
             if (DEBUG) Log.d(TAG, "FaceLock cancel()");
-            hideArea(); // Expose fallback
-            stopAndUnbind();
+            hide(); // Expose fallback
+            stop();
             mKeyguardScreenCallback.pokeWakelock(BACKUP_LOCK_TIMEOUT);
         }
 
@@ -355,8 +352,8 @@
         public void reportFailedAttempt() {
             if (DEBUG) Log.d(TAG, "FaceLock reportFailedAttempt()");
             mUpdateMonitor.reportFailedFaceUnlockAttempt();
-            hideArea(); // Expose fallback
-            stopAndUnbind();
+            hide(); // Expose fallback
+            stop();
             mKeyguardScreenCallback.pokeWakelock(BACKUP_LOCK_TIMEOUT);
         }
 
@@ -364,7 +361,7 @@
         @Override
         public void exposeFallback() {
             if (DEBUG) Log.d(TAG, "FaceLock exposeFallback()");
-            hideArea(); // Expose fallback
+            hide(); // Expose fallback
         }
 
         // Allows the Face Unlock service to poke the wake lock to keep the lockscreen alive
diff --git a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
index d42f96a..c382646 100644
--- a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
+++ b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
@@ -101,15 +101,17 @@
 
     private boolean mShowLockBeforeUnlock = false;
 
-    // The following were added to support FaceLock
-    private FaceUnlock mFaceUnlock;
-    private final Object mFaceLockStartupLock = new Object();
+    // Interface to a biometric sensor that can optionally be used to unlock the device
+    private BiometricSensorUnlock mBiometricUnlock;
+    private final Object mBiometricUnlockStartupLock = new Object();
+    // Long enough to stay visible while dialer comes up
+    // Short enough to not be visible if the user goes back immediately
+    private final int BIOMETRIC_AREA_EMERGENCY_DIALER_TIMEOUT = 1000;
 
     private boolean mRequiresSim;
-    //True if we have some sort of overlay on top of the Lockscreen
-    //Also true if we've activated a phone call, either emergency dialing or incoming
-    //This resets when the phone is turned off with no current call
-    private boolean mHasOverlay;
+    // True if the biometric unlock should not be displayed.  For example, if there is an overlay on
+    // lockscreen or the user is plugging in / unplugging the device.
+    private boolean mSupressBiometricUnlock;
     //True if a dialog is currently displaying on top of this window
     //Unlike other overlays, this does not close with a power button cycle
     private boolean mHasDialog = false;
@@ -308,15 +310,15 @@
         }
 
         public void takeEmergencyCallAction() {
-            mHasOverlay = true;
+            mSupressBiometricUnlock = true;
 
-            // Continue showing FaceLock area until dialer comes up or call is resumed
-            if (mFaceUnlock.installedAndSelected() && mFaceUnlock.isServiceRunning()) {
-                mFaceUnlock.showAreaWithTimeout(mFaceUnlock.viewAreaEmergencyDialerTimeout());
+            if (mBiometricUnlock.installedAndSelected() && mBiometricUnlock.isRunning()) {
+                // Continue covering backup lock until dialer comes up or call is resumed
+                mBiometricUnlock.show(BIOMETRIC_AREA_EMERGENCY_DIALER_TIMEOUT);
             }
 
-            // FaceLock must be stopped if it is running when emergency call is pressed
-            mFaceUnlock.stopAndUnbind();
+            // The biometric unlock must be stopped if it is running when emergency call is pressed
+            mBiometricUnlock.stop();
 
             pokeWakelock(EMERGENCY_CALL_TIMEOUT);
             if (TelephonyManager.getDefault().getCallState()
@@ -421,7 +423,7 @@
             LockPatternUtils lockPatternUtils, KeyguardWindowController controller) {
         super(context, callback);
 
-        mFaceUnlock = new FaceUnlock(context, updateMonitor, lockPatternUtils,
+        mBiometricUnlock = new FaceUnlock(context, updateMonitor, lockPatternUtils,
                 mKeyguardScreenCallback);
         mConfiguration = context.getResources().getConfiguration();
         mEnableFallback = false;
@@ -429,7 +431,7 @@
         mUpdateMonitor = updateMonitor;
         mLockPatternUtils = lockPatternUtils;
         mWindowController = controller;
-        mHasOverlay = false;
+        mSupressBiometricUnlock = false;
         mPluggedIn = mUpdateMonitor.isDevicePluggedIn();
         mScreenOn = ((PowerManager)context.getSystemService(Context.POWER_SERVICE)).isScreenOn();
 
@@ -528,8 +530,8 @@
         if (DEBUG) Log.d(TAG, "screen off");
         mScreenOn = false;
         mForgotPattern = false;
-        mHasOverlay = mUpdateMonitor.getPhoneState() != TelephonyManager.CALL_STATE_IDLE ||
-                mHasDialog;
+        mSupressBiometricUnlock =
+                mUpdateMonitor.getPhoneState() != TelephonyManager.CALL_STATE_IDLE || mHasDialog;
 
         // Emulate activity life-cycle for both lock and unlock screen.
         if (mLockScreen != null) {
@@ -541,25 +543,25 @@
 
         saveWidgetState();
 
-        // When screen is turned off, need to unbind from FaceLock service if using FaceLock
-        mFaceUnlock.stopAndUnbind();
+        // The biometric unlock must stop when screen turns off.
+        mBiometricUnlock.stop();
     }
 
     @Override
     public void onScreenTurnedOn() {
         if (DEBUG) Log.d(TAG, "screen on");
-        boolean runFaceLock = false;
-        //Make sure to start facelock iff the screen is both on and focused
-        synchronized(mFaceLockStartupLock) {
+        boolean startBiometricUnlock = false;
+        // Start the biometric unlock if and only if the screen is both on and focused
+        synchronized(mBiometricUnlockStartupLock) {
             mScreenOn = true;
-            runFaceLock = mWindowFocused;
+            startBiometricUnlock = mWindowFocused;
         }
 
         show();
 
         restoreWidgetState();
 
-        if (runFaceLock) mFaceUnlock.activateIfAble(mHasOverlay);
+        if (startBiometricUnlock) mBiometricUnlock.start(mSupressBiometricUnlock);
     }
 
     private void saveWidgetState() {
@@ -578,25 +580,26 @@
         }
     }
 
-    /** Unbind from facelock if something covers this window (such as an alarm)
-     * bind to facelock if the lockscreen window just came into focus, and the screen is on
+    /**
+     * Stop the biometric unlock if something covers this window (such as an alarm)
+     * Start the biometric unlock if the lockscreen window just came into focus and the screen is on
      */
     @Override
     public void onWindowFocusChanged (boolean hasWindowFocus) {
         if (DEBUG) Log.d(TAG, hasWindowFocus ? "focused" : "unfocused");
-        boolean runFaceLock = false;
-        //Make sure to start facelock iff the screen is both on and focused
-        synchronized(mFaceLockStartupLock) {
-            if(mScreenOn && !mWindowFocused) runFaceLock = hasWindowFocus;
+        boolean startBiometricUnlock = false;
+        // Start the biometric unlock if and only if the screen is both on and focused
+        synchronized(mBiometricUnlockStartupLock) {
+            if (mScreenOn && !mWindowFocused) startBiometricUnlock = hasWindowFocus;
             mWindowFocused = hasWindowFocus;
         }
         if (!hasWindowFocus) {
-            mHasOverlay = true;
-            mFaceUnlock.stopAndUnbind();
-            mFaceUnlock.hideArea();
+            mSupressBiometricUnlock = true;
+            mBiometricUnlock.stop();
+            mBiometricUnlock.hide();
         } else {
             mHasDialog = false;
-            if (runFaceLock) mFaceUnlock.activateIfAble(mHasOverlay);
+            if (startBiometricUnlock) mBiometricUnlock.start(mSupressBiometricUnlock);
         }
     }
 
@@ -610,14 +613,14 @@
             ((KeyguardScreen) mUnlockScreen).onResume();
         }
 
-        if (mFaceUnlock.installedAndSelected() && !mHasOverlay) {
+        if (mBiometricUnlock.installedAndSelected() && !mSupressBiometricUnlock) {
             // Note that show() gets called before the screen turns off to set it up for next time
-            // it is turned on.  We don't want to set a timeout on the FaceLock area here because it
-            // may be gone by the time the screen is turned on again.  We set the timeout when the
-            // screen turns on instead.
-            mFaceUnlock.showArea();
+            // it is turned on.  We don't want to set a timeout on the biometric unlock here because
+            // it may be gone by the time the screen is turned on again.  We set the timeout when
+            // the screen turns on instead.
+            mBiometricUnlock.show(0);
         } else {
-            mFaceUnlock.hideArea();
+            mBiometricUnlock.hide();
         }
     }
 
@@ -651,9 +654,9 @@
 
         removeCallbacks(mRecreateRunnable);
 
-        // When view is hidden, need to unbind from FaceLock service if we are using FaceLock
+        // When view is hidden, we need to stop the biometric unlock
         // e.g., when device becomes unlocked
-        mFaceUnlock.stopAndUnbind();
+        mBiometricUnlock.stop();
 
         super.onDetachedFromWindow();
     }
@@ -670,16 +673,19 @@
 
     InfoCallbackImpl mInfoCallback = new InfoCallbackImpl() {
 
-        /** When somebody plugs in or unplugs the device, we don't want to display faceunlock */
+        /**
+         * When somebody plugs in or unplugs the device, we don't want to display the biometric
+         * unlock.
+         */
         @Override
         public void onRefreshBatteryInfo(boolean showBatteryInfo, boolean pluggedIn,
                 int batteryLevel) {
-            mHasOverlay |= mPluggedIn != pluggedIn;
+            mSupressBiometricUnlock |= mPluggedIn != pluggedIn;
             mPluggedIn = pluggedIn;
-            //If it's already running, don't close it down: the unplug didn't start it
-            if (!mFaceUnlock.isServiceRunning()) {
-                mFaceUnlock.stopAndUnbind();
-                mFaceUnlock.hideArea();
+            // If it's already running, don't close it down: the unplug didn't start it
+            if (!mBiometricUnlock.isRunning()) {
+                mBiometricUnlock.stop();
+                mBiometricUnlock.hide();
             }
         }
 
@@ -690,20 +696,20 @@
                     | (mUpdateMonitor.isClockVisible() ? View.STATUS_BAR_DISABLE_CLOCK : 0));
         }
 
-        //We need to stop faceunlock when a phonecall comes in
+        // We need to stop the biometric unlock when a phone call comes in
         @Override
         public void onPhoneStateChanged(int phoneState) {
             if (DEBUG) Log.d(TAG, "phone state: " + phoneState);
             if(phoneState == TelephonyManager.CALL_STATE_RINGING) {
-                mHasOverlay = true;
-                mFaceUnlock.stopAndUnbind();
-                mFaceUnlock.hideArea();
+                mSupressBiometricUnlock = true;
+                mBiometricUnlock.stop();
+                mBiometricUnlock.hide();
             }
         }
 
         @Override
         public void onUserChanged(int userId) {
-            mFaceUnlock.stopAndUnbind();
+            mBiometricUnlock.stop();
             mLockPatternUtils.setCurrentUser(userId);
             updateScreen(getInitialMode(), true);
         }
@@ -766,7 +772,7 @@
             mUnlockScreen = null;
         }
         mUpdateMonitor.removeCallback(this);
-        mFaceUnlock.cleanUp();
+        mBiometricUnlock.cleanUp();
     }
 
     private boolean isSecure() {
@@ -816,10 +822,10 @@
         final UnlockMode unlockMode = getUnlockMode();
         if (mode == Mode.UnlockScreen && unlockMode != UnlockMode.Unknown) {
             if (force || mUnlockScreen == null || unlockMode != mUnlockScreenMode) {
-                boolean restartFaceLock = mFaceUnlock.stopIfRunning();
+                boolean restartBiometricUnlock = mBiometricUnlock.stop();
                 recreateUnlockScreen(unlockMode);
-                if (restartFaceLock || force) {
-                    mFaceUnlock.activateIfAble(mHasOverlay);
+                if (restartBiometricUnlock) {
+                    mBiometricUnlock.start(mSupressBiometricUnlock);
                 }
             }
         }
@@ -933,7 +939,8 @@
             throw new IllegalArgumentException("unknown unlock mode " + unlockMode);
         }
         initializeTransportControlView(unlockView);
-        mFaceUnlock.initializeAreaView(unlockView); // Only shows view if FaceLock is enabled
+        // Only shows view if the biometric unlock is enabled
+        mBiometricUnlock.initializeAreaView(unlockView);
 
         mUnlockScreenMode = unlockMode;
         return unlockView;
diff --git a/services/java/com/android/server/DeviceStorageMonitorService.java b/services/java/com/android/server/DeviceStorageMonitorService.java
index 16eeb7ba..b943c09 100644
--- a/services/java/com/android/server/DeviceStorageMonitorService.java
+++ b/services/java/com/android/server/DeviceStorageMonitorService.java
@@ -25,6 +25,7 @@
 import android.content.pm.IPackageDataObserver;
 import android.content.pm.IPackageManager;
 import android.os.Binder;
+import android.os.Environment;
 import android.os.Handler;
 import android.os.Message;
 import android.os.Process;
@@ -336,7 +337,9 @@
         //log the event to event log with the amount of free storage(in bytes) left on the device
         EventLog.writeEvent(EventLogTags.LOW_STORAGE, mFreeMem);
         //  Pack up the values and broadcast them to everyone
-        Intent lowMemIntent = new Intent(Intent.ACTION_MANAGE_PACKAGE_STORAGE);
+        Intent lowMemIntent = new Intent(Environment.isExternalStorageEmulated()
+                ? Settings.ACTION_INTERNAL_STORAGE_SETTINGS
+                : Intent.ACTION_MANAGE_PACKAGE_STORAGE);
         lowMemIntent.putExtra("memory", mFreeMem);
         lowMemIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
         NotificationManager mNotificationMgr =
diff --git a/services/java/com/android/server/pm/Settings.java b/services/java/com/android/server/pm/Settings.java
index bb7f4fc..bb73b29 100644
--- a/services/java/com/android/server/pm/Settings.java
+++ b/services/java/com/android/server/pm/Settings.java
@@ -21,6 +21,7 @@
 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER;
 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
 import static android.content.pm.PackageManager.ENFORCEMENT_DEFAULT;
+import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
 
 import com.android.internal.util.FastXmlSerializer;
 import com.android.internal.util.JournaledFile;
@@ -2558,9 +2559,13 @@
             if (p.perm != null) {
                 pw.print("    perm="); pw.println(p.perm);
             }
+            if (READ_EXTERNAL_STORAGE.equals(p.name)) {
+                pw.print("    enforcement=");
+                pw.println(PackageManager.enforcementToString(mReadExternalStorageEnforcement));
+            }
         }
     }
-    
+
     void dumpSharedUsersLPr(PrintWriter pw, String packageName, DumpState dumpState) {
         boolean printedSomething = false;
         for (SharedUserSetting su : mSharedUsers.values()) {
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index d9425aab..f48b56d1 100644
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -3974,7 +3974,6 @@
 
         wtoken.willBeHidden = false;
         if (wtoken.hidden == visible) {
-            final int N = wtoken.allAppWindows.size();
             boolean changed = false;
             if (DEBUG_APP_TRANSITIONS) Slog.v(
                 TAG, "Changing app " + wtoken + " hidden=" + wtoken.hidden
@@ -3986,23 +3985,19 @@
                 if (wtoken.mAppAnimator.animation == sDummyAnimation) {
                     wtoken.mAppAnimator.animation = null;
                 }
-                applyAnimationLocked(wtoken, lp, transit, visible);
-                changed = true;
-                if (wtoken.mAppAnimator.animation != null) {
+                if (applyAnimationLocked(wtoken, lp, transit, visible)) {
                     delayed = runningAppAnimation = true;
                 }
+                changed = true;
             }
 
+            final int N = wtoken.allAppWindows.size();
             for (int i=0; i<N; i++) {
                 WindowState win = wtoken.allAppWindows.get(i);
                 if (win == wtoken.startingWindow) {
                     continue;
                 }
 
-                if (win.mWinAnimator.isAnimating()) {
-                    delayed = true;
-                }
-
                 //Slog.i(TAG, "Window " + win + ": vis=" + win.isVisible());
                 //win.dump("  ");
                 if (visible) {
@@ -4055,6 +4050,12 @@
             delayed = true;
         }
 
+        for (int i = wtoken.allAppWindows.size() - 1; i >= 0 && !delayed; i--) {
+            if (wtoken.allAppWindows.get(i).mWinAnimator.isWindowAnimating()) {
+                delayed = true;
+            }
+        }
+
         return delayed;
     }
 
@@ -4917,7 +4918,11 @@
                 // have been drawn.
                 boolean haveBootMsg = false;
                 boolean haveApp = false;
+                // if the wallpaper service is disabled on the device, we're never going to have
+                // wallpaper, don't bother waiting for it
                 boolean haveWallpaper = false;
+                boolean wallpaperEnabled = mContext.getResources().getBoolean(
+                        com.android.internal.R.bool.config_enableWallpaperService);
                 boolean haveKeyguard = true;
                 final int N = mWindows.size();
                 for (int i=0; i<N; i++) {
@@ -4953,7 +4958,8 @@
                 if (DEBUG_SCREEN_ON || DEBUG_BOOT) {
                     Slog.i(TAG, "******** booted=" + mSystemBooted + " msg=" + mShowingBootMessages
                             + " haveBoot=" + haveBootMsg + " haveApp=" + haveApp
-                            + " haveWall=" + haveWallpaper + " haveKeyguard=" + haveKeyguard);
+                            + " haveWall=" + haveWallpaper + " wallEnabled=" + wallpaperEnabled
+                            + " haveKeyguard=" + haveKeyguard);
                 }
 
                 // If we are turning on the screen to show the boot message,
@@ -4965,7 +4971,8 @@
                 // If we are turning on the screen after the boot is completed
                 // normally, don't do so until we have the application and
                 // wallpaper.
-                if (mSystemBooted && ((!haveApp && !haveKeyguard) || !haveWallpaper)) {
+                if (mSystemBooted && ((!haveApp && !haveKeyguard) ||
+                        (wallpaperEnabled && !haveWallpaper))) {
                     return;
                 }
             }
@@ -7262,6 +7269,7 @@
                     pw.flush();
                     Slog.w(TAG, "This window was lost: " + ws);
                     Slog.w(TAG, sw.toString());
+                    ws.mWinAnimator.destroySurfaceLocked();
                 }
             }
             Slog.w(TAG, "Current app token list:");
@@ -9333,7 +9341,7 @@
                     pw.print(" mWaitingForConfig="); pw.println(mWaitingForConfig);
             pw.print("  mRotation="); pw.print(mRotation);
                     pw.print(" mAltOrientation="); pw.println(mAltOrientation);
-            pw.print("  mLastWindowForcedOrientation"); pw.print(mLastWindowForcedOrientation);
+            pw.print("  mLastWindowForcedOrientation="); pw.print(mLastWindowForcedOrientation);
                     pw.print(" mForcedAppOrientation="); pw.println(mForcedAppOrientation);
             pw.print("  mDeferredRotationPauseCount="); pw.println(mDeferredRotationPauseCount);
             if (mAnimator.mScreenRotationAnimation != null) {
@@ -9535,4 +9543,9 @@
     void bulkSetParameters(final int bulkUpdateParams) {
         mH.sendMessage(mH.obtainMessage(H.BULK_UPDATE_PARAMETERS, bulkUpdateParams, 0));
     }
+
+    static String getCaller() {
+        StackTraceElement caller = Thread.currentThread().getStackTrace()[4];
+        return caller.getClassName() + "." + caller.getMethodName() + ":" + caller.getLineNumber();
+    }
 }
diff --git a/test-runner/src/android/test/AssertionFailedError.java b/test-runner/src/android/test/AssertionFailedError.java
index 7af5806..b3ac6d1 100644
--- a/test-runner/src/android/test/AssertionFailedError.java
+++ b/test-runner/src/android/test/AssertionFailedError.java
@@ -19,8 +19,7 @@
 /**
  * Thrown when an assertion failed.
  * 
- * Note:  Most users of this class should simply use junit.framework.AssertionFailedError,
- * which provides the same functionality.
+ * @deprecated use junit.framework.AssertionFailedError
  */
 public class AssertionFailedError extends Error {
     
diff --git a/test-runner/src/android/test/ComparisonFailure.java b/test-runner/src/android/test/ComparisonFailure.java
index e7e9698..3fa76f5 100644
--- a/test-runner/src/android/test/ComparisonFailure.java
+++ b/test-runner/src/android/test/ComparisonFailure.java
@@ -19,8 +19,7 @@
 /**
  * Thrown when an assert equals for Strings failed.
  * 
- * Note:  Most users of this class should simply use junit.framework.ComparisonFailure,
- * which provides the same functionality at a lighter weight.
+ * @deprecated use junit.framework.ComparisonFailure
  */
 public class ComparisonFailure extends AssertionFailedError {
     private junit.framework.ComparisonFailure mComparison;
diff --git a/test-runner/src/junit/runner/BaseTestRunner.java b/test-runner/src/junit/runner/BaseTestRunner.java
index e073ef7..8cfd7fa 100644
--- a/test-runner/src/junit/runner/BaseTestRunner.java
+++ b/test-runner/src/junit/runner/BaseTestRunner.java
@@ -1,10 +1,24 @@
 package junit.runner;
 
-import junit.framework.*;
-import java.lang.reflect.*;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintWriter;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
 import java.text.NumberFormat;
-import java.io.*;
-import java.util.*;
+import java.util.Properties;
+
+import junit.framework.AssertionFailedError;
+import junit.framework.Test;
+import junit.framework.TestListener;
+import junit.framework.TestSuite;
 
 /**
  * Base class for all test runners.
@@ -19,8 +33,8 @@
     boolean fLoading= true;
 
     /*
-    * Implementation of TestListener
-    */
+     * Implementation of TestListener
+     */
     public synchronized void startTest(Test test) {
         testStarted(test.toString());
     }
@@ -32,9 +46,9 @@
     protected static Properties getPreferences() {
         if (fPreferences == null) {
             fPreferences= new Properties();
-             fPreferences.put("loading", "true");
-             fPreferences.put("filterstack", "true");
-              readPreferences();
+            fPreferences.put("loading", "true");
+            fPreferences.put("filterstack", "true");
+            readPreferences();
         }
         return fPreferences;
     }
@@ -48,8 +62,9 @@
         }
     }
 
+    // android-changed remove 'static' qualifier for API compatibility
     public void setPreference(String key, String value) {
-        getPreferences().setProperty(key, value);
+        getPreferences().put(key, value);
     }
 
     public synchronized void endTest(Test test) {
@@ -97,8 +112,8 @@
         Method suiteMethod= null;
         try {
             suiteMethod= testClass.getMethod(SUITE_METHODNAME, new Class[0]);
-         } catch(Exception e) {
-             // try to extract a test suite automatically
+        } catch(Exception e) {
+            // try to extract a test suite automatically
             clearStatus();
             return new TestSuite(testClass);
         }
@@ -108,7 +123,7 @@
         }
         Test test= null;
         try {
-            test= (Test)suiteMethod.invoke(null); // static method
+            test= (Test)suiteMethod.invoke(null, (Object[])new Class[0]); // static method
             if (test == null)
                 return test;
         }
@@ -163,7 +178,7 @@
         fLoading= enable;
     }
     /**
-     * Extract the class name from a String
+     * Extract the class name from a String in VA/Java style
      */
     public String extractClassName(String className) {
         if(className.startsWith("Default package for"))
@@ -186,11 +201,24 @@
      */
     protected abstract void runFailed(String message);
 
+    // BEGIN android-changed - add back getLoader() for API compatibility
+    /**
+     * Returns the loader to be used.
+     * 
+     * @deprecated not present in JUnit4.10
+     */
+    public TestSuiteLoader getLoader() {
+        if (useReloadingTestSuiteLoader())
+            return new ReloadingTestSuiteLoader();
+        return new StandardTestSuiteLoader();
+    }
+    // END android-changed
+
     /**
      * Returns the loaded Class for a suite name.
      */
-    protected Class loadSuiteClass(String suiteClassName) throws ClassNotFoundException {
-        return getLoader().load(suiteClassName);
+    protected Class<?> loadSuiteClass(String suiteClassName) throws ClassNotFoundException {
+        return Class.forName(suiteClassName);
     }
 
     /**
@@ -199,29 +227,20 @@
     protected void clearStatus() { // Belongs in the GUI TestRunner class
     }
 
-    /**
-     * Returns the loader to be used.
-     */
-    public TestSuiteLoader getLoader() {
-        if (useReloadingTestSuiteLoader())
-            return new ReloadingTestSuiteLoader();
-        return new StandardTestSuiteLoader();
-    }
-
     protected boolean useReloadingTestSuiteLoader() {
-        return getPreference("loading").equals("true") && !inVAJava() && fLoading;
+        return getPreference("loading").equals("true") && fLoading;
     }
 
     private static File getPreferencesFile() {
-         String home= System.getProperty("user.home");
-         return new File(home, "junit.properties");
-     }
+        String home= System.getProperty("user.home");
+        return new File(home, "junit.properties");
+    }
 
-     private static void readPreferences() {
-         InputStream is= null;
-         try {
-             is= new FileInputStream(getPreferencesFile());
-             setPreferences(new Properties(getPreferences()));
+    private static void readPreferences() {
+        InputStream is= null;
+        try {
+            is= new FileInputStream(getPreferencesFile());
+            setPreferences(new Properties(getPreferences()));
             getPreferences().load(is);
         } catch (IOException e) {
             try {
@@ -230,32 +249,22 @@
             } catch (IOException e1) {
             }
         }
-     }
+    }
 
-     public static String getPreference(String key) {
-         return getPreferences().getProperty(key);
-     }
+    public static String getPreference(String key) {
+        return getPreferences().getProperty(key);
+    }
 
-     public static int getPreference(String key, int dflt) {
-         String value= getPreference(key);
-         int intValue= dflt;
-         if (value == null)
-             return intValue;
-         try {
-             intValue= Integer.parseInt(value);
-          } catch (NumberFormatException ne) {
-         }
-         return intValue;
-     }
-
-     public static boolean inVAJava() {
+    public static int getPreference(String key, int dflt) {
+        String value= getPreference(key);
+        int intValue= dflt;
+        if (value == null)
+            return intValue;
         try {
-            Class.forName("com.ibm.uvm.tools.DebugSupport");
+            intValue= Integer.parseInt(value);
+        } catch (NumberFormatException ne) {
         }
-        catch (Exception e) {
-            return false;
-        }
-        return true;
+        return intValue;
     }
 
     /**
@@ -270,6 +279,13 @@
         return BaseTestRunner.getFilteredTrace(trace);
     }
 
+    // BEGIN android-changed - add back this method for API compatibility
+    /** @deprecated not present in JUnit4.10 */
+    public static boolean inVAJava() {
+        return false;
+    }
+    // END android-changed
+
     /**
      * Filters stack frames from internal JUnit classes
      */
@@ -303,14 +319,14 @@
 
     static boolean filterLine(String line) {
         String[] patterns= new String[] {
-            "junit.framework.TestCase",
-            "junit.framework.TestResult",
-            "junit.framework.TestSuite",
-            "junit.framework.Assert.", // don't filter AssertionFailure
-            "junit.swingui.TestRunner",
-            "junit.awtui.TestRunner",
-            "junit.textui.TestRunner",
-            "java.lang.reflect.Method.invoke("
+                "junit.framework.TestCase",
+                "junit.framework.TestResult",
+                "junit.framework.TestSuite",
+                "junit.framework.Assert.", // don't filter AssertionFailure
+                "junit.swingui.TestRunner",
+                "junit.awtui.TestRunner",
+                "junit.textui.TestRunner",
+                "java.lang.reflect.Method.invoke("
         };
         for (int i= 0; i < patterns.length; i++) {
             if (line.indexOf(patterns[i]) > 0)
@@ -319,8 +335,8 @@
         return false;
     }
 
-     static {
-         fgMaxMessageLength= getPreference("maxmessage", fgMaxMessageLength);
-     }
+    static {
+        fgMaxMessageLength= getPreference("maxmessage", fgMaxMessageLength);
+    }
 
 }
diff --git a/test-runner/src/junit/runner/ClassPathTestCollector.java b/test-runner/src/junit/runner/ClassPathTestCollector.java
index 8a3c702..f48ddee 100644
--- a/test-runner/src/junit/runner/ClassPathTestCollector.java
+++ b/test-runner/src/junit/runner/ClassPathTestCollector.java
@@ -13,69 +13,69 @@
  * {@hide} - Not needed for 1.0 SDK
  */
 public abstract class ClassPathTestCollector implements TestCollector {
-	
-	static final int SUFFIX_LENGTH= ".class".length();
-	
-	public ClassPathTestCollector() {
-	}
-	
-	public Enumeration collectTests() {
-		String classPath= System.getProperty("java.class.path");
-		Hashtable result = collectFilesInPath(classPath);
-		return result.elements();
-	}
 
-	public Hashtable collectFilesInPath(String classPath) {
-		Hashtable result= collectFilesInRoots(splitClassPath(classPath));
-		return result;
-	}
-	
-	Hashtable collectFilesInRoots(Vector roots) {
-		Hashtable result= new Hashtable(100);
-		Enumeration e= roots.elements();
-		while (e.hasMoreElements()) 
-			gatherFiles(new File((String)e.nextElement()), "", result);
-		return result;
-	}
+    static final int SUFFIX_LENGTH= ".class".length();
 
-	void gatherFiles(File classRoot, String classFileName, Hashtable result) {
-		File thisRoot= new File(classRoot, classFileName);
-		if (thisRoot.isFile()) {
-			if (isTestClass(classFileName)) {
-				String className= classNameFromFile(classFileName);
-				result.put(className, className);
-			}
-			return;
-		}		
-		String[] contents= thisRoot.list();
-		if (contents != null) { 
-			for (int i= 0; i < contents.length; i++) 
-				gatherFiles(classRoot, classFileName+File.separatorChar+contents[i], result);		
-		}
-	}
-	
-	Vector splitClassPath(String classPath) {
-		Vector result= new Vector();
-		String separator= System.getProperty("path.separator");
-		StringTokenizer tokenizer= new StringTokenizer(classPath, separator);
-		while (tokenizer.hasMoreTokens()) 
-			result.addElement(tokenizer.nextToken());
-		return result;
-	}
-	
-	protected boolean isTestClass(String classFileName) {
-		return 
-			classFileName.endsWith(".class") && 
-			classFileName.indexOf('$') < 0 &&
-			classFileName.indexOf("Test") > 0;
-	}
-	
-	protected String classNameFromFile(String classFileName) {
-		// convert /a/b.class to a.b
-		String s= classFileName.substring(0, classFileName.length()-SUFFIX_LENGTH);
-		String s2= s.replace(File.separatorChar, '.');
-		if (s2.startsWith("."))
-			return s2.substring(1);
-		return s2;
-	}	
+    public ClassPathTestCollector() {
+    }
+
+    public Enumeration collectTests() {
+        String classPath= System.getProperty("java.class.path");
+        Hashtable result = collectFilesInPath(classPath);
+        return result.elements();
+    }
+
+    public Hashtable collectFilesInPath(String classPath) {
+        Hashtable result= collectFilesInRoots(splitClassPath(classPath));
+        return result;
+    }
+
+    Hashtable collectFilesInRoots(Vector roots) {
+        Hashtable result= new Hashtable(100);
+        Enumeration e= roots.elements();
+        while (e.hasMoreElements())
+            gatherFiles(new File((String)e.nextElement()), "", result);
+        return result;
+    }
+
+    void gatherFiles(File classRoot, String classFileName, Hashtable result) {
+        File thisRoot= new File(classRoot, classFileName);
+        if (thisRoot.isFile()) {
+            if (isTestClass(classFileName)) {
+                String className= classNameFromFile(classFileName);
+                result.put(className, className);
+            }
+            return;
+        }
+        String[] contents= thisRoot.list();
+        if (contents != null) {
+            for (int i= 0; i < contents.length; i++)
+                gatherFiles(classRoot, classFileName+File.separatorChar+contents[i], result);
+        }
+    }
+
+    Vector splitClassPath(String classPath) {
+        Vector result= new Vector();
+        String separator= System.getProperty("path.separator");
+        StringTokenizer tokenizer= new StringTokenizer(classPath, separator);
+        while (tokenizer.hasMoreTokens())
+            result.addElement(tokenizer.nextToken());
+        return result;
+    }
+
+    protected boolean isTestClass(String classFileName) {
+        return
+                classFileName.endsWith(".class") &&
+                classFileName.indexOf('$') < 0 &&
+                classFileName.indexOf("Test") > 0;
+    }
+
+    protected String classNameFromFile(String classFileName) {
+        // convert /a/b.class to a.b
+        String s= classFileName.substring(0, classFileName.length()-SUFFIX_LENGTH);
+        String s2= s.replace(File.separatorChar, '.');
+        if (s2.startsWith("."))
+            return s2.substring(1);
+        return s2;
+    }
 }
diff --git a/test-runner/src/junit/runner/FailureDetailView.java b/test-runner/src/junit/runner/FailureDetailView.java
index 7108cec..1b8365a 100644
--- a/test-runner/src/junit/runner/FailureDetailView.java
+++ b/test-runner/src/junit/runner/FailureDetailView.java
@@ -1,7 +1,7 @@
 package junit.runner;
 
 // The following line was removed for compatibility with Android libraries.
-//import java.awt.Component; 
+//import java.awt.Component;
 
 import junit.framework.*;
 
@@ -17,12 +17,12 @@
     //   */
     //  public Component getComponent();
 
-	/**
-	 * Shows details of a TestFailure
-	 */
-	public void showFailure(TestFailure failure);
-	/**
-	 * Clears the view
-	 */
-	public void clear();
+    /**
+     * Shows details of a TestFailure
+     */
+    public void showFailure(TestFailure failure);
+    /**
+     * Clears the view
+     */
+    public void clear();
 }
diff --git a/test-runner/src/junit/runner/LoadingTestCollector.java b/test-runner/src/junit/runner/LoadingTestCollector.java
index b1760b1..489d9d6 100644
--- a/test-runner/src/junit/runner/LoadingTestCollector.java
+++ b/test-runner/src/junit/runner/LoadingTestCollector.java
@@ -12,59 +12,59 @@
  * {@hide} - Not needed for 1.0 SDK
  */
 public class LoadingTestCollector extends ClassPathTestCollector {
-	
-	TestCaseClassLoader fLoader;
-	
-	public LoadingTestCollector() {
-		fLoader= new TestCaseClassLoader();
-	}
-	
-	protected boolean isTestClass(String classFileName) {	
-		try {
-			if (classFileName.endsWith(".class")) {
-				Class testClass= classFromFile(classFileName);
-				return (testClass != null) && isTestClass(testClass);
-			}
-		} 
-		catch (ClassNotFoundException expected) {
-		}
-		catch (NoClassDefFoundError notFatal) {
-		} 
-		return false;
-	}
-	
-	Class classFromFile(String classFileName) throws ClassNotFoundException {
-		String className= classNameFromFile(classFileName);
-		if (!fLoader.isExcluded(className))
-			return fLoader.loadClass(className, false);
-		return null;
-	}
-	
-	boolean isTestClass(Class testClass) {
-		if (hasSuiteMethod(testClass))
-			return true;
-		if (Test.class.isAssignableFrom(testClass) &&
-			Modifier.isPublic(testClass.getModifiers()) &&
-			hasPublicConstructor(testClass)) 
-			return true;
-		return false;
-	}
-	
-	boolean hasSuiteMethod(Class testClass) {
-		try {
-			testClass.getMethod(BaseTestRunner.SUITE_METHODNAME, new Class[0]);
-	 	} catch(Exception e) {
-	 		return false;
-		}
-		return true;
-	}
-	
-	boolean hasPublicConstructor(Class testClass) {
-		try {
-			TestSuite.getTestConstructor(testClass);
-		} catch(NoSuchMethodException e) {
-			return false;
-		}
-		return true;
-	}
+
+    TestCaseClassLoader fLoader;
+
+    public LoadingTestCollector() {
+        fLoader= new TestCaseClassLoader();
+    }
+
+    protected boolean isTestClass(String classFileName) {
+        try {
+            if (classFileName.endsWith(".class")) {
+                Class testClass= classFromFile(classFileName);
+                return (testClass != null) && isTestClass(testClass);
+            }
+        }
+        catch (ClassNotFoundException expected) {
+        }
+        catch (NoClassDefFoundError notFatal) {
+        }
+        return false;
+    }
+
+    Class classFromFile(String classFileName) throws ClassNotFoundException {
+        String className= classNameFromFile(classFileName);
+        if (!fLoader.isExcluded(className))
+            return fLoader.loadClass(className, false);
+        return null;
+    }
+
+    boolean isTestClass(Class testClass) {
+        if (hasSuiteMethod(testClass))
+            return true;
+        if (Test.class.isAssignableFrom(testClass) &&
+                Modifier.isPublic(testClass.getModifiers()) &&
+                hasPublicConstructor(testClass))
+            return true;
+        return false;
+    }
+
+    boolean hasSuiteMethod(Class testClass) {
+        try {
+            testClass.getMethod(BaseTestRunner.SUITE_METHODNAME, new Class[0]);
+        } catch(Exception e) {
+            return false;
+        }
+        return true;
+    }
+
+    boolean hasPublicConstructor(Class testClass) {
+        try {
+            TestSuite.getTestConstructor(testClass);
+        } catch(NoSuchMethodException e) {
+            return false;
+        }
+        return true;
+    }
 }
diff --git a/test-runner/src/junit/runner/ReloadingTestSuiteLoader.java b/test-runner/src/junit/runner/ReloadingTestSuiteLoader.java
index a6d84fe..c4d80d0 100644
--- a/test-runner/src/junit/runner/ReloadingTestSuiteLoader.java
+++ b/test-runner/src/junit/runner/ReloadingTestSuiteLoader.java
@@ -5,16 +5,16 @@
  * {@hide} - Not needed for 1.0 SDK
  */
 public class ReloadingTestSuiteLoader implements TestSuiteLoader {
-	
-	public Class load(String suiteClassName) throws ClassNotFoundException {
-		return createLoader().loadClass(suiteClassName, true);
-	}
-	
-	public Class reload(Class aClass) throws ClassNotFoundException {
-		return createLoader().loadClass(aClass.getName(), true);
-	}
-	
-	protected TestCaseClassLoader createLoader() {
-		return new TestCaseClassLoader();
-	}
+
+    public Class load(String suiteClassName) throws ClassNotFoundException {
+        return createLoader().loadClass(suiteClassName, true);
+    }
+
+    public Class reload(Class aClass) throws ClassNotFoundException {
+        return createLoader().loadClass(aClass.getName(), true);
+    }
+
+    protected TestCaseClassLoader createLoader() {
+        return new TestCaseClassLoader();
+    }
 }
diff --git a/test-runner/src/junit/runner/SimpleTestCollector.java b/test-runner/src/junit/runner/SimpleTestCollector.java
index 543168f..6cb0e19 100644
--- a/test-runner/src/junit/runner/SimpleTestCollector.java
+++ b/test-runner/src/junit/runner/SimpleTestCollector.java
@@ -8,14 +8,14 @@
  * {@hide} - Not needed for 1.0 SDK
  */
 public class SimpleTestCollector extends ClassPathTestCollector {
-	
-	public SimpleTestCollector() {
-	}
-	
-	protected boolean isTestClass(String classFileName) {
-		return 
-			classFileName.endsWith(".class") && 
-			classFileName.indexOf('$') < 0 &&
-			classFileName.indexOf("Test") > 0;
-	}
+
+    public SimpleTestCollector() {
+    }
+
+    protected boolean isTestClass(String classFileName) {
+        return
+                classFileName.endsWith(".class") &&
+                classFileName.indexOf('$') < 0 &&
+                classFileName.indexOf("Test") > 0;
+    }
 }
diff --git a/test-runner/src/junit/runner/Sorter.java b/test-runner/src/junit/runner/Sorter.java
index 66f551e..7731f66 100644
--- a/test-runner/src/junit/runner/Sorter.java
+++ b/test-runner/src/junit/runner/Sorter.java
@@ -11,29 +11,29 @@
  * {@hide} - Not needed for 1.0 SDK
  */
 public class Sorter {
-	public static interface Swapper {
-		public void swap(Vector values, int left, int right);
-	}
-		
-	public static void sortStrings(Vector values , int left, int right, Swapper swapper) { 
-		int oleft= left;
-		int oright= right;
-		String mid= (String)values.elementAt((left + right) / 2); 
-		do { 
-			while (((String)(values.elementAt(left))).compareTo(mid) < 0)  
-				left++; 
-			while (mid.compareTo((String)(values.elementAt(right))) < 0)  
-				right--; 
-			if (left <= right) {
-				swapper.swap(values, left, right); 
-				left++; 
-				right--; 
-			} 
-		} while (left <= right);
-		
-		if (oleft < right) 
-			sortStrings(values, oleft, right, swapper); 
-		if (left < oright) 
-			 sortStrings(values, left, oright, swapper); 
-	}
+    public static interface Swapper {
+        public void swap(Vector values, int left, int right);
+    }
+
+    public static void sortStrings(Vector values , int left, int right, Swapper swapper) {
+        int oleft= left;
+        int oright= right;
+        String mid= (String)values.elementAt((left + right) / 2);
+        do {
+            while (((String)(values.elementAt(left))).compareTo(mid) < 0)
+                left++;
+            while (mid.compareTo((String)(values.elementAt(right))) < 0)
+                right--;
+            if (left <= right) {
+                swapper.swap(values, left, right);
+                left++;
+                right--;
+            }
+        } while (left <= right);
+
+        if (oleft < right)
+            sortStrings(values, oleft, right, swapper);
+        if (left < oright)
+            sortStrings(values, left, oright, swapper);
+    }
 }
diff --git a/test-runner/src/junit/runner/StandardTestSuiteLoader.java b/test-runner/src/junit/runner/StandardTestSuiteLoader.java
index bce7dec..381e684 100644
--- a/test-runner/src/junit/runner/StandardTestSuiteLoader.java
+++ b/test-runner/src/junit/runner/StandardTestSuiteLoader.java
@@ -5,16 +5,16 @@
  * {@hide} - Not needed for 1.0 SDK
  */
 public class StandardTestSuiteLoader implements TestSuiteLoader {
-	/**
-	 * Uses the system class loader to load the test class
-	 */
-	public Class load(String suiteClassName) throws ClassNotFoundException {
-		return Class.forName(suiteClassName);
-	}
-	/**
-	 * Uses the system class loader to load the test class
-	 */
-	public Class reload(Class aClass) throws ClassNotFoundException {
-		return aClass;
-	}
+    /**
+     * Uses the system class loader to load the test class
+     */
+    public Class load(String suiteClassName) throws ClassNotFoundException {
+        return Class.forName(suiteClassName);
+    }
+    /**
+     * Uses the system class loader to load the test class
+     */
+    public Class reload(Class aClass) throws ClassNotFoundException {
+        return aClass;
+    }
 }
diff --git a/test-runner/src/junit/runner/TestCaseClassLoader.java b/test-runner/src/junit/runner/TestCaseClassLoader.java
index 3a510c6..09eec7f 100644
--- a/test-runner/src/junit/runner/TestCaseClassLoader.java
+++ b/test-runner/src/junit/runner/TestCaseClassLoader.java
@@ -14,7 +14,7 @@
  * loader. They will be shared across test runs.
  * <p>
  * The list of excluded package paths is specified in
- * a properties file "excluded.properties" that is located in 
+ * a properties file "excluded.properties" that is located in
  * the same place as the TestCaseClassLoader class.
  * <p>
  * <b>Known limitation:</b> the TestCaseClassLoader cannot load classes
@@ -22,204 +22,204 @@
  * {@hide} - Not needed for 1.0 SDK
  */
 public class TestCaseClassLoader extends ClassLoader {
-	/** scanned class path */
-	private Vector fPathItems;
-	/** default excluded paths */
-	private String[] defaultExclusions= {
-		"junit.framework.", 
-		"junit.extensions.", 
-		"junit.runner."
-	};
-	/** name of excluded properties file */
-	static final String EXCLUDED_FILE= "excluded.properties";
-	/** excluded paths */
-	private Vector fExcluded;
-	 
-	/**
-	 * Constructs a TestCaseLoader. It scans the class path
-	 * and the excluded package paths
-	 */
-	public TestCaseClassLoader() {
-		this(System.getProperty("java.class.path"));
-	}
-	
-	/**
-	 * Constructs a TestCaseLoader. It scans the class path
-	 * and the excluded package paths
-	 */
-	public TestCaseClassLoader(String classPath) {
-		scanPath(classPath);
-		readExcludedPackages();
-	}
+    /** scanned class path */
+    private Vector fPathItems;
+    /** default excluded paths */
+    private String[] defaultExclusions= {
+            "junit.framework.",
+            "junit.extensions.",
+            "junit.runner."
+    };
+    /** name of excluded properties file */
+    static final String EXCLUDED_FILE= "excluded.properties";
+    /** excluded paths */
+    private Vector fExcluded;
 
-	private void scanPath(String classPath) {
-		String separator= System.getProperty("path.separator");
-		fPathItems= new Vector(10);
-		StringTokenizer st= new StringTokenizer(classPath, separator);
-		while (st.hasMoreTokens()) {
-			fPathItems.addElement(st.nextToken());
-		}
-	}
-	
-	public URL getResource(String name) {
-		return ClassLoader.getSystemResource(name);
-	}
-	
-	public InputStream getResourceAsStream(String name) {
-		return ClassLoader.getSystemResourceAsStream(name);
-	} 
-	
-	public boolean isExcluded(String name) {
-		for (int i= 0; i < fExcluded.size(); i++) {
-			if (name.startsWith((String) fExcluded.elementAt(i))) {
-				return true;
-			}
-		}
-		return false;	
-	}
-	
-	public synchronized Class loadClass(String name, boolean resolve)
-		throws ClassNotFoundException {
-			
-		Class c= findLoadedClass(name);
-		if (c != null)
-			return c;
-		//
-		// Delegate the loading of excluded classes to the
-		// standard class loader.
-		//
-		if (isExcluded(name)) {
-			try {
-				c= findSystemClass(name);
-				return c;
-			} catch (ClassNotFoundException e) {
-				// keep searching
-			}
-		}
-		if (c == null) {
-			byte[] data= lookupClassData(name);
-			if (data == null)
-				throw new ClassNotFoundException();
-			c= defineClass(name, data, 0, data.length);
-		}
-		if (resolve) 
-			resolveClass(c);
-		return c;
-	}
-	
-	private byte[] lookupClassData(String className) throws ClassNotFoundException {
-		byte[] data= null;
-		for (int i= 0; i < fPathItems.size(); i++) {
-			String path= (String) fPathItems.elementAt(i);
-			String fileName= className.replace('.', '/')+".class";
-			if (isJar(path)) {
-				data= loadJarData(path, fileName);
-			} else {
-				data= loadFileData(path, fileName);
-			}
-			if (data != null)
-				return data;
-		}
-		throw new ClassNotFoundException(className);
-	}
-		
-	boolean isJar(String pathEntry) {
-		return pathEntry.endsWith(".jar") ||
-		       pathEntry.endsWith(".apk") ||
-                       pathEntry.endsWith(".zip");
-	}
+    /**
+     * Constructs a TestCaseLoader. It scans the class path
+     * and the excluded package paths
+     */
+    public TestCaseClassLoader() {
+        this(System.getProperty("java.class.path"));
+    }
 
-	private byte[] loadFileData(String path, String fileName) {
-		File file= new File(path, fileName);
-		if (file.exists()) { 
-			return getClassData(file);
-		}
-		return null;
-	}
-	
-	private byte[] getClassData(File f) {
-		try {
-			FileInputStream stream= new FileInputStream(f);
-			ByteArrayOutputStream out= new ByteArrayOutputStream(1000);
-			byte[] b= new byte[1000];
-			int n;
-			while ((n= stream.read(b)) != -1) 
-				out.write(b, 0, n);
-			stream.close();
-			out.close();
-			return out.toByteArray();
+    /**
+     * Constructs a TestCaseLoader. It scans the class path
+     * and the excluded package paths
+     */
+    public TestCaseClassLoader(String classPath) {
+        scanPath(classPath);
+        readExcludedPackages();
+    }
 
-		} catch (IOException e) {
-		}
-		return null;
-	}
+    private void scanPath(String classPath) {
+        String separator= System.getProperty("path.separator");
+        fPathItems= new Vector(10);
+        StringTokenizer st= new StringTokenizer(classPath, separator);
+        while (st.hasMoreTokens()) {
+            fPathItems.addElement(st.nextToken());
+        }
+    }
 
-	private byte[] loadJarData(String path, String fileName) {
-		ZipFile zipFile= null;
-		InputStream stream= null;
-		File archive= new File(path);
-		if (!archive.exists())
-			return null;
-		try {
-			zipFile= new ZipFile(archive);
-		} catch(IOException io) {
-			return null;
-		}
-		ZipEntry entry= zipFile.getEntry(fileName);
-		if (entry == null)
-			return null;
-		int size= (int) entry.getSize();
-		try {
-			stream= zipFile.getInputStream(entry);
-			byte[] data= new byte[size];
-			int pos= 0;
-			while (pos < size) {
-				int n= stream.read(data, pos, data.length - pos);
-				pos += n;
-			}
-			zipFile.close();
-			return data;
-		} catch (IOException e) {
-		} finally {
-			try {
-				if (stream != null)
-					stream.close();
-			} catch (IOException e) {
-			}
-		}
-		return null;
-	}
-	
-	private void readExcludedPackages() {		
-		fExcluded= new Vector(10);
-		for (int i= 0; i < defaultExclusions.length; i++)
-			fExcluded.addElement(defaultExclusions[i]);
-			
-		InputStream is= getClass().getResourceAsStream(EXCLUDED_FILE);
-		if (is == null) 
-			return;
-		Properties p= new Properties();
-		try {
-			p.load(is);
-		}
-		catch (IOException e) {
-			return;
-		} finally {
-			try {
-				is.close();
-			} catch (IOException e) {
-			}
-		}
-		for (Enumeration e= p.propertyNames(); e.hasMoreElements(); ) {
-			String key= (String)e.nextElement();
-			if (key.startsWith("excluded.")) {
-				String path= p.getProperty(key);
-				path= path.trim();
-				if (path.endsWith("*"))
-					path= path.substring(0, path.length()-1);
-				if (path.length() > 0) 
-					fExcluded.addElement(path);				
-			}
-		}
-	}
+    public URL getResource(String name) {
+        return ClassLoader.getSystemResource(name);
+    }
+
+    public InputStream getResourceAsStream(String name) {
+        return ClassLoader.getSystemResourceAsStream(name);
+    }
+
+    public boolean isExcluded(String name) {
+        for (int i= 0; i < fExcluded.size(); i++) {
+            if (name.startsWith((String) fExcluded.elementAt(i))) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public synchronized Class loadClass(String name, boolean resolve)
+            throws ClassNotFoundException {
+
+        Class c= findLoadedClass(name);
+        if (c != null)
+            return c;
+        //
+        // Delegate the loading of excluded classes to the
+        // standard class loader.
+        //
+        if (isExcluded(name)) {
+            try {
+                c= findSystemClass(name);
+                return c;
+            } catch (ClassNotFoundException e) {
+                // keep searching
+            }
+        }
+        if (c == null) {
+            byte[] data= lookupClassData(name);
+            if (data == null)
+                throw new ClassNotFoundException();
+            c= defineClass(name, data, 0, data.length);
+        }
+        if (resolve)
+            resolveClass(c);
+        return c;
+    }
+
+    private byte[] lookupClassData(String className) throws ClassNotFoundException {
+        byte[] data= null;
+        for (int i= 0; i < fPathItems.size(); i++) {
+            String path= (String) fPathItems.elementAt(i);
+            String fileName= className.replace('.', '/')+".class";
+            if (isJar(path)) {
+                data= loadJarData(path, fileName);
+            } else {
+                data= loadFileData(path, fileName);
+            }
+            if (data != null)
+                return data;
+        }
+        throw new ClassNotFoundException(className);
+    }
+
+    boolean isJar(String pathEntry) {
+        return pathEntry.endsWith(".jar") ||
+                pathEntry.endsWith(".apk") ||
+                pathEntry.endsWith(".zip");
+    }
+
+    private byte[] loadFileData(String path, String fileName) {
+        File file= new File(path, fileName);
+        if (file.exists()) {
+            return getClassData(file);
+        }
+        return null;
+    }
+
+    private byte[] getClassData(File f) {
+        try {
+            FileInputStream stream= new FileInputStream(f);
+            ByteArrayOutputStream out= new ByteArrayOutputStream(1000);
+            byte[] b= new byte[1000];
+            int n;
+            while ((n= stream.read(b)) != -1)
+                out.write(b, 0, n);
+            stream.close();
+            out.close();
+            return out.toByteArray();
+
+        } catch (IOException e) {
+        }
+        return null;
+    }
+
+    private byte[] loadJarData(String path, String fileName) {
+        ZipFile zipFile= null;
+        InputStream stream= null;
+        File archive= new File(path);
+        if (!archive.exists())
+            return null;
+        try {
+            zipFile= new ZipFile(archive);
+        } catch(IOException io) {
+            return null;
+        }
+        ZipEntry entry= zipFile.getEntry(fileName);
+        if (entry == null)
+            return null;
+        int size= (int) entry.getSize();
+        try {
+            stream= zipFile.getInputStream(entry);
+            byte[] data= new byte[size];
+            int pos= 0;
+            while (pos < size) {
+                int n= stream.read(data, pos, data.length - pos);
+                pos += n;
+            }
+            zipFile.close();
+            return data;
+        } catch (IOException e) {
+        } finally {
+            try {
+                if (stream != null)
+                    stream.close();
+            } catch (IOException e) {
+            }
+        }
+        return null;
+    }
+
+    private void readExcludedPackages() {
+        fExcluded= new Vector(10);
+        for (int i= 0; i < defaultExclusions.length; i++)
+            fExcluded.addElement(defaultExclusions[i]);
+
+        InputStream is= getClass().getResourceAsStream(EXCLUDED_FILE);
+        if (is == null)
+            return;
+        Properties p= new Properties();
+        try {
+            p.load(is);
+        }
+        catch (IOException e) {
+            return;
+        } finally {
+            try {
+                is.close();
+            } catch (IOException e) {
+            }
+        }
+        for (Enumeration e= p.propertyNames(); e.hasMoreElements(); ) {
+            String key= (String)e.nextElement();
+            if (key.startsWith("excluded.")) {
+                String path= p.getProperty(key);
+                path= path.trim();
+                if (path.endsWith("*"))
+                    path= path.substring(0, path.length()-1);
+                if (path.length() > 0)
+                    fExcluded.addElement(path);
+            }
+        }
+    }
 }
diff --git a/test-runner/src/junit/runner/TestCollector.java b/test-runner/src/junit/runner/TestCollector.java
index 208dccd..3ac9d9e 100644
--- a/test-runner/src/junit/runner/TestCollector.java
+++ b/test-runner/src/junit/runner/TestCollector.java
@@ -5,13 +5,13 @@
 
 /**
  * Collects Test class names to be presented
- * by the TestSelector. 
+ * by the TestSelector.
  * @see TestSelector
  * {@hide} - Not needed for 1.0 SDK
  */
 public interface TestCollector {
-	/**
-	 * Returns an enumeration of Strings with qualified class names
-	 */
-	public Enumeration collectTests();
+    /**
+     * Returns an enumeration of Strings with qualified class names
+     */
+    public Enumeration collectTests();
 }
diff --git a/test-runner/src/junit/runner/TestRunListener.java b/test-runner/src/junit/runner/TestRunListener.java
index 0e95819..0410f0c 100644
--- a/test-runner/src/junit/runner/TestRunListener.java
+++ b/test-runner/src/junit/runner/TestRunListener.java
@@ -6,15 +6,15 @@
  * making it suitable for remote test execution.
  * {@hide} - Not needed for 1.0 SDK
  */
- public interface TestRunListener {
-     /* test status constants*/
-     public static final int STATUS_ERROR= 1;
-     public static final int STATUS_FAILURE= 2;
+public interface TestRunListener {
+    /* test status constants*/
+    public static final int STATUS_ERROR= 1;
+    public static final int STATUS_FAILURE= 2;
 
-     public void testRunStarted(String testSuiteName, int testCount);
-     public void testRunEnded(long elapsedTime);
-     public void testRunStopped(long elapsedTime);
-     public void testStarted(String testName);
-     public void testEnded(String testName);
-     public void testFailed(int status, String testName, String trace);
+    public void testRunStarted(String testSuiteName, int testCount);
+    public void testRunEnded(long elapsedTime);
+    public void testRunStopped(long elapsedTime);
+    public void testStarted(String testName);
+    public void testEnded(String testName);
+    public void testFailed(int status, String testName, String trace);
 }
diff --git a/test-runner/src/junit/runner/TestSuiteLoader.java b/test-runner/src/junit/runner/TestSuiteLoader.java
index 39a4cf7..581ea23 100644
--- a/test-runner/src/junit/runner/TestSuiteLoader.java
+++ b/test-runner/src/junit/runner/TestSuiteLoader.java
@@ -4,6 +4,6 @@
  * An interface to define how a test suite should be loaded.
  */
 public interface TestSuiteLoader {
-	abstract public Class load(String suiteClassName) throws ClassNotFoundException;
-	abstract public Class reload(Class aClass) throws ClassNotFoundException;
+    abstract public Class load(String suiteClassName) throws ClassNotFoundException;
+    abstract public Class reload(Class aClass) throws ClassNotFoundException;
 }
diff --git a/test-runner/src/junit/runner/Version.java b/test-runner/src/junit/runner/Version.java
index b4541ab..4a6dc85 100644
--- a/test-runner/src/junit/runner/Version.java
+++ b/test-runner/src/junit/runner/Version.java
@@ -4,11 +4,17 @@
  * This class defines the current version of JUnit
  */
 public class Version {
-	private Version() {
-		// don't instantiate
-	}
+    private Version() {
+        // don't instantiate
+    }
 
-	public static String id() {
-		return "3.8.1";
-	}
+    public static String id() {
+        return "4.10";
+    }
+
+    // android-changed
+    /** @hide - not needed for public API */
+    public static void main(String[] args) {
+        System.out.println(id());
+    }
 }
diff --git a/test-runner/src/junit/textui/ResultPrinter.java b/test-runner/src/junit/textui/ResultPrinter.java
index 5c97112..4b26558 100644
--- a/test-runner/src/junit/textui/ResultPrinter.java
+++ b/test-runner/src/junit/textui/ResultPrinter.java
@@ -14,129 +14,129 @@
 import junit.runner.BaseTestRunner;
 
 public class ResultPrinter implements TestListener {
-	PrintStream fWriter;
-	int fColumn= 0;
-	
-	public ResultPrinter(PrintStream writer) {
-		fWriter= writer;
-	}
-	
-	/* API for use by textui.TestRunner
-	 */
+    PrintStream fWriter;
+    int fColumn= 0;
 
-	synchronized void print(TestResult result, long runTime) {
-		printHeader(runTime);
-	    printErrors(result);
-	    printFailures(result);
-	    printFooter(result);
-	}
+    public ResultPrinter(PrintStream writer) {
+        fWriter= writer;
+    }
 
-	void printWaitPrompt() {
-		getWriter().println();
-		getWriter().println("<RETURN> to continue");
-	}
-	
-	/* Internal methods 
-	 */
+    /* API for use by textui.TestRunner
+     */
 
-	protected void printHeader(long runTime) {
-		getWriter().println();
-		getWriter().println("Time: "+elapsedTimeAsString(runTime));
-	}
-	
-	protected void printErrors(TestResult result) {
-		printDefects(result.errors(), result.errorCount(), "error");
-	}
-	
-	protected void printFailures(TestResult result) {
-		printDefects(result.failures(), result.failureCount(), "failure");
-	}
-	
-	protected void printDefects(Enumeration booBoos, int count, String type) {
-		if (count == 0) return;
-		if (count == 1)
-			getWriter().println("There was " + count + " " + type + ":");
-		else
-			getWriter().println("There were " + count + " " + type + "s:");
-		for (int i= 1; booBoos.hasMoreElements(); i++) {
-			printDefect((TestFailure) booBoos.nextElement(), i);
-		}
-	}
-	
-	public void printDefect(TestFailure booBoo, int count) { // only public for testing purposes
-		printDefectHeader(booBoo, count);
-		printDefectTrace(booBoo);
-	}
+    synchronized void print(TestResult result, long runTime) {
+        printHeader(runTime);
+        printErrors(result);
+        printFailures(result);
+        printFooter(result);
+    }
 
-	protected void printDefectHeader(TestFailure booBoo, int count) {
-		// I feel like making this a println, then adding a line giving the throwable a chance to print something
-		// before we get to the stack trace.
-		getWriter().print(count + ") " + booBoo.failedTest());
-	}
+    void printWaitPrompt() {
+        getWriter().println();
+        getWriter().println("<RETURN> to continue");
+    }
 
-	protected void printDefectTrace(TestFailure booBoo) {
-		getWriter().print(BaseTestRunner.getFilteredTrace(booBoo.trace()));
-	}
+    /* Internal methods
+     */
 
-	protected void printFooter(TestResult result) {
-		if (result.wasSuccessful()) {
-			getWriter().println();
-			getWriter().print("OK");
-			getWriter().println (" (" + result.runCount() + " test" + (result.runCount() == 1 ? "": "s") + ")");
+    protected void printHeader(long runTime) {
+        getWriter().println();
+        getWriter().println("Time: "+elapsedTimeAsString(runTime));
+    }
 
-		} else {
-			getWriter().println();
-			getWriter().println("FAILURES!!!");
-			getWriter().println("Tests run: "+result.runCount()+ 
-				         ",  Failures: "+result.failureCount()+
-				         ",  Errors: "+result.errorCount());
-		}
-	    getWriter().println();
-	}
+    protected void printErrors(TestResult result) {
+        printDefects(result.errors(), result.errorCount(), "error");
+    }
+
+    protected void printFailures(TestResult result) {
+        printDefects(result.failures(), result.failureCount(), "failure");
+    }
+
+    protected void printDefects(Enumeration<TestFailure> booBoos, int count, String type) {
+        if (count == 0) return;
+        if (count == 1)
+            getWriter().println("There was " + count + " " + type + ":");
+        else
+            getWriter().println("There were " + count + " " + type + "s:");
+        for (int i= 1; booBoos.hasMoreElements(); i++) {
+            printDefect(booBoos.nextElement(), i);
+        }
+    }
+
+    public void printDefect(TestFailure booBoo, int count) { // only public for testing purposes
+        printDefectHeader(booBoo, count);
+        printDefectTrace(booBoo);
+    }
+
+    protected void printDefectHeader(TestFailure booBoo, int count) {
+        // I feel like making this a println, then adding a line giving the throwable a chance to print something
+        // before we get to the stack trace.
+        getWriter().print(count + ") " + booBoo.failedTest());
+    }
+
+    protected void printDefectTrace(TestFailure booBoo) {
+        getWriter().print(BaseTestRunner.getFilteredTrace(booBoo.trace()));
+    }
+
+    protected void printFooter(TestResult result) {
+        if (result.wasSuccessful()) {
+            getWriter().println();
+            getWriter().print("OK");
+            getWriter().println (" (" + result.runCount() + " test" + (result.runCount() == 1 ? "": "s") + ")");
+
+        } else {
+            getWriter().println();
+            getWriter().println("FAILURES!!!");
+            getWriter().println("Tests run: "+result.runCount()+
+                    ",  Failures: "+result.failureCount()+
+                    ",  Errors: "+result.errorCount());
+        }
+        getWriter().println();
+    }
 
 
-	/**
-	 * Returns the formatted string of the elapsed time.
-	 * Duplicated from BaseTestRunner. Fix it.
-	 */
-	protected String elapsedTimeAsString(long runTime) {
-            // The following line was altered for compatibility with
-            // Android libraries.
-	    return Double.toString((double)runTime/1000);
-	}
+    /**
+     * Returns the formatted string of the elapsed time.
+     * Duplicated from BaseTestRunner. Fix it.
+     */
+    protected String elapsedTimeAsString(long runTime) {
+        // The following line was altered for compatibility with
+        // Android libraries.
+        return Double.toString((double)runTime/1000);
+    }
 
-	public PrintStream getWriter() {
-		return fWriter;
-	}
-	/**
-	 * @see junit.framework.TestListener#addError(Test, Throwable)
-	 */
-	public void addError(Test test, Throwable t) {
-		getWriter().print("E");
-	}
+    public PrintStream getWriter() {
+        return fWriter;
+    }
+    /**
+     * @see junit.framework.TestListener#addError(Test, Throwable)
+     */
+    public void addError(Test test, Throwable t) {
+        getWriter().print("E");
+    }
 
-	/**
-	 * @see junit.framework.TestListener#addFailure(Test, AssertionFailedError)
-	 */
-	public void addFailure(Test test, AssertionFailedError t) {
-		getWriter().print("F");
-	}
+    /**
+     * @see junit.framework.TestListener#addFailure(Test, AssertionFailedError)
+     */
+    public void addFailure(Test test, AssertionFailedError t) {
+        getWriter().print("F");
+    }
 
-	/**
-	 * @see junit.framework.TestListener#endTest(Test)
-	 */
-	public void endTest(Test test) {
-	}
+    /**
+     * @see junit.framework.TestListener#endTest(Test)
+     */
+    public void endTest(Test test) {
+    }
 
-	/**
-	 * @see junit.framework.TestListener#startTest(Test)
-	 */
-	public void startTest(Test test) {
-		getWriter().print(".");
-		if (fColumn++ >= 40) {
-			getWriter().println();
-			fColumn= 0;
-		}
-	}
+    /**
+     * @see junit.framework.TestListener#startTest(Test)
+     */
+    public void startTest(Test test) {
+        getWriter().print(".");
+        if (fColumn++ >= 40) {
+            getWriter().println();
+            fColumn= 0;
+        }
+    }
 
 }
diff --git a/test-runner/src/junit/textui/TestRunner.java b/test-runner/src/junit/textui/TestRunner.java
index 8bdc325..e955e0e 100644
--- a/test-runner/src/junit/textui/TestRunner.java
+++ b/test-runner/src/junit/textui/TestRunner.java
@@ -3,187 +3,201 @@
 
 import java.io.PrintStream;
 
-import junit.framework.*;
-import junit.runner.*;
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestResult;
+import junit.framework.TestSuite;
+import junit.runner.BaseTestRunner;
+import junit.runner.Version;
 
 /**
  * A command line based tool to run tests.
  * <pre>
  * java junit.textui.TestRunner [-wait] TestCaseClass
  * </pre>
- * TestRunner expects the name of a TestCase class as argument.
- * If this class defines a static <code>suite</code> method it 
- * will be invoked and the returned test is run. Otherwise all 
+ * 
+ * <p>TestRunner expects the name of a TestCase class as argument.
+ * If this class defines a static <code>suite</code> method it
+ * will be invoked and the returned test is run. Otherwise all
  * the methods starting with "test" having no arguments are run.
  * <p>
  * When the wait command line argument is given TestRunner
  * waits until the users types RETURN.
  * <p>
  * TestRunner prints a trace as the tests are executed followed by a
- * summary at the end. 
+ * summary at the end.
  */
 public class TestRunner extends BaseTestRunner {
-	private ResultPrinter fPrinter;
-	
-	public static final int SUCCESS_EXIT= 0;
-	public static final int FAILURE_EXIT= 1;
-	public static final int EXCEPTION_EXIT= 2;
+    private ResultPrinter fPrinter;
 
-	/**
-	 * Constructs a TestRunner.
-	 */
-	public TestRunner() {
-		this(System.out);
-	}
+    public static final int SUCCESS_EXIT= 0;
+    public static final int FAILURE_EXIT= 1;
+    public static final int EXCEPTION_EXIT= 2;
 
-	/**
-	 * Constructs a TestRunner using the given stream for all the output
-	 */
-	public TestRunner(PrintStream writer) {
-		this(new ResultPrinter(writer));
-	}
-	
-	/**
-	 * Constructs a TestRunner using the given ResultPrinter all the output
-	 */
-	public TestRunner(ResultPrinter printer) {
-		fPrinter= printer;
-	}
-	
-	/**
-	 * Runs a suite extracted from a TestCase subclass.
-	 */
-	static public void run(Class testClass) {
-		run(new TestSuite(testClass));
-	}
+    /**
+     * Constructs a TestRunner.
+     */
+    public TestRunner() {
+        this(System.out);
+    }
 
-	/**
-	 * Runs a single test and collects its results.
-	 * This method can be used to start a test run
-	 * from your program.
-	 * <pre>
-	 * public static void main (String[] args) {
-	 *     test.textui.TestRunner.run(suite());
-	 * }
-	 * </pre>
-	 */
-	static public TestResult run(Test test) {
-		TestRunner runner= new TestRunner();
-		return runner.doRun(test);
-	}
+    /**
+     * Constructs a TestRunner using the given stream for all the output
+     */
+    public TestRunner(PrintStream writer) {
+        this(new ResultPrinter(writer));
+    }
 
-	/**
-	 * Runs a single test and waits until the user
-	 * types RETURN.
-	 */
-	static public void runAndWait(Test suite) {
-		TestRunner aTestRunner= new TestRunner();
-		aTestRunner.doRun(suite, true);
-	}
+    /**
+     * Constructs a TestRunner using the given ResultPrinter all the output
+     */
+    public TestRunner(ResultPrinter printer) {
+        fPrinter= printer;
+    }
 
-	/**
-	 * Always use the StandardTestSuiteLoader. Overridden from
-	 * BaseTestRunner.
-	 */
-	public TestSuiteLoader getLoader() {
-		return new StandardTestSuiteLoader();
-	}
+    /**
+     * Runs a suite extracted from a TestCase subclass.
+     */
+    static public void run(Class<? extends TestCase> testClass) {
+        run(new TestSuite(testClass));
+    }
 
-	public void testFailed(int status, Test test, Throwable t) {
-	}
-	
-	public void testStarted(String testName) {
-	}
-	
-	public void testEnded(String testName) {
-	}
+    /**
+     * Runs a single test and collects its results.
+     * This method can be used to start a test run
+     * from your program.
+     * <pre>
+     * public static void main (String[] args) {
+     *    test.textui.TestRunner.run(suite());
+     * }
+     * </pre>
+     */
+    static public TestResult run(Test test) {
+        TestRunner runner= new TestRunner();
+        return runner.doRun(test);
+    }
 
-	/**
-	 * Creates the TestResult to be used for the test run.
-	 */
-	protected TestResult createTestResult() {
-		return new TestResult();
-	}
-	
-	public TestResult doRun(Test test) {
-		return doRun(test, false);
-	}
-	
-	public TestResult doRun(Test suite, boolean wait) {
-		TestResult result= createTestResult();
-		result.addListener(fPrinter);
-		long startTime= System.currentTimeMillis();
-		suite.run(result);
-		long endTime= System.currentTimeMillis();
-		long runTime= endTime-startTime;
-		fPrinter.print(result, runTime);
+    /**
+     * Runs a single test and waits until the user
+     * types RETURN.
+     */
+    static public void runAndWait(Test suite) {
+        TestRunner aTestRunner= new TestRunner();
+        aTestRunner.doRun(suite, true);
+    }
 
-		pause(wait);
-		return result;
-	}
+    @Override
+    public void testFailed(int status, Test test, Throwable t) {
+    }
 
-	protected void pause(boolean wait) {
-		if (!wait) return;
-		fPrinter.printWaitPrompt();
-		try {
-			System.in.read();
-		}
-		catch(Exception e) {
-		}
-	}
-	
-	public static void main(String args[]) {
-		TestRunner aTestRunner= new TestRunner();
-		try {
-			TestResult r= aTestRunner.start(args);
-			if (!r.wasSuccessful()) 
-				System.exit(FAILURE_EXIT);
-			System.exit(SUCCESS_EXIT);
-		} catch(Exception e) {
-			System.err.println(e.getMessage());
-			System.exit(EXCEPTION_EXIT);
-		}
-	}
+    @Override
+    public void testStarted(String testName) {
+    }
 
-	/**
-	 * Starts a test run. Analyzes the command line arguments
-	 * and runs the given test suite.
-	 */
-	protected TestResult start(String args[]) throws Exception {
-		String testCase= "";
-		boolean wait= false;
-		
-		for (int i= 0; i < args.length; i++) {
-			if (args[i].equals("-wait"))
-				wait= true;
-			else if (args[i].equals("-c")) 
-				testCase= extractClassName(args[++i]);
-			else if (args[i].equals("-v"))
-				System.err.println("JUnit "+Version.id()+" by Kent Beck and Erich Gamma");
-			else
-				testCase= args[i];
-		}
-		
-		if (testCase.equals("")) 
-			throw new Exception("Usage: TestRunner [-wait] testCaseName, where name is the name of the TestCase class");
+    @Override
+    public void testEnded(String testName) {
+    }
 
-		try {
-			Test suite= getTest(testCase);
-			return doRun(suite, wait);
-		}
-		catch(Exception e) {
-			throw new Exception("Could not create and run test suite: "+e);
-		}
-	}
-		
-	protected void runFailed(String message) {
-		System.err.println(message);
-		System.exit(FAILURE_EXIT);
-	}
-	
-	public void setPrinter(ResultPrinter printer) {
-		fPrinter= printer;
-	}
-		
-	
+    /**
+     * Creates the TestResult to be used for the test run.
+     */
+    protected TestResult createTestResult() {
+        return new TestResult();
+    }
+
+    public TestResult doRun(Test test) {
+        return doRun(test, false);
+    }
+
+    public TestResult doRun(Test suite, boolean wait) {
+        TestResult result= createTestResult();
+        result.addListener(fPrinter);
+        long startTime= System.currentTimeMillis();
+        suite.run(result);
+        long endTime= System.currentTimeMillis();
+        long runTime= endTime-startTime;
+        fPrinter.print(result, runTime);
+
+        pause(wait);
+        return result;
+    }
+
+    protected void pause(boolean wait) {
+        if (!wait) return;
+        fPrinter.printWaitPrompt();
+        try {
+            System.in.read();
+        }
+        catch(Exception e) {
+        }
+    }
+
+    public static void main(String args[]) {
+        TestRunner aTestRunner= new TestRunner();
+        try {
+            TestResult r= aTestRunner.start(args);
+            if (!r.wasSuccessful())
+                System.exit(FAILURE_EXIT);
+            System.exit(SUCCESS_EXIT);
+        } catch(Exception e) {
+            System.err.println(e.getMessage());
+            System.exit(EXCEPTION_EXIT);
+        }
+    }
+
+    /**
+     * Starts a test run. Analyzes the command line arguments
+     * and runs the given test suite.
+     */
+    public TestResult start(String args[]) throws Exception {
+        String testCase= "";
+        String method= "";
+        boolean wait= false;
+
+        for (int i= 0; i < args.length; i++) {
+            if (args[i].equals("-wait"))
+                wait= true;
+            else if (args[i].equals("-c"))
+                testCase= extractClassName(args[++i]);
+            else if (args[i].equals("-m")) {
+                String arg= args[++i];
+                int lastIndex= arg.lastIndexOf('.');
+                testCase= arg.substring(0, lastIndex);
+                method= arg.substring(lastIndex + 1);
+            } else if (args[i].equals("-v"))
+                System.err.println("JUnit " + Version.id() + " by Kent Beck and Erich Gamma");
+            else
+                testCase= args[i];
+        }
+
+        if (testCase.equals(""))
+            throw new Exception("Usage: TestRunner [-wait] testCaseName, where name is the name of the TestCase class");
+
+        try {
+            if (!method.equals(""))
+                return runSingleMethod(testCase, method, wait);
+            Test suite= getTest(testCase);
+            return doRun(suite, wait);
+        } catch (Exception e) {
+            throw new Exception("Could not create and run test suite: " + e);
+        }
+    }
+
+    protected TestResult runSingleMethod(String testCase, String method, boolean wait) throws Exception {
+        Class<? extends TestCase> testClass= loadSuiteClass(testCase).asSubclass(TestCase.class);
+        Test test= TestSuite.createTest(testClass, method);
+        return doRun(test, wait);
+    }
+
+    @Override
+    protected void runFailed(String message) {
+        System.err.println(message);
+        System.exit(FAILURE_EXIT);
+    }
+
+    public void setPrinter(ResultPrinter printer) {
+        fPrinter= printer;
+    }
+
+
 }
