Merge "Fix wallpaper restore"
diff --git a/Android.mk b/Android.mk
index 5a40318..a38723a 100644
--- a/Android.mk
+++ b/Android.mk
@@ -464,6 +464,8 @@
 		            resources/samples/USB "USB" \
 		-samplecode $(sample_dir)/WeatherListWidget \
 		            resources/samples/WeatherListWidget "Weather List Widget" \
+		-samplecode $(sample_dir)/WiFiDirectDemo \
+                            resources/samples/WiFiDirectDemo "Wi-Fi Direct Demo" \
 		-samplecode $(sample_dir)/Wiktionary \
 		            resources/samples/Wiktionary "Wiktionary" \
 		-samplecode $(sample_dir)/WiktionarySimple \
diff --git a/CleanSpec.mk b/CleanSpec.mk
index 1c85279..9381437 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -115,6 +115,7 @@
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/media/audio/)
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/fonts/DroidSans*)
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/media/audio/)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/fonts/DroidSans*)
 # ************************************************
 # NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
 # ************************************************
diff --git a/core/java/android/animation/LayoutTransition.java b/core/java/android/animation/LayoutTransition.java
index 355b1fc..f383af9 100644
--- a/core/java/android/animation/LayoutTransition.java
+++ b/core/java/android/animation/LayoutTransition.java
@@ -24,6 +24,7 @@
 import android.view.animation.DecelerateInterpolator;
 
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.HashMap;
 import java.util.LinkedHashMap;
 import java.util.List;
@@ -615,10 +616,13 @@
         observer.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
             public boolean onPreDraw() {
                 parent.getViewTreeObserver().removeOnPreDrawListener(this);
-                int numChildren = parent.getChildCount();
-                for (int i = 0; i < numChildren; ++i) {
-                    final View child = parent.getChildAt(i);
-                    child.removeOnLayoutChangeListener(layoutChangeListenerMap.get(child));
+                int count = layoutChangeListenerMap.size();
+                if (count > 0) {
+                    Collection<View> views = layoutChangeListenerMap.keySet();
+                    for (View view : views) {
+                        View.OnLayoutChangeListener listener = layoutChangeListenerMap.get(view);
+                        view.removeOnLayoutChangeListener(listener);
+                    }
                 }
                 layoutChangeListenerMap.clear();
                 return true;
diff --git a/core/java/android/database/CursorWindow.java b/core/java/android/database/CursorWindow.java
index f7cbf7a..183662f 100644
--- a/core/java/android/database/CursorWindow.java
+++ b/core/java/android/database/CursorWindow.java
@@ -18,6 +18,7 @@
 
 import android.content.res.Resources;
 import android.database.sqlite.SQLiteClosable;
+import android.database.sqlite.SQLiteException;
 import android.os.Binder;
 import android.os.IBinder;
 import android.os.Parcel;
@@ -39,538 +40,613 @@
         Resources.getSystem().getInteger(
                 com.android.internal.R.integer.config_cursorWindowSize) * 1024;
 
-    /** The pointer to the native window class. set by the native methods in
-     * android_database_CursorWindow.cpp
+    /**
+     * The native CursorWindow object pointer.  (FOR INTERNAL USE ONLY)
+     * @hide
      */
-    private int nWindow;
+    public int mWindowPtr;
 
     private int mStartPos;
 
+    private static native int nativeInitializeEmpty(int cursorWindowSize, boolean localOnly);
+    private static native int nativeInitializeFromBinder(IBinder nativeBinder);
+    private static native void nativeDispose(int windowPtr);
+    private static native IBinder nativeGetBinder(int windowPtr);
+
+    private static native void nativeClear(int windowPtr);
+
+    private static native int nativeGetNumRows(int windowPtr);
+    private static native boolean nativeSetNumColumns(int windowPtr, int columnNum);
+    private static native boolean nativeAllocRow(int windowPtr);
+    private static native void nativeFreeLastRow(int windowPtr);
+
+    private static native int nativeGetType(int windowPtr, int row, int column);
+    private static native byte[] nativeGetBlob(int windowPtr, int row, int column);
+    private static native String nativeGetString(int windowPtr, int row, int column);
+    private static native long nativeGetLong(int windowPtr, int row, int column);
+    private static native double nativeGetDouble(int windowPtr, int row, int column);
+    private static native void nativeCopyStringToBuffer(int windowPtr, int row, int column,
+            CharArrayBuffer buffer);
+
+    private static native boolean nativePutBlob(int windowPtr, byte[] value, int row, int column);
+    private static native boolean nativePutString(int windowPtr, String value, int row, int column);
+    private static native boolean nativePutLong(int windowPtr, long value, int row, int column);
+    private static native boolean nativePutDouble(int windowPtr, double value, int row, int column);
+    private static native boolean nativePutNull(int windowPtr, int row, int column);
+
     /**
-     * Creates a new empty window.
+     * Creates a new empty cursor window.
+     * <p>
+     * The cursor initially has no rows or columns.  Call {@link #setNumColumns(int)} to
+     * set the number of columns before adding any rows to the cursor.
+     * </p>
      *
-     * @param localWindow true if this window will be used in this process only
+     * @param localWindow True if this window will be used in this process only,
+     * false if it might be sent to another processes.
      */
     public CursorWindow(boolean localWindow) {
         mStartPos = 0;
-        int rslt = native_init(sCursorWindowSize, localWindow);
-        printDebugMsgIfError(rslt);
-        recordNewWindow(Binder.getCallingPid(), nWindow);
+        mWindowPtr = nativeInitializeEmpty(sCursorWindowSize, localWindow);
+        if (mWindowPtr == 0) {
+            throw new CursorWindowAllocationException("Cursor window allocation of " +
+                    (sCursorWindowSize / 1024) + " kb failed. " + printStats());
+        }
+        recordNewWindow(Binder.getCallingPid(), mWindowPtr);
     }
 
-    private void printDebugMsgIfError(int rslt) {
-        if (rslt > 0) {
-            // cursor window allocation failed. either low memory or too many cursors being open.
-            // print info to help in debugging this.
-            throw new CursorWindowAllocationException("Cursor Window allocation of " +
-                    sCursorWindowSize/1024 + " kb failed. " + printStats());
+    private CursorWindow(Parcel source) {
+        IBinder binder = source.readStrongBinder();
+        mStartPos = source.readInt();
+        mWindowPtr = nativeInitializeFromBinder(binder);
+        if (mWindowPtr == 0) {
+            throw new CursorWindowAllocationException("Cursor window could not be "
+                    + "created from binder.");
+        }
+    }
+
+    @Override
+    protected void finalize() {
+        dispose();
+    }
+
+    private void dispose() {
+        if (mWindowPtr != 0) {
+            recordClosingOfWindow(mWindowPtr);
+            nativeDispose(mWindowPtr);
+            mWindowPtr = 0;
         }
     }
 
     /**
-     * Returns the starting position of this window within the entire
-     * Cursor's result set.
+     * Closes the cursor window and frees its underlying resources when all other
+     * remaining references have been released.
+     */
+    public void close() {
+        releaseReference();
+    }
+
+    /**
+     * Clears out the existing contents of the window, making it safe to reuse
+     * for new data.
+     * <p>
+     * The start position ({@link #getStartPosition()}), number of rows ({@link #getNumRows()}),
+     * and number of columns in the cursor are all reset to zero.
+     * </p>
+     */
+    public void clear() {
+        acquireReference();
+        try {
+            mStartPos = 0;
+            nativeClear(mWindowPtr);
+        } finally {
+            releaseReference();
+        }
+    }
+
+    /**
+     * Gets the start position of this cursor window.
+     * The start position is the index of the first row that this window contains
+     * relative to the entire result set of the {@link Cursor}.
      *
-     * @return the starting position of this window within the entire
-     * Cursor's result set.
+     * @return The start position.
      */
     public int getStartPosition() {
         return mStartPos;
     }
 
     /**
-     * Set the start position of cursor window
-     * @param pos
+     * Sets the start position of this cursor window.
+     * The start position is the index of the first row that this window contains
+     * relative to the entire result set of the {@link Cursor}.
+     *
+     * @param pos The new start position.
      */
     public void setStartPosition(int pos) {
         mStartPos = pos;
-    }    
- 
+    }
+
     /**
-     * Returns the number of rows in this window.
-     * 
-     * @return the number of rows in this window.
+     * Gets the number of rows in this window.
+     *
+     * @return The number of rows in this cursor window.
      */
     public int getNumRows() {
         acquireReference();
         try {
-            return getNumRows_native();
+            return nativeGetNumRows(mWindowPtr);
         } finally {
             releaseReference();
         }
     }
-    
-    private native int getNumRows_native();
+
     /**
-     * Set number of Columns 
-     * @param columnNum
-     * @return true if success
+     * Sets the number of columns in this window.
+     * <p>
+     * This method must be called before any rows are added to the window, otherwise
+     * it will fail to set the number of columns if it differs from the current number
+     * of columns.
+     * </p>
+     *
+     * @param columnNum The new number of columns.
+     * @return True if successful.
      */
     public boolean setNumColumns(int columnNum) {
         acquireReference();
         try {
-            return setNumColumns_native(columnNum);
+            return nativeSetNumColumns(mWindowPtr, columnNum);
         } finally {
             releaseReference();
         }
     }
-    
-    private native boolean setNumColumns_native(int columnNum);
-    
+
     /**
-     * Allocate a row in cursor window
-     * @return false if cursor window is out of memory
+     * Allocates a new row at the end of this cursor window.
+     *
+     * @return True if successful, false if the cursor window is out of memory.
      */
     public boolean allocRow(){
         acquireReference();
         try {
-            return allocRow_native();
+            return nativeAllocRow(mWindowPtr);
         } finally {
             releaseReference();
         }
     }
-    
-    private native boolean allocRow_native();    
-    
+
     /**
-     * Free the last row
+     * Frees the last row in this cursor window.
      */
     public void freeLastRow(){
         acquireReference();
         try {
-            freeLastRow_native();
+            nativeFreeLastRow(mWindowPtr);
         } finally {
             releaseReference();
         }
     }
-    
-    private native void freeLastRow_native();
 
     /**
-     * copy byte array to cursor window
-     * @param value
-     * @param row
-     * @param col
-     * @return false if fail to copy
-     */
-    public boolean putBlob(byte[] value, int row, int col) {
-        acquireReference();
-        try {
-            return putBlob_native(value, row - mStartPos, col);
-        } finally {
-            releaseReference();
-        }
-    }
-    
-    private native boolean putBlob_native(byte[] value, int row, int col);    
-
-    /**
-     * Copy String to cursor window
-     * @param value
-     * @param row
-     * @param col
-     * @return false if fail to copy
-     */
-    public boolean putString(String value, int row, int col) {
-        acquireReference();
-        try {
-            return putString_native(value, row - mStartPos, col);
-        } finally {
-            releaseReference();
-        }
-    }
-    
-    private native boolean putString_native(String value, int row, int col);    
-    
-    /**
-     * Copy integer to cursor window
-     * @param value
-     * @param row
-     * @param col
-     * @return false if fail to copy
-     */
-    public boolean putLong(long value, int row, int col) {
-        acquireReference();
-        try {
-            return putLong_native(value, row - mStartPos, col);
-        } finally {
-            releaseReference();
-        }
-    }
-    
-    private native boolean putLong_native(long value, int row, int col);
-    
-
-    /**
-     * Copy double to cursor window 
-     * @param value
-     * @param row
-     * @param col
-     * @return false if fail to copy
-     */
-    public boolean putDouble(double value, int row, int col) {
-        acquireReference();
-        try {
-            return putDouble_native(value, row - mStartPos, col);
-        } finally {
-            releaseReference();
-        }
-    }
-    
-    private native boolean putDouble_native(double value, int row, int col);    
-
-    /**
-     * Set the [row, col] value to NULL
-     * @param row
-     * @param col
-     * @return false if fail to copy
-     */
-    public boolean putNull(int row, int col) {
-        acquireReference();
-        try {
-            return putNull_native(row - mStartPos, col);
-        } finally {
-            releaseReference();
-        }
-    }
-    
-    private native boolean putNull_native(int row, int col);
-    
-
-    /**
-     * Returns {@code true} if given field is {@code NULL}.
-     * 
-     * @param row the row to read from, row - getStartPosition() being the actual row in the window
-     * @param col the column to read from
-     * @return {@code true} if given field is {@code NULL}
-     * @deprecated use {@link #getType(int, int)} instead
+     * Returns true if the field at the specified row and column index
+     * has type {@link Cursor#FIELD_TYPE_NULL}.
+     *
+     * @param row The zero-based row index, relative to the cursor window's
+     * start position ({@link #getStartPosition()}).
+     * @param column The zero-based column index.
+     * @return True if the field has type {@link Cursor#FIELD_TYPE_NULL}.
+     * @deprecated Use {@link #getType(int, int)} instead.
      */
     @Deprecated
-    public boolean isNull(int row, int col) {
-        return getType(row, col) == Cursor.FIELD_TYPE_NULL;
-    }
-    
-    /**
-     * Returns a byte array for the given field.
-     *
-     * @param row the row to read from, row - getStartPosition() being the actual row in the window
-     * @param col the column to read from
-     * @return a String value for the given field
-     */
-    public byte[] getBlob(int row, int col) {
-        acquireReference();
-        try {
-            return getBlob_native(row - mStartPos, col);
-        } finally {
-            releaseReference();
-        }
+    public boolean isNull(int row, int column) {
+        return getType(row, column) == Cursor.FIELD_TYPE_NULL;
     }
 
     /**
-     * Returns the value at (<code>row</code>, <code>col</code>) as a <code>byte</code> array.
+     * Returns true if the field at the specified row and column index
+     * has type {@link Cursor#FIELD_TYPE_BLOB} or {@link Cursor#FIELD_TYPE_NULL}.
      *
-     * <p>If the value is null, then <code>null</code> is returned. If the
-     * type of column <code>col</code> is a string type, then the result
-     * is the array of bytes that make up the internal representation of the
-     * string value. If the type of column <code>col</code> is integral or floating-point,
-     * then an {@link SQLiteException} is thrown.
-     */
-    private native byte[] getBlob_native(int row, int col);
-
-    /**
-     * Returns data type of the given column's value.
-     *<p>
-     * Returned column types are
-     * <ul>
-     *   <li>{@link Cursor#FIELD_TYPE_NULL}</li>
-     *   <li>{@link Cursor#FIELD_TYPE_INTEGER}</li>
-     *   <li>{@link Cursor#FIELD_TYPE_FLOAT}</li>
-     *   <li>{@link Cursor#FIELD_TYPE_STRING}</li>
-     *   <li>{@link Cursor#FIELD_TYPE_BLOB}</li>
-     *</ul>
-     *</p>
-     *
-     * @param row the row to read from, row - getStartPosition() being the actual row in the window
-     * @param col the column to read from
-     * @return the value type
-     */
-    public int getType(int row, int col) {
-        acquireReference();
-        try {
-            return getType_native(row - mStartPos, col);
-        } finally {
-            releaseReference();
-        }
-    }
-
-    /**
-     * Checks if a field contains either a blob or is null.
-     *
-     * @param row the row to read from, row - getStartPosition() being the actual row in the window
-     * @param col the column to read from
-     * @return {@code true} if given field is {@code NULL} or a blob
-     * @deprecated use {@link #getType(int, int)} instead
+     * @param row The zero-based row index, relative to the cursor window's
+     * start position ({@link #getStartPosition()}).
+     * @param column The zero-based column index.
+     * @return True if the field has type {@link Cursor#FIELD_TYPE_BLOB} or
+     * {@link Cursor#FIELD_TYPE_NULL}.
+     * @deprecated Use {@link #getType(int, int)} instead.
      */
     @Deprecated
-    public boolean isBlob(int row, int col) {
-        int type = getType(row, col);
+    public boolean isBlob(int row, int column) {
+        int type = getType(row, column);
         return type == Cursor.FIELD_TYPE_BLOB || type == Cursor.FIELD_TYPE_NULL;
     }
 
     /**
-     * Checks if a field contains a long
+     * Returns true if the field at the specified row and column index
+     * has type {@link Cursor#FIELD_TYPE_INTEGER}.
      *
-     * @param row the row to read from, row - getStartPosition() being the actual row in the window
-     * @param col the column to read from
-     * @return {@code true} if given field is a long
-     * @deprecated use {@link #getType(int, int)} instead
+     * @param row The zero-based row index, relative to the cursor window's
+     * start position ({@link #getStartPosition()}).
+     * @param column The zero-based column index.
+     * @return True if the field has type {@link Cursor#FIELD_TYPE_INTEGER}.
+     * @deprecated Use {@link #getType(int, int)} instead.
      */
     @Deprecated
-    public boolean isLong(int row, int col) {
-        return getType(row, col) == Cursor.FIELD_TYPE_INTEGER;
+    public boolean isLong(int row, int column) {
+        return getType(row, column) == Cursor.FIELD_TYPE_INTEGER;
     }
 
     /**
-     * Checks if a field contains a float.
+     * Returns true if the field at the specified row and column index
+     * has type {@link Cursor#FIELD_TYPE_FLOAT}.
      *
-     * @param row the row to read from, row - getStartPosition() being the actual row in the window
-     * @param col the column to read from
-     * @return {@code true} if given field is a float
-     * @deprecated use {@link #getType(int, int)} instead
+     * @param row The zero-based row index, relative to the cursor window's
+     * start position ({@link #getStartPosition()}).
+     * @param column The zero-based column index.
+     * @return True if the field has type {@link Cursor#FIELD_TYPE_FLOAT}.
+     * @deprecated Use {@link #getType(int, int)} instead.
      */
     @Deprecated
-    public boolean isFloat(int row, int col) {
-        return getType(row, col) == Cursor.FIELD_TYPE_FLOAT;
+    public boolean isFloat(int row, int column) {
+        return getType(row, column) == Cursor.FIELD_TYPE_FLOAT;
     }
 
     /**
-     * Checks if a field contains either a String or is null.
+     * Returns true if the field at the specified row and column index
+     * has type {@link Cursor#FIELD_TYPE_STRING} or {@link Cursor#FIELD_TYPE_NULL}.
      *
-     * @param row the row to read from, row - getStartPosition() being the actual row in the window
-     * @param col the column to read from
-     * @return {@code true} if given field is {@code NULL} or a String
-     * @deprecated use {@link #getType(int, int)} instead
+     * @param row The zero-based row index, relative to the cursor window's
+     * start position ({@link #getStartPosition()}).
+     * @param column The zero-based column index.
+     * @return True if the field has type {@link Cursor#FIELD_TYPE_STRING}
+     * or {@link Cursor#FIELD_TYPE_NULL}.
+     * @deprecated Use {@link #getType(int, int)} instead.
      */
     @Deprecated
-    public boolean isString(int row, int col) {
-        int type = getType(row, col);
+    public boolean isString(int row, int column) {
+        int type = getType(row, column);
         return type == Cursor.FIELD_TYPE_STRING || type == Cursor.FIELD_TYPE_NULL;
     }
 
-    private native int getType_native(int row, int col);
-
     /**
-     * Returns a String for the given field.
-     * 
-     * @param row the row to read from, row - getStartPosition() being the actual row in the window 
-     * @param col the column to read from
-     * @return a String value for the given field
+     * Returns the type of the field at the specified row and column index.
+     * <p>
+     * The returned field types are:
+     * <ul>
+     * <li>{@link Cursor#FIELD_TYPE_NULL}</li>
+     * <li>{@link Cursor#FIELD_TYPE_INTEGER}</li>
+     * <li>{@link Cursor#FIELD_TYPE_FLOAT}</li>
+     * <li>{@link Cursor#FIELD_TYPE_STRING}</li>
+     * <li>{@link Cursor#FIELD_TYPE_BLOB}</li>
+     * </ul>
+     * </p>
+     *
+     * @param row The zero-based row index, relative to the cursor window's
+     * start position ({@link #getStartPosition()}).
+     * @param column The zero-based column index.
+     * @return The field type.
      */
-    public String getString(int row, int col) {
+    public int getType(int row, int column) {
         acquireReference();
         try {
-            return getString_native(row - mStartPos, col);
+            return nativeGetType(mWindowPtr, row - mStartPos, column);
         } finally {
             releaseReference();
         }
     }
-    
-    /**
-     * Returns the value at (<code>row</code>, <code>col</code>) as a <code>String</code>.
-     *
-     * <p>If the value is null, then <code>null</code> is returned. If the
-     * type of column <code>col</code> is integral, then the result is the string
-     * that is obtained by formatting the integer value with the <code>printf</code>
-     * family of functions using format specifier <code>%lld</code>. If the
-     * type of column <code>col</code> is floating-point, then the result is the string
-     * that is obtained by formatting the floating-point value with the
-     * <code>printf</code> family of functions using format specifier <code>%g</code>.
-     * If the type of column <code>col</code> is a blob type, then an
-     * {@link SQLiteException} is thrown.
-     */
-    private native String getString_native(int row, int col);
 
     /**
-     * copy the text for the given field in the provided char array.
-     * 
-     * @param row the row to read from, row - getStartPosition() being the actual row in the window 
-     * @param col the column to read from
-     * @param buffer the CharArrayBuffer to copy the text into,      
-     * If the requested string is larger than the buffer 
-     * a new char buffer will be created to hold the string. and assigne to
-     * CharArrayBuffer.data
+     * Gets the value of the field at the specified row and column index as a byte array.
+     * <p>
+     * The result is determined as follows:
+     * <ul>
+     * <li>If the field is of type {@link Cursor#FIELD_TYPE_NULL}, then the result
+     * is <code>null</code>.</li>
+     * <li>If the field is of type {@link Cursor#FIELD_TYPE_BLOB}, then the result
+     * is the blob value.</li>
+     * <li>If the field is of type {@link Cursor#FIELD_TYPE_STRING}, then the result
+     * is the array of bytes that make up the internal representation of the
+     * string value.</li>
+     * <li>If the field is of type {@link Cursor#FIELD_TYPE_INTEGER} or
+     * {@link Cursor#FIELD_TYPE_FLOAT}, then a {@link SQLiteException} is thrown.</li>
+     * </ul>
+     * </p>
+     *
+     * @param row The zero-based row index, relative to the cursor window's
+     * start position ({@link #getStartPosition()}).
+     * @param column The zero-based column index.
+     * @return The value of the field as a byte array.
+     */
+    public byte[] getBlob(int row, int column) {
+        acquireReference();
+        try {
+            return nativeGetBlob(mWindowPtr, row - mStartPos, column);
+        } finally {
+            releaseReference();
+        }
+    }
+
+    /**
+     * Gets the value of the field at the specified row and column index as a string.
+     * <p>
+     * The result is determined as follows:
+     * <ul>
+     * <li>If the field is of type {@link Cursor#FIELD_TYPE_NULL}, then the result
+     * is <code>null</code>.</li>
+     * <li>If the field is of type {@link Cursor#FIELD_TYPE_STRING}, then the result
+     * is the string value.</li>
+     * <li>If the field is of type {@link Cursor#FIELD_TYPE_INTEGER}, then the result
+     * is a string representation of the integer in decimal, obtained by formatting the
+     * value with the <code>printf</code> family of functions using
+     * format specifier <code>%lld</code>.</li>
+     * <li>If the field is of type {@link Cursor#FIELD_TYPE_FLOAT}, then the result
+     * is a string representation of the floating-point value in decimal, obtained by
+     * formatting the value with the <code>printf</code> family of functions using
+     * format specifier <code>%g</code>.</li>
+     * <li>If the field is of type {@link Cursor#FIELD_TYPE_BLOB}, then a
+     * {@link SQLiteException} is thrown.</li>
+     * </ul>
+     * </p>
+     *
+     * @param row The zero-based row index, relative to the cursor window's
+     * start position ({@link #getStartPosition()}).
+     * @param column The zero-based column index.
+     * @return The value of the field as a string.
+     */
+    public String getString(int row, int column) {
+        acquireReference();
+        try {
+            return nativeGetString(mWindowPtr, row - mStartPos, column);
+        } finally {
+            releaseReference();
+        }
+    }
+
+    /**
+     * Copies the text of the field at the specified row and column index into
+     * a {@link CharArrayBuffer}.
+     * <p>
+     * The buffer is populated as follows:
+     * <ul>
+     * <li>If the buffer is too small for the value to be copied, then it is
+     * automatically resized.</li>
+     * <li>If the field is of type {@link Cursor#FIELD_TYPE_NULL}, then the buffer
+     * is set to an empty string.</li>
+     * <li>If the field is of type {@link Cursor#FIELD_TYPE_STRING}, then the buffer
+     * is set to the contents of the string.</li>
+     * <li>If the field is of type {@link Cursor#FIELD_TYPE_INTEGER}, then the buffer
+     * is set to a string representation of the integer in decimal, obtained by formatting the
+     * value with the <code>printf</code> family of functions using
+     * format specifier <code>%lld</code>.</li>
+     * <li>If the field is of type {@link Cursor#FIELD_TYPE_FLOAT}, then the buffer is
+     * set to a string representation of the floating-point value in decimal, obtained by
+     * formatting the value with the <code>printf</code> family of functions using
+     * format specifier <code>%g</code>.</li>
+     * <li>If the field is of type {@link Cursor#FIELD_TYPE_BLOB}, then a
+     * {@link SQLiteException} is thrown.</li>
+     * </ul>
+     * </p>
+     *
+     * @param row The zero-based row index, relative to the cursor window's
+     * start position ({@link #getStartPosition()}).
+     * @param column The zero-based column index.
+     * @param buffer The {@link CharArrayBuffer} to hold the string.  It is automatically
+     * resized if the requested string is larger than the buffer's current capacity.
       */
-    public void copyStringToBuffer(int row, int col, CharArrayBuffer buffer) {
+    public void copyStringToBuffer(int row, int column, CharArrayBuffer buffer) {
         if (buffer == null) {
             throw new IllegalArgumentException("CharArrayBuffer should not be null");
         }
-        if (buffer.data == null) {
-            buffer.data = new char[64];
-        }
         acquireReference();
         try {
-            char[] newbuf = copyStringToBuffer_native(
-                    row - mStartPos, col, buffer.data.length, buffer);
-            if (newbuf != null) {
-                buffer.data = newbuf;
-            }
+            nativeCopyStringToBuffer(mWindowPtr, row, column, buffer);
         } finally {
             releaseReference();
         }
     }
-    
-    private native char[] copyStringToBuffer_native(
-            int row, int col, int bufferSize, CharArrayBuffer buffer);
-    
+
     /**
-     * Returns a long for the given field.
-     * row is 0 based
-     * 
-     * @param row the row to read from, row - getStartPosition() being the actual row in the window 
-     * @param col the column to read from
-     * @return a long value for the given field
-     */
-    public long getLong(int row, int col) {
-        acquireReference();
-        try {
-            return getLong_native(row - mStartPos, col);
-        } finally {
-            releaseReference();
-        }
-    }
-    
-    /**
-     * Returns the value at (<code>row</code>, <code>col</code>) as a <code>long</code>.
+     * Gets the value of the field at the specified row and column index as a <code>long</code>.
+     * <p>
+     * The result is determined as follows:
+     * <ul>
+     * <li>If the field is of type {@link Cursor#FIELD_TYPE_NULL}, then the result
+     * is <code>0L</code>.</li>
+     * <li>If the field is of type {@link Cursor#FIELD_TYPE_STRING}, then the result
+     * is the value obtained by parsing the string value with <code>strtoll</code>.
+     * <li>If the field is of type {@link Cursor#FIELD_TYPE_INTEGER}, then the result
+     * is the <code>long</code> value.</li>
+     * <li>If the field is of type {@link Cursor#FIELD_TYPE_FLOAT}, then the result
+     * is the floating-point value converted to a <code>long</code>.</li>
+     * <li>If the field is of type {@link Cursor#FIELD_TYPE_BLOB}, then a
+     * {@link SQLiteException} is thrown.</li>
+     * </ul>
+     * </p>
      *
-     * <p>If the value is null, then <code>0L</code> is returned. If the
-     * type of column <code>col</code> is a string type, then the result
-     * is the <code>long</code> that is obtained by parsing the string value with
-     * <code>strtoll</code>. If the type of column <code>col</code> is
-     * floating-point, then the result is the floating-point value casted to a <code>long</code>.
-     * If the type of column <code>col</code> is a blob type, then an
-     * {@link SQLiteException} is thrown.
+     * @param row The zero-based row index, relative to the cursor window's
+     * start position ({@link #getStartPosition()}).
+     * @param column The zero-based column index.
+     * @return The value of the field as a <code>long</code>.
      */
-    private native long getLong_native(int row, int col);
-
-    /**
-     * Returns a double for the given field.
-     * row is 0 based
-     * 
-     * @param row the row to read from, row - getStartPosition() being the actual row in the window 
-     * @param col the column to read from
-     * @return a double value for the given field
-     */
-    public double getDouble(int row, int col) {
+    public long getLong(int row, int column) {
         acquireReference();
         try {
-            return getDouble_native(row - mStartPos, col);
+            return nativeGetLong(mWindowPtr, row - mStartPos, column);
         } finally {
             releaseReference();
         }
     }
-    
+
     /**
-     * Returns the value at (<code>row</code>, <code>col</code>) as a <code>double</code>.
+     * Gets the value of the field at the specified row and column index as a
+     * <code>double</code>.
+     * <p>
+     * The result is determined as follows:
+     * <ul>
+     * <li>If the field is of type {@link Cursor#FIELD_TYPE_NULL}, then the result
+     * is <code>0.0</code>.</li>
+     * <li>If the field is of type {@link Cursor#FIELD_TYPE_STRING}, then the result
+     * is the value obtained by parsing the string value with <code>strtod</code>.
+     * <li>If the field is of type {@link Cursor#FIELD_TYPE_INTEGER}, then the result
+     * is the integer value converted to a <code>double</code>.</li>
+     * <li>If the field is of type {@link Cursor#FIELD_TYPE_FLOAT}, then the result
+     * is the <code>double</code> value.</li>
+     * <li>If the field is of type {@link Cursor#FIELD_TYPE_BLOB}, then a
+     * {@link SQLiteException} is thrown.</li>
+     * </ul>
+     * </p>
      *
-     * <p>If the value is null, then <code>0.0</code> is returned. If the
-     * type of column <code>col</code> is a string type, then the result
-     * is the <code>double</code> that is obtained by parsing the string value with
-     * <code>strtod</code>. If the type of column <code>col</code> is
-     * integral, then the result is the integer value casted to a <code>double</code>.
-     * If the type of column <code>col</code> is a blob type, then an
-     * {@link SQLiteException} is thrown.
+     * @param row The zero-based row index, relative to the cursor window's
+     * start position ({@link #getStartPosition()}).
+     * @param column The zero-based column index.
+     * @return The value of the field as a <code>double</code>.
      */
-    private native double getDouble_native(int row, int col);
-
-    /**
-     * Returns a short for the given field.
-     * row is 0 based
-     * 
-     * @param row the row to read from, row - getStartPosition() being the actual row in the window 
-     * @param col the column to read from
-     * @return a short value for the given field
-     */
-    public short getShort(int row, int col) {
+    public double getDouble(int row, int column) {
         acquireReference();
         try {
-            return (short) getLong_native(row - mStartPos, col);
+            return nativeGetDouble(mWindowPtr, row - mStartPos, column);
         } finally {
             releaseReference();
         }
     }
 
     /**
-     * Returns an int for the given field.
-     * 
-     * @param row the row to read from, row - getStartPosition() being the actual row in the window 
-     * @param col the column to read from
-     * @return an int value for the given field
+     * Gets the value of the field at the specified row and column index as a
+     * <code>short</code>.
+     * <p>
+     * The result is determined by invoking {@link #getLong} and converting the
+     * result to <code>short</code>.
+     * </p>
+     *
+     * @param row The zero-based row index, relative to the cursor window's
+     * start position ({@link #getStartPosition()}).
+     * @param column The zero-based column index.
+     * @return The value of the field as a <code>short</code>.
      */
-    public int getInt(int row, int col) {
-        acquireReference();
-        try {
-            return (int) getLong_native(row - mStartPos, col);
-        } finally {
-            releaseReference();
-        }
+    public short getShort(int row, int column) {
+        return (short) getLong(row, column);
     }
-    
+
     /**
-     * Returns a float for the given field.
-     * row is 0 based
-     * 
-     * @param row the row to read from, row - getStartPosition() being the actual row in the window 
-     * @param col the column to read from
-     * @return a float value for the given field
+     * Gets the value of the field at the specified row and column index as an
+     * <code>int</code>.
+     * <p>
+     * The result is determined by invoking {@link #getLong} and converting the
+     * result to <code>int</code>.
+     * </p>
+     *
+     * @param row The zero-based row index, relative to the cursor window's
+     * start position ({@link #getStartPosition()}).
+     * @param column The zero-based column index.
+     * @return The value of the field as an <code>int</code>.
      */
-    public float getFloat(int row, int col) {
+    public int getInt(int row, int column) {
+        return (int) getLong(row, column);
+    }
+
+    /**
+     * Gets the value of the field at the specified row and column index as a
+     * <code>float</code>.
+     * <p>
+     * The result is determined by invoking {@link #getDouble} and converting the
+     * result to <code>float</code>.
+     * </p>
+     *
+     * @param row The zero-based row index, relative to the cursor window's
+     * start position ({@link #getStartPosition()}).
+     * @param column The zero-based column index.
+     * @return The value of the field as an <code>float</code>.
+     */
+    public float getFloat(int row, int column) {
+        return (float) getDouble(row, column);
+    }
+
+    /**
+     * Copies a byte array into the field at the specified row and column index.
+     *
+     * @param value The value to store.
+     * @param row The zero-based row index, relative to the cursor window's
+     * start position ({@link #getStartPosition()}).
+     * @param column The zero-based column index.
+     * @return True if successful.
+     */
+    public boolean putBlob(byte[] value, int row, int column) {
         acquireReference();
         try {
-            return (float) getDouble_native(row - mStartPos, col);
-        } finally {
-            releaseReference();
-        }
-    } 
-    
-    /**
-     * Clears out the existing contents of the window, making it safe to reuse
-     * for new data. Note that the number of columns in the window may NOT
-     * change across a call to clear().
-     */
-    public void clear() {
-        acquireReference();
-        try {
-            mStartPos = 0;        
-            native_clear();
+            return nativePutBlob(mWindowPtr, value, row - mStartPos, column);
         } finally {
             releaseReference();
         }
     }
 
-    /** Clears out the native side of things */
-    private native void native_clear();
+    /**
+     * Copies a string into the field at the specified row and column index.
+     *
+     * @param value The value to store.
+     * @param row The zero-based row index, relative to the cursor window's
+     * start position ({@link #getStartPosition()}).
+     * @param column The zero-based column index.
+     * @return True if successful.
+     */
+    public boolean putString(String value, int row, int column) {
+        acquireReference();
+        try {
+            return nativePutString(mWindowPtr, value, row - mStartPos, column);
+        } finally {
+            releaseReference();
+        }
+    }
 
     /**
-     * Cleans up the native resources associated with the window.
+     * Puts a long integer into the field at the specified row and column index.
+     *
+     * @param value The value to store.
+     * @param row The zero-based row index, relative to the cursor window's
+     * start position ({@link #getStartPosition()}).
+     * @param column The zero-based column index.
+     * @return True if successful.
      */
-    public void close() {
-        releaseReference();
-    }
-    
-    private native void close_native();
-
-    @Override
-    protected void finalize() {
-        if (nWindow == 0) {
-            return;
+    public boolean putLong(long value, int row, int column) {
+        acquireReference();
+        try {
+            return nativePutLong(mWindowPtr, value, row - mStartPos, column);
+        } finally {
+            releaseReference();
         }
-        // due to bugs 3329504, 3502276, cursorwindow sometimes is closed in fialize()
-        // don't print any warning saying "don't release cursor in finzlize"
-        // because it is a bug in framework code - NOT an app bug.
-        recordClosingOfWindow(nWindow);
-        close_native();
     }
-    
+
+    /**
+     * Puts a double-precision floating point value into the field at the
+     * specified row and column index.
+     *
+     * @param value The value to store.
+     * @param row The zero-based row index, relative to the cursor window's
+     * start position ({@link #getStartPosition()}).
+     * @param column The zero-based column index.
+     * @return True if successful.
+     */
+    public boolean putDouble(double value, int row, int column) {
+        acquireReference();
+        try {
+            return nativePutDouble(mWindowPtr, value, row - mStartPos, column);
+        } finally {
+            releaseReference();
+        }
+    }
+
+    /**
+     * Puts a null value into the field at the specified row and column index.
+     *
+     * @param row The zero-based row index, relative to the cursor window's
+     * start position ({@link #getStartPosition()}).
+     * @param column The zero-based column index.
+     * @return True if successful.
+     */
+    public boolean putNull(int row, int column) {
+        acquireReference();
+        try {
+            return nativePutNull(mWindowPtr, row - mStartPos, column);
+        } finally {
+            releaseReference();
+        }
+    }
+
     public static final Parcelable.Creator<CursorWindow> CREATOR
             = new Parcelable.Creator<CursorWindow>() {
         public CursorWindow createFromParcel(Parcel source) {
@@ -591,30 +667,13 @@
     }
 
     public void writeToParcel(Parcel dest, int flags) {
-        dest.writeStrongBinder(native_getBinder());
+        dest.writeStrongBinder(nativeGetBinder(mWindowPtr));
         dest.writeInt(mStartPos);
     }
 
-    private CursorWindow(Parcel source) {
-        IBinder nativeBinder = source.readStrongBinder();
-        mStartPos = source.readInt();
-        int rslt = native_init(nativeBinder);
-        printDebugMsgIfError(rslt);
-    }
-
-    /** Get the binder for the native side of the window */
-    private native IBinder native_getBinder();
-
-    /** Does the native side initialization for an empty window */
-    private native int native_init(int cursorWindowSize, boolean localOnly);
-
-    /** Does the native side initialization with an existing binder from another process */
-    private native int native_init(IBinder nativeBinder);
-
     @Override
     protected void onAllReferencesReleased() {
-        recordClosingOfWindow(nWindow);
-        close_native();
+        dispose();
     }
 
     private static final SparseIntArray sWindowToPidMap = new SparseIntArray();
@@ -637,6 +696,7 @@
             sWindowToPidMap.delete(window);
         }
     }
+
     private String printStats() {
         StringBuilder buff = new StringBuilder();
         int myPid = Process.myPid();
diff --git a/core/java/android/database/CursorWindowAllocationException.java b/core/java/android/database/CursorWindowAllocationException.java
index ba7df68..2e3227d 100644
--- a/core/java/android/database/CursorWindowAllocationException.java
+++ b/core/java/android/database/CursorWindowAllocationException.java
@@ -18,17 +18,12 @@
 
 /**
  * This exception is thrown when a CursorWindow couldn't be allocated,
- * most probably due to memory not being available
+ * most probably due to memory not being available.
+ *
+ * @hide
  */
-class CursorWindowAllocationException extends java.lang.RuntimeException
-{
-    public CursorWindowAllocationException()
-    {
-        super();
-    }
-
-    public CursorWindowAllocationException(String description)
-    {
+public class CursorWindowAllocationException extends RuntimeException {
+    public CursorWindowAllocationException(String description) {
         super(description);
     }
 }
diff --git a/core/java/android/database/sqlite/SQLiteQuery.java b/core/java/android/database/sqlite/SQLiteQuery.java
index dc882d9..06a41b2 100644
--- a/core/java/android/database/sqlite/SQLiteQuery.java
+++ b/core/java/android/database/sqlite/SQLiteQuery.java
@@ -79,7 +79,7 @@
                 // if the start pos is not equal to 0, then most likely window is
                 // too small for the data set, loading by another thread
                 // is not safe in this situation. the native code will ignore maxRead
-                int numRows = native_fill_window(window, window.getStartPosition(),
+                int numRows = native_fill_window(window.mWindowPtr, window.getStartPosition(),
                         mOffsetIndex, maxRead, lastPos);
                 mDatabase.logTimeStat(mSql, timeStart);
                 return numRows;
@@ -154,7 +154,7 @@
         compileAndbindAllArgs();
     }
 
-    private final native int native_fill_window(CursorWindow window,
+    private final native int native_fill_window(int windowPtr,
             int startPos, int offsetParam, int maxRead, int lastPos);
 
     private final native int native_column_count();
diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java
index c3a14ca..d65e6df 100644
--- a/core/java/android/hardware/Camera.java
+++ b/core/java/android/hardware/Camera.java
@@ -1007,6 +1007,10 @@
      *     camera.setDisplayOrientation(result);
      * }
      * </pre>
+     *
+     * <p>Starting from API level 14, this method can be called when preview is
+     * active.
+     *
      * @param degrees the angle that the picture will be rotated clockwise.
      *                Valid values are 0, 90, 180, and 270. The starting
      *                position is 0 (landscape).
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index e2d5af0..0052dd0 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -515,7 +515,7 @@
      * All applications that have background services that use the network
      * should listen to {@link #ACTION_BACKGROUND_DATA_SETTING_CHANGED}.
      * <p>
-     * As of {@link VERSION_CODES#ICE_CREAM_SANDWICH}, availability of
+     * @deprecated As of {@link VERSION_CODES#ICE_CREAM_SANDWICH}, availability of
      * background data depends on several combined factors, and this method will
      * always return {@code true}. Instead, when background data is unavailable,
      * {@link #getActiveNetworkInfo()} will now appear disconnected.
diff --git a/core/java/android/provider/Telephony.java b/core/java/android/provider/Telephony.java
index 237a892..79995d0 100755
--- a/core/java/android/provider/Telephony.java
+++ b/core/java/android/provider/Telephony.java
@@ -666,6 +666,7 @@
             public static SmsMessage[] getMessagesFromIntent(
                     Intent intent) {
                 Object[] messages = (Object[]) intent.getSerializableExtra("pdus");
+                String format = intent.getStringExtra("format");
                 byte[][] pduObjs = new byte[messages.length][];
 
                 for (int i = 0; i < messages.length; i++) {
@@ -676,7 +677,7 @@
                 SmsMessage[] msgs = new SmsMessage[pduCount];
                 for (int i = 0; i < pduCount; i++) {
                     pdus[i] = pduObjs[i];
-                    msgs[i] = SmsMessage.createFromPdu(pdus[i]);
+                    msgs[i] = SmsMessage.createFromPdu(pdus[i], format);
                 }
                 return msgs;
             }
diff --git a/core/java/android/server/BluetoothHealthProfileHandler.java b/core/java/android/server/BluetoothHealthProfileHandler.java
index 2961fd2..5e93b81 100644
--- a/core/java/android/server/BluetoothHealthProfileHandler.java
+++ b/core/java/android/server/BluetoothHealthProfileHandler.java
@@ -45,8 +45,7 @@
  */
 final class BluetoothHealthProfileHandler {
     private static final String TAG = "BluetoothHealthProfileHandler";
-    /*STOPSHIP*/
-    private static final boolean DBG = true;
+    private static final boolean DBG = false;
 
     private static BluetoothHealthProfileHandler sInstance;
     private BluetoothService mBluetoothService;
diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java
index 713bb91..ba94ab2 100644
--- a/core/java/android/service/wallpaper/WallpaperService.java
+++ b/core/java/android/service/wallpaper/WallpaperService.java
@@ -565,7 +565,7 @@
                         mLayout.windowAnimations =
                                 com.android.internal.R.style.Animation_Wallpaper;
                         mInputChannel = new InputChannel();
-                        if (mSession.add(mWindow, mLayout, View.VISIBLE, mContentInsets,
+                        if (mSession.add(mWindow, mWindow.mSeq, mLayout, View.VISIBLE, mContentInsets,
                                 mInputChannel) < 0) {
                             Log.w(TAG, "Failed to add window while updating wallpaper surface.");
                             return;
@@ -580,7 +580,7 @@
                     mDrawingAllowed = true;
 
                     final int relayoutResult = mSession.relayout(
-                        mWindow, mLayout, mWidth, mHeight,
+                        mWindow, mWindow.mSeq, mLayout, mWidth, mHeight,
                             View.VISIBLE, false, mWinFrame, mContentInsets,
                             mVisibleInsets, mConfiguration, mSurfaceHolder.mSurface);
 
diff --git a/core/java/android/view/IWindow.aidl b/core/java/android/view/IWindow.aidl
index 0e482d6..715fa7b 100644
--- a/core/java/android/view/IWindow.aidl
+++ b/core/java/android/view/IWindow.aidl
@@ -74,5 +74,6 @@
     /**
      * System chrome visibility changes
      */
-     void dispatchSystemUiVisibilityChanged(int visibility);
+     void dispatchSystemUiVisibilityChanged(int seq, int globalVisibility,
+            int localValue, int localChanges);
 }
diff --git a/core/java/android/view/IWindowSession.aidl b/core/java/android/view/IWindowSession.aidl
index 990af083..282d7be 100644
--- a/core/java/android/view/IWindowSession.aidl
+++ b/core/java/android/view/IWindowSession.aidl
@@ -34,10 +34,10 @@
  * {@hide}
  */
 interface IWindowSession {
-    int add(IWindow window, in WindowManager.LayoutParams attrs,
+    int add(IWindow window, int seq, in WindowManager.LayoutParams attrs,
             in int viewVisibility, out Rect outContentInsets,
             out InputChannel outInputChannel);
-    int addWithoutInputChannel(IWindow window, in WindowManager.LayoutParams attrs,
+    int addWithoutInputChannel(IWindow window, int seq, in WindowManager.LayoutParams attrs,
             in int viewVisibility, out Rect outContentInsets);
     void remove(IWindow window);
     
@@ -49,6 +49,7 @@
      * to draw the window's contents.
      * 
      * @param window The window being modified.
+     * @param seq Ordering sequence number.
      * @param attrs If non-null, new attributes to apply to the window.
      * @param requestedWidth The width the window wants to be.
      * @param requestedHeight The height the window wants to be.
@@ -77,7 +78,7 @@
      * @return int Result flags: {@link WindowManagerImpl#RELAYOUT_SHOW_FOCUS},
      * {@link WindowManagerImpl#RELAYOUT_FIRST_TIME}.
      */
-    int relayout(IWindow window, in WindowManager.LayoutParams attrs,
+    int relayout(IWindow window, int seq, in WindowManager.LayoutParams attrs,
             int requestedWidth, int requestedHeight, int viewVisibility,
             boolean insetsPending, out Rect outFrame, out Rect outContentInsets,
             out Rect outVisibleInsets, out Configuration outConfig,
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index cbdb38e..9a57ea0 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -266,7 +266,7 @@
             try {
                 DisplayMetrics metrics = getResources().getDisplayMetrics();
                 mLayout.x = metrics.widthPixels * 3;
-                mSession.relayout(mWindow, mLayout, mWidth, mHeight, VISIBLE, false,
+                mSession.relayout(mWindow, mWindow.mSeq, mLayout, mWidth, mHeight, VISIBLE, false,
                         mWinFrame, mContentInsets, mVisibleInsets, mConfiguration, mSurface);
             } catch (RemoteException e) {
                 // Ignore
@@ -492,7 +492,7 @@
                     mWindow = new MyWindow(this);
                     mLayout.type = mWindowType;
                     mLayout.gravity = Gravity.LEFT|Gravity.TOP;
-                    mSession.addWithoutInputChannel(mWindow, mLayout,
+                    mSession.addWithoutInputChannel(mWindow, mWindow.mSeq, mLayout,
                             mVisible ? VISIBLE : GONE, mContentInsets);
                 }
                 
@@ -513,7 +513,7 @@
                     mDrawingStopped = !visible;
     
                     final int relayoutResult = mSession.relayout(
-                        mWindow, mLayout, mWidth, mHeight,
+                        mWindow, mWindow.mSeq, mLayout, mWidth, mHeight,
                             visible ? VISIBLE : GONE, false, mWinFrame, mContentInsets,
                             mVisibleInsets, mConfiguration, mSurface);
                     if ((relayoutResult&WindowManagerImpl.RELAYOUT_FIRST_TIME) != 0) {
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 8e5aefd..15544cc 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -1925,6 +1925,15 @@
     public static final int PUBLIC_STATUS_BAR_VISIBILITY_MASK = 0x0000FFFF;
 
     /**
+     * These are the system UI flags that can be cleared by events outside
+     * of an application.  Currently this is just the ability to tap on the
+     * screen while hiding the navigation bar to have it return.
+     * @hide
+     */
+    public static final int SYSTEM_UI_CLEARABLE_FLAGS =
+            SYSTEM_UI_FLAG_LOW_PROFILE | SYSTEM_UI_FLAG_HIDE_NAVIGATION;
+
+    /**
      * Find views that render the specified text.
      *
      * @see #findViewsWithText(ArrayList, CharSequence, int)
@@ -3335,7 +3344,9 @@
         if (mOnLayoutChangeListeners == null) {
             mOnLayoutChangeListeners = new ArrayList<OnLayoutChangeListener>();
         }
-        mOnLayoutChangeListeners.add(listener);
+        if (!mOnLayoutChangeListeners.contains(listener)) {
+            mOnLayoutChangeListeners.add(listener);
+        }
     }
 
     /**
@@ -4001,23 +4012,13 @@
         event.setEnabled(isEnabled());
         event.setContentDescription(mContentDescription);
 
-        final int eventType = event.getEventType();
-        switch (eventType) {
-            case AccessibilityEvent.TYPE_VIEW_FOCUSED: {
-                if (mAttachInfo != null) {
-                    ArrayList<View> focusablesTempList = mAttachInfo.mFocusablesTempList;
-                    getRootView().addFocusables(focusablesTempList, View.FOCUS_FORWARD,
-                            FOCUSABLES_ALL);
-                    event.setItemCount(focusablesTempList.size());
-                    event.setCurrentItemIndex(focusablesTempList.indexOf(this));
-                    focusablesTempList.clear();
-                }
-            } break;
-            case AccessibilityEvent.TYPE_VIEW_SCROLLED: {
-                event.setScrollX(mScrollX);
-                event.setScrollY(mScrollY);
-                event.setItemCount(getHeight());
-            } break;
+        if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_FOCUSED && mAttachInfo != null) {
+            ArrayList<View> focusablesTempList = mAttachInfo.mFocusablesTempList;
+            getRootView().addFocusables(focusablesTempList, View.FOCUS_FORWARD,
+                    FOCUSABLES_ALL);
+            event.setItemCount(focusablesTempList.size());
+            event.setCurrentItemIndex(focusablesTempList.indexOf(this));
+            focusablesTempList.clear();
         }
     }
 
@@ -13027,6 +13028,8 @@
     }
 
     /**
+     * Dispatch callbacks to {@link #setOnSystemUiVisibilityChangeListener} down
+     * the view hierarchy.
      */
     public void dispatchSystemUiVisibilityChanged(int visibility) {
         if (mOnSystemUiVisibilityChangeListener != null) {
@@ -13035,6 +13038,13 @@
         }
     }
 
+    void updateLocalSystemUiVisibility(int localValue, int localChanges) {
+        int val = (mSystemUiVisibility&~localChanges) | (localValue&localChanges);
+        if (val != mSystemUiVisibility) {
+            setSystemUiVisibility(val);
+        }
+    }
+
     /**
      * Creates an image that the system displays during the drag and drop
      * operation. This is called a &quot;drag shadow&quot;. The default implementation
@@ -14108,7 +14118,8 @@
 
     /**
      * Interface definition for a callback to be invoked when the status bar changes
-     * visibility.
+     * visibility.  This reports <strong>global</strong> changes to the system UI
+     * state, not just what the application is requesting.
      *
      * @see View#setOnSystemUiVisibilityChangeListener(android.view.View.OnSystemUiVisibilityChangeListener) 
      */
@@ -14118,7 +14129,9 @@
          * {@link View#setSystemUiVisibility(int)}.
          *
          * @param visibility  Bitwise-or of flags {@link #SYSTEM_UI_FLAG_LOW_PROFILE} or
-         * {@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION}.
+         * {@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION}.  This tells you the
+         * <strong>global</strong> state of the UI visibility flags, not what your
+         * app is currently applying.
          */
         public void onSystemUiVisibilityChange(int visibility);
     }
@@ -14376,6 +14389,11 @@
         boolean mRecomputeGlobalAttributes;
 
         /**
+         * Always report new attributes at next traversal.
+         */
+        boolean mForceReportNewAttributes;
+
+        /**
          * Set during a traveral if any views want to keep the screen on.
          */
         boolean mKeepScreenOn;
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 5b4a6f8..9266ae2 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -1200,6 +1200,18 @@
         }
     }
 
+    @Override
+    void updateLocalSystemUiVisibility(int localValue, int localChanges) {
+        super.updateLocalSystemUiVisibility(localValue, localChanges);
+
+        final int count = mChildrenCount;
+        final View[] children = mChildren;
+        for (int i=0; i <count; i++) {
+            final View child = children[i];
+            child.updateLocalSystemUiVisibility(localValue, localChanges);
+        }
+    }
+
     /**
      * {@inheritDoc}
      */
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 615a5f6..7eae739 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -165,6 +165,8 @@
 
     final int mTargetSdkVersion;
 
+    int mSeq;
+
     View mView;
     View mFocusedView;
     View mRealFocusedView;  // this is not set to null in touch mode
@@ -308,6 +310,13 @@
             return sWindowSession;
         }
     }
+
+    static final class SystemUiVisibilityInfo {
+        int seq;
+        int globalVisibility;
+        int localValue;
+        int localChanges;
+    }
     
     public ViewRootImpl(Context context) {
         super();
@@ -465,7 +474,7 @@
                 }
                 try {
                     mOrigWindowType = mWindowAttributes.type;
-                    res = sWindowSession.add(mWindow, mWindowAttributes,
+                    res = sWindowSession.add(mWindow, mSeq, mWindowAttributes,
                             getHostVisibility(), mAttachInfo.mContentInsets,
                             mInputChannel);
                 } catch (RemoteException e) {
@@ -1044,16 +1053,21 @@
             attachInfo.mRecomputeGlobalAttributes = false;
             boolean oldScreenOn = attachInfo.mKeepScreenOn;
             int oldVis = attachInfo.mSystemUiVisibility;
+            boolean oldHasSystemUiListeners = attachInfo.mHasSystemUiListeners;
             attachInfo.mKeepScreenOn = false;
             attachInfo.mSystemUiVisibility = 0;
             attachInfo.mHasSystemUiListeners = false;
             host.dispatchCollectViewAttributes(0);
             if (attachInfo.mKeepScreenOn != oldScreenOn
                     || attachInfo.mSystemUiVisibility != oldVis
-                    || attachInfo.mHasSystemUiListeners) {
+                    || attachInfo.mHasSystemUiListeners != oldHasSystemUiListeners) {
                 params = lp;
             }
         }
+        if (attachInfo.mForceReportNewAttributes) {
+            attachInfo.mForceReportNewAttributes = false;
+            params = lp;
+        }
 
         if (mFirst || attachInfo.mViewVisibilityChanged) {
             attachInfo.mViewVisibilityChanged = false;
@@ -1134,9 +1148,7 @@
                         params.flags |= WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
                     }
                     params.subtreeSystemUiVisibility = attachInfo.mSystemUiVisibility;
-                    params.hasSystemUiListeners = attachInfo.mHasSystemUiListeners
-                            || params.subtreeSystemUiVisibility != 0
-                            || params.systemUiVisibility != 0;
+                    params.hasSystemUiListeners = attachInfo.mHasSystemUiListeners;
                 }
                 if (DEBUG_LAYOUT) {
                     Log.i(TAG, "host=w:" + host.getMeasuredWidth() + ", h:" +
@@ -2545,7 +2557,7 @@
             handleDragEvent(event);
         } break;
         case DISPATCH_SYSTEM_UI_VISIBILITY: {
-            handleDispatchSystemUiVisibilityChanged(msg.arg1);
+            handleDispatchSystemUiVisibilityChanged((SystemUiVisibilityInfo)msg.obj);
         } break;
         case UPDATE_CONFIGURATION: {
             Configuration config = (Configuration)msg.obj;
@@ -3429,12 +3441,27 @@
         event.recycle();
     }
 
-    public void handleDispatchSystemUiVisibilityChanged(int visibility) {
-        if (mView == null) return;
-        if (mAttachInfo != null) {
-            mAttachInfo.mSystemUiVisibility = visibility;
+    public void handleDispatchSystemUiVisibilityChanged(SystemUiVisibilityInfo args) {
+        if (mSeq != args.seq) {
+            // The sequence has changed, so we need to update our value and make
+            // sure to do a traversal afterward so the window manager is given our
+            // most recent data.
+            mSeq = args.seq;
+            mAttachInfo.mForceReportNewAttributes = true;
+            scheduleTraversals();            
         }
-        mView.dispatchSystemUiVisibilityChanged(visibility);
+        if (mView == null) return;
+        if (args.localChanges != 0) {
+            if (mAttachInfo != null) {
+                mAttachInfo.mSystemUiVisibility =
+                        (mAttachInfo.mSystemUiVisibility&~args.localChanges)
+                        | (args.localValue&args.localChanges);
+            }
+            mView.updateLocalSystemUiVisibility(args.localValue, args.localChanges);
+            mAttachInfo.mRecomputeGlobalAttributes = true;
+            scheduleTraversals();            
+        }
+        mView.dispatchSystemUiVisibilityChanged(args.globalVisibility);
     }
 
     public void getLastTouchPoint(Point outLocation) {
@@ -3493,7 +3520,7 @@
             }
         }
         int relayoutResult = sWindowSession.relayout(
-                mWindow, params,
+                mWindow, mSeq, params,
                 (int) (mView.getMeasuredWidth() * appScale + 0.5f),
                 (int) (mView.getMeasuredHeight() * appScale + 0.5f),
                 viewVisibility, insetsPending, mWinFrame,
@@ -3796,8 +3823,14 @@
         sendMessage(msg);
     }
 
-    public void dispatchSystemUiVisibilityChanged(int visibility) {
-        sendMessage(obtainMessage(DISPATCH_SYSTEM_UI_VISIBILITY, visibility, 0));
+    public void dispatchSystemUiVisibilityChanged(int seq, int globalVisibility,
+            int localValue, int localChanges) {
+        SystemUiVisibilityInfo args = new SystemUiVisibilityInfo();
+        args.seq = seq;
+        args.globalVisibility = globalVisibility;
+        args.localValue = localValue;
+        args.localChanges = localChanges;
+        sendMessage(obtainMessage(DISPATCH_SYSTEM_UI_VISIBILITY, args));
     }
 
     /**
@@ -4052,10 +4085,12 @@
             }
         }
 
-        public void dispatchSystemUiVisibilityChanged(int visibility) {
+        public void dispatchSystemUiVisibilityChanged(int seq, int globalVisibility,
+                int localValue, int localChanges) {
             final ViewRootImpl viewAncestor = mViewAncestor.get();
             if (viewAncestor != null) {
-                viewAncestor.dispatchSystemUiVisibilityChanged(visibility);
+                viewAncestor.dispatchSystemUiVisibilityChanged(seq, globalVisibility,
+                        localValue, localChanges);
             }
         }
     }
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
index 4f67675..aaf45e5 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -237,6 +237,12 @@
         public WindowManager.LayoutParams getAttrs();
 
         /**
+         * Retrieve the current system UI visibility flags associated with
+         * this window.
+         */
+        public int getSystemUiVisibility();
+
+        /**
          * Get the layer at which this window's surface will be Z-ordered.
          */
         public int getSurfaceLayer();
diff --git a/core/java/android/view/accessibility/AccessibilityEvent.java b/core/java/android/view/accessibility/AccessibilityEvent.java
index 91fbb0e..25bc559 100644
--- a/core/java/android/view/accessibility/AccessibilityEvent.java
+++ b/core/java/android/view/accessibility/AccessibilityEvent.java
@@ -79,6 +79,16 @@
  *   <li>{@link #isPassword()} - Whether the source is password.</li>
  *   <li>{@link #isChecked()} - Whether the source is checked.</li>
  *   <li>{@link #getContentDescription()} - The content description of the source.</li>
+ *   <li>{@link #getScrollX()} - The offset of the source left edge in pixels
+ *       (without descendants of AdapterView).</li>
+ *   <li>{@link #getScrollY()} - The offset of the source top edge in pixels
+ *       (without descendants of AdapterView).</li>
+ *   <li>{@link #getFromIndex()} - The zero based index of the first visible item of the source,
+ *       inclusive (for descendants of AdapterView).</li>
+ *   <li>{@link #getToIndex()} - The zero based index of the last visible item of the source,
+ *       inclusive (for descendants of AdapterView).</li>
+ *   <li>{@link #getItemCount()} - The total items of the source
+ *       (for descendants of AdapterView).</li>
  * </ul>
  * </p>
  * <p>
@@ -97,6 +107,16 @@
  *   <li>{@link #isPassword()} - Whether the source is password.</li>
  *   <li>{@link #isChecked()} - Whether the source is checked.</li>
  *   <li>{@link #getContentDescription()} - The content description of the source.</li>
+ *   <li>{@link #getScrollX()} - The offset of the source left edge in pixels
+ *       (without descendants of AdapterView).</li>
+ *   <li>{@link #getScrollY()} - The offset of the source top edge in pixels
+ *       (without descendants of AdapterView).</li>
+ *   <li>{@link #getFromIndex()} - The zero based index of the first visible item of the source,
+ *       inclusive (for descendants of AdapterView).</li>
+ *   <li>{@link #getToIndex()} - The zero based index of the last visible item of the source,
+ *       inclusive (for descendants of AdapterView).</li>
+ *   <li>{@link #getItemCount()} - The total items of the source
+ *       (for descendants of AdapterView).</li>
  * </ul>
  * </p>
  * <p>
@@ -117,6 +137,16 @@
  *   <li>{@link #getItemCount()} - The number of selectable items of the source.</li>
  *   <li>{@link #getCurrentItemIndex()} - The currently selected item index.</li>
  *   <li>{@link #getContentDescription()} - The content description of the source.</li>
+ *   <li>{@link #getScrollX()} - The offset of the source left edge in pixels
+ *       (without descendants of AdapterView).</li>
+ *   <li>{@link #getScrollY()} - The offset of the source top edge in pixels
+ *       (without descendants of AdapterView).</li>
+ *   <li>{@link #getFromIndex()} - The zero based index of the first visible item of the source,
+ *       inclusive (for descendants of AdapterView).</li>
+ *   <li>{@link #getToIndex()} - The zero based index of the last visible item of the source,
+ *       inclusive (for descendants of AdapterView).</li>
+ *   <li>{@link #getItemCount()} - The total items of the source
+ *       (for descendants of AdapterView).</li>
  * </ul>
  * </p>
  * <p>
@@ -137,6 +167,16 @@
  *   <li>{@link #getItemCount()} - The number of focusable items on the screen.</li>
  *   <li>{@link #getCurrentItemIndex()} - The currently focused item index.</li>
  *   <li>{@link #getContentDescription()} - The content description of the source.</li>
+ *   <li>{@link #getScrollX()} - The offset of the source left edge in pixels
+ *       (without descendants of AdapterView).</li>
+ *   <li>{@link #getScrollY()} - The offset of the source top edge in pixels
+ *       (without descendants of AdapterView).</li>
+ *   <li>{@link #getFromIndex()} - The zero based index of the first visible item of the source,
+ *       inclusive (for descendants of AdapterView).</li>
+ *   <li>{@link #getToIndex()} - The zero based index of the last visible item of the source,
+ *       inclusive (for descendants of AdapterView).</li>
+ *   <li>{@link #getItemCount()} - The total items of the source
+ *       (for descendants of AdapterView).</li>
  * </ul>
  * </p>
  * <p>
@@ -218,18 +258,17 @@
  *   <li>{@link #getEventTime()}  - The event time.</li>
  *   <li>{@link #getText()} - The text of the source's sub-tree.</li>
  *   <li>{@link #isEnabled()} - Whether the source is enabled.</li>
- *   <li>{@link #getScrollX()} - The horizontal offset of the source
- *                                (without descendants of AdapterView)).</li>
- *   <li>{@link #getScrollY()} - The vertical offset of the source
- *                                (without descendants of AdapterView)).</li>
- *   <li>{@link #getFromIndex()} - The index of the first visible item of the source
- *                                 (for descendants of AdapterView).</li>
- *   <li>{@link #getToIndex()} - The index of the last visible item of the source
- *                               (for descendants of AdapterView).</li>
- *   <li>{@link #getItemCount()} - The total items of the source (for descendants of AdapterView)
- *                                 or the height of the source in pixels (all other cases).</li>
- *   <li>{@link #getText()} - Text for providing more context.</li>
  *   <li>{@link #getContentDescription()} - The content description of the source.</li>
+ *   <li>{@link #getScrollX()} - The offset of the source left edge in pixels
+ *       (without descendants of AdapterView).</li>
+ *   <li>{@link #getScrollY()} - The offset of the source top edge in pixels
+ *       (without descendants of AdapterView).</li>
+ *   <li>{@link #getFromIndex()} - The zero based index of the first visible item of the source,
+ *       inclusive (for descendants of AdapterView).</li>
+ *   <li>{@link #getToIndex()} - The zero based index of the last visible item of the source,
+ *       inclusive (for descendants of AdapterView).</li>
+ *   <li>{@link #getItemCount()} - The total items of the source
+ *       (for descendants of AdapterView).</li>
  * </ul>
  * <em>Note:</em> This event type is not dispatched to descendants though
  * {@link android.view.View#dispatchPopulateAccessibilityEvent(AccessibilityEvent)
@@ -334,6 +373,16 @@
  *   <li>{@link #getText()} - The text of the source's sub-tree.</li>
  *   <li>{@link #isEnabled()} - Whether the source is enabled.</li>
  *   <li>{@link #getContentDescription()} - The content description of the source.</li>
+ *   <li>{@link #getScrollX()} - The offset of the source left edge in pixels
+ *       (without descendants of AdapterView).</li>
+ *   <li>{@link #getScrollY()} - The offset of the source top edge in pixels
+ *       (without descendants of AdapterView).</li>
+ *   <li>{@link #getFromIndex()} - The zero based index of the first visible item of the source,
+ *       inclusive (for descendants of AdapterView).</li>
+ *   <li>{@link #getToIndex()} - The zero based index of the last visible item of the source,
+ *       inclusive (for descendants of AdapterView).</li>
+ *   <li>{@link #getItemCount()} - The total items of the source
+ *       (for descendants of AdapterView).</li>
  * </ul>
  * </p>
  * <b>View hover exit</b> - represents the event of stopping to hover
@@ -350,6 +399,16 @@
  *   <li>{@link #getText()} - The text of the source's sub-tree.</li>
  *   <li>{@link #isEnabled()} - Whether the source is enabled.</li>
  *   <li>{@link #getContentDescription()} - The content description of the source.</li>
+ *   <li>{@link #getScrollX()} - The offset of the source left edge in pixels
+ *       (without descendants of AdapterView).</li>
+ *   <li>{@link #getScrollY()} - The offset of the source top edge in pixels
+ *       (without descendants of AdapterView).</li>
+ *   <li>{@link #getFromIndex()} - The zero based index of the first visible item of the source,
+ *       inclusive (for descendants of AdapterView).</li>
+ *   <li>{@link #getToIndex()} - The zero based index of the last visible item of the source,
+ *       inclusive (for descendants of AdapterView).</li>
+ *   <li>{@link #getItemCount()} - The total items of the source
+ *       (for descendants of AdapterView).</li>
  * </ul>
  * </p>
  * <p>
@@ -816,6 +875,8 @@
         record.mToIndex = parcel.readInt();
         record.mScrollX = parcel.readInt();
         record.mScrollY =  parcel.readInt();
+        record.mMaxScrollX = parcel.readInt();
+        record.mMaxScrollY =  parcel.readInt();
         record.mAddedCount = parcel.readInt();
         record.mRemovedCount = parcel.readInt();
         record.mClassName = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel);
@@ -868,6 +929,8 @@
         parcel.writeInt(record.mToIndex);
         parcel.writeInt(record.mScrollX);
         parcel.writeInt(record.mScrollY);
+        parcel.writeInt(record.mMaxScrollX);
+        parcel.writeInt(record.mMaxScrollY);
         parcel.writeInt(record.mAddedCount);
         parcel.writeInt(record.mRemovedCount);
         TextUtils.writeToParcel(record.mClassName, parcel, flags);
diff --git a/core/java/android/view/accessibility/AccessibilityRecord.java b/core/java/android/view/accessibility/AccessibilityRecord.java
index afd7473..fe06d98 100644
--- a/core/java/android/view/accessibility/AccessibilityRecord.java
+++ b/core/java/android/view/accessibility/AccessibilityRecord.java
@@ -73,6 +73,8 @@
     int mToIndex = UNDEFINED;
     int mScrollX = UNDEFINED;
     int mScrollY = UNDEFINED;
+    int mMaxScrollX = UNDEFINED;
+    int mMaxScrollY = UNDEFINED;
 
     int mAddedCount= UNDEFINED;
     int mRemovedCount = UNDEFINED;
@@ -348,18 +350,18 @@
     }
 
     /**
-     * Gets the scroll position of the source along the X axis.
+     * Gets the scroll offset of the source left edge in pixels.
      *
-     * @return The scroll along the X axis.
+     * @return The scroll.
      */
     public int getScrollX() {
         return mScrollX;
     }
 
     /**
-     * Sets the scroll position of the source along the X axis.
+     * Sets the scroll offset of the source left edge in pixels.
      *
-     * @param scrollX The scroll along the X axis.
+     * @param scrollX The scroll.
      */
     public void setScrollX(int scrollX) {
         enforceNotSealed();
@@ -367,18 +369,18 @@
     }
 
     /**
-     * Gets the scroll position of the source along the Y axis.
+     * Gets the scroll offset of the source top edge in pixels.
      *
-     * @return The scroll along the Y axis.
+     * @return The scroll.
      */
     public int getScrollY() {
         return mScrollY;
     }
 
     /**
-     * Sets the scroll position of the source along the Y axis.
+     * Sets the scroll offset of the source top edge in pixels.
      *
-     * @param scrollY The scroll along the Y axis.
+     * @param scrollY The scroll.
      */
     public void setScrollY(int scrollY) {
         enforceNotSealed();
@@ -386,6 +388,51 @@
     }
 
     /**
+     * Gets the max scroll offset of the source left edge in pixels.
+     *
+     * @return The max scroll.
+     *
+     * @hide
+     */
+    public int getMaxScrollX() {
+        return mMaxScrollX;
+    }
+    /**
+     * Sets the max scroll offset of the source left edge in pixels.
+     *
+     * @param maxScrollX The max scroll.
+     *
+     * @hide
+     */
+    public void setMaxScrollX(int maxScrollX) {
+        enforceNotSealed();
+        mMaxScrollX = maxScrollX;
+    }
+
+    /**
+     * Gets the max scroll offset of the source top edge in pixels.
+     *
+     * @return The max scroll.
+     *
+     * @hide
+     */
+    public int getMaxScrollY() {
+        return mMaxScrollY;
+    }
+
+    /**
+     * Sets the max scroll offset of the source top edge in pixels.
+     *
+     * @param maxScrollY The max scroll.
+     *
+     * @hide
+     */
+    public void setMaxScrollY(int maxScrollY) {
+        enforceNotSealed();
+        mMaxScrollY = maxScrollY;
+    }
+
+    /**
      * Gets the number of added characters.
      *
      * @return The number of added characters.
@@ -658,6 +705,8 @@
         mToIndex = record.mToIndex;
         mScrollX = record.mScrollX;
         mScrollY = record.mScrollY;
+        mMaxScrollX = record.mMaxScrollX;
+        mMaxScrollY = record.mMaxScrollY;
         mAddedCount = record.mAddedCount;
         mRemovedCount = record.mRemovedCount;
         mClassName = record.mClassName;
@@ -682,6 +731,8 @@
         mToIndex = UNDEFINED;
         mScrollX = UNDEFINED;
         mScrollY = UNDEFINED;
+        mMaxScrollX = UNDEFINED;
+        mMaxScrollY = UNDEFINED;
         mAddedCount = UNDEFINED;
         mRemovedCount = UNDEFINED;
         mClassName = null;
@@ -711,6 +762,8 @@
         builder.append("; ToIndex: " + mToIndex);
         builder.append("; ScrollX: " + mScrollX);
         builder.append("; ScrollY: " + mScrollY);
+        builder.append("; MaxScrollX: " + mMaxScrollX);
+        builder.append("; MaxScrollY: " + mMaxScrollY);
         builder.append("; AddedCount: " + mAddedCount);
         builder.append("; RemovedCount: " + mRemovedCount);
         builder.append("; ParcelableData: " + mParcelableData);
diff --git a/core/java/android/webkit/BrowserFrame.java b/core/java/android/webkit/BrowserFrame.java
index 8c22da0..c8b67a8 100644
--- a/core/java/android/webkit/BrowserFrame.java
+++ b/core/java/android/webkit/BrowserFrame.java
@@ -471,6 +471,7 @@
 
     /**
      * We have received an SSL certificate for the main top-level page.
+     * Used by the Android HTTP stack only.
      */
     void certificate(SslCertificate certificate) {
         if (mIsMainFrame) {
@@ -1178,6 +1179,7 @@
 
         if (SslCertLookupTable.getInstance().isAllowed(sslError)) {
             nativeSslCertErrorProceed(handle);
+            mCallbackProxy.onProceededAfterSslError(sslError);
             return;
         }
 
@@ -1267,7 +1269,8 @@
     }
 
     /**
-     * Called by JNI when we load a page over SSL.
+     * Called by JNI when we recieve a certificate for the page's main resource.
+     * Used by the Chromium HTTP stack only.
      */
     private void setCertificate(byte cert_der[]) {
         try {
diff --git a/core/java/android/webkit/CallbackProxy.java b/core/java/android/webkit/CallbackProxy.java
index 5ee90a4..75ee338 100644
--- a/core/java/android/webkit/CallbackProxy.java
+++ b/core/java/android/webkit/CallbackProxy.java
@@ -77,53 +77,54 @@
     // Used to call startActivity during url override.
     private final Context mContext;
 
-    // Message Ids
-    private static final int PAGE_STARTED                        = 100;
-    private static final int RECEIVED_ICON                       = 101;
-    private static final int RECEIVED_TITLE                      = 102;
-    private static final int OVERRIDE_URL                        = 103;
-    private static final int AUTH_REQUEST                        = 104;
-    private static final int SSL_ERROR                           = 105;
-    private static final int PROGRESS                            = 106;
-    private static final int UPDATE_VISITED                      = 107;
-    private static final int LOAD_RESOURCE                       = 108;
-    private static final int CREATE_WINDOW                       = 109;
-    private static final int CLOSE_WINDOW                        = 110;
-    private static final int SAVE_PASSWORD                       = 111;
-    private static final int JS_ALERT                            = 112;
-    private static final int JS_CONFIRM                          = 113;
-    private static final int JS_PROMPT                           = 114;
-    private static final int JS_UNLOAD                           = 115;
-    private static final int ASYNC_KEYEVENTS                     = 116;
-    private static final int DOWNLOAD_FILE                       = 118;
-    private static final int REPORT_ERROR                        = 119;
-    private static final int RESEND_POST_DATA                    = 120;
-    private static final int PAGE_FINISHED                       = 121;
-    private static final int REQUEST_FOCUS                       = 122;
-    private static final int SCALE_CHANGED                       = 123;
-    private static final int RECEIVED_CERTIFICATE                = 124;
-    private static final int SWITCH_OUT_HISTORY                  = 125;
-    private static final int EXCEEDED_DATABASE_QUOTA             = 126;
-    private static final int REACHED_APPCACHE_MAXSIZE            = 127;
-    private static final int JS_TIMEOUT                          = 128;
-    private static final int ADD_MESSAGE_TO_CONSOLE              = 129;
-    private static final int GEOLOCATION_PERMISSIONS_SHOW_PROMPT = 130;
-    private static final int GEOLOCATION_PERMISSIONS_HIDE_PROMPT = 131;
-    private static final int RECEIVED_TOUCH_ICON_URL             = 132;
-    private static final int GET_VISITED_HISTORY                 = 133;
-    private static final int OPEN_FILE_CHOOSER                   = 134;
-    private static final int ADD_HISTORY_ITEM                    = 135;
-    private static final int HISTORY_INDEX_CHANGED               = 136;
-    private static final int AUTH_CREDENTIALS                    = 137;
-    private static final int SET_INSTALLABLE_WEBAPP              = 138;
-    private static final int NOTIFY_SEARCHBOX_LISTENERS          = 139;
-    private static final int AUTO_LOGIN                          = 140;
-    private static final int CLIENT_CERT_REQUEST                 = 141;
-    private static final int SEARCHBOX_IS_SUPPORTED_CALLBACK     = 142;
-    private static final int SEARCHBOX_DISPATCH_COMPLETE_CALLBACK= 143;
+    // Message IDs
+    private static final int PAGE_STARTED                         = 100;
+    private static final int RECEIVED_ICON                        = 101;
+    private static final int RECEIVED_TITLE                       = 102;
+    private static final int OVERRIDE_URL                         = 103;
+    private static final int AUTH_REQUEST                         = 104;
+    private static final int SSL_ERROR                            = 105;
+    private static final int PROGRESS                             = 106;
+    private static final int UPDATE_VISITED                       = 107;
+    private static final int LOAD_RESOURCE                        = 108;
+    private static final int CREATE_WINDOW                        = 109;
+    private static final int CLOSE_WINDOW                         = 110;
+    private static final int SAVE_PASSWORD                        = 111;
+    private static final int JS_ALERT                             = 112;
+    private static final int JS_CONFIRM                           = 113;
+    private static final int JS_PROMPT                            = 114;
+    private static final int JS_UNLOAD                            = 115;
+    private static final int ASYNC_KEYEVENTS                      = 116;
+    private static final int DOWNLOAD_FILE                        = 118;
+    private static final int REPORT_ERROR                         = 119;
+    private static final int RESEND_POST_DATA                     = 120;
+    private static final int PAGE_FINISHED                        = 121;
+    private static final int REQUEST_FOCUS                        = 122;
+    private static final int SCALE_CHANGED                        = 123;
+    private static final int RECEIVED_CERTIFICATE                 = 124;
+    private static final int SWITCH_OUT_HISTORY                   = 125;
+    private static final int EXCEEDED_DATABASE_QUOTA              = 126;
+    private static final int REACHED_APPCACHE_MAXSIZE             = 127;
+    private static final int JS_TIMEOUT                           = 128;
+    private static final int ADD_MESSAGE_TO_CONSOLE               = 129;
+    private static final int GEOLOCATION_PERMISSIONS_SHOW_PROMPT  = 130;
+    private static final int GEOLOCATION_PERMISSIONS_HIDE_PROMPT  = 131;
+    private static final int RECEIVED_TOUCH_ICON_URL              = 132;
+    private static final int GET_VISITED_HISTORY                  = 133;
+    private static final int OPEN_FILE_CHOOSER                    = 134;
+    private static final int ADD_HISTORY_ITEM                     = 135;
+    private static final int HISTORY_INDEX_CHANGED                = 136;
+    private static final int AUTH_CREDENTIALS                     = 137;
+    private static final int SET_INSTALLABLE_WEBAPP               = 138;
+    private static final int NOTIFY_SEARCHBOX_LISTENERS           = 139;
+    private static final int AUTO_LOGIN                           = 140;
+    private static final int CLIENT_CERT_REQUEST                  = 141;
+    private static final int SEARCHBOX_IS_SUPPORTED_CALLBACK      = 142;
+    private static final int SEARCHBOX_DISPATCH_COMPLETE_CALLBACK = 143;
+    private static final int PROCEEDED_AFTER_SSL_ERROR            = 144;
 
     // Message triggered by the client to resume execution
-    private static final int NOTIFY                              = 200;
+    private static final int NOTIFY                               = 200;
 
     // Result transportation object for returning results across thread
     // boundaries.
@@ -349,6 +350,13 @@
                 }
                 break;
 
+            case PROCEEDED_AFTER_SSL_ERROR:
+                if (mWebViewClient != null) {
+                    mWebViewClient.onProceededAfterSslError(mWebView,
+                            (SslError) msg.obj);
+                }
+                break;
+
             case CLIENT_CERT_REQUEST:
                 if (mWebViewClient != null) {
                     HashMap<String, Object> map =
@@ -1024,6 +1032,15 @@
         sendMessage(msg);
     }
 
+    public void onProceededAfterSslError(SslError error) {
+        if (mWebViewClient == null) {
+            return;
+        }
+        Message msg = obtainMessage(PROCEEDED_AFTER_SSL_ERROR);
+        msg.obj = error;
+        sendMessage(msg);
+    }
+
     public void onReceivedClientCertRequest(ClientCertRequestHandler handler, String host_and_port) {
         // Do an unsynchronized quick check to avoid posting if no callback has
         // been set.
diff --git a/core/java/android/webkit/FindActionModeCallback.java b/core/java/android/webkit/FindActionModeCallback.java
index 7398262..b85fd17 100644
--- a/core/java/android/webkit/FindActionModeCallback.java
+++ b/core/java/android/webkit/FindActionModeCallback.java
@@ -22,16 +22,14 @@
 import android.text.Selection;
 import android.text.Spannable;
 import android.text.TextWatcher;
-import android.webkit.WebView;
-import android.widget.EditText;
-import android.widget.TextView;
 import android.view.ActionMode;
 import android.view.LayoutInflater;
 import android.view.Menu;
-import android.view.MenuInflater;
 import android.view.MenuItem;
 import android.view.View;
 import android.view.inputmethod.InputMethodManager;
+import android.widget.EditText;
+import android.widget.TextView;
 
 class FindActionModeCallback implements ActionMode.Callback, TextWatcher,
         View.OnLongClickListener, View.OnClickListener {
@@ -203,6 +201,7 @@
 
     @Override
     public void onDestroyActionMode(ActionMode mode) {
+        mActionMode = null;
         mWebView.notifyFindDialogDismissed();
         mInput.hideSoftInputFromWindow(mWebView.getWindowToken(), 0);
     }
@@ -255,4 +254,13 @@
         // Does nothing.  Needed to implement TextWatcher.
     }
 
+    public int getActionModeHeight() {
+        if (mActionMode == null) {
+            return 0;
+        }
+        View parent = (View) mCustomView.getParent();
+        return parent != null ? parent.getMeasuredHeight()
+                : mCustomView.getMeasuredHeight();
+    }
+
 }
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 5111969..05d8da2 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -77,7 +77,9 @@
 import android.view.ViewGroup;
 import android.view.ViewParent;
 import android.view.ViewTreeObserver;
+import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityManager;
+import android.view.accessibility.AccessibilityNodeInfo;
 import android.view.inputmethod.EditorInfo;
 import android.view.inputmethod.InputConnection;
 import android.view.inputmethod.InputMethodManager;
@@ -1303,6 +1305,31 @@
     }
 
     @Override
+    public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
+        super.onInitializeAccessibilityNodeInfo(info);
+        info.setScrollable(isScrollableForAccessibility());
+    }
+
+    @Override
+    public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
+        super.onInitializeAccessibilityEvent(event);
+        event.setScrollable(isScrollableForAccessibility());
+        event.setScrollX(mScrollX);
+        event.setScrollY(mScrollY);
+        final int convertedContentWidth = contentToViewX(getContentWidth());
+        final int adjustedViewWidth = getWidth() - mPaddingLeft - mPaddingRight;
+        event.setMaxScrollX(Math.max(convertedContentWidth - adjustedViewWidth, 0));
+        final int convertedContentHeight = contentToViewY(getContentHeight());
+        final int adjustedViewHeight = getHeight() - mPaddingTop - mPaddingBottom;
+        event.setMaxScrollY(Math.max(convertedContentHeight - adjustedViewHeight, 0));
+    }
+
+    private boolean isScrollableForAccessibility() {
+        return (contentToViewX(getContentWidth()) > getWidth() - mPaddingLeft - mPaddingRight
+                || contentToViewY(getContentHeight()) > getHeight() - mPaddingTop - mPaddingBottom);
+    }
+
+    @Override
     public void setOverScrollMode(int mode) {
         super.setOverScrollMode(mode);
         if (mode != OVER_SCROLL_NEVER) {
@@ -1456,7 +1483,8 @@
 
     private int getVisibleTitleHeightImpl() {
         // need to restrict mScrollY due to over scroll
-        return Math.max(getTitleHeight() - Math.max(0, mScrollY), 0);
+        return Math.max(getTitleHeight() - Math.max(0, mScrollY),
+                mFindCallback != null ? mFindCallback.getActionModeHeight() : 0);
     }
 
     /*
diff --git a/core/java/android/webkit/WebViewClient.java b/core/java/android/webkit/WebViewClient.java
index d3be2bf..81de356 100644
--- a/core/java/android/webkit/WebViewClient.java
+++ b/core/java/android/webkit/WebViewClient.java
@@ -186,11 +186,11 @@
     }
 
     /**
-     * Notify the host application to handle a SSL certificate error request
-     * (display the error to the user and ask whether to proceed or not). The
-     * host application has to call either handler.cancel() or handler.proceed()
-     * as the connection is suspended and waiting for the response. The default
-     * behavior is to cancel the load.
+     * Notify the host application that an SSL error occurred while loading a
+     * resource. The host application must call either handler.cancel() or
+     * handler.proceed(). Note that the decision may be retained for use in
+     * response to future SSL errors. The default behavior is to cancel the
+     * load.
      *
      * @param view The WebView that is initiating the callback.
      * @param handler An SslErrorHandler object that will handle the user's
@@ -203,6 +203,15 @@
     }
 
     /**
+     * Notify the host application that an SSL error occurred while loading a
+     * resource, but the WebView but chose to proceed anyway based on a
+     * decision retained from a previous response to onReceivedSslError().
+     * @hide
+     */
+    public void onProceededAfterSslError(WebView view, SslError error) {
+    }
+
+    /**
      * Notify the host application to handle a SSL client certificate
      * request (display the request to the user and ask whether to
      * proceed with a client certificate or not). The host application
diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java
index ea29ad1..44688b8 100644
--- a/core/java/android/webkit/WebViewCore.java
+++ b/core/java/android/webkit/WebViewCore.java
@@ -2010,10 +2010,10 @@
         if (nativeUpdateLayers(mLastDrawData.mBaseLayer)) {
             // If anything more complex than position has been touched, let's do a full draw
             webkitDraw();
-        } else {
-            Message.obtain(mWebView.mPrivateHandler,
-                    WebView.INVAL_RECT_MSG_ID).sendToTarget();
         }
+        mWebView.mPrivateHandler.removeMessages(WebView.INVAL_RECT_MSG_ID);
+        mWebView.mPrivateHandler.sendMessageAtFrontOfQueue(mWebView.mPrivateHandler
+                .obtainMessage(WebView.INVAL_RECT_MSG_ID));
     }
 
     private void webkitDraw() {
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 7b8c7f2..0d287cf 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -237,9 +237,11 @@
     SparseBooleanArray mCheckStates;
 
     /**
-     * Running state of which IDs are currently checked
+     * Running state of which IDs are currently checked.
+     * If there is a value for a given key, the checked state for that ID is true
+     * and the value holds the last known position in the adapter for that id.
      */
-    LongSparseArray<Boolean> mCheckedIdStates;
+    LongSparseArray<Integer> mCheckedIdStates;
 
     /**
      * Controls how the next layout will happen
@@ -472,6 +474,13 @@
     static final int OVERSCROLL_LIMIT_DIVISOR = 3;
 
     /**
+     * How many positions in either direction we will search to try to
+     * find a checked item with a stable ID that moved position across
+     * a data set change. If the item isn't found it will be unselected.
+     */
+    private static final int CHECK_POSITION_SEARCH_DISTANCE = 20;
+
+    /**
      * Used to request a layout when we changed touch mode
      */
     private static final int TOUCH_MODE_UNKNOWN = -1;
@@ -806,7 +815,7 @@
         if (adapter != null) {
             if (mChoiceMode != CHOICE_MODE_NONE && mAdapter.hasStableIds() &&
                     mCheckedIdStates == null) {
-                mCheckedIdStates = new LongSparseArray<Boolean>();
+                mCheckedIdStates = new LongSparseArray<Integer>();
             }
         }
 
@@ -901,7 +910,7 @@
             return new long[0];
         }
 
-        final LongSparseArray<Boolean> idStates = mCheckedIdStates;
+        final LongSparseArray<Integer> idStates = mCheckedIdStates;
         final int count = idStates.size();
         final long[] ids = new long[count];
 
@@ -948,7 +957,7 @@
             mCheckStates.put(position, value);
             if (mCheckedIdStates != null && mAdapter.hasStableIds()) {
                 if (value) {
-                    mCheckedIdStates.put(mAdapter.getItemId(position), Boolean.TRUE);
+                    mCheckedIdStates.put(mAdapter.getItemId(position), position);
                 } else {
                     mCheckedIdStates.delete(mAdapter.getItemId(position));
                 }
@@ -980,7 +989,7 @@
             if (value) {
                 mCheckStates.put(position, true);
                 if (updateIds) {
-                    mCheckedIdStates.put(mAdapter.getItemId(position), Boolean.TRUE);
+                    mCheckedIdStates.put(mAdapter.getItemId(position), position);
                 }
                 mCheckedItemCount = 1;
             } else if (mCheckStates.size() == 0 || !mCheckStates.valueAt(0)) {
@@ -1010,7 +1019,7 @@
                 mCheckStates.put(position, newValue);
                 if (mCheckedIdStates != null && mAdapter.hasStableIds()) {
                     if (newValue) {
-                        mCheckedIdStates.put(mAdapter.getItemId(position), Boolean.TRUE);
+                        mCheckedIdStates.put(mAdapter.getItemId(position), position);
                     } else {
                         mCheckedIdStates.delete(mAdapter.getItemId(position));
                     }
@@ -1032,7 +1041,7 @@
                     mCheckStates.put(position, true);
                     if (mCheckedIdStates != null && mAdapter.hasStableIds()) {
                         mCheckedIdStates.clear();
-                        mCheckedIdStates.put(mAdapter.getItemId(position), Boolean.TRUE);
+                        mCheckedIdStates.put(mAdapter.getItemId(position), position);
                     }
                     mCheckedItemCount = 1;
                 } else if (mCheckStates.size() == 0 || !mCheckStates.valueAt(0)) {
@@ -1081,7 +1090,7 @@
                 mCheckStates = new SparseBooleanArray();
             }
             if (mCheckedIdStates == null && mAdapter != null && mAdapter.hasStableIds()) {
-                mCheckedIdStates = new LongSparseArray<Boolean>();
+                mCheckedIdStates = new LongSparseArray<Integer>();
             }
             // Modal multi-choice mode only has choices when the mode is active. Clear them.
             if (mChoiceMode == CHOICE_MODE_MULTIPLE_MODAL) {
@@ -1270,40 +1279,24 @@
     }
 
     @Override
-    public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
-        super.onInitializeAccessibilityNodeInfo(info);
-        info.setScrollable(true);
-    }
-
-    @Override
     public void sendAccessibilityEvent(int eventType) {
         // Since this class calls onScrollChanged even if the mFirstPosition and the
         // child count have not changed we will avoid sending duplicate accessibility
         // events.
         if (eventType == AccessibilityEvent.TYPE_VIEW_SCROLLED) {
-            final int lastPosition = mFirstPosition + getChildCount();
-            if (mLastAccessibilityScrollEventFromIndex == mFirstPosition
-                    && mLastAccessibilityScrollEventToIndex == lastPosition) {
+            final int firstVisiblePosition = getFirstVisiblePosition();
+            final int lastVisiblePosition = getLastVisiblePosition();
+            if (mLastAccessibilityScrollEventFromIndex == firstVisiblePosition
+                    && mLastAccessibilityScrollEventToIndex == lastVisiblePosition) {
                 return;   
             } else {
-                mLastAccessibilityScrollEventFromIndex = mFirstPosition;
-                mLastAccessibilityScrollEventToIndex = lastPosition;       
+                mLastAccessibilityScrollEventFromIndex = firstVisiblePosition;
+                mLastAccessibilityScrollEventToIndex = lastVisiblePosition;
             }
         }
         super.sendAccessibilityEvent(eventType);
     }
 
-    @Override
-    public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
-        super.onInitializeAccessibilityEvent(event);
-        event.setScrollable(true);
-        if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_SCROLLED) {
-            event.setFromIndex(mFirstPosition);
-            event.setToIndex(mFirstPosition +  getChildCount());
-            event.setItemCount(mItemCount);
-        }
-    }
-
     /**
      * Indicates whether the children's drawing cache is used during a scroll.
      * By default, the drawing cache is enabled but this will consume more memory.
@@ -1427,7 +1420,7 @@
         boolean inActionMode;
         int checkedItemCount;
         SparseBooleanArray checkState;
-        LongSparseArray<Boolean> checkIdState;
+        LongSparseArray<Integer> checkIdState;
 
         /**
          * Constructor called from {@link AbsListView#onSaveInstanceState()}
@@ -1451,10 +1444,14 @@
             checkedItemCount = in.readInt();
             checkState = in.readSparseBooleanArray();
             long[] idState = in.createLongArray();
+            int[] idPositions = in.createIntArray();
 
-            if (idState.length > 0) {
-                checkIdState = new LongSparseArray<Boolean>();
-                checkIdState.setValues(idState, Boolean.TRUE);
+            final int idLength = idState.length;
+            if (idLength > 0) {
+                checkIdState = new LongSparseArray<Integer>();
+                for (int i = 0; i < idLength; i++) {
+                    checkIdState.put(idState[i], idPositions[i]);
+                }
             }
         }
 
@@ -1471,6 +1468,15 @@
             out.writeInt(checkedItemCount);
             out.writeSparseBooleanArray(checkState);
             out.writeLongArray(checkIdState != null ? checkIdState.getKeys() : new long[0]);
+
+            int size = checkIdState != null ? checkIdState.size() : 0;
+            int[] idPositions = new int[size];
+            if (size > 0) {
+                for (int i = 0; i < size; i++) {
+                    idPositions[i] = checkIdState.valueAt(i);
+                }
+                out.writeIntArray(idPositions);
+            }
         }
 
         @Override
@@ -1565,7 +1571,7 @@
             ss.checkState = mCheckStates.clone();
         }
         if (mCheckedIdStates != null) {
-            final LongSparseArray<Boolean> idState = new LongSparseArray<Boolean>();
+            final LongSparseArray<Integer> idState = new LongSparseArray<Integer>();
             final int count = mCheckedIdStates.size();
             for (int i = 0; i < count; i++) {
                 idState.put(mCheckedIdStates.keyAt(i), mCheckedIdStates.valueAt(i));
@@ -4786,15 +4792,63 @@
         return selectedPos >= 0;
     }
 
+    void confirmCheckedPositionsById() {
+        // Clear out the positional check states, we'll rebuild it below from IDs.
+        mCheckStates.clear();
+
+        boolean checkedCountChanged = false;
+        for (int checkedIndex = 0; checkedIndex < mCheckedIdStates.size(); checkedIndex++) {
+            final long id = mCheckedIdStates.keyAt(checkedIndex);
+            final int lastPos = mCheckedIdStates.valueAt(checkedIndex);
+
+            final long lastPosId = mAdapter.getItemId(lastPos);
+            if (id != lastPosId) {
+                // Look around to see if the ID is nearby. If not, uncheck it.
+                final int start = Math.max(0, lastPos - CHECK_POSITION_SEARCH_DISTANCE);
+                final int end = Math.min(lastPos + CHECK_POSITION_SEARCH_DISTANCE, mItemCount);
+                boolean found = false;
+                for (int searchPos = start; searchPos < end; searchPos++) {
+                    final long searchId = mAdapter.getItemId(searchPos);
+                    if (id == searchId) {
+                        found = true;
+                        mCheckStates.put(searchPos, true);
+                        mCheckedIdStates.setValueAt(checkedIndex, searchPos);
+                        break;
+                    }
+                }
+
+                if (!found) {
+                    mCheckedIdStates.delete(id);
+                    checkedIndex--;
+                    mCheckedItemCount--;
+                    checkedCountChanged = true;
+                    if (mChoiceActionMode != null && mMultiChoiceModeCallback != null) {
+                        mMultiChoiceModeCallback.onItemCheckedStateChanged(mChoiceActionMode,
+                                lastPos, id, false);
+                    }
+                }
+            } else {
+                mCheckStates.put(lastPos, true);
+            }
+        }
+
+        if (checkedCountChanged && mChoiceActionMode != null) {
+            mChoiceActionMode.invalidate();
+        }
+    }
+
     @Override
     protected void handleDataChanged() {
         int count = mItemCount;
         int lastHandledItemCount = mLastHandledItemCount;
         mLastHandledItemCount = mItemCount;
+
+        if (mChoiceMode != CHOICE_MODE_NONE && mAdapter != null && mAdapter.hasStableIds()) {
+            confirmCheckedPositionsById();
+        }
+
         if (count > 0) {
-
             int newPos;
-
             int selectablePos;
 
             // Find the row we are supposed to sync to
diff --git a/core/java/android/widget/AdapterView.java b/core/java/android/widget/AdapterView.java
index 61c5dd4..fd19b5f 100644
--- a/core/java/android/widget/AdapterView.java
+++ b/core/java/android/widget/AdapterView.java
@@ -29,6 +29,7 @@
 import android.view.ViewDebug;
 import android.view.ViewGroup;
 import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityNodeInfo;
 
 
 /**
@@ -881,19 +882,10 @@
 
     @Override
     public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
-        if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_FOCUSED) {
-            // This is an exceptional case which occurs when a window gets the
-            // focus and sends a focus event via its focused child to announce
-            // current focus/selection. AdapterView fires selection but not focus
-            // events so we change the event type here.
-            if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_FOCUSED) {
-                event.setEventType(AccessibilityEvent.TYPE_VIEW_SELECTED);
-            }
-        }
-
         View selectedView = getSelectedView();
-        if (selectedView != null && selectedView.getVisibility() == VISIBLE) {
-            getSelectedView().dispatchPopulateAccessibilityEvent(event);
+        if (selectedView != null && selectedView.getVisibility() == VISIBLE
+                && selectedView.dispatchPopulateAccessibilityEvent(event)) {
+            return true;
         }
         return false;
     }
@@ -913,19 +905,32 @@
     }
 
     @Override
+    public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
+        super.onInitializeAccessibilityNodeInfo(info);
+        info.setScrollable(isScrollableForAccessibility());
+        View selectedView = getSelectedView();
+        if (selectedView != null) {
+            info.setEnabled(selectedView.isEnabled());
+        }
+    }
+
+    @Override
     public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
         super.onInitializeAccessibilityEvent(event);
-
+        event.setScrollable(isScrollableForAccessibility());
         View selectedView = getSelectedView();
         if (selectedView != null) {
             event.setEnabled(selectedView.isEnabled());
         }
-        event.setItemCount(getCount());
-        event.setCurrentItemIndex(getSelectedItemPosition());
-        if (getChildCount() > 0) {
-            event.setFromIndex(getFirstVisiblePosition());
-            event.setToIndex(getLastVisiblePosition());
-        }
+        event.setFromIndex(getFirstVisiblePosition());
+        event.setToIndex(getLastVisiblePosition());
+        event.setItemCount(getAdapter().getCount());
+    }
+
+    private boolean isScrollableForAccessibility() {
+        final int itemCount = getAdapter().getCount();
+        return itemCount > 0
+            && (getFirstVisiblePosition() > 0 || getLastVisiblePosition() < itemCount - 1);
     }
 
     @Override
diff --git a/core/java/android/widget/Gallery.java b/core/java/android/widget/Gallery.java
index a0eba9a..5e37fa8 100644
--- a/core/java/android/widget/Gallery.java
+++ b/core/java/android/widget/Gallery.java
@@ -32,8 +32,6 @@
 import android.view.View;
 import android.view.ViewConfiguration;
 import android.view.ViewGroup;
-import android.view.accessibility.AccessibilityEvent;
-import android.view.accessibility.AccessibilityNodeInfo;
 import android.view.animation.Transformation;
 
 import com.android.internal.R;
@@ -354,23 +352,6 @@
         return child.getMeasuredHeight();
     }
 
-    @Override
-    public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
-        super.onInitializeAccessibilityNodeInfo(info);
-        info.setScrollable(true);
-    }
-
-    @Override
-    public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
-        super.onInitializeAccessibilityEvent(event);
-        event.setScrollable(true);
-        if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_SCROLLED) {
-            event.setFromIndex(mFirstPosition);
-            event.setToIndex(mFirstPosition +  getChildCount());
-            event.setItemCount(mItemCount);
-        }
-    }
-
     /**
      * Tracks a motion scroll. In reality, this is used to do just about any
      * movement to items (touch scroll, arrow-key scroll, set an item as selected).
diff --git a/core/java/android/widget/HorizontalScrollView.java b/core/java/android/widget/HorizontalScrollView.java
index 324dfd7..57701ae 100644
--- a/core/java/android/widget/HorizontalScrollView.java
+++ b/core/java/android/widget/HorizontalScrollView.java
@@ -716,13 +716,17 @@
     @Override
     public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
         super.onInitializeAccessibilityNodeInfo(info);
-        info.setScrollable(true);
+        info.setScrollable(getScrollRange() > 0);
     }
 
     @Override
     public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
         super.onInitializeAccessibilityEvent(event);
-        event.setScrollable(true);
+        event.setScrollable(getScrollRange() > 0);
+        event.setScrollX(mScrollX);
+        event.setScrollY(mScrollY);
+        event.setMaxScrollX(getScrollRange());
+        event.setMaxScrollY(mScrollY);
     }
 
     private int getScrollRange() {
diff --git a/core/java/android/widget/ListView.java b/core/java/android/widget/ListView.java
index 42e27b1..9ef1aa1 100644
--- a/core/java/android/widget/ListView.java
+++ b/core/java/android/widget/ListView.java
@@ -1997,31 +1997,6 @@
         }
     }
 
-    @Override
-    public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
-        super.onInitializeAccessibilityEvent(event);
-
-        // If the item count is less than 15 then subtract disabled items from the count and
-        // position. Otherwise ignore disabled items.
-        int itemCount = 0;
-        int currentItemIndex = getSelectedItemPosition();
-
-        ListAdapter adapter = getAdapter();
-        if (adapter != null) {
-            final int count = adapter.getCount();
-            for (int i = 0; i < count; i++) {
-                if (adapter.isEnabled(i)) {
-                    itemCount++;
-                } else if (i <= currentItemIndex) {
-                    currentItemIndex--;
-                }
-            }
-        }
-
-        event.setItemCount(itemCount);
-        event.setCurrentItemIndex(currentItemIndex);
-    }
-
     /**
      * setSelectionAfterHeaderView set the selection to be the first list item
      * after the header views.
diff --git a/core/java/android/widget/ScrollView.java b/core/java/android/widget/ScrollView.java
index 3ac4e80..767eaee 100644
--- a/core/java/android/widget/ScrollView.java
+++ b/core/java/android/widget/ScrollView.java
@@ -721,13 +721,18 @@
     @Override
     public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
         super.onInitializeAccessibilityNodeInfo(info);
-        info.setScrollable(true);
+        info.setScrollable(getScrollRange() > 0);
     }
 
     @Override
     public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
         super.onInitializeAccessibilityEvent(event);
-        event.setScrollable(true);
+        final boolean scrollable = getScrollRange() > 0;
+        event.setScrollable(scrollable);
+        event.setScrollX(mScrollX);
+        event.setScrollY(mScrollY);
+        event.setMaxScrollX(mScrollX);
+        event.setMaxScrollY(getScrollRange());
     }
 
     private int getScrollRange() {
diff --git a/core/java/com/android/internal/view/BaseIWindow.java b/core/java/com/android/internal/view/BaseIWindow.java
index b9948fe..b227700 100644
--- a/core/java/com/android/internal/view/BaseIWindow.java
+++ b/core/java/com/android/internal/view/BaseIWindow.java
@@ -27,6 +27,7 @@
 
 public class BaseIWindow extends IWindow.Stub {
     private IWindowSession mSession;
+    public int mSeq;
     
     public void setSession(IWindowSession session) {
         mSession = session;
@@ -69,7 +70,9 @@
     public void dispatchDragEvent(DragEvent event) {
     }
 
-    public void dispatchSystemUiVisibilityChanged(int visibility) {
+    public void dispatchSystemUiVisibilityChanged(int seq, int globalUi,
+            int localValue, int localChanges) {
+        mSeq = seq;
     }
 
     public void dispatchWallpaperCommand(String action, int x, int y,
diff --git a/core/jni/android/graphics/Canvas.cpp b/core/jni/android/graphics/Canvas.cpp
index 02c5bb3..7724646 100644
--- a/core/jni/android/graphics/Canvas.cpp
+++ b/core/jni/android/graphics/Canvas.cpp
@@ -767,20 +767,17 @@
 
         sp<TextLayoutCacheValue> value;
 #if USE_TEXT_LAYOUT_CACHE
-        value = TextLayoutCache::getInstance().getValue(paint, textArray, contextCount, flags);
+        value = TextLayoutCache::getInstance().getValue(paint, textArray, start, count,
+                contextCount, flags);
         if (value == NULL) {
             LOGE("Cannot get TextLayoutCache value");
             return ;
         }
 #else
         value = new TextLayoutCacheValue();
-        value->computeValues(paint, textArray, contextCount, flags);
+        value->computeValues(paint, textArray, start, count, contextCount, flags);
 #endif
-        size_t startIndex = 0;
-        size_t glyphsCount = 0;
-        value->getGlyphsIndexAndCount(start, count, &startIndex, &glyphsCount);
-        const jchar* glyphs = value->getGlyphs(startIndex, glyphsCount);
-        doDrawGlyphs(canvas, glyphs, 0, glyphsCount, x, y, flags, paint);
+        doDrawGlyphs(canvas, value->getGlyphs(), 0, value->getGlyphsCount(), x, y, flags, paint);
     }
 
     static void doDrawGlyphs(SkCanvas* canvas, const jchar* glyphArray, int index, int count,
diff --git a/core/jni/android/graphics/Paint.cpp b/core/jni/android/graphics/Paint.cpp
index 3daf7d0..2ab7da9 100644
--- a/core/jni/android/graphics/Paint.cpp
+++ b/core/jni/android/graphics/Paint.cpp
@@ -483,18 +483,15 @@
         }
 
         jchar* glyphsArray = env->GetCharArrayElements(glyphs, NULL);
-        HB_ShaperItem shaperItem;
-        HB_FontRec font;
-        FontData fontData;
-        TextLayoutCacheValue::shapeWithHarfbuzz(&shaperItem, &font, &fontData, paint, text,
-                start, count, contextCount, flags);
 
-        int glyphCount = shaperItem.num_glyphs;
-        for (int i = 0; i < glyphCount; i++) {
-            glyphsArray[i] = (jchar) shaperItem.glyphs[i];
-        }
+        TextLayoutCacheValue value;
+        value.computeValues(paint, text, start, count, contextCount, flags);
+        const jchar* shapedGlyphs = value.getGlyphs();
+        size_t glyphsCount = value.getGlyphsCount();
+        memcpy(glyphsArray, shapedGlyphs, sizeof(jchar) * glyphsCount);
+
         env->ReleaseCharArrayElements(glyphs, glyphsArray, JNI_ABORT);
-        return glyphCount;
+        return glyphsCount;
     }
 
     static int getTextGlyphs__StringIIIII_C(JNIEnv* env, jobject clazz, SkPaint* paint,
diff --git a/core/jni/android/graphics/TextLayout.cpp b/core/jni/android/graphics/TextLayout.cpp
index ae17aed..9b424f2 100644
--- a/core/jni/android/graphics/TextLayout.cpp
+++ b/core/jni/android/graphics/TextLayout.cpp
@@ -257,17 +257,18 @@
     sp<TextLayoutCacheValue> value;
 #if USE_TEXT_LAYOUT_CACHE
     // Return advances from the cache. Compute them if needed
-    value = TextLayoutCache::getInstance().getValue(paint, chars, contextCount, dirFlags);
+    value = TextLayoutCache::getInstance().getValue(paint, chars, start, count,
+            contextCount, dirFlags);
 #else
     value = new TextLayoutCacheValue();
-    value->computeValues(paint, chars, contextCount, dirFlags);
+    value->computeValues(paint, chars, start, count, contextCount, dirFlags);
 #endif
     if (value != NULL) {
-        if (resultAdvances != NULL) {
-            value->getAdvances(start, count, resultAdvances);
+        if (resultAdvances) {
+            memcpy(resultAdvances, value->getAdvances(), value->getAdvancesCount() * sizeof(jfloat));
         }
         if (resultTotalAdvance) {
-            *resultTotalAdvance = value->getTotalAdvance(start, count);
+            *resultTotalAdvance = value->getTotalAdvance();
         }
     }
 }
diff --git a/core/jni/android/graphics/TextLayoutCache.cpp b/core/jni/android/graphics/TextLayoutCache.cpp
index 9ba95bd..0b53850 100644
--- a/core/jni/android/graphics/TextLayoutCache.cpp
+++ b/core/jni/android/graphics/TextLayoutCache.cpp
@@ -106,7 +106,7 @@
  * Caching
  */
 sp<TextLayoutCacheValue> TextLayoutCache::getValue(SkPaint* paint,
-            const jchar* text, jint count, jint dirFlags) {
+            const jchar* text, jint start, jint count, jint contextCount, jint dirFlags) {
     AutoMutex _l(mLock);
     nsecs_t startTime = 0;
     if (mDebugEnabled) {
@@ -114,7 +114,7 @@
     }
 
     // Create the key
-    TextLayoutCacheKey key(paint, text, count, dirFlags);
+    TextLayoutCacheKey key(paint, text, start, count, contextCount, dirFlags);
 
     // Get value from cache if possible
     sp<TextLayoutCacheValue> value = mCache.get(key);
@@ -128,7 +128,7 @@
         value = new TextLayoutCacheValue();
 
         // Compute advances and store them
-        value->computeValues(paint, text, count, dirFlags);
+        value->computeValues(paint, text, start, count, contextCount, dirFlags);
 
         nsecs_t endTime = systemTime(SYSTEM_TIME_MONOTONIC);
 
@@ -166,10 +166,10 @@
         } else {
             if (mDebugEnabled) {
                 LOGD("CACHE MISS: Calculated but not storing entry because it is too big "
-                        "with count=%d, "
+                        "with start=%d count=%d contextCount=%d, "
                         "entry size %d bytes, remaining space %d bytes"
                         " - Compute time in nanos: %lld - Text='%s'",
-                        count, size, mMaxSize - mSize, endTime,
+                        start, count, contextCount, size, mMaxSize - mSize, endTime,
                         String8(text, count).string());
             }
             value.clear();
@@ -184,10 +184,10 @@
             if (value->getElapsedTime() > 0) {
                 float deltaPercent = 100 * ((value->getElapsedTime() - elapsedTimeThruCacheGet)
                         / ((float)value->getElapsedTime()));
-                LOGD("CACHE HIT #%d with count=%d "
+                LOGD("CACHE HIT #%d with start=%d count=%d contextCount=%d"
                         "- Compute time in nanos: %d - "
                         "Cache get time in nanos: %lld - Gain in percent: %2.2f - Text='%s' ",
-                        mCacheHitCount, count,
+                        mCacheHitCount, start, count, contextCount,
                         value->getElapsedTime(), elapsedTimeThruCacheGet, deltaPercent,
                         String8(text, count).string());
             }
@@ -218,14 +218,14 @@
 /**
  * TextLayoutCacheKey
  */
-TextLayoutCacheKey::TextLayoutCacheKey(): text(NULL), count(0),
+TextLayoutCacheKey::TextLayoutCacheKey(): text(NULL), start(0), count(0), contextCount(0),
         dirFlags(0), typeface(NULL), textSize(0), textSkewX(0), textScaleX(0), flags(0),
         hinting(SkPaint::kNo_Hinting)  {
 }
 
-TextLayoutCacheKey::TextLayoutCacheKey(const SkPaint* paint,
-        const UChar* text, size_t count, int dirFlags) :
-            text(text), count(count),
+TextLayoutCacheKey::TextLayoutCacheKey(const SkPaint* paint, const UChar* text,
+        size_t start, size_t count, size_t contextCount, int dirFlags) :
+            text(text), start(start), count(count), contextCount(contextCount),
             dirFlags(dirFlags) {
     typeface = paint->getTypeface();
     textSize = paint->getTextSize();
@@ -238,7 +238,9 @@
 TextLayoutCacheKey::TextLayoutCacheKey(const TextLayoutCacheKey& other) :
         text(NULL),
         textCopy(other.textCopy),
+        start(other.start),
         count(other.count),
+        contextCount(other.contextCount),
         dirFlags(other.dirFlags),
         typeface(other.typeface),
         textSize(other.textSize),
@@ -252,7 +254,13 @@
 }
 
 int TextLayoutCacheKey::compare(const TextLayoutCacheKey& lhs, const TextLayoutCacheKey& rhs) {
-    int deltaInt = lhs.count - rhs.count;
+    int deltaInt = lhs.start - rhs.start;
+    if (deltaInt != 0) return (deltaInt);
+
+    deltaInt = lhs.count - rhs.count;
+    if (deltaInt != 0) return (deltaInt);
+
+    deltaInt = lhs.contextCount - rhs.contextCount;
     if (deltaInt != 0) return (deltaInt);
 
     if (lhs.typeface < rhs.typeface) return -1;
@@ -276,16 +284,16 @@
     deltaInt = lhs.dirFlags - rhs.dirFlags;
     if (deltaInt) return (deltaInt);
 
-    return memcmp(lhs.getText(), rhs.getText(), lhs.count * sizeof(UChar));
+    return memcmp(lhs.getText(), rhs.getText(), lhs.contextCount * sizeof(UChar));
 }
 
 void TextLayoutCacheKey::internalTextCopy() {
-    textCopy.setTo(text, count);
+    textCopy.setTo(text, contextCount);
     text = NULL;
 }
 
 size_t TextLayoutCacheKey::getSize() {
-    return sizeof(TextLayoutCacheKey) + sizeof(UChar) * count;
+    return sizeof(TextLayoutCacheKey) + sizeof(UChar) * contextCount;
 }
 
 /**
@@ -304,29 +312,32 @@
 }
 
 void TextLayoutCacheValue::computeValues(SkPaint* paint, const UChar* chars,
-        size_t contextCount, int dirFlags) {
+        size_t start, size_t count, size_t contextCount, int dirFlags) {
     // Give a hint for advances, glyphs and log clusters vectors size
     mAdvances.setCapacity(contextCount);
     mGlyphs.setCapacity(contextCount);
-    mLogClusters.setCapacity(contextCount);
 
-    computeValuesWithHarfbuzz(paint, chars, contextCount, dirFlags,
-            &mAdvances, &mTotalAdvance, &mGlyphs, &mLogClusters);
+    computeValuesWithHarfbuzz(paint, chars, start, count, contextCount, dirFlags,
+            &mAdvances, &mTotalAdvance, &mGlyphs);
 #if DEBUG_ADVANCES
-    LOGD("Advances - countextCount=%d - totalAdvance=%f", contextCount, mTotalAdvance);
+    LOGD("Advances - start=%d, count=%d, countextCount=%d, totalAdvance=%f", start, count,
+            contextCount, mTotalAdvance);
 #endif
 }
 
 size_t TextLayoutCacheValue::getSize() {
     return sizeof(TextLayoutCacheValue) + sizeof(jfloat) * mAdvances.capacity() +
-            sizeof(jchar) * mGlyphs.capacity() + sizeof(unsigned short) * mLogClusters.capacity();
+            sizeof(jchar) * mGlyphs.capacity();
 }
 
-void TextLayoutCacheValue::setupShaperItem(HB_ShaperItem* shaperItem, HB_FontRec* font,
-        FontData* fontData, SkPaint* paint, const UChar* chars, size_t start, size_t count,
-        size_t contextCount, bool isRTL) {
+void TextLayoutCacheValue::initShaperItem(HB_ShaperItem& shaperItem, HB_FontRec* font,
+        FontData* fontData, SkPaint* paint, const UChar* chars, size_t contextCount) {
+    // Zero the Shaper struct
+    memset(&shaperItem, 0, sizeof(shaperItem));
+
     font->klass = &harfbuzzSkiaClass;
     font->userData = 0;
+
     // The values which harfbuzzSkiaClass returns are already scaled to
     // pixel units, so we just set all these to one to disable further
     // scaling.
@@ -335,33 +346,13 @@
     font->x_scale = 1;
     font->y_scale = 1;
 
-    memset(shaperItem, 0, sizeof(*shaperItem));
-    shaperItem->font = font;
-    shaperItem->face = HB_NewFace(shaperItem->font, harfbuzzSkiaGetTable);
+    shaperItem.font = font;
+    shaperItem.face = HB_NewFace(shaperItem.font, harfbuzzSkiaGetTable);
 
-    shaperItem->kerning_applied = false;
+    // Reset kerning
+    shaperItem.kerning_applied = false;
 
-    // We cannot know, ahead of time, how many glyphs a given script run
-    // will produce. We take a guess that script runs will not produce more
-    // than twice as many glyphs as there are code points plus a bit of
-    // padding and fallback if we find that we are wrong.
-    createGlyphArrays(shaperItem, (contextCount + 2) * 2);
-
-    // Free memory for clusters if needed and recreate the clusters array
-    if (shaperItem->log_clusters) {
-        delete shaperItem->log_clusters;
-    }
-    shaperItem->log_clusters = new unsigned short[contextCount];
-
-    shaperItem->item.pos = start;
-    shaperItem->item.length = count;
-    shaperItem->item.bidiLevel = isRTL;
-
-    shaperItem->item.script = isRTL ? HB_Script_Arabic : HB_Script_Common;
-
-    shaperItem->string = chars;
-    shaperItem->stringLength = contextCount;
-
+    // Define font data
     fontData->typeFace = paint->getTypeface();
     fontData->textSize = paint->getTextSize();
     fontData->textSkewX = paint->getTextSkewX();
@@ -369,31 +360,50 @@
     fontData->flags = paint->getFlags();
     fontData->hinting = paint->getHinting();
 
-    shaperItem->font->userData = fontData;
+    shaperItem.font->userData = fontData;
+
+    // We cannot know, ahead of time, how many glyphs a given script run
+    // will produce. We take a guess that script runs will not produce more
+    // than twice as many glyphs as there are code points plus a bit of
+    // padding and fallback if we find that we are wrong.
+    createGlyphArrays(shaperItem, (contextCount + 2) * 2);
+
+    // Create log clusters array
+    shaperItem.log_clusters = new unsigned short[contextCount];
+
+    // Set the string properties
+    shaperItem.string = chars;
+    shaperItem.stringLength = contextCount;
 }
 
-void TextLayoutCacheValue::shapeWithHarfbuzz(HB_ShaperItem* shaperItem, HB_FontRec* font,
-        FontData* fontData, SkPaint* paint, const UChar* chars, size_t start, size_t count,
-        size_t contextCount, bool isRTL) {
-    // Setup Harfbuzz Shaper
-    setupShaperItem(shaperItem, font, fontData, paint, chars, start, count,
-            contextCount, isRTL);
+void TextLayoutCacheValue::freeShaperItem(HB_ShaperItem& shaperItem) {
+    deleteGlyphArrays(shaperItem);
+    delete[] shaperItem.log_clusters;
+    HB_FreeFace(shaperItem.face);
+}
+
+void TextLayoutCacheValue::shapeRun(HB_ShaperItem& shaperItem, size_t start, size_t count,
+        bool isRTL) {
+    // Update Harfbuzz Shaper
+    shaperItem.item.pos = start;
+    shaperItem.item.length = count;
+    shaperItem.item.bidiLevel = isRTL;
+
+    shaperItem.item.script = isRTL ? HB_Script_Arabic : HB_Script_Common;
 
     // Shape
-    resetGlyphArrays(shaperItem);
-    while (!HB_ShapeItem(shaperItem)) {
+    while (!HB_ShapeItem(&shaperItem)) {
         // We overflowed our arrays. Resize and retry.
         // HB_ShapeItem fills in shaperItem.num_glyphs with the needed size.
         deleteGlyphArrays(shaperItem);
-        createGlyphArrays(shaperItem, shaperItem->num_glyphs << 1);
-        resetGlyphArrays(shaperItem);
+        createGlyphArrays(shaperItem, shaperItem.num_glyphs << 1);
     }
 }
 
 void TextLayoutCacheValue::computeValuesWithHarfbuzz(SkPaint* paint, const UChar* chars,
-        size_t contextCount, int dirFlags,
+        size_t start, size_t count, size_t contextCount, int dirFlags,
         Vector<jfloat>* const outAdvances, jfloat* outTotalAdvance,
-        Vector<jchar>* const outGlyphs, Vector<unsigned short>* const outLogClusters) {
+        Vector<jchar>* const outGlyphs) {
 
         UBiDiLevel bidiReq = 0;
         bool forceLTR = false;
@@ -408,13 +418,21 @@
             case kBidi_Force_RTL: forceRTL = true; break; // every char is RTL
         }
 
+        HB_ShaperItem shaperItem;
+        HB_FontRec font;
+        FontData fontData;
+
+        // Initialize Harfbuzz Shaper
+        initShaperItem(shaperItem, &font, &fontData, paint, chars, contextCount);
+
         if (forceLTR || forceRTL) {
 #if DEBUG_GLYPHS
                     LOGD("computeValuesWithHarfbuzz -- forcing run with LTR=%d RTL=%d",
                             forceLTR, forceRTL);
 #endif
-            computeRunValuesWithHarfbuzz(paint, chars, 0, contextCount, contextCount, forceRTL,
-                    outAdvances, outTotalAdvance, outGlyphs, outLogClusters);
+            computeRunValuesWithHarfbuzz(shaperItem, paint,
+                    start, count, forceRTL,
+                    outAdvances, outTotalAdvance, outGlyphs);
         } else {
             UBiDi* bidi = ubidi_open();
             if (bidi) {
@@ -427,32 +445,49 @@
                     int paraDir = ubidi_getParaLevel(bidi) & kDirection_Mask; // 0 if ltr, 1 if rtl
                     size_t rc = ubidi_countRuns(bidi, &status);
 #if DEBUG_GLYPHS
-                    LOGD("computeValuesWithHarfbuzz -- dirFlags=%d run-count=%d paraDir=%d", dirFlags, rc, paraDir);
+                    LOGD("computeValuesWithHarfbuzz -- dirFlags=%d run-count=%d paraDir=%d",
+                            dirFlags, rc, paraDir);
 #endif
                     if (rc == 1 || !U_SUCCESS(status)) {
                         bool isRTL = (paraDir == 1);
 #if DEBUG_GLYPHS
                         LOGD("computeValuesWithHarfbuzz -- processing SINGLE run "
-                                "-- run-start=%d run-len=%d isRTL=%d", 0, contextCount, isRTL);
+                                "-- run-start=%d run-len=%d isRTL=%d", start, count, isRTL);
 #endif
-                        computeRunValuesWithHarfbuzz(paint, chars, 0, contextCount, contextCount,
-                                isRTL, outAdvances, outTotalAdvance, outGlyphs, outLogClusters);
+                        computeRunValuesWithHarfbuzz(shaperItem, paint,
+                                start, count, isRTL,
+                                outAdvances, outTotalAdvance, outGlyphs);
                     } else {
+                        int32_t end = start + count;
                         for (size_t i = 0; i < rc; ++i) {
                             int32_t startRun;
                             int32_t lengthRun;
                             UBiDiDirection runDir = ubidi_getVisualRun(bidi, i, &startRun, &lengthRun);
 
+                            if (startRun >= end) {
+                                continue;
+                            }
+                            int32_t endRun = startRun + lengthRun;
+                            if (endRun <= start) {
+                                continue;
+                            }
+                            if (startRun < start) {
+                                startRun = start;
+                            }
+                            if (endRun > end) {
+                                endRun = end;
+                            }
+
+                            lengthRun = endRun - startRun;
                             bool isRTL = (runDir == UBIDI_RTL);
                             jfloat runTotalAdvance = 0;
 #if DEBUG_GLYPHS
                             LOGD("computeValuesWithHarfbuzz -- run-start=%d run-len=%d isRTL=%d",
                                     startRun, lengthRun, isRTL);
 #endif
-                            computeRunValuesWithHarfbuzz(paint, chars, startRun,
-                                    lengthRun, contextCount, isRTL,
-                                    outAdvances, &runTotalAdvance,
-                                    outGlyphs, outLogClusters);
+                            computeRunValuesWithHarfbuzz(shaperItem, paint,
+                                    startRun, lengthRun, isRTL,
+                                    outAdvances, &runTotalAdvance, outGlyphs);
 
                             *outTotalAdvance += runTotalAdvance;
                         }
@@ -464,12 +499,17 @@
                 bool isRTL = (bidiReq = 1) || (bidiReq = UBIDI_DEFAULT_RTL);
 #if DEBUG_GLYPHS
                 LOGD("computeValuesWithHarfbuzz -- cannot run BiDi, considering a SINGLE Run "
-                        "-- run-start=%d run-len=%d isRTL=%d", 0, contextCount, isRTL);
+                        "-- run-start=%d run-len=%d isRTL=%d", start, count, isRTL);
 #endif
-                computeRunValuesWithHarfbuzz(paint, chars, 0, contextCount, contextCount, isRTL,
-                        outAdvances, outTotalAdvance, outGlyphs, outLogClusters);
+                computeRunValuesWithHarfbuzz(shaperItem, paint,
+                        start, count, isRTL,
+                        outAdvances, outTotalAdvance, outGlyphs);
             }
         }
+
+        // Cleaning
+        freeShaperItem(shaperItem);
+
 #if DEBUG_GLYPHS
         LOGD("computeValuesWithHarfbuzz -- total-glyphs-count=%d", outGlyphs->size());
 #endif
@@ -484,17 +524,12 @@
     }
 }
 
-void TextLayoutCacheValue::computeRunValuesWithHarfbuzz(SkPaint* paint, const UChar* chars,
-        size_t start, size_t count, size_t contextCount, bool isRTL,
+void TextLayoutCacheValue::computeRunValuesWithHarfbuzz(HB_ShaperItem& shaperItem, SkPaint* paint,
+        size_t start, size_t count, bool isRTL,
         Vector<jfloat>* const outAdvances, jfloat* outTotalAdvance,
-        Vector<jchar>* const outGlyphs, Vector<unsigned short>* const outLogClusters) {
+        Vector<jchar>* const outGlyphs) {
 
-    HB_ShaperItem shaperItem;
-    HB_FontRec font;
-    FontData fontData;
-
-    shapeWithHarfbuzz(&shaperItem, &font, &fontData, paint, chars, start, count,
-            contextCount, isRTL);
+    shapeRun(shaperItem, start, count, isRTL);
 
 #if DEBUG_GLYPHS
     LOGD("HARFBUZZ -- num_glypth=%d - kerning_applied=%d", shaperItem.num_glyphs,
@@ -511,10 +546,6 @@
 #endif
         outAdvances->insertAt(0, outAdvances->size(), count);
         *outTotalAdvance = 0;
-
-        // Cleaning
-        deleteGlyphArrays(&shaperItem);
-        HB_FreeFace(shaperItem.face);
         return;
     }
 
@@ -553,103 +584,21 @@
             outGlyphs->add(glyph);
         }
     }
-
-    // Get LogClusters
-    if (outLogClusters) {
-        size_t countLogClusters = outLogClusters->size();
-        for (size_t i = 0; i < count; i++) {
-            // As there may be successive runs, we need to shift the log clusters
-            unsigned short logCluster = shaperItem.log_clusters[i] + countLogClusters;
-#if DEBUG_GLYPHS
-            LOGD("HARFBUZZ  -- logCluster[%d] relative=%d - absolute=%d", i, shaperItem.log_clusters[i], logCluster);
-#endif
-            outLogClusters->add(logCluster);
-        }
-    }
-
-    // Cleaning
-    deleteGlyphArrays(&shaperItem);
-    HB_FreeFace(shaperItem.face);
 }
 
-void TextLayoutCacheValue::deleteGlyphArrays(HB_ShaperItem* shaperItem) {
-    delete[] shaperItem->glyphs;
-    delete[] shaperItem->attributes;
-    delete[] shaperItem->advances;
-    delete[] shaperItem->offsets;
+void TextLayoutCacheValue::deleteGlyphArrays(HB_ShaperItem& shaperItem) {
+    delete[] shaperItem.glyphs;
+    delete[] shaperItem.attributes;
+    delete[] shaperItem.advances;
+    delete[] shaperItem.offsets;
 }
 
-void TextLayoutCacheValue::createGlyphArrays(HB_ShaperItem* shaperItem, int size) {
-    shaperItem->glyphs = new HB_Glyph[size];
-    shaperItem->attributes = new HB_GlyphAttributes[size];
-    shaperItem->advances = new HB_Fixed[size];
-    shaperItem->offsets = new HB_FixedPoint[size];
-    shaperItem->num_glyphs = size;
-}
-
-void TextLayoutCacheValue::resetGlyphArrays(HB_ShaperItem* shaperItem) {
-    int size = shaperItem->num_glyphs;
-    // All the types here don't have pointers. It is safe to reset to
-    // zero unless Harfbuzz breaks the compatibility in the future.
-    memset(shaperItem->glyphs, 0, size * sizeof(shaperItem->glyphs[0]));
-    memset(shaperItem->attributes, 0, size * sizeof(shaperItem->attributes[0]));
-    memset(shaperItem->advances, 0, size * sizeof(shaperItem->advances[0]));
-    memset(shaperItem->offsets, 0, size * sizeof(shaperItem->offsets[0]));
-}
-
-void TextLayoutCacheValue::getAdvances(size_t start, size_t count, jfloat* outAdvances) const {
-    memcpy(outAdvances, mAdvances.array() + start, count * sizeof(jfloat));
-#if DEBUG_ADVANCES
-    LOGD("getAdvances - start=%d count=%d", start, count);
-    for (size_t i = 0; i < count; i++) {
-        LOGD("  adv[%d] = %f", i, outAdvances[i]);
-    }
-#endif
-}
-
-jfloat TextLayoutCacheValue::getTotalAdvance(size_t start, size_t count) const {
-    jfloat outTotalAdvance = 0;
-    for (size_t i = start; i < start + count; i++) {
-        outTotalAdvance += mAdvances[i];
-    }
-#if DEBUG_ADVANCES
-    LOGD("getTotalAdvance - start=%d count=%d - total=%f", start, count, outTotalAdvance);
-#endif
-     return outTotalAdvance;
-}
-
-void TextLayoutCacheValue::getGlyphsIndexAndCount(size_t start, size_t count, size_t* outStartIndex,
-        size_t* outGlyphsCount) const {
-    *outStartIndex = 0;
-    if (count == 0) {
-        *outGlyphsCount = 0;
-        return;
-    }
-    *outStartIndex = mLogClusters[start];
-    size_t endIndex = (start + count >= mAdvances.size()) ?
-            mGlyphs.size() : mLogClusters[start + count];
-    *outGlyphsCount = endIndex - *outStartIndex;
-#if DEBUG_GLYPHS
-    LOGD("getGlyphsIndexes - start=%d count=%d - startIndex=%d count=%d", start, count,
-            *outStartIndex, *outGlyphsCount);
-    for(size_t i = 0; i < mGlyphs.size(); i++) {
-        LOGD("getGlyphs - all - glyph[%d] = %d", i, mGlyphs[i]);
-    }
-    for(size_t i = 0; i < mAdvances.size(); i++) {
-        LOGD("getGlyphs - all - logcl[%d] = %d", i, mLogClusters[i]);
-    }
-#endif
-}
-
-const jchar* TextLayoutCacheValue::getGlyphs(size_t startIndex, size_t count) {
-    const jchar* glyphs = mGlyphs.array() + startIndex;
-#if DEBUG_GLYPHS
-    LOGD("getGlyphs - with startIndex = %d  count = %d", startIndex, count);
-    for (size_t i = 0; i < count; i++) {
-        LOGD("getGlyphs - result - glyph[%d] = %d", i, glyphs[i]);
-    }
-#endif
-    return glyphs;
+void TextLayoutCacheValue::createGlyphArrays(HB_ShaperItem& shaperItem, int size) {
+    shaperItem.glyphs = new HB_Glyph[size];
+    shaperItem.attributes = new HB_GlyphAttributes[size];
+    shaperItem.advances = new HB_Fixed[size];
+    shaperItem.offsets = new HB_FixedPoint[size];
+    shaperItem.num_glyphs = size;
 }
 
 } // namespace android
diff --git a/core/jni/android/graphics/TextLayoutCache.h b/core/jni/android/graphics/TextLayoutCache.h
index 6dda1e5..580079d 100644
--- a/core/jni/android/graphics/TextLayoutCache.h
+++ b/core/jni/android/graphics/TextLayoutCache.h
@@ -68,7 +68,8 @@
 public:
     TextLayoutCacheKey();
 
-    TextLayoutCacheKey(const SkPaint* paint, const UChar* text, size_t count, int dirFlags);
+    TextLayoutCacheKey(const SkPaint* paint, const UChar* text, size_t start, size_t count,
+            size_t contextCount, int dirFlags);
 
     TextLayoutCacheKey(const TextLayoutCacheKey& other);
 
@@ -88,7 +89,9 @@
 private:
     const UChar* text; // if text is NULL, use textCopy
     String16 textCopy;
+    size_t start;
     size_t count;
+    size_t contextCount;
     int dirFlags;
     SkTypeface* typeface;
     SkScalar textSize;
@@ -119,32 +122,20 @@
     void setElapsedTime(uint32_t time);
     uint32_t getElapsedTime();
 
-    void computeValues(SkPaint* paint, const UChar* chars, size_t contextCount, int dirFlags);
+    void computeValues(SkPaint* paint, const UChar* chars, size_t start, size_t count,
+            size_t contextCount, int dirFlags);
 
-    void    getAdvances(size_t start, size_t count, jfloat* outAdvances) const;
-    jfloat  getTotalAdvance(size_t start, size_t count) const;
-    void    getGlyphsIndexAndCount(size_t start, size_t count, size_t* outStartIndex,
-                size_t* outGlyphsCount) const;
-    const jchar*  getGlyphs(size_t startIndex, size_t count);
+    inline const jfloat* getAdvances() const { return mAdvances.array(); }
+    inline size_t getAdvancesCount() const { return mAdvances.size(); }
+    inline jfloat getTotalAdvance() const { return mTotalAdvance; }
+    inline const jchar* getGlyphs() const { return mGlyphs.array(); }
+    inline size_t getGlyphsCount() const { return mGlyphs.size(); }
 
     /**
      * Get the size of the Cache entry
      */
     size_t getSize();
 
-    static void setupShaperItem(HB_ShaperItem* shaperItem, HB_FontRec* font, FontData* fontData,
-            SkPaint* paint, const UChar* chars, size_t start, size_t count, size_t contextCount,
-            bool isRTL);
-
-    static void shapeWithHarfbuzz(HB_ShaperItem* shaperItem, HB_FontRec* font, FontData* fontData,
-            SkPaint* paint, const UChar* chars, size_t start, size_t count, size_t contextCount,
-            bool isRTL);
-
-    static void computeValuesWithHarfbuzz(SkPaint* paint, const UChar* chars,
-            size_t contextCount, int dirFlags,
-            Vector<jfloat>* const outAdvances, jfloat* outTotalAdvance,
-            Vector<jchar>* const outGlyphs, Vector<unsigned short>* const outLogClusters);
-
 private:
     /**
      * Advances vector
@@ -162,23 +153,31 @@
     Vector<jchar> mGlyphs;
 
     /**
-     * Harfbuzz Log Clusters
-     */
-    Vector<unsigned short> mLogClusters;
-
-    /**
      * Time for computing the values (in milliseconds)
      */
     uint32_t mElapsedTime;
 
-    static void deleteGlyphArrays(HB_ShaperItem* shaperItem);
-    static void createGlyphArrays(HB_ShaperItem* shaperItem, int size);
-    static void resetGlyphArrays(HB_ShaperItem* shaperItem);
-
-    static void computeRunValuesWithHarfbuzz(SkPaint* paint, const UChar* chars, size_t start,
-            size_t count, size_t contextCount, bool isRTL,
+    static void computeValuesWithHarfbuzz(SkPaint* paint, const UChar* chars,
+            size_t start, size_t count, size_t contextCount, int dirFlags,
             Vector<jfloat>* const outAdvances, jfloat* outTotalAdvance,
-            Vector<jchar>* const outGlyphs, Vector<unsigned short>* const outLogClusters);
+            Vector<jchar>* const outGlyphs);
+
+    static void computeRunValuesWithHarfbuzz(HB_ShaperItem& shaperItem, SkPaint* paint,
+            size_t start, size_t count, bool isRTL,
+            Vector<jfloat>* const outAdvances, jfloat* outTotalAdvance,
+            Vector<jchar>* const outGlyphs);
+
+    static void initShaperItem(HB_ShaperItem& shaperItem, HB_FontRec* font, FontData* fontData,
+            SkPaint* paint, const UChar* chars, size_t contextCount);
+
+    static void freeShaperItem(HB_ShaperItem& shaperItem);
+
+    static void shapeRun(HB_ShaperItem& shaperItem, size_t start, size_t count, bool isRTL);
+
+    static void deleteGlyphArrays(HB_ShaperItem& shaperItem);
+
+    static void createGlyphArrays(HB_ShaperItem& shaperItem, int size);
+
 }; // TextLayoutCacheValue
 
 /**
@@ -202,8 +201,8 @@
      */
     void operator()(TextLayoutCacheKey& text, sp<TextLayoutCacheValue>& desc);
 
-    sp<TextLayoutCacheValue> getValue(SkPaint* paint, const jchar* text, jint count,
-            jint dirFlags);
+    sp<TextLayoutCacheValue> getValue(SkPaint* paint, const jchar* text, jint start, jint count,
+            jint contextCount, jint dirFlags);
 
     /**
      * Clear the cache
@@ -256,6 +255,7 @@
      * Dump Cache statistics
      */
     void dumpCacheStats();
+
 }; // TextLayoutCache
 
 } // namespace android
diff --git a/core/jni/android_database_CursorWindow.cpp b/core/jni/android_database_CursorWindow.cpp
index 419e464..14c6397 100644
--- a/core/jni/android_database_CursorWindow.cpp
+++ b/core/jni/android_database_CursorWindow.cpp
@@ -24,6 +24,7 @@
 #include <utils/Log.h>
 #include <utils/String8.h>
 #include <utils/String16.h>
+#include <utils/Unicode.h>
 
 #include <stdio.h>
 #include <string.h>
@@ -33,69 +34,75 @@
 #include "sqlite3_exception.h"
 #include "android_util_Binder.h"
 
-
 namespace android {
 
-static jfieldID gWindowField;
-static jfieldID gBufferField;
-static jfieldID gSizeCopiedField;
+static struct {
+    jfieldID data;
+    jfieldID sizeCopied;
+} gCharArrayBufferClassInfo;
 
-#define GET_WINDOW(env, object) ((CursorWindow *)env->GetIntField(object, gWindowField))
-#define SET_WINDOW(env, object, window) (env->SetIntField(object, gWindowField, (int)window))
-#define SET_BUFFER(env, object, buf) (env->SetObjectField(object, gBufferField, buf))
-#define SET_SIZE_COPIED(env, object, size) (env->SetIntField(object, gSizeCopiedField, size))
+static jstring gEmptyString;
 
-CursorWindow * get_window_from_object(JNIEnv * env, jobject javaWindow)
-{
-    return GET_WINDOW(env, javaWindow);
+static void throwExceptionWithRowCol(JNIEnv* env, jint row, jint column) {
+    String8 msg;
+    msg.appendFormat("Couldn't read row %d, col %d from CursorWindow.  "
+            "Make sure the Cursor is initialized correctly before accessing data from it.",
+            row, column);
+    jniThrowException(env, "java/lang/IllegalStateException", msg.string());
 }
 
-static jint native_init_empty(JNIEnv * env, jobject object, jint cursorWindowSize,
-        jboolean localOnly)
-{
-    uint8_t * data;
-    size_t size;
-    CursorWindow * window;
+static void throwUnknownTypeException(JNIEnv * env, jint type) {
+    String8 msg;
+    msg.appendFormat("UNKNOWN type %d", type);
+    jniThrowException(env, "java/lang/IllegalStateException", msg.string());
+}
 
-    window = new CursorWindow(cursorWindowSize);
+static jint nativeInitializeEmpty(JNIEnv* env, jclass clazz,
+        jint cursorWindowSize, jboolean localOnly) {
+    CursorWindow* window = new CursorWindow(cursorWindowSize);
     if (!window) {
-        return 1;
+        return 0;
     }
     if (!window->initBuffer(localOnly)) {
         delete window;
-        return 1;
+        return 0;
     }
 
-    LOG_WINDOW("native_init_empty: window = %p", window);
-    SET_WINDOW(env, object, window);
-    return 0;
+    LOG_WINDOW("nativeInitializeEmpty: window = %p", window);
+    return reinterpret_cast<jint>(window);
 }
 
-static jint native_init_memory(JNIEnv * env, jobject object, jobject memObj)
-{
-    sp<IMemory> memory = interface_cast<IMemory>(ibinderForJavaObject(env, memObj));
+static jint nativeInitializeFromBinder(JNIEnv* env, jclass clazz, jobject binderObj) {
+    sp<IMemory> memory = interface_cast<IMemory>(ibinderForJavaObject(env, binderObj));
     if (memory == NULL) {
         jniThrowException(env, "java/lang/IllegalStateException", "Couldn't get native binder");
-        return 1;
+        return 0;
     }
 
-    CursorWindow * window = new CursorWindow();
+    CursorWindow* window = new CursorWindow();
     if (!window) {
-        return 1;
+        return 0;
     }
     if (!window->setMemory(memory)) {
         delete window;
-        return 1;
+        return 0;
     }
 
-    LOG_WINDOW("native_init_memory: numRows = %d, numColumns = %d, window = %p", window->getNumRows(), window->getNumColumns(), window);
-    SET_WINDOW(env, object, window);
-    return 0;
+    LOG_WINDOW("nativeInitializeFromBinder: numRows = %d, numColumns = %d, window = %p",
+            window->getNumRows(), window->getNumColumns(), window);
+    return reinterpret_cast<jint>(window);
 }
 
-static jobject native_getBinder(JNIEnv * env, jobject object)
-{
-    CursorWindow * window = GET_WINDOW(env, object);
+static void nativeDispose(JNIEnv* env, jclass clazz, jint windowPtr) {
+    CursorWindow* window = reinterpret_cast<CursorWindow*>(windowPtr);
+    if (window) {
+        LOG_WINDOW("Closing window %p", window);
+        delete window;
+    }
+}
+
+static jobject nativeGetBinder(JNIEnv * env, jclass clazz, jint windowPtr) {
+    CursorWindow* window = reinterpret_cast<CursorWindow*>(windowPtr);
     if (window) {
         sp<IMemory> memory = window->getMemory();
         if (memory != NULL) {
@@ -106,568 +113,484 @@
     return NULL;
 }
 
-static void native_clear(JNIEnv * env, jobject object)
-{
-    CursorWindow * window = GET_WINDOW(env, object);
-LOG_WINDOW("Clearing window %p", window);
-    if (window == NULL) {
-        jniThrowException(env, "java/lang/IllegalStateException", "clear() called after close()");
-        return;
-    }
+static void nativeClear(JNIEnv * env, jclass clazz, jint windowPtr) {
+    CursorWindow* window = reinterpret_cast<CursorWindow*>(windowPtr);
+    LOG_WINDOW("Clearing window %p", window);
     window->clear();
 }
 
-static void native_close(JNIEnv * env, jobject object)
-{
-    CursorWindow * window = GET_WINDOW(env, object);
-    if (window) {
-LOG_WINDOW("Closing window %p", window);
-        delete window;
-        SET_WINDOW(env, object, 0);
+static jint nativeGetNumRows(JNIEnv* env, jclass clazz, jint windowPtr) {
+    CursorWindow* window = reinterpret_cast<CursorWindow*>(windowPtr);
+    return window->getNumRows();
+}
+
+static jboolean nativeSetNumColumns(JNIEnv* env, jclass clazz, jint windowPtr,
+        jint columnNum) {
+    CursorWindow* window = reinterpret_cast<CursorWindow*>(windowPtr);
+    return window->setNumColumns(columnNum);
+}
+
+static jboolean nativeAllocRow(JNIEnv* env, jclass clazz, jint windowPtr) {
+    CursorWindow* window = reinterpret_cast<CursorWindow*>(windowPtr);
+    return window->allocRow() != NULL;
+}
+
+static void nativeFreeLastRow(JNIEnv* env, jclass clazz, jint windowPtr) {
+    CursorWindow* window = reinterpret_cast<CursorWindow*>(windowPtr);
+    window->freeLastRow();
+}
+
+static jint nativeGetType(JNIEnv* env, jclass clazz, jint windowPtr,
+        jint row, jint column) {
+    CursorWindow* window = reinterpret_cast<CursorWindow*>(windowPtr);
+    LOG_WINDOW("returning column type affinity for %d,%d from %p", row, column, window);
+
+    field_slot_t* fieldSlot = window->getFieldSlotWithCheck(row, column);
+    if (!fieldSlot) {
+        throwExceptionWithRowCol(env, row, column);
+        return NULL;
+    }
+    return fieldSlot->type;
+}
+
+static jbyteArray nativeGetBlob(JNIEnv* env, jclass clazz, jint windowPtr,
+        jint row, jint column) {
+    CursorWindow* window = reinterpret_cast<CursorWindow*>(windowPtr);
+    LOG_WINDOW("Getting blob for %d,%d from %p", row, column, window);
+
+    field_slot_t* fieldSlot = window->getFieldSlotWithCheck(row, column);
+    if (!fieldSlot) {
+        throwExceptionWithRowCol(env, row, column);
+        return NULL;
+    }
+
+    uint8_t type = fieldSlot->type;
+    if (type == FIELD_TYPE_BLOB || type == FIELD_TYPE_STRING) {
+        uint32_t size = fieldSlot->data.buffer.size;
+        jbyteArray byteArray = env->NewByteArray(size);
+        if (!byteArray) {
+            env->ExceptionClear();
+            throw_sqlite3_exception(env, "Native could not create new byte[]");
+            return NULL;
+        }
+        env->SetByteArrayRegion(byteArray, 0, size,
+                reinterpret_cast<jbyte*>(window->offsetToPtr(fieldSlot->data.buffer.offset)));
+        return byteArray;
+    } else if (type == FIELD_TYPE_INTEGER) {
+        throw_sqlite3_exception(env, "INTEGER data in nativeGetBlob ");
+    } else if (type == FIELD_TYPE_FLOAT) {
+        throw_sqlite3_exception(env, "FLOAT data in nativeGetBlob ");
+    } else if (type == FIELD_TYPE_NULL) {
+        // do nothing
+    } else {
+        throwUnknownTypeException(env, type);
+    }
+    return NULL;
+}
+
+static jstring nativeGetString(JNIEnv* env, jclass clazz, jint windowPtr,
+        jint row, jint column) {
+    CursorWindow* window = reinterpret_cast<CursorWindow*>(windowPtr);
+    LOG_WINDOW("Getting string for %d,%d from %p", row, column, window);
+
+    field_slot_t* fieldSlot = window->getFieldSlotWithCheck(row, column);
+    if (!fieldSlot) {
+        throwExceptionWithRowCol(env, row, column);
+        return NULL;
+    }
+
+    uint8_t type = fieldSlot->type;
+    if (type == FIELD_TYPE_STRING) {
+        uint32_t size = fieldSlot->data.buffer.size;
+#if WINDOW_STORAGE_UTF8
+        return size > 1 ? env->NewStringUTF(window->getFieldSlotValueString(fieldSlot))
+                : gEmptyString;
+#else
+        size_t chars = size / sizeof(char16_t);
+        return chars ? env->NewString(reinterpret_cast<jchar*>(
+                window->getFieldSlotValueString(fieldSlot)), chars)
+                : gEmptyString;
+#endif
+    } else if (type == FIELD_TYPE_INTEGER) {
+        int64_t value = window->getFieldSlotValueLong(fieldSlot);
+        char buf[32];
+        snprintf(buf, sizeof(buf), "%lld", value);
+        return env->NewStringUTF(buf);
+    } else if (type == FIELD_TYPE_FLOAT) {
+        double value = window->getFieldSlotValueDouble(fieldSlot);
+        char buf[32];
+        snprintf(buf, sizeof(buf), "%g", value);
+        return env->NewStringUTF(buf);
+    } else if (type == FIELD_TYPE_NULL) {
+        return NULL;
+    } else if (type == FIELD_TYPE_BLOB) {
+        throw_sqlite3_exception(env, "Unable to convert BLOB to string");
+        return NULL;
+    } else {
+        throwUnknownTypeException(env, type);
+        return NULL;
     }
 }
 
-static void throwExceptionWithRowCol(JNIEnv * env, jint row, jint column)
-{
-    char buf[200];
-    snprintf(buf, sizeof(buf), "Couldn't read row %d, col %d from CursorWindow. Make sure the Cursor is initialized correctly before accessing data from it",
-            row, column);
-    jniThrowException(env, "java/lang/IllegalStateException", buf);
+static jcharArray allocCharArrayBuffer(JNIEnv* env, jobject bufferObj, size_t size) {
+    jcharArray dataObj = jcharArray(env->GetObjectField(bufferObj,
+            gCharArrayBufferClassInfo.data));
+    if (dataObj && size) {
+        jsize capacity = env->GetArrayLength(dataObj);
+        if (size_t(capacity) < size) {
+            env->DeleteLocalRef(dataObj);
+            dataObj = NULL;
+        }
+    }
+    if (!dataObj) {
+        jsize capacity = size;
+        if (capacity < 64) {
+            capacity = 64;
+        }
+        dataObj = env->NewCharArray(capacity); // might throw OOM
+        if (dataObj) {
+            env->SetObjectField(bufferObj, gCharArrayBufferClassInfo.data, dataObj);
+        }
+    }
+    return dataObj;
 }
 
-static void throwUnknowTypeException(JNIEnv * env, jint type)
-{
-    char buf[80];
-    snprintf(buf, sizeof(buf), "UNKNOWN type %d", type);
-    jniThrowException(env, "java/lang/IllegalStateException", buf);
+static void fillCharArrayBufferUTF(JNIEnv* env, jobject bufferObj,
+        const char* str, size_t len) {
+    ssize_t size = utf8_to_utf16_length(reinterpret_cast<const uint8_t*>(str), len);
+    if (size < 0) {
+        size = 0; // invalid UTF8 string
+    }
+    jcharArray dataObj = allocCharArrayBuffer(env, bufferObj, size);
+    if (dataObj) {
+        if (size) {
+            jchar* data = static_cast<jchar*>(env->GetPrimitiveArrayCritical(dataObj, NULL));
+            utf8_to_utf16(reinterpret_cast<const uint8_t*>(str), len,
+                    reinterpret_cast<char16_t*>(data));
+            env->ReleasePrimitiveArrayCritical(dataObj, data, 0);
+        }
+        env->SetIntField(bufferObj, gCharArrayBufferClassInfo.sizeCopied, size);
+    }
 }
 
-static jlong getLong_native(JNIEnv * env, jobject object, jint row, jint column)
-{
-    int32_t err;
-    CursorWindow * window = GET_WINDOW(env, object);
-LOG_WINDOW("Getting long for %d,%d from %p", row, column, window);
+#if !WINDOW_STORAGE_UTF8
+static void fillCharArrayBuffer(JNIEnv* env, jobject bufferObj,
+        const char16_t* str, size_t len) {
+    jcharArray dataObj = allocCharArrayBuffer(env, bufferObj, len);
+    if (dataObj) {
+        if (len) {
+            jchar* data = static_cast<jchar*>(env->GetPrimitiveArrayCritical(dataObj, NULL));
+            memcpy(data, str, len * sizeof(jchar));
+            env->ReleasePrimitiveArrayCritical(dataObj, data, 0);
+        }
+        env->SetIntField(bufferObj, gCharArrayBufferClassInfo.sizeCopied, len);
+    }
+}
+#endif
 
-    field_slot_t field;
-    err = window->read_field_slot(row, column, &field);
-    if (err != 0) {
+static void clearCharArrayBuffer(JNIEnv* env, jobject bufferObj) {
+    jcharArray dataObj = allocCharArrayBuffer(env, bufferObj, 0);
+    if (dataObj) {
+        env->SetIntField(bufferObj, gCharArrayBufferClassInfo.sizeCopied, 0);
+    }
+}
+
+static void nativeCopyStringToBuffer(JNIEnv* env, jclass clazz, jint windowPtr,
+        jint row, jint column, jobject bufferObj) {
+    CursorWindow* window = reinterpret_cast<CursorWindow*>(windowPtr);
+    LOG_WINDOW("Copying string for %d,%d from %p", row, column, window);
+
+    field_slot_t* fieldSlot = window->getFieldSlotWithCheck(row, column);
+    if (!fieldSlot) {
+        throwExceptionWithRowCol(env, row, column);
+        return;
+    }
+
+    uint8_t type = fieldSlot->type;
+    if (type == FIELD_TYPE_STRING) {
+        uint32_t size = fieldSlot->data.buffer.size;
+#if WINDOW_STORAGE_UTF8
+        if (size > 1) {
+            fillCharArrayBufferUTF(env, bufferObj,
+                    window->getFieldSlotValueString(fieldSlot), size - 1);
+        } else {
+            clearCharArrayBuffer(env, bufferObj);
+        }
+#else
+        size_t chars = size / sizeof(char16_t);
+        if (chars) {
+            fillCharArrayBuffer(env, bufferObj,
+                    window->getFieldSlotValueString(fieldSlot), chars);
+        } else {
+            clearCharArrayBuffer(env, bufferObj);
+        }
+#endif
+    } else if (type == FIELD_TYPE_INTEGER) {
+        int64_t value = window->getFieldSlotValueLong(fieldSlot);
+        char buf[32];
+        snprintf(buf, sizeof(buf), "%lld", value);
+        fillCharArrayBufferUTF(env, bufferObj, buf, strlen(buf));
+    } else if (type == FIELD_TYPE_FLOAT) {
+        double value = window->getFieldSlotValueDouble(fieldSlot);
+        char buf[32];
+        snprintf(buf, sizeof(buf), "%g", value);
+        fillCharArrayBufferUTF(env, bufferObj, buf, strlen(buf));
+    } else if (type == FIELD_TYPE_NULL) {
+        clearCharArrayBuffer(env, bufferObj);
+    } else if (type == FIELD_TYPE_BLOB) {
+        throw_sqlite3_exception(env, "Unable to convert BLOB to string");
+    } else {
+        throwUnknownTypeException(env, type);
+    }
+}
+
+static jlong nativeGetLong(JNIEnv* env, jclass clazz, jint windowPtr,
+        jint row, jint column) {
+    CursorWindow* window = reinterpret_cast<CursorWindow*>(windowPtr);
+    LOG_WINDOW("Getting long for %d,%d from %p", row, column, window);
+
+    field_slot_t* fieldSlot = window->getFieldSlotWithCheck(row, column);
+    if (!fieldSlot) {
         throwExceptionWithRowCol(env, row, column);
         return 0;
     }
 
-    uint8_t type = field.type;
+    uint8_t type = fieldSlot->type;
     if (type == FIELD_TYPE_INTEGER) {
-        int64_t value;
-        if (window->getLong(row, column, &value)) {
-            return value;
-        }
-        return 0;
+        return window->getFieldSlotValueLong(fieldSlot);
     } else if (type == FIELD_TYPE_STRING) {
-        uint32_t size = field.data.buffer.size;
-        if (size > 0) {
+        uint32_t size = fieldSlot->data.buffer.size;
 #if WINDOW_STORAGE_UTF8
-            return strtoll((char const *)window->offsetToPtr(field.data.buffer.offset), NULL, 0);
+        return size > 1 ? strtoll(window->getFieldSlotValueString(fieldSlot), NULL, 0) : 0L;
 #else
-            String8 ascii((char16_t *) window->offsetToPtr(field.data.buffer.offset), size / 2);
-            char const * str = ascii.string();
-            return strtoll(str, NULL, 0);
+        size_t chars = size / sizeof(char16_t);
+        return chars ? strtoll(String8(window->getFieldSlotValueString(fieldSlot), chars)
+                .string(), NULL, 0) : 0L;
 #endif
-        } else {
-            return 0;
-        }
     } else if (type == FIELD_TYPE_FLOAT) {
-        double value;
-        if (window->getDouble(row, column, &value)) {
-            return value;
-        }
-        return 0;
+        return jlong(window->getFieldSlotValueDouble(fieldSlot));
     } else if (type == FIELD_TYPE_NULL) {
         return 0;
     } else if (type == FIELD_TYPE_BLOB) {
         throw_sqlite3_exception(env, "Unable to convert BLOB to long");
         return 0;
     } else {
-        throwUnknowTypeException(env, type);
+        throwUnknownTypeException(env, type);
         return 0;
     }
 }
 
-static jbyteArray getBlob_native(JNIEnv* env, jobject object, jint row, jint column)
-{
-    int32_t err;
-    CursorWindow * window = GET_WINDOW(env, object);
-LOG_WINDOW("Getting blob for %d,%d from %p", row, column, window);
+static jdouble nativeGetDouble(JNIEnv* env, jclass clazz, jint windowPtr,
+        jint row, jint column) {
+    CursorWindow* window = reinterpret_cast<CursorWindow*>(windowPtr);
+    LOG_WINDOW("Getting double for %d,%d from %p", row, column, window);
 
-    field_slot_t field;
-    err = window->read_field_slot(row, column, &field);
-    if (err != 0) {
-        throwExceptionWithRowCol(env, row, column);
-        return NULL;
-    }
-
-    uint8_t type = field.type;
-    if (type == FIELD_TYPE_BLOB || type == FIELD_TYPE_STRING) {
-        jbyteArray byteArray = env->NewByteArray(field.data.buffer.size);
-        if (!byteArray) {
-            throw_sqlite3_exception(env, "Native could not create new byte[]");
-            return NULL;
-        }
-        env->SetByteArrayRegion(byteArray, 0, field.data.buffer.size,
-            (const jbyte*)window->offsetToPtr(field.data.buffer.offset));
-        return byteArray;
-    } else if (type == FIELD_TYPE_INTEGER) {
-        throw_sqlite3_exception(env, "INTEGER data in getBlob_native ");
-    } else if (type == FIELD_TYPE_FLOAT) {
-        throw_sqlite3_exception(env, "FLOAT data in getBlob_native ");
-    } else if (type == FIELD_TYPE_NULL) {
-        // do nothing
-    } else {
-        throwUnknowTypeException(env, type);
-    }
-    return NULL;
-}
-
-static jstring getString_native(JNIEnv* env, jobject object, jint row, jint column)
-{
-    int32_t err;
-    CursorWindow * window = GET_WINDOW(env, object);
-LOG_WINDOW("Getting string for %d,%d from %p", row, column, window);
-
-    field_slot_t field;
-    err = window->read_field_slot(row, column, &field);
-    if (err != 0) {
-        throwExceptionWithRowCol(env, row, column);
-        return NULL;
-    }
-
-    uint8_t type = field.type;
-    if (type == FIELD_TYPE_STRING) {
-        uint32_t size = field.data.buffer.size;
-        if (size > 0) {
-#if WINDOW_STORAGE_UTF8
-            // Pass size - 1 since the UTF8 is null terminated and we don't want a null terminator on the UTF16 string
-            String16 utf16((char const *)window->offsetToPtr(field.data.buffer.offset), size - 1);
-            return env->NewString((jchar const *)utf16.string(), utf16.size());
-#else
-            return env->NewString((jchar const *)window->offsetToPtr(field.data.buffer.offset), size / 2);
-#endif
-        } else {
-            return env->NewStringUTF("");
-        }
-    } else if (type == FIELD_TYPE_INTEGER) {
-        int64_t value;
-        if (window->getLong(row, column, &value)) {
-            char buf[32];
-            snprintf(buf, sizeof(buf), "%lld", value);
-            return env->NewStringUTF(buf);
-        }
-        return NULL;
-    } else if (type == FIELD_TYPE_FLOAT) {
-        double value;
-        if (window->getDouble(row, column, &value)) {
-            char buf[32];
-            snprintf(buf, sizeof(buf), "%g", value);
-            return env->NewStringUTF(buf);
-        }
-        return NULL;
-    } else if (type == FIELD_TYPE_NULL) {
-        return NULL;
-    } else if (type == FIELD_TYPE_BLOB) {
-        throw_sqlite3_exception(env, "Unable to convert BLOB to string");
-        return NULL;
-    } else {
-        throwUnknowTypeException(env, type);
-        return NULL;
-    }
-}
-
-/**
- * Use this only to convert characters that are known to be within the
- * 0-127 range for direct conversion to UTF-16
- */
-static jint charToJchar(const char* src, jchar* dst, jint bufferSize)
-{
-    int32_t len = strlen(src);
-
-    if (bufferSize < len) {
-        len = bufferSize;
-    }
-
-    for (int i = 0; i < len; i++) {
-        *dst++ = (*src++ & 0x7F);
-    }
-    return len;
-}
-
-static jcharArray copyStringToBuffer_native(JNIEnv* env, jobject object, jint row,
-                                      jint column, jint bufferSize, jobject buf)
-{
-    int32_t err;
-    CursorWindow * window = GET_WINDOW(env, object);
-LOG_WINDOW("Copying string for %d,%d from %p", row, column, window);
-
-    field_slot_t field;
-    err = window->read_field_slot(row, column, &field);
-    if (err != 0) {
-        jniThrowException(env, "java/lang/IllegalStateException", "Unable to get field slot");
-        return NULL;
-    }
-
-    jcharArray buffer = (jcharArray)env->GetObjectField(buf, gBufferField);
-    if (buffer == NULL) {
-        jniThrowException(env, "java/lang/IllegalStateException", "buf should not be null");
-        return NULL;
-    }
-    jchar* dst = env->GetCharArrayElements(buffer, NULL);
-    uint8_t type = field.type;
-    uint32_t sizeCopied = 0;
-    jcharArray newArray = NULL;
-    if (type == FIELD_TYPE_STRING) {
-        uint32_t size = field.data.buffer.size;
-        if (size > 0) {
-#if WINDOW_STORAGE_UTF8
-            // Pass size - 1 since the UTF8 is null terminated and we don't want a null terminator on the UTF16 string
-            String16 utf16((char const *)window->offsetToPtr(field.data.buffer.offset), size - 1);
-            int32_t strSize = utf16.size();
-            if (strSize > bufferSize || dst == NULL) {
-                newArray = env->NewCharArray(strSize);
-                env->SetCharArrayRegion(newArray, 0, strSize, (jchar const *)utf16.string());
-            } else {
-                memcpy(dst, (jchar const *)utf16.string(), strSize * 2);
-            }
-            sizeCopied = strSize;
-#else
-            sizeCopied = size/2 + size % 2;
-            if (size > bufferSize * 2 || dst == NULL) {
-                newArray = env->NewCharArray(sizeCopied);
-                memcpy(newArray, (jchar const *)window->offsetToPtr(field.data.buffer.offset), size);
-            } else {
-                memcpy(dst, (jchar const *)window->offsetToPtr(field.data.buffer.offset), size);
-            }
-#endif
-        }
-    } else if (type == FIELD_TYPE_INTEGER) {
-        int64_t value;
-        if (window->getLong(row, column, &value)) {
-            char buf[32];
-            int len;
-            snprintf(buf, sizeof(buf), "%lld", value);
-            sizeCopied = charToJchar(buf, dst, bufferSize);
-         }
-    } else if (type == FIELD_TYPE_FLOAT) {
-        double value;
-        if (window->getDouble(row, column, &value)) {
-            char tempbuf[32];
-            snprintf(tempbuf, sizeof(tempbuf), "%g", value);
-            sizeCopied = charToJchar(tempbuf, dst, bufferSize);
-        }
-    } else if (type == FIELD_TYPE_NULL) {
-    } else if (type == FIELD_TYPE_BLOB) {
-        throw_sqlite3_exception(env, "Unable to convert BLOB to string");
-    } else {
-        LOGE("Unknown field type %d", type);
-        throw_sqlite3_exception(env, "UNKNOWN type in copyStringToBuffer_native()");
-    }
-    SET_SIZE_COPIED(env, buf, sizeCopied);
-    env->ReleaseCharArrayElements(buffer, dst, JNI_OK);
-    return newArray;
-}
-
-static jdouble getDouble_native(JNIEnv* env, jobject object, jint row, jint column)
-{
-    int32_t err;
-    CursorWindow * window = GET_WINDOW(env, object);
-LOG_WINDOW("Getting double for %d,%d from %p", row, column, window);
-
-    field_slot_t field;
-    err = window->read_field_slot(row, column, &field);
-    if (err != 0) {
+    field_slot_t* fieldSlot = window->getFieldSlotWithCheck(row, column);
+    if (!fieldSlot) {
         throwExceptionWithRowCol(env, row, column);
         return 0.0;
     }
 
-    uint8_t type = field.type;
+    uint8_t type = fieldSlot->type;
     if (type == FIELD_TYPE_FLOAT) {
-        double value;
-        if (window->getDouble(row, column, &value)) {
-            return value;
-        }
-        return 0.0;
+        return window->getFieldSlotValueDouble(fieldSlot);
     } else if (type == FIELD_TYPE_STRING) {
-        uint32_t size = field.data.buffer.size;
-        if (size > 0) {
+        uint32_t size = fieldSlot->data.buffer.size;
 #if WINDOW_STORAGE_UTF8
-            return strtod((char const *)window->offsetToPtr(field.data.buffer.offset), NULL);
+        return size > 1 ? strtod(window->getFieldSlotValueString(fieldSlot), NULL) : 0.0;
 #else
-            String8 ascii((char16_t *) window->offsetToPtr(field.data.buffer.offset), size / 2);
-            char const * str = ascii.string();
-            return strtod(str, NULL);
+        size_t chars = size / sizeof(char16_t);
+        return chars ? strtod(String8(window->getFieldSlotValueString(fieldSlot), chars)
+                .string(), NULL) : 0.0;
 #endif
-        } else {
-            return 0.0;
-        }
     } else if (type == FIELD_TYPE_INTEGER) {
-        int64_t value;
-        if (window->getLong(row, column, &value)) {
-            return (double) value;
-        }
-        return 0.0;
+        return jdouble(window->getFieldSlotValueLong(fieldSlot));
     } else if (type == FIELD_TYPE_NULL) {
         return 0.0;
     } else if (type == FIELD_TYPE_BLOB) {
         throw_sqlite3_exception(env, "Unable to convert BLOB to double");
         return 0.0;
     } else {
-        throwUnknowTypeException(env, type);
+        throwUnknownTypeException(env, type);
         return 0.0;
     }
 }
 
-bool isNull_native(CursorWindow *window, jint row, jint column)
-{
-    LOG_WINDOW("Checking for NULL at %d,%d from %p", row, column, window);
-
-    bool isNull;
-    if (window->getNull(row, column, &isNull)) {
-        return isNull;
-    }
-
-    //TODO throw execption?
-    return true;
-}
-
-static jint getNumRows(JNIEnv * env, jobject object)
-{
-    CursorWindow * window = GET_WINDOW(env, object);
-    return window->getNumRows();
-}
-
-static jboolean setNumColumns(JNIEnv * env, jobject object, jint columnNum)
-{
-    CursorWindow * window = GET_WINDOW(env, object);
-    return window->setNumColumns(columnNum);
-}
-
-static jboolean allocRow(JNIEnv * env, jobject object)
-{
-    CursorWindow * window = GET_WINDOW(env, object);
-    return window->allocRow() != NULL;
-}
-
-static jboolean putBlob_native(JNIEnv * env, jobject object, jbyteArray value, jint row, jint col)
-{
-    CursorWindow * window = GET_WINDOW(env, object);
-    if (!value) {
-        LOG_WINDOW("How did a null value send to here");
-        return false;
-    }
-    field_slot_t * fieldSlot = window->getFieldSlotWithCheck(row, col);
+static jboolean nativePutBlob(JNIEnv* env, jclass clazz, jint windowPtr,
+        jbyteArray valueObj, jint row, jint column) {
+    CursorWindow* window = reinterpret_cast<CursorWindow*>(windowPtr);
+    field_slot_t * fieldSlot = window->getFieldSlotWithCheck(row, column);
     if (fieldSlot == NULL) {
         LOG_WINDOW(" getFieldSlotWithCheck error ");
         return false;
     }
 
-    jint len = env->GetArrayLength(value);
-    int offset = window->alloc(len);
+    jsize len = env->GetArrayLength(valueObj);
+    uint32_t offset = window->alloc(len);
     if (!offset) {
         LOG_WINDOW("Failed allocating %u bytes", len);
         return false;
     }
-    jbyte * bytes = env->GetByteArrayElements(value, NULL);
-    window->copyIn(offset, (uint8_t const *)bytes, len);
 
-    // This must be updated after the call to alloc(), since that
-    // may move the field around in the window
+    void* value = env->GetPrimitiveArrayCritical(valueObj, NULL);
+    window->copyIn(offset, static_cast<const uint8_t*>(value), len);
+    env->ReleasePrimitiveArrayCritical(valueObj, value, JNI_ABORT);
+
     fieldSlot->type = FIELD_TYPE_BLOB;
     fieldSlot->data.buffer.offset = offset;
     fieldSlot->data.buffer.size = len;
-    env->ReleaseByteArrayElements(value, bytes, JNI_ABORT);
-    LOG_WINDOW("%d,%d is BLOB with %u bytes @ %d", row, col, len, offset);
+    LOG_WINDOW("%d,%d is BLOB with %u bytes @ %d", row, column, len, offset);
     return true;
 }
 
-static jboolean putString_native(JNIEnv * env, jobject object, jstring value, jint row, jint col)
-{
-    CursorWindow * window = GET_WINDOW(env, object);
-    if (!value) {
-        LOG_WINDOW("How did a null value send to here");
-        return false;
-    }
-    field_slot_t * fieldSlot = window->getFieldSlotWithCheck(row, col);
+static jboolean nativePutString(JNIEnv* env, jclass clazz, jint windowPtr,
+        jstring valueObj, jint row, jint column) {
+    CursorWindow* window = reinterpret_cast<CursorWindow*>(windowPtr);
+    field_slot_t * fieldSlot = window->getFieldSlotWithCheck(row, column);
     if (fieldSlot == NULL) {
         LOG_WINDOW(" getFieldSlotWithCheck error ");
         return false;
     }
 
 #if WINDOW_STORAGE_UTF8
-    int len = env->GetStringUTFLength(value) + 1;
-    char const * valStr = env->GetStringUTFChars(value, NULL);
+    size_t size = env->GetStringUTFLength(valueObj) + 1;
+    const char* valueStr = env->GetStringUTFChars(valueObj, NULL);
 #else
-    int len = env->GetStringLength(value);
-    // GetStringLength return number of chars and one char takes 2 bytes
-    len *= 2;
-    const jchar* valStr = env->GetStringChars(value, NULL);
+    size_t size = env->GetStringLength(valueObj) * sizeof(jchar);
+    const jchar* valueStr = env->GetStringChars(valueObj, NULL);
 #endif
-    if (!valStr) {
+    if (!valueStr) {
         LOG_WINDOW("value can't be transfer to UTFChars");
         return false;
     }
 
-    int offset = window->alloc(len);
+    uint32_t offset = window->alloc(size);
     if (!offset) {
-        LOG_WINDOW("Failed allocating %u bytes", len);
+        LOG_WINDOW("Failed allocating %u bytes", size);
 #if WINDOW_STORAGE_UTF8
-        env->ReleaseStringUTFChars(value, valStr);
+        env->ReleaseStringUTFChars(valueObj, valueStr);
 #else
-        env->ReleaseStringChars(value, valStr);
+        env->ReleaseStringChars(valueObj, valueStr);
 #endif
         return false;
     }
 
-    window->copyIn(offset, (uint8_t const *)valStr, len);
+    window->copyIn(offset, reinterpret_cast<const uint8_t*>(valueStr), size);
 
-    // This must be updated after the call to alloc(), since that
-    // may move the field around in the window
+#if WINDOW_STORAGE_UTF8
+    env->ReleaseStringUTFChars(valueObj, valueStr);
+#else
+    env->ReleaseStringChars(valueObj, valueStr);
+#endif
+
     fieldSlot->type = FIELD_TYPE_STRING;
     fieldSlot->data.buffer.offset = offset;
-    fieldSlot->data.buffer.size = len;
-
-    LOG_WINDOW("%d,%d is TEXT with %u bytes @ %d", row, col, len, offset);
-#if WINDOW_STORAGE_UTF8
-    env->ReleaseStringUTFChars(value, valStr);
-#else
-    env->ReleaseStringChars(value, valStr);
-#endif
-
+    fieldSlot->data.buffer.size = size;
+    LOG_WINDOW("%d,%d is TEXT with %u bytes @ %d", row, column, size, offset);
     return true;
 }
 
-static jboolean putLong_native(JNIEnv * env, jobject object, jlong value, jint row, jint col)
-{
-    CursorWindow * window = GET_WINDOW(env, object);
-    if (!window->putLong(row, col, value)) {
+static jboolean nativePutLong(JNIEnv* env, jclass clazz, jint windowPtr,
+        jlong value, jint row, jint column) {
+    CursorWindow* window = reinterpret_cast<CursorWindow*>(windowPtr);
+    if (!window->putLong(row, column, value)) {
         LOG_WINDOW(" getFieldSlotWithCheck error ");
         return false;
     }
 
-    LOG_WINDOW("%d,%d is INTEGER 0x%016llx", row, col, value);
-
+    LOG_WINDOW("%d,%d is INTEGER 0x%016llx", row, column, value);
     return true;
 }
 
-static jboolean putDouble_native(JNIEnv * env, jobject object, jdouble value, jint row, jint col)
-{
-    CursorWindow * window = GET_WINDOW(env, object);
-    if (!window->putDouble(row, col, value)) {
+static jboolean nativePutDouble(JNIEnv* env, jclass clazz, jint windowPtr,
+        jdouble value, jint row, jint column) {
+    CursorWindow* window = reinterpret_cast<CursorWindow*>(windowPtr);
+    if (!window->putDouble(row, column, value)) {
         LOG_WINDOW(" getFieldSlotWithCheck error ");
         return false;
     }
 
-    LOG_WINDOW("%d,%d is FLOAT %lf", row, col, value);
-
+    LOG_WINDOW("%d,%d is FLOAT %lf", row, column, value);
     return true;
 }
 
-static jboolean putNull_native(JNIEnv * env, jobject object, jint row, jint col)
-{
-    CursorWindow * window = GET_WINDOW(env, object);
-    if (!window->putNull(row, col)) {
+static jboolean nativePutNull(JNIEnv* env, jclass clazz, jint windowPtr,
+        jint row, jint column) {
+    CursorWindow* window = reinterpret_cast<CursorWindow*>(windowPtr);
+    if (!window->putNull(row, column)) {
         LOG_WINDOW(" getFieldSlotWithCheck error ");
         return false;
     }
 
-    LOG_WINDOW("%d,%d is NULL", row, col);
-
+    LOG_WINDOW("%d,%d is NULL", row, column);
     return true;
 }
 
-// free the last row
-static void freeLastRow(JNIEnv * env, jobject object) {
-    CursorWindow * window = GET_WINDOW(env, object);
-    window->freeLastRow();
-}
-
-static jint getType_native(JNIEnv* env, jobject object, jint row, jint column)
-{
-    int32_t err;
-    CursorWindow * window = GET_WINDOW(env, object);
-    LOG_WINDOW("returning column type affinity for %d,%d from %p", row, column, window);
-
-    if (isNull_native(window, row, column)) {
-      return FIELD_TYPE_NULL;
-    }
-
-    field_slot_t field;
-    err = window->read_field_slot(row, column, &field);
-    if (err != 0) {
-        throwExceptionWithRowCol(env, row, column);
-        return NULL;
-    }
-
-    return field.type;
-}
-
 static JNINativeMethod sMethods[] =
 {
-     /* name, signature, funcPtr */
-    {"native_init", "(IZ)I", (void *)native_init_empty},
-    {"native_init", "(Landroid/os/IBinder;)I", (void *)native_init_memory},
-    {"native_getBinder", "()Landroid/os/IBinder;", (void *)native_getBinder},
-    {"native_clear", "()V", (void *)native_clear},
-    {"close_native", "()V", (void *)native_close},
-    {"getLong_native", "(II)J", (void *)getLong_native},
-    {"getBlob_native", "(II)[B", (void *)getBlob_native},
-    {"getString_native", "(II)Ljava/lang/String;", (void *)getString_native},
-    {"copyStringToBuffer_native", "(IIILandroid/database/CharArrayBuffer;)[C", (void *)copyStringToBuffer_native},
-    {"getDouble_native", "(II)D", (void *)getDouble_native},
-    {"getNumRows_native", "()I", (void *)getNumRows},
-    {"setNumColumns_native", "(I)Z", (void *)setNumColumns},
-    {"allocRow_native", "()Z", (void *)allocRow},
-    {"putBlob_native", "([BII)Z", (void *)putBlob_native},
-    {"putString_native", "(Ljava/lang/String;II)Z", (void *)putString_native},
-    {"putLong_native", "(JII)Z", (void *)putLong_native},
-    {"putDouble_native", "(DII)Z", (void *)putDouble_native},
-    {"freeLastRow_native", "()V", (void *)freeLastRow},
-    {"putNull_native", "(II)Z", (void *)putNull_native},
-    {"getType_native", "(II)I", (void *)getType_native},
+    /* name, signature, funcPtr */
+    { "nativeInitializeEmpty", "(IZ)I",
+            (void*)nativeInitializeEmpty },
+    { "nativeInitializeFromBinder", "(Landroid/os/IBinder;)I",
+            (void*)nativeInitializeFromBinder },
+    { "nativeDispose", "(I)V",
+            (void*)nativeDispose },
+    { "nativeGetBinder", "(I)Landroid/os/IBinder;",
+            (void*)nativeGetBinder },
+    { "nativeClear", "(I)V",
+            (void*)nativeClear },
+    { "nativeGetNumRows", "(I)I",
+            (void*)nativeGetNumRows },
+    { "nativeSetNumColumns", "(II)Z",
+            (void*)nativeSetNumColumns },
+    { "nativeAllocRow", "(I)Z",
+            (void*)nativeAllocRow },
+    { "nativeFreeLastRow", "(I)V",
+            (void*)nativeFreeLastRow },
+    { "nativeGetType", "(III)I",
+            (void*)nativeGetType },
+    { "nativeGetBlob", "(III)[B",
+            (void*)nativeGetBlob },
+    { "nativeGetString", "(III)Ljava/lang/String;",
+            (void*)nativeGetString },
+    { "nativeGetLong", "(III)J",
+            (void*)nativeGetLong },
+    { "nativeGetDouble", "(III)D",
+            (void*)nativeGetDouble },
+    { "nativeCopyStringToBuffer", "(IIILandroid/database/CharArrayBuffer;)V",
+            (void*)nativeCopyStringToBuffer },
+    { "nativePutBlob", "(I[BII)Z",
+            (void*)nativePutBlob },
+    { "nativePutString", "(ILjava/lang/String;II)Z",
+            (void*)nativePutString },
+    { "nativePutLong", "(IJII)Z",
+            (void*)nativePutLong },
+    { "nativePutDouble", "(IDII)Z",
+            (void*)nativePutDouble },
+    { "nativePutNull", "(III)Z",
+            (void*)nativePutNull },
 };
 
+#define FIND_CLASS(var, className) \
+        var = env->FindClass(className); \
+        LOG_FATAL_IF(! var, "Unable to find class " className);
+
+#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \
+        var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \
+        LOG_FATAL_IF(! var, "Unable to find field " fieldName);
+
 int register_android_database_CursorWindow(JNIEnv * env)
 {
     jclass clazz;
+    FIND_CLASS(clazz, "android/database/CharArrayBuffer");
 
-    clazz = env->FindClass("android/database/CursorWindow");
-    if (clazz == NULL) {
-        LOGE("Can't find android/database/CursorWindow");
-        return -1;
-    }
+    GET_FIELD_ID(gCharArrayBufferClassInfo.data, clazz,
+            "data", "[C");
+    GET_FIELD_ID(gCharArrayBufferClassInfo.sizeCopied, clazz,
+            "sizeCopied", "I");
 
-    gWindowField = env->GetFieldID(clazz, "nWindow", "I");
-
-    if (gWindowField == NULL) {
-        LOGE("Error locating fields");
-        return -1;
-    }
-
-    clazz =  env->FindClass("android/database/CharArrayBuffer");
-    if (clazz == NULL) {
-        LOGE("Can't find android/database/CharArrayBuffer");
-        return -1;
-    }
-
-    gBufferField = env->GetFieldID(clazz, "data", "[C");
-
-    if (gBufferField == NULL) {
-        LOGE("Error locating fields data in CharArrayBuffer");
-        return -1;
-    }
-
-    gSizeCopiedField = env->GetFieldID(clazz, "sizeCopied", "I");
-
-    if (gSizeCopiedField == NULL) {
-        LOGE("Error locating fields sizeCopied in CharArrayBuffer");
-        return -1;
-    }
+    gEmptyString = jstring(env->NewGlobalRef(env->NewStringUTF("")));
+    LOG_FATAL_IF(!gEmptyString, "Unable to create empty string");
 
     return AndroidRuntime::registerNativeMethods(env, "android/database/CursorWindow",
             sMethods, NELEM(sMethods));
diff --git a/core/jni/android_database_SQLiteQuery.cpp b/core/jni/android_database_SQLiteQuery.cpp
index 9e42189..fe62256 100644
--- a/core/jni/android_database_SQLiteQuery.cpp
+++ b/core/jni/android_database_SQLiteQuery.cpp
@@ -35,12 +35,6 @@
 
 namespace android {
 
-sqlite3_stmt * compile(JNIEnv* env, jobject object,
-                       sqlite3 * handle, jstring sqlString);
-
-// From android_database_CursorWindow.cpp
-CursorWindow * get_window_from_object(JNIEnv * env, jobject javaWindow);
-
 static jfieldID gHandleField;
 static jfieldID gStatementField;
 
@@ -105,7 +99,7 @@
     return numRows;
 }
 
-static jint native_fill_window(JNIEnv* env, jobject object, jobject javaWindow,
+static jint native_fill_window(JNIEnv* env, jobject object, jint windowPtr,
                                jint startPos, jint offsetParam, jint maxRead, jint lastPos)
 {
     int err;
@@ -142,7 +136,7 @@
     }
 
     // Get the native window
-    window = get_window_from_object(env, javaWindow);
+    window = reinterpret_cast<CursorWindow*>(windowPtr);
     if (!window) {
         LOGE("Invalid CursorWindow");
         jniThrowException(env, "java/lang/IllegalArgumentException",
@@ -360,7 +354,7 @@
 static JNINativeMethod sMethods[] =
 {
      /* name, signature, funcPtr */
-    {"native_fill_window", "(Landroid/database/CursorWindow;IIII)I",
+    {"native_fill_window", "(IIIII)I",
             (void *)native_fill_window},
     {"native_column_count", "()I", (void*)native_column_count},
     {"native_column_name", "(I)Ljava/lang/String;", (void *)native_column_name},
diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp
index e542a47..e79de2d 100644
--- a/core/jni/android_view_GLES20Canvas.cpp
+++ b/core/jni/android_view_GLES20Canvas.cpp
@@ -477,19 +477,17 @@
 #if RTL_USE_HARFBUZZ
     sp<TextLayoutCacheValue> value;
 #if USE_TEXT_LAYOUT_CACHE
-    value = TextLayoutCache::getInstance().getValue(paint, text, count, flags);
+    value = TextLayoutCache::getInstance().getValue(paint, text, 0, count, count, flags);
     if (value == NULL) {
         LOGE("Cannot get TextLayoutCache value");
         return ;
     }
 #else
     value = new TextLayoutCacheValue();
-    value->computeValues(paint, text, count, flags);
+    value->computeValues(paint, text, 0, count, count, flags);
 #endif
-    size_t startIndex = 0;
-    size_t glyphsCount = 0;
-    value->getGlyphsIndexAndCount(0, count, &startIndex, &glyphsCount);
-    const jchar* glyphs = value->getGlyphs(startIndex, glyphsCount);
+    const jchar* glyphs = value->getGlyphs();
+    size_t glyphsCount = value->getGlyphsCount();
     int bytesCount = glyphsCount * sizeof(jchar);
     renderer->drawText((const char*) glyphs, bytesCount, glyphsCount, x, y, paint);
 #else
@@ -509,19 +507,17 @@
 #if RTL_USE_HARFBUZZ
     sp<TextLayoutCacheValue> value;
 #if USE_TEXT_LAYOUT_CACHE
-    value = TextLayoutCache::getInstance().getValue(paint, text, contextCount, flags);
+    value = TextLayoutCache::getInstance().getValue(paint, text, start, count, contextCount, flags);
     if (value == NULL) {
         LOGE("Cannot get TextLayoutCache value");
         return ;
     }
 #else
     value = new TextLayoutCacheValue();
-    value->computeValues(paint, text, contextCount, flags);
+    value->computeValues(paint, text, start, count, contextCount, flags);
 #endif
-    size_t startIndex = 0;
-    size_t glyphsCount = 0;
-    value->getGlyphsIndexAndCount(start, count, &startIndex, &glyphsCount);
-    const jchar* glyphs = value->getGlyphs(startIndex, glyphsCount);
+    const jchar* glyphs = value->getGlyphs();
+    size_t glyphsCount = value->getGlyphsCount();
     int bytesCount = glyphsCount * sizeof(jchar);
     renderer->drawText((const char*) glyphs, bytesCount, glyphsCount, x, y, paint);
 #else
diff --git a/core/res/res/drawable/stat_sys_download_done_static.xml b/core/res/res/drawable/stat_sys_download_done_static.xml
new file mode 100644
index 0000000..8d5f836
--- /dev/null
+++ b/core/res/res/drawable/stat_sys_download_done_static.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+    android:src="@drawable/stat_sys_download_anim0" />
diff --git a/core/res/res/values/colors.xml b/core/res/res/values/colors.xml
index f0c6d09..a9c603f 100644
--- a/core/res/res/values/colors.xml
+++ b/core/res/res/values/colors.xml
@@ -61,7 +61,7 @@
     <color name="suggestion_highlight_text">#177bbd</color>
 
     <drawable name="stat_notify_sync_noanim">@drawable/stat_notify_sync_anim0</drawable>
-    <drawable name="stat_sys_download_done">@drawable/stat_sys_download_anim0</drawable>
+    <drawable name="stat_sys_download_done">@drawable/stat_sys_download_done_static</drawable>
     <drawable name="stat_sys_upload_done">@drawable/stat_sys_upload_anim0</drawable>
     <drawable name="dialog_frame">@drawable/panel_background</drawable>
     <drawable name="alert_dark_frame">@drawable/popup_full_dark</drawable>
diff --git a/core/tests/coretests/src/android/accessibilityservice/InterrogationActivityTest.java b/core/tests/coretests/src/android/accessibilityservice/InterrogationActivityTest.java
index cd8dcb9..3521296 100644
--- a/core/tests/coretests/src/android/accessibilityservice/InterrogationActivityTest.java
+++ b/core/tests/coretests/src/android/accessibilityservice/InterrogationActivityTest.java
@@ -19,14 +19,10 @@
 import static android.view.accessibility.AccessibilityNodeInfo.ACTION_FOCUS;
 import static android.view.accessibility.AccessibilityNodeInfo.ACTION_SELECT;
 
-import com.android.frameworks.coretests.R;
-
 import android.content.Context;
 import android.graphics.Rect;
-import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.SystemClock;
-import android.provider.Settings;
 import android.test.ActivityInstrumentationTestCase2;
 import android.test.suitebuilder.annotation.LargeTest;
 import android.util.Log;
@@ -36,8 +32,8 @@
 import android.view.accessibility.AccessibilityNodeInfo;
 import android.view.accessibility.IAccessibilityManager;
 
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
+import com.android.frameworks.coretests.R;
+
 import java.util.ArrayList;
 import java.util.LinkedList;
 import java.util.List;
@@ -55,14 +51,9 @@
 
     private static String LOG_TAG = "InterrogationActivityTest";
 
-    // Timeout before give up wait for the system to process an accessibility setting change.
+    // Timeout before give up wait for the system to process an accessibility setting change.       
     private static final int TIMEOUT_PROPAGATE_ACCESSIBLITY_SETTING = 2000;
 
-    // Helpers to figure out the first and last test methods
-    // This is a workaround for the lack of such support in JUnit3
-    private static int sTestMethodCount;
-    private static int sExecutedTestMethodCount;
-
     // Handle to a connection to the AccessibilityManagerService
     private static IAccessibilityServiceConnection sConnection;
 
@@ -71,19 +62,20 @@
 
     public InterrogationActivityTest() {
         super(InterrogationActivity.class);
-        sTestMethodCount = getTestMethodCount();
     }
 
     @LargeTest
     public void testFindAccessibilityNodeInfoByViewId() throws Exception {
-        beforeClassIfNeeded();
         final long startTimeMillis = SystemClock.uptimeMillis();
         try {
+            // hook into the system first
+            IAccessibilityServiceConnection connection = getConnection();
+
             // bring up the activity
             getActivity();
 
             AccessibilityNodeInfo button = AccessibilityInteractionClient.getInstance()
-                .findAccessibilityNodeInfoByViewIdInActiveWindow(getConnection(), R.id.button5);
+                .findAccessibilityNodeInfoByViewIdInActiveWindow(connection, R.id.button5);
             assertNotNull(button);
             assertEquals(0, button.getChildCount());
 
@@ -116,7 +108,6 @@
             assertEquals(ACTION_FOCUS | ACTION_SELECT | ACTION_CLEAR_SELECTION,
                 button.getActions());
         } finally {
-            afterClassIfNeeded();
             if (DEBUG) {
                 final long elapsedTimeMillis = SystemClock.uptimeMillis() - startTimeMillis;
                 Log.i(LOG_TAG, "testFindAccessibilityNodeInfoByViewId: "
@@ -127,18 +118,19 @@
 
     @LargeTest
     public void testFindAccessibilityNodeInfoByViewText() throws Exception {
-        beforeClassIfNeeded();
         final long startTimeMillis = SystemClock.uptimeMillis();
         try {
+            // hook into the system first
+            IAccessibilityServiceConnection connection = getConnection();
+
             // bring up the activity
             getActivity();
 
             // find a view by text
             List<AccessibilityNodeInfo> buttons =  AccessibilityInteractionClient.getInstance()
-                .findAccessibilityNodeInfosByViewTextInActiveWindow(getConnection(), "butto");
+                .findAccessibilityNodeInfosByViewTextInActiveWindow(connection, "butto");
             assertEquals(9, buttons.size());
         } finally {
-            afterClassIfNeeded();
             if (DEBUG) {
                 final long elapsedTimeMillis = SystemClock.uptimeMillis() - startTimeMillis;
                 Log.i(LOG_TAG, "testFindAccessibilityNodeInfoByViewText: "
@@ -149,19 +141,20 @@
 
     @LargeTest
     public void testFindAccessibilityNodeInfoByViewTextContentDescription() throws Exception {
-        beforeClassIfNeeded();
         final long startTimeMillis = SystemClock.uptimeMillis();
         try {
+            // hook into the system first
+            IAccessibilityServiceConnection connection = getConnection();
+
             // bring up the activity
             getActivity();
 
             // find a view by text
             List<AccessibilityNodeInfo> buttons =  AccessibilityInteractionClient.getInstance()
-                .findAccessibilityNodeInfosByViewTextInActiveWindow(getConnection(),
+                .findAccessibilityNodeInfosByViewTextInActiveWindow(connection,
                         "contentDescription");
             assertEquals(1, buttons.size());
         } finally {
-            afterClassIfNeeded();
             if (DEBUG) {
                 final long elapsedTimeMillis = SystemClock.uptimeMillis() - startTimeMillis;
                 Log.i(LOG_TAG, "testFindAccessibilityNodeInfoByViewTextContentDescription: "
@@ -172,9 +165,11 @@
 
     @LargeTest
     public void testTraverseAllViews() throws Exception {
-        beforeClassIfNeeded();
         final long startTimeMillis = SystemClock.uptimeMillis();
         try {
+            // hook into the system first
+            IAccessibilityServiceConnection connection = getConnection();
+
             // bring up the activity
             getActivity();
 
@@ -195,7 +190,7 @@
             classNameAndTextList.add("android.widget.ButtonButton9");
 
             AccessibilityNodeInfo root = AccessibilityInteractionClient.getInstance()
-                .findAccessibilityNodeInfoByViewIdInActiveWindow(getConnection(), R.id.root);
+                .findAccessibilityNodeInfoByViewIdInActiveWindow(connection, R.id.root);
             assertNotNull("We must find the existing root.", root);
 
             Queue<AccessibilityNodeInfo> fringe = new LinkedList<AccessibilityNodeInfo>();
@@ -221,7 +216,6 @@
                 }
             }
         } finally {
-            afterClassIfNeeded();
             if (DEBUG) {
                 final long elapsedTimeMillis = SystemClock.uptimeMillis() - startTimeMillis;
                 Log.i(LOG_TAG, "testTraverseAllViews: " + elapsedTimeMillis + "ms");
@@ -231,15 +225,17 @@
 
     @LargeTest
     public void testPerformAccessibilityActionFocus() throws Exception {
-        beforeClassIfNeeded();
         final long startTimeMillis = SystemClock.uptimeMillis();
         try {
+            // hook into the system first
+            IAccessibilityServiceConnection connection = getConnection();
+
             // bring up the activity
             getActivity();
 
             // find a view and make sure it is not focused
             AccessibilityNodeInfo button = AccessibilityInteractionClient.getInstance()
-                .findAccessibilityNodeInfoByViewIdInActiveWindow(getConnection(), R.id.button5);
+                .findAccessibilityNodeInfoByViewIdInActiveWindow(connection, R.id.button5);
             assertFalse(button.isFocused());
 
             // focus the view
@@ -247,10 +243,9 @@
 
             // find the view again and make sure it is focused
             button =  AccessibilityInteractionClient.getInstance()
-                .findAccessibilityNodeInfoByViewIdInActiveWindow(getConnection(), R.id.button5);
+                .findAccessibilityNodeInfoByViewIdInActiveWindow(connection, R.id.button5);
             assertTrue(button.isFocused());
         } finally {
-            afterClassIfNeeded();
             if (DEBUG) {
                 final long elapsedTimeMillis = SystemClock.uptimeMillis() - startTimeMillis;
                 Log.i(LOG_TAG, "testPerformAccessibilityActionFocus: " + elapsedTimeMillis + "ms");
@@ -260,15 +255,17 @@
 
     @LargeTest
     public void testPerformAccessibilityActionClearFocus() throws Exception {
-        beforeClassIfNeeded();
         final long startTimeMillis = SystemClock.uptimeMillis();
         try {
+            // hook into the system first
+            IAccessibilityServiceConnection connection = getConnection();
+
             // bring up the activity
             getActivity();
 
             // find a view and make sure it is not focused
             AccessibilityNodeInfo button = AccessibilityInteractionClient.getInstance()
-                .findAccessibilityNodeInfoByViewIdInActiveWindow(getConnection(), R.id.button5);
+                .findAccessibilityNodeInfoByViewIdInActiveWindow(connection, R.id.button5);
             assertFalse(button.isFocused());
 
             // focus the view
@@ -276,7 +273,7 @@
 
             // find the view again and make sure it is focused
             button = AccessibilityInteractionClient.getInstance()
-                .findAccessibilityNodeInfoByViewIdInActiveWindow(getConnection(), R.id.button5);
+                .findAccessibilityNodeInfoByViewIdInActiveWindow(connection, R.id.button5);
             assertTrue(button.isFocused());
 
             // unfocus the view
@@ -284,10 +281,9 @@
 
             // find the view again and make sure it is not focused
             button = AccessibilityInteractionClient.getInstance()
-                .findAccessibilityNodeInfoByViewIdInActiveWindow(getConnection(), R.id.button5);
+                .findAccessibilityNodeInfoByViewIdInActiveWindow(connection, R.id.button5);
             assertFalse(button.isFocused());
         } finally {
-            afterClassIfNeeded();
             if (DEBUG) {
                 final long elapsedTimeMillis = SystemClock.uptimeMillis() - startTimeMillis;
                 Log.i(LOG_TAG, "testPerformAccessibilityActionClearFocus: "
@@ -298,15 +294,17 @@
 
     @LargeTest
     public void testPerformAccessibilityActionSelect() throws Exception {
-        beforeClassIfNeeded();
         final long startTimeMillis = SystemClock.uptimeMillis();
         try {
+            // hook into the system first
+            IAccessibilityServiceConnection connection = getConnection();
+
             // bring up the activity
             getActivity();
 
             // find a view and make sure it is not selected
             AccessibilityNodeInfo button = AccessibilityInteractionClient.getInstance()
-                .findAccessibilityNodeInfoByViewIdInActiveWindow(getConnection(), R.id.button5);
+                .findAccessibilityNodeInfoByViewIdInActiveWindow(connection, R.id.button5);
             assertFalse(button.isSelected());
 
             // select the view
@@ -314,10 +312,9 @@
 
             // find the view again and make sure it is selected
             button = AccessibilityInteractionClient.getInstance()
-                .findAccessibilityNodeInfoByViewIdInActiveWindow(getConnection(), R.id.button5);
+                .findAccessibilityNodeInfoByViewIdInActiveWindow(connection, R.id.button5);
             assertTrue(button.isSelected());
         } finally {
-            afterClassIfNeeded();
             if (DEBUG) {
                 final long elapsedTimeMillis = SystemClock.uptimeMillis() - startTimeMillis;
                 Log.i(LOG_TAG, "testPerformAccessibilityActionSelect: " + elapsedTimeMillis + "ms");
@@ -327,15 +324,17 @@
 
     @LargeTest
     public void testPerformAccessibilityActionClearSelection() throws Exception {
-        beforeClassIfNeeded();
         final long startTimeMillis = SystemClock.uptimeMillis();
         try {
+            // hook into the system first
+            IAccessibilityServiceConnection connection = getConnection();
+
             // bring up the activity
             getActivity();
 
             // find a view and make sure it is not selected
             AccessibilityNodeInfo button = AccessibilityInteractionClient.getInstance()
-                .findAccessibilityNodeInfoByViewIdInActiveWindow(getConnection(), R.id.button5);
+                .findAccessibilityNodeInfoByViewIdInActiveWindow(connection, R.id.button5);
             assertFalse(button.isSelected());
 
             // select the view
@@ -343,7 +342,7 @@
 
             // find the view again and make sure it is selected
             button = AccessibilityInteractionClient.getInstance()
-                .findAccessibilityNodeInfoByViewIdInActiveWindow(getConnection(), R.id.button5);
+                .findAccessibilityNodeInfoByViewIdInActiveWindow(connection, R.id.button5);
             assertTrue(button.isSelected());
 
             // unselect the view
@@ -351,10 +350,9 @@
 
             // find the view again and make sure it is not selected
             button =  AccessibilityInteractionClient.getInstance()
-                .findAccessibilityNodeInfoByViewIdInActiveWindow(getConnection(), R.id.button5);
+                .findAccessibilityNodeInfoByViewIdInActiveWindow(connection, R.id.button5);
             assertFalse(button.isSelected());
         } finally {
-            afterClassIfNeeded();
             if (DEBUG) {
                 final long elapsedTimeMillis = SystemClock.uptimeMillis() - startTimeMillis;
                 Log.i(LOG_TAG, "testPerformAccessibilityActionClearSelection: "
@@ -365,15 +363,17 @@
 
     @LargeTest
     public void testAccessibilityEventGetSource() throws Exception {
-        beforeClassIfNeeded();
         final long startTimeMillis = SystemClock.uptimeMillis();
         try {
+            // hook into the system first
+            IAccessibilityServiceConnection connection = getConnection();
+
             // bring up the activity
-            getActivity();
+            getActivity();  
 
             // find a view and make sure it is not focused
             AccessibilityNodeInfo button = AccessibilityInteractionClient.getInstance()
-                .findAccessibilityNodeInfoByViewIdInActiveWindow(getConnection(), R.id.button5);
+                .findAccessibilityNodeInfoByViewIdInActiveWindow(connection, R.id.button5);
             assertFalse(button.isSelected());
 
             // focus the view
@@ -419,7 +419,6 @@
             assertSame(button.isCheckable(), source.isCheckable());
             assertSame(button.isChecked(), source.isChecked());
         } finally {
-            afterClassIfNeeded();
             if (DEBUG) {
                 final long elapsedTimeMillis = SystemClock.uptimeMillis() - startTimeMillis;
                 Log.i(LOG_TAG, "testAccessibilityEventGetSource: " + elapsedTimeMillis + "ms");
@@ -429,15 +428,17 @@
 
     @LargeTest
     public void testObjectContract() throws Exception {
-        beforeClassIfNeeded();
         final long startTimeMillis = SystemClock.uptimeMillis();
         try {
+            // hook into the system first
+            IAccessibilityServiceConnection connection = getConnection();
+
             // bring up the activity
             getActivity();
 
             // find a view and make sure it is not focused
             AccessibilityNodeInfo button = AccessibilityInteractionClient.getInstance()
-                .findAccessibilityNodeInfoByViewIdInActiveWindow(getConnection(), R.id.button5);
+                .findAccessibilityNodeInfoByViewIdInActiveWindow(connection, R.id.button5);
             AccessibilityNodeInfo parent = button.getParent();
             final int childCount = parent.getChildCount();
             for (int i = 0; i < childCount; i++) {
@@ -451,7 +452,6 @@
             }
             fail("Parent's children do not have the info whose parent is the parent.");
         } finally {
-            afterClassIfNeeded();
             if (DEBUG) {
                 final long elapsedTimeMillis = SystemClock.uptimeMillis() - startTimeMillis;
                 Log.i(LOG_TAG, "testObjectContract: " + elapsedTimeMillis + "ms");
@@ -464,90 +464,10 @@
         /* intentionally do not scrub */
     }
 
-    /**
-     * Sets accessibility in a given state by writing the state to the
-     * settings and waiting until the accessibility manager service picks
-     * it up for max {@link #TIMEOUT_PROPAGATE_ACCESSIBLITY_SETTING}.
-     *
-     * @param state The accessibility state.
-     * @throws Exception If any error occurs.
-     */
-    private void ensureAccessibilityState(boolean state) throws Exception {
-        Context context = getInstrumentation().getContext();
-        // If the local manager ready => nothing to do.
-        AccessibilityManager accessibilityManager = AccessibilityManager.getInstance(context);
-        if (accessibilityManager.isEnabled() == state) {
-            return;
-        }
-        synchronized (this) {
-            // Check if the system already knows about the desired state. 
-            final boolean currentState = Settings.Secure.getInt(context.getContentResolver(),
-                    Settings.Secure.ACCESSIBILITY_ENABLED) == 1;
-            if (currentState != state) {
-                // Make sure we wake ourselves as the desired state is propagated.
-                accessibilityManager.addAccessibilityStateChangeListener(
-                        new AccessibilityManager.AccessibilityStateChangeListener() {
-                            public void onAccessibilityStateChanged(boolean enabled) {
-                                synchronized (this) {
-                                    notifyAll();
-                                }
-                            }
-                        });
-                Settings.Secure.putInt(context.getContentResolver(),
-                        Settings.Secure.ACCESSIBILITY_ENABLED, state ? 1 : 0);
-            }
-            // No while one attempt and that is it.
-            try {
-                wait(TIMEOUT_PROPAGATE_ACCESSIBLITY_SETTING);
-            } catch (InterruptedException ie) {
-                /* ignore */
-            }
-        }
-        if (accessibilityManager.isEnabled() != state) {
-            throw new IllegalStateException("Could not set accessibility state to: " + state);
-        }
-    }
-
-    /**
-     * Execute some set up code before any test method.
-     *
-     * NOTE: I miss Junit4's @BeforeClass
-     *
-     * @throws Exception If an error occurs.
-     */
-    private void beforeClassIfNeeded() throws Exception {
-        sExecutedTestMethodCount++;
-        if (sExecutedTestMethodCount == 1) {
-            ensureAccessibilityState(true);
-        }
-    }
-
-    /**
-     * Execute some clean up code after all test methods.
-     *
-     * NOTE: I miss Junit4's @AfterClass
-     *
-     * @throws Exception If an error occurs.
-     */
-    public void afterClassIfNeeded() throws Exception {
-        if (sExecutedTestMethodCount == sTestMethodCount) {
-            sExecutedTestMethodCount = 0;
-            ensureAccessibilityState(false);
-        }
-    }
-
-    private static IAccessibilityServiceConnection getConnection() throws Exception {
+    private IAccessibilityServiceConnection getConnection() throws Exception {
         if (sConnection == null) {
             IEventListener listener = new IEventListener.Stub() {
-                public void setConnection(IAccessibilityServiceConnection connection)
-                        throws RemoteException {
-                    AccessibilityServiceInfo info = new AccessibilityServiceInfo();
-                    info.eventTypes = AccessibilityEvent.TYPES_ALL_MASK;
-                    info.feedbackType = AccessibilityServiceInfo.FEEDBACK_SPOKEN;
-                    info.notificationTimeout = 0;
-                    info.flags = AccessibilityServiceInfo.DEFAULT;
-                    connection.setServiceInfo(info);
-                }
+                public void setConnection(IAccessibilityServiceConnection connection) {}
 
                 public void onInterrupt() {}
 
@@ -560,26 +480,33 @@
                     }
                 }
             };
-            IAccessibilityManager manager = IAccessibilityManager.Stub.asInterface(
-                ServiceManager.getService(Context.ACCESSIBILITY_SERVICE));
-            sConnection = manager.registerEventListener(listener);
-        }
-        return sConnection;
-    }
 
-    /**
-     * @return The number of test methods.
-     */
-    private int getTestMethodCount() {
-        int testMethodCount = 0;
-        for (Method method : getClass().getMethods()) {
-            final int modifiers = method.getModifiers();
-            if (method.getName().startsWith("test")
-                    && (modifiers & Modifier.PUBLIC) != 0
-                    && (modifiers & Modifier.STATIC) == 0) {
-                testMethodCount++;
+            AccessibilityManager accessibilityManager =
+                AccessibilityManager.getInstance(getInstrumentation().getContext());
+
+            synchronized (this) {
+                if (!accessibilityManager.isEnabled()) {
+                    // Make sure we wake ourselves as the desired state is propagated.
+                    accessibilityManager.addAccessibilityStateChangeListener(
+                            new AccessibilityManager.AccessibilityStateChangeListener() {
+                                public void onAccessibilityStateChanged(boolean enabled) {
+                                    synchronized (this) {
+                                        notifyAll();
+                                    }
+                                }
+                            });
+                    IAccessibilityManager manager = IAccessibilityManager.Stub.asInterface(
+                        ServiceManager.getService(Context.ACCESSIBILITY_SERVICE));
+                    sConnection = manager.registerEventListener(listener);
+
+                    wait(TIMEOUT_PROPAGATE_ACCESSIBLITY_SETTING);
+                } else {
+                    IAccessibilityManager manager = IAccessibilityManager.Stub.asInterface(
+                          ServiceManager.getService(Context.ACCESSIBILITY_SERVICE));
+                    sConnection = manager.registerEventListener(listener);
+                }
             }
         }
-        return testMethodCount;
+        return sConnection;
     }
 }
diff --git a/data/fonts/Android.mk b/data/fonts/Android.mk
index db27cdc..02d2f3d 100644
--- a/data/fonts/Android.mk
+++ b/data/fonts/Android.mk
@@ -17,13 +17,56 @@
 
 LOCAL_PATH := $(call my-dir)
 
+##########################################
+# We may only afford small font footprint.
+##########################################
+# Use only symlinks.
+# Symlink: DroidSans.ttf -> Roboto-Regular.ttf
+LOCAL_MODULE := DroidSans.ttf
+font_symlink_src := $(PRODUCT_OUT)/system/fonts/Roboto-Regular.ttf
+font_symlink := $(dir $(font_symlink_src))$(LOCAL_MODULE)
+$(font_symlink) : $(font_symlink_src)
+	@echo "Symlink: $@ -> $<"
+	@mkdir -p $(dir $@)
+	@rm -rf $@
+	$(hide) ln -sf $(notdir $<) $@
+
+# this magic makes LOCAL_REQUIRED_MODULES work
+ALL_MODULES.$(LOCAL_MODULE).INSTALLED := \
+    $(ALL_MODULES.$(LOCAL_MODULE).INSTALLED) $(font_symlink)
+
+################################
+# Symlink: DroidSans-Bold.ttf -> Roboto-Bold.ttf
+LOCAL_MODULE := DroidSans-Bold.ttf
+font_symlink_src := $(PRODUCT_OUT)/system/fonts/Roboto-Bold.ttf
+font_symlink := $(dir $(font_symlink_src))$(LOCAL_MODULE)
+$(font_symlink) : $(font_symlink_src)
+	@echo "Symlink: $@ -> $<"
+	@mkdir -p $(dir $@)
+	@rm -rf $@
+	$(hide) ln -sf $(notdir $<) $@
+
+# this magic makes LOCAL_REQUIRED_MODULES work
+ALL_MODULES.$(LOCAL_MODULE).INSTALLED := \
+    $(ALL_MODULES.$(LOCAL_MODULE).INSTALLED) $(font_symlink)
+
+################################
+include $(CLEAR_VARS)
+LOCAL_MODULE := DroidSansEthiopic-Regular.ttf
+LOCAL_SRC_FILES := $(LOCAL_MODULE)
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_PATH := $(TARGET_OUT)/fonts
+include $(BUILD_PREBUILT)
+
+################################
 ifeq ($(SMALLER_FONT_FOOTPRINT),true)
 droidsans_fallback_src := DroidSansFallback.ttf
-extra_droidsans_fonts :=
+extra_droidsans_fonts := DroidSans.ttf DroidSans-Bold.ttf
 else
 droidsans_fallback_src := DroidSansFallbackFull.ttf
 extra_droidsans_fonts := DroidSans.ttf DroidSans-Bold.ttf DroidSansEthiopic-Regular.ttf
-endif
+endif  # SMALLER_FONT_FOOTPRINT
 
 include $(CLEAR_VARS)
 LOCAL_MODULE := DroidSansFallback.ttf
@@ -32,30 +75,9 @@
 LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE_PATH := $(TARGET_OUT)/fonts
 LOCAL_REQUIRED_MODULES := $(extra_droidsans_fonts)
+include $(BUILD_PREBUILT)
+
+font_symlink_src :=
+font_symlink :=
 droidsans_fallback_src :=
 extra_droidsans_fonts :=
-include $(BUILD_PREBUILT)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := DroidSans.ttf
-LOCAL_SRC_FILES := $(LOCAL_MODULE)
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_PATH := $(TARGET_OUT)/fonts
-include $(BUILD_PREBUILT)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := DroidSans-Bold.ttf
-LOCAL_SRC_FILES := $(LOCAL_MODULE)
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_PATH := $(TARGET_OUT)/fonts
-include $(BUILD_PREBUILT)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := DroidSansEthiopic-Regular.ttf
-LOCAL_SRC_FILES := $(LOCAL_MODULE)
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_PATH := $(TARGET_OUT)/fonts
-include $(BUILD_PREBUILT)
diff --git a/data/sounds/AudioPackage7.mk b/data/sounds/AudioPackage7.mk
index 9983f38..629ceb3 100755
--- a/data/sounds/AudioPackage7.mk
+++ b/data/sounds/AudioPackage7.mk
@@ -26,6 +26,7 @@
 	$(LOCAL_PATH)/effects/ogg/Undock.ogg:system/media/audio/ui/Undock.ogg \
 	$(LOCAL_PATH)/effects/ogg/Lock.ogg:system/media/audio/ui/Lock.ogg \
 	$(LOCAL_PATH)/effects/ogg/Unlock.ogg:system/media/audio/ui/Unlock.ogg \
+	$(LOCAL_PATH)/notifications/ogg/Adara.ogg:system/media/audio/notifications/Adara.ogg \
 	$(LOCAL_PATH)/notifications/ogg/Altair.ogg:system/media/audio/notifications/Altair.ogg \
 	$(LOCAL_PATH)/notifications/ogg/Arcturus.ogg:system/media/audio/notifications/Arcturus.ogg \
 	$(LOCAL_PATH)/notifications/ogg/Betelgeuse.ogg:system/media/audio/notifications/Betelgeuse.ogg \
@@ -39,6 +40,8 @@
 	$(LOCAL_PATH)/notifications/ogg/Procyon.ogg:system/media/audio/notifications/Procyon.ogg \
 	$(LOCAL_PATH)/notifications/ogg/Proxima.ogg:system/media/audio/notifications/Proxima.ogg \
 	$(LOCAL_PATH)/notifications/ogg/Upsilon.ogg:system/media/audio/notifications/Upsilon.ogg \
+	$(LOCAL_PATH)/notifications/ogg/Shaula.ogg:system/media/audio/notifications/Shaula.ogg \
+	$(LOCAL_PATH)/notifications/ogg/Spica.ogg:system/media/audio/notifications/Spica.ogg \
 	$(LOCAL_PATH)/notifications/ogg/Vega.ogg:system/media/audio/notifications/Vega.ogg \
 	$(LOCAL_PATH)/ringtones/ogg/Acheron.ogg:system/media/audio/ringtones/Acheron.ogg \
 	$(LOCAL_PATH)/ringtones/ogg/Andromeda.ogg:system/media/audio/ringtones/Andromeda.ogg \
diff --git a/data/sounds/notifications/ogg/Adara.ogg b/data/sounds/notifications/ogg/Adara.ogg
new file mode 100755
index 0000000..e87f379
--- /dev/null
+++ b/data/sounds/notifications/ogg/Adara.ogg
Binary files differ
diff --git a/data/sounds/notifications/ogg/Shaula.ogg b/data/sounds/notifications/ogg/Shaula.ogg
new file mode 100755
index 0000000..1c0aa89
--- /dev/null
+++ b/data/sounds/notifications/ogg/Shaula.ogg
Binary files differ
diff --git a/data/sounds/notifications/ogg/Spica.ogg b/data/sounds/notifications/ogg/Spica.ogg
new file mode 100755
index 0000000..a9e91cb
--- /dev/null
+++ b/data/sounds/notifications/ogg/Spica.ogg
Binary files differ
diff --git a/docs/html/resources/resources-data.js b/docs/html/resources/resources-data.js
index c0a2284..3e673a5 100644
--- a/docs/html/resources/resources-data.js
+++ b/docs/html/resources/resources-data.js
@@ -728,6 +728,16 @@
     }
   },
   {
+    tags: ['sample','newfeature', 'new'],
+    path: 'samples/WiFiDirectDemo/index.html',
+    title: {
+      en: 'Wi-Fi Direct Demo'
+    },
+    description: {
+      en: 'A demo application to demonstrate how to use Wi-Fi Direct APIs.'
+    }
+  },
+  {
     tags: ['sample', 'ui', 'widgets'],
     path: 'samples/Wiktionary/index.html',
     title: {
diff --git a/docs/html/resources/samples/images/WifiDirect.png b/docs/html/resources/samples/images/WifiDirect.png
new file mode 100644
index 0000000..86f7f2f
--- /dev/null
+++ b/docs/html/resources/samples/images/WifiDirect.png
Binary files differ
diff --git a/docs/html/sdk/android-4.0.jd b/docs/html/sdk/android-4.0.jd
new file mode 100644
index 0000000..8f7ac55
--- /dev/null
+++ b/docs/html/sdk/android-4.0.jd
@@ -0,0 +1,1740 @@
+page.title=Android 4.0 Platform
+sdk.platform.version=4.0
+sdk.platform.apiLevel=14
+@jd:body
+
+<div id="qv-wrapper">
+<div id="qv">
+
+<h2>In this document</h2>
+<ol>
+  <li><a href="#relnotes">Revisions</a></li>
+  <li><a href="#api">API Overview</a></li>
+  <li><a href="#api-diff">API Differences Report</a></li>
+  <li><a href="#api-level">API Level</a></li>
+  <li><a href="#apps">Built-in Applications</a></li>
+  <li><a href="#locs">Locales</a></li>
+  <li><a href="#skins">Emulator Skins</a></li>
+</ol>
+
+<h2>Reference</h2>
+<ol>
+<li><a
+href="{@docRoot}sdk/api_diff/14/changes.html">API
+Differences Report &raquo;</a> </li>
+</ol>
+
+</div>
+</div>
+
+
+<p><em>API Level:</em>&nbsp;<strong>{@sdkPlatformApiLevel}</strong></p>
+
+<p>Android 4.0 (Ice Cream Sandwich) is a major platform release that adds new
+capabilities for users and developers. The sections below provide an overview
+of the new features and developer APIs.</p>
+
+<p>For developers, the Android {@sdkPlatformVersion} platform is available as a
+downloadable component for the Android SDK. The downloadable platform includes
+an Android library and system image, as well as a set of emulator skins and
+more. The downloadable platform includes no external libraries.</p>
+
+<p>To start developing or testing against Android {@sdkPlatformVersion},
+use the Android SDK Manager to download the platform into your SDK. For more
+information, see <a href="{@docRoot}sdk/adding-components.html">Adding SDK
+Components</a>. If you are new to Android, <a
+href="{@docRoot}sdk/index.html">download the SDK Starter Package</a> first.</p>
+
+<p>For a high-level introduction to the new user and developer features in Android 4.0, see the
+<a href="http://developer.android.com/sdk/android-4.0-highlights.html">Platform Highlights</a>.</p>
+
+<p class="note"><strong>Reminder:</strong> If you've already published an
+Android application, please test your application on Android {@sdkPlatformVersion} as
+soon as possible to be sure your application provides the best
+experience possible on the latest Android-powered devices.</p>
+
+
+<h2 id="relnotes">Revisions</h2>
+
+<p>To determine what revision of the Android {@sdkPlatformVersion} platform you
+have installed, refer to the "Installed Packages" listing in the Android SDK Manager.</p>
+
+
+<div class="toggle-content opened" style="padding-left:1em;">
+
+  <p><a href="#" onclick="return toggleContent(this)">
+    <img src="{@docRoot}assets/images/triangle-opened.png"
+class="toggle-content-img" alt="" />
+    Android {@sdkPlatformVersion}, Revision 1</a> <em>(October 2011)</em>
+  </a></p>
+
+  <div class="toggle-content-toggleme" style="padding-left:2em;">
+
+<dl>
+<dt>Initial release. SDK Tools r14 or higher is recommended.</dt>
+</dl>
+
+  </div>
+</div>
+
+
+<h2 id="api">API Overview</h2>
+
+<p>The sections below provide a technical overview of new APIs in Android 4.0.</p>
+
+<div class="toggle-content closed" style="padding-left:1em;">
+
+  <p><a href="#" onclick="return toggleContent(this)">
+    <img src="{@docRoot}assets/images/triangle-closed.png"
+class="toggle-content-img" alt="" />
+    <strong>Table of Contents</strong>
+  </a></p>
+
+  <div class="toggle-content-toggleme" style="padding-left:2em;">
+    <ol class="toc" style="margin-left:-1em">
+      <li><a href="#Contacts">Contacts</a></li>
+      <li><a href="#Calendar">Calendar</a></li>
+      <li><a href="#Camera">Camera</a></li>
+      <li><a href="#Multimedia">Multimedia</a></li>
+      <li><a href="#Bluetooth">Bluetooth</a></li>
+      <li><a href="#AndroidBeam">Android Beam (NDEF Push with NFC)</a></li>
+      <li><a href="#P2pWiFi">Peer-to-peer Wi-Fi</a></li>
+      <li><a href="#NetworkData">Network Data</a></li>
+      <li><a href="#Sensors">Device Sensors</a></li>
+      <li><a href="#Renderscript">Renderscript</a></li>
+      <li><a href="#A11y">Accessibility</a></li>
+      <li><a href="#Enterprise">Enterprise</a></li>
+      <li><a href="#Voicemail">Voicemail</a></li>
+      <li><a href="#SpellChecker">Spell Checker Services</a></li>
+      <li><a href="#TTS">Text-to-speech Engines</a></li>
+      <li><a href="#ActionBar">Action Bar</a></li>
+      <li><a href="#UI">User Interface and Views</a></li>
+      <li><a href="#Properties">Properties</a></li>
+      <li><a href="#HwAccel">Hardware Acceleration</a></li>
+      <li><a href="#Jni">JNI Changes</a></li>
+      <li><a href="#WebKit">WebKit</a></li>
+      <li><a href="#Permissions">Permissions</a></li>
+      <li><a href="#DeviceFeatures">Device Features</a></li>
+    </ol>
+  </div>
+</div>
+
+
+
+
+
+<h3 id="Contacts">Contacts</h3>
+
+<p>The Contact APIs that are defined by the {@link android.provider.ContactsContract} provider have
+been extended to support new features such as a personal profile for the device owner, large contact
+photos, and the ability for users to invite individual contacts to social networks that are
+installed on the device.</p>
+
+
+<h4>User Profile</h4>
+
+<p>Android now includes a personal profile that represents the device owner, as defined by the
+{@link
+android.provider.ContactsContract.Profile} table.  Social apps that maintain a user identity     can
+contribute to the user's profile data by creating a new {@link
+android.provider.ContactsContract.RawContacts} entry within the {@link
+android.provider.ContactsContract.Profile}. That is, raw contacts that represent the device user do
+not belong in the traditional raw contacts table defined by the {@link
+android.provider.ContactsContract.RawContacts} Uri; instead, you must add a profile raw contact in
+the table at {@link android.provider.ContactsContract.Profile#CONTENT_RAW_CONTACTS_URI}. Raw
+contacts in this table are then aggregated into the single user-visible profile information.</p>
+
+<p>Adding a new raw contact for the profile requires the {@link
+android.Manifest.permission#WRITE_PROFILE} permission. Likewise, in order to read from the profile
+table, you must request the {@link android.Manifest.permission#READ_PROFILE} permission. However,
+reading the user profile should not be required by most apps, even when contributing data to the
+profile. Reading the user profile is a sensitive permission and users will be very skeptical of apps
+that request reading their profile information.</p>
+
+<h4>Large photos</h4>
+
+<p>Android now supports high resolution photos for contacts. Now, when you push a photo into a
+contact
+record, the system processes it into both a 96x96 thumbnail (as it has previously) and a 256x256
+"display photo" stored in a new file-based photo store (the exact dimensions that the system chooses
+may vary in the future). You can add a large photo to a contact by putting a large photo in the
+usual {@link android.provider.ContactsContract.CommonDataKinds.Photo#PHOTO} column of a data row,
+which the system will then process into the appropriate thumbnail and display photo records.</p>
+
+<h4>Invite Intent</h4>
+
+<p>The {@link android.provider.ContactsContract.Intents#INVITE_CONTACT} intent action allows you to
+invoke an action that indicates the user wants to add a contact to a social network that understand
+this intent and use it to invite the contact specified in the contact to that social network.</p> 
+
+<p>Apps that use a sync adapter to provide information about contacts can register with the system
+to
+receive the invite intent when there’s an opportunity for the user to “invite” a contact to the
+app’s social network (such as from a contact card in the People app). To receive the invite intent,
+you simply need to add the {@code inviteContactActivity} attribute to your app’s XML sync
+configuration file, providing a fully-qualified name of the activity that the system should start
+when the user wants to “invite” a contact in your social network. The activity that starts can then
+retrieve the URI for the contact in question from the intent’s data and perform the necessary work
+to
+invite that contact to the network or add the person to the user’s connections.</p>
+
+<h4>Contact Usage Feedback</h4>
+
+<p>The new {@link android.provider.ContactsContract.DataUsageFeedback} APIs allow you to  help track
+how often the user uses particular methods of contacting people, such as how often the user uses
+each phone number or e-mail address. This information helps improve the ranking for each contact
+method associated with each person and provide such contact methods as suggestions.</p>
+
+
+
+
+
+<h3 id="Calendar">Calendar</h3>
+
+<p>The new calendar API allows you to access and modify the user’s calendars and events. The
+calendar
+APIs are provided with the {@link android.provider.CalendarContract} provider. Using the calendar
+provider, you can:</p>
+<ul>
+<li>Read, write, and modify calendars.</li>
+<li>Add and modify events, attendees, reminders, and alarms.</li>
+</ul>
+
+<p>{@link android.provider.CalendarContract} defines the data model of calendar and event-related
+information. All of the user’s calendar data is stored in a number of tables defined by subclasses
+of {@link android.provider.CalendarContract}:</p>
+
+<ul>
+<li>The {@link android.provider.CalendarContract.Calendars} table holds the calendar-specific
+information. Each row in this table contains the details for a single calendar, such as the name,
+color, sync information, and so on.</li>
+
+<li>The {@link android.provider.CalendarContract.Events} table holds event-specific information.
+Each
+row in this table has the information for a single event. It contains information such as event
+title, location, start time, end time, and so on. The event can occur one-time or can recur multiple
+times. Attendees, reminders, and extended properties are stored in separate tables and reference the
+event’s _ID to link them with the event.</li>
+
+<li>The {@link android.provider.CalendarContract.Instances} table holds the start and end time for
+occurrences of an event. Each row in this table represents a single occurrence. For one-time events
+there is a one-to-one mapping of instances to events. For recurring events, multiple rows are
+automatically generated to correspond to the multiple occurrences of that event.</li>
+
+<li>The {@link android.provider.CalendarContract.Attendees} table holds the event attendee or guest
+information. Each row represents a single guest of an event. It specifies the type of guest the
+person is and the person’s attendance response for the event.</li>
+
+<li>The {@link android.provider.CalendarContract.Reminders} table holds the alert/notification data.
+Each row represents a single alert for an event. An event can have multiple reminders. The number of
+reminders per event is specified in MAX_REMINDERS, which is set by the Sync Adapter that owns the
+given calendar. Reminders are specified in minutes before the event and have a type.</li>
+
+<li>The {@link android.provider.CalendarContract.ExtendedProperties} table hold opaque data fields
+used
+by the sync adapter. The provider takes no action with items in this table except to delete them
+when their related events are deleted.</li>
+</ul>
+
+<p>To access a user’s calendar data with the calendar provider, your application must request
+permission from the user by declaring <uses-permission
+android:name="android.permission.READ_CALENDAR" /> (for read access) and <uses-permission
+android:name="android.permission.WRITE_CALENDAR" /> (for write access) in their manifest files.</p>
+
+<p>However, if all you want to do is add an event to the user’s calendar, you can instead use an
+INSERT
+{@link android.content.Intent} to start an activity in the Calendar app that creates new events.
+Using the intent does not require the WRITE_CALENDAR permission and you can specify the {@link
+android.provider.CalendarContract#EXTRA_EVENT_BEGIN_TIME} and {@link
+android.provider.CalendarContract#EXTRA_EVENT_END_TIME} extra fields to pre-populate the form with
+the time of the event. The values for these times must be in milliseconds from the epoch. You must
+also specify {@code “vnd.android.cursor.item/event”} as the intent type.</p>
+
+
+
+
+
+<h3 id="Camera">Camera</h3>
+
+<p>The {@link android.hardware.Camera} APIs now support face detection and control for metering and
+focus areas.</p>
+
+<h4>Face Detection</h4>
+
+<p>Camera apps can now enhance their abilities with Android’s face detection software, which not
+only
+detects the face of a subject, but also specific facial features, such as the eyes and mouth. </p>
+
+<p>To detect faces in your camera application, you must register a {@link
+android.hardware.Camera.FaceDetectionListener} by calling {@link
+android.hardware.Camera#setFaceDetectionListener setFaceDetectionListener()}. You can then start
+your camera surface and start  detecting faces by calling {@link
+android.hardware.Camera#startFaceDetection}.</p>
+
+<p>When the system detects a face, it calls the {@link
+android.hardware.Camera.FaceDetectionListener#onFaceDetection onFaceDetection()} callback in your
+implementation of {@link android.hardware.Camera.FaceDetectionListener}, including an array of
+{@link android.hardware.Camera.Face} objects.</p>
+
+<p>An instance of the {@link android.hardware.Camera.Face} class provides various information about
+the
+face detected by the camera, including:</p>
+<ul>
+<li>A {@link android.graphics.Rect} that specifies the bounds of the face, relative to the camera's
+current field of view</li>
+<li>An integer betwen 0 and 100 that indicates how confident the system is that the object is a
+human
+face</li>
+<li>A unique ID so you can track multiple faces</li>
+<li>Several {@link android.graphics.Point} objects that indicate where the eyes and mouth are
+located</li>
+</ul>
+
+  
+<h4>Focus and Metering Areas</h4>
+
+<p>Camera apps can now control the areas that the camera uses for focus and when metering white
+balance
+and auto-exposure (when supported by the hardware). Both features use the new {@link
+android.hardware.Camera.Area} class to specify the region of the camera’s current view that should
+be focused or metered. An instance of the {@link android.hardware.Camera.Area} class defines the
+bounds of the area with a {@link android.graphics.Rect} and the weight of the
+area&mdash;representing the level of importance of that area, relative to other areas in
+consideration&mdash;with an integer.</p>
+
+<p>Before setting either a focus area or metering area, you should first call {@link
+android.hardware.Camera.Parameters#getMaxNumFocusAreas} or {@link
+android.hardware.Camera.Parameters#getMaxNumMeteringAreas}, respectively. If these return zero, then
+the device does not support the respective feature. </p>
+
+<p>To specify the focus or metering areas to use, simply call {@link
+android.hardware.Camera.Parameters#setFocusAreas setFocusAreas()} or {@link
+android.hardware.Camera.Parameters#setFocusAreas setMeteringAreas()}. Each take a {@link
+java.util.List} of {@link android.hardware.Camera.Area} objects that indicate the areas to consider
+for focus or metering. For example, you might implement a feature that allows the user to set the
+focus area by touching an area of the preview, which you then translate to an {@link
+android.hardware.Camera.Area} object and set the focus to that spot. The focus or exposure in that
+area will continually update as the scene in the area changes.</p>
+
+
+<h4>Other Camera Features</h4>
+<ul>
+<li>Capture photos during video recording
+While recording video, you can now call {@link android.hardware.Camera#takePicture takePicture()} to
+save a photo without interrupting the video session. Before doing so, you should call {@link
+android.hardware.Camera.Parameters#isVideoSnapshotSupported} to be sure the hardware supports
+it.</li>
+
+<li>Lock auto exposure and white balance with {@link
+android.hardware.Camera.Parameters#setAutoExposureLock setAutoExposureLock()} and {@link
+android.hardware.Camera.Parameters#setAutoWhiteBalanceLock setAutoWhiteBalanceLock()}, to prevent
+these properties from changing.</li>
+</ul>
+
+<h4>Camera Broadcast Intents</h4>
+
+<ul>
+<li>{@link android.hardware.Camera#ACTION_NEW_PICTURE Camera.ACTION_NEW_PICTURE} 
+This indicates that the user has captured a new photo. The built-in camera app invokes this
+broadcast after a photo is captured and third-party camera apps should also broadcast this intent
+after capturing a photo.</li>
+<li>{@link android.hardware.Camera#ACTION_NEW_VIDEO Camera.ACTION_NEW_VIDEO}
+This indicates that the user has captured a new video. The built-in camera app invokes this
+broadcast after a video is recorded and third-party camera apps should also broadcast this intent
+after capturing a video.</li>
+</ul>
+
+  
+  
+
+  
+<h3 id="Multimedia">Multimedia</h3>
+
+<p>Android 4.0 adds several new APIs for applications that interact with media such as photos,
+videos,
+and music.</p>
+
+
+<h4>Media Player</h4>
+
+<ul>
+<li>Streaming online media from {@link android.media.MediaPlayer} now requires {@link
+android.Manifest.permission#INTERNET} permission. If you use {@link android.media.MediaPlayer} to
+play content from the internet, be sure to add the {@link android.Manifest.permission#INTERNET}
+permission or else your media playback will not work beginning with Android 4.0.</li>
+<li>{@link android.media.MediaPlayer#setSurface(Surface) setSurface()} allows you define a {@link
+android.view.Surface} to behave as the video sink.</li>
+<li>{@link android.media.MediaPlayer#setDataSource(Context,Uri,Map) setDataSource()} allows you to
+send additional HTTP headers with your request, which can be useful for HTTP(S) live streaming</li>
+<li>HTTP(S) live streaming now respects HTTP cookies across requests</li>
+</ul>
+
+<h4>Media Type Support</h4>
+
+<p>Android 4.0 adds support for:</p>
+<ul>
+<li>HTTP/HTTPS live streaming protocol version 3 </li>
+<li>ADTS raw AAC audio encoding</li>
+<li>WEBP images</li>
+<li>Matroska video</li>
+</ul>
+<p>For more info, see <a href=”{@docRoot}guide/appendix/media-formats.html”>Supported Media
+Formats</a>.</p>
+
+
+<h4>Remote Control Client</h4>
+
+<p>The new {@link android.media.RemoteControlClient} allows media players to enable playback
+controls
+from remote control clients such as the device lock screen. Media players can also expose
+information about the media currently playing for display on the remote control, such as track
+information and album art.</p>
+
+<p>To enable remote control clients for your media player, instantiate a {@link
+android.media.RemoteControlClient} with a {@link android.app.PendingIntent} that broadcasts {@link
+android.content.Intent#ACTION_MEDIA_BUTTON}. The intent must also declare the explicit {@link
+android.content.BroadcastReceiver} component in your app that handles the {@link
+android.content.Intent#ACTION_MEDIA_BUTTON} event.</p>
+
+<p>To declare which media control inputs your player can handle, you must call {@link
+android.media.RemoteControlClient#setTransportControlFlags setTransportControlFlags()} on your
+{@link android.media.RemoteControlClient}, passing a set of {@code FLAG_KEY_MEDIA_*} flags, such as
+{@link android.media.RemoteControlClient#FLAG_KEY_MEDIA_PREVIOUS} and {@link
+android.media.RemoteControlClient#FLAG_KEY_MEDIA_NEXT}.</p>
+
+<p>You must then register your {@link android.media.RemoteControlClient} by passing it to {@link
+android.media.AudioManager#registerRemoteControlClient MediaManager.registerRemoteControlClient()}.
+Once registered, the broadcast receiver you declared when you instantiated the {@link
+android.media.RemoteControlClient} will receive {@link android.content.Intent#ACTION_MEDIA_BUTTON}
+events when a button is pressed from a remote control. The intent you receive includes the {@link
+android.view.KeyEvent} for the media key pressed, which you can retrieve from the intent with {@link
+android.content.Intent#getParcelableExtra getParcelableExtra(Intent.EXTRA_KEY_EVENT)}.</p>
+
+<p>To display information on the remote control about the media playing, call {@link
+android.media.RemoteControlClient#editMetadata editMetaData()} and add metadata to the returned
+{@link android.media.RemoteControlClient.MetadataEditor}. You can supply a bitmap for media artwork,
+numerical information such as elapsed time, and text information such as the track title. For
+information on available keys see the {@code METADATA_KEY_*} flags in {@link
+android.media.MediaMetadataRetriever}.</p>
+
+<p>For a sample implementation, see the <a
+href=”{@docRoot}resources/samples/RandomMusicPlayer/index.html”>Random Music Player</a>, which
+provides compatibility logic such that it enables the remote control client while continuing to
+support Android 2.1 devices.</p>
+
+
+<h4>Media Effects</h4>
+
+<p>A new media effects framework allows you to apply a variety of visual effects to images and
+videos.
+The system performs all effects processing on the GPU to obtain maximum performance. Applications in
+Android 4.0 such as Google Talk or the Gallery editor make use of the effects API to apply real-time
+effects to video and photos.</p>
+
+<p>For maximum performance, effects are applied directly to OpenGL textures, so your application
+must
+have a valid OpenGL context before it can use the effects APIs. The textures to which you apply
+effects may be from bitmaps, videos or even the camera. However, there are certain restrictions that
+textures must meet:</p>
+<ol>
+<li>They must be bound to a {@link android.opengl.GLES20#GL_TEXTURE_2D} texture image</li>
+<li>They must contain at least one mipmap level</li>
+</ol>
+
+<p>An {@link android.media.effect.Effect} object defines a single media effect that you can apply to
+an
+image frame. The basic workflow to create an {@link android.media.effect.Effect} is:</p>
+
+<ol>
+<li>Call {@link android.media.effect.EffectContext#createWithCurrentGlContext
+EffectContext.createWithCurrentGlContext()} from your OpenGL ES 2.0 context.</li>
+<li>Use the returned {@link android.media.effect.EffectContext} to call {@link
+android.media.effect.EffectContext#getFactory EffectContext.getFactory()}, which returns an instance
+of {@link android.media.effect.EffectFactory}.</li>
+<li>Call {@link android.media.effect.EffectFactory#createEffect createEffect()}, passing it an
+effect
+name from @link android.media.effect.EffectFactory}, such as {@link
+android.media.effect.EffectFactory#EFFECT_FISHEYE} or {@link
+android.media.effect.EffectFactory#EFFECT_VIGNETTE}.</li>
+</ol>
+
+<p>Not all devices support all effects, so you must first check if the desired effect is supported
+by
+calling {@link android.media.effect.EffectFactory#isEffectSupported isEffectSupported()}.</p>
+
+<p>You can adjust the effect’s parameters by calling {@link android.media.effect.Effect#setParameter
+setParameter()} and passing a parameter name and parameter value. Each type of effect accepts
+different parameters, which are documented with the effect name. For example, {@link
+android.media.effect.EffectFactory#EFFECT_FISHEYE} has one parameter for the {@code scale} of the
+distortion.</p>
+
+<p>To apply an effect on a texture, call {@link android.media.effect.Effect#apply apply()} on the
+{@link
+android.media.effect.Effect} and pass in the input texture, it’s width and height, and the output
+texture. The input texture  must be bound to a {@link android.opengl.GLES20#GL_TEXTURE_2D} texture
+image (usually done by calling the {@link android.opengl.GLES20#glTexImage2D glTexImage2D()}
+function). You may provide multiple mipmap levels. If the output texture has not been bound to a
+texture image, it will be automatically bound by the effect as a {@link
+android.opengl.GLES20#GL_TEXTURE_2D}. It will contain one mipmap level (0), which will have the same
+size as the input.</p> 
+
+
+
+
+
+
+
+<h3 id="Bluetooth">Bluetooth</h3>
+
+<p>Android now supports Bluetooth Health Profile devices, so you can create applications that use
+Bluetooth to communicate with health devices that support Bluetooth, such as heart-rate monitors,
+blood meters, thermometers, and scales.</p>
+
+<p>Similar to regular headset and A2DP profile devices, you must call {@link
+android.bluetooth.BluetoothAdapter#getProfileProxy getProfileProxy()} with a {@link
+android.bluetooth.BluetoothProfile.ServiceListener} and the {@link
+android.bluetooth.BluetoothProfile#HEALTH} profile type to establish a connection with the profile
+proxy object.</p>
+
+<p>Once you’ve acquired the Health profile proxy (the {@link android.bluetooth.BluetoothHealth}
+object), connecting to and communicating with paired health devices involves the following new
+Bluetooth classes:</p>
+<ul>
+<li>{@link android.bluetooth.BluetoothHealthCallback}: You must extend this class and implement the
+callback methods to receive updates about changes in the application’s registration state and
+Bluetooth channel state.</li>
+<li>{@link android.bluetooth.BluetoothHealthAppConfiguration}: During callbacks to your {@link
+android.bluetooth.BluetoothHealthCallback}, you’ll receive an instance of this object, which
+provides configuration information about the available Bluetooth health device, which you must use
+to perform various operations such as initiate and terminate connections with the {@link
+android.bluetooth.BluetoothHealth} APIs.</li>
+</ul>
+
+<p>For more information about using the Bluetooth Health profile, see the documentation for {@link
+android.bluetooth.BluetoothHealth}.</p>
+
+
+<h3 id="AndroidBeam">Android Beam (NDEF Push with NFC)</h3>
+
+<p>Android Beam allows you to send NDEF messages (an NFC standard for data stored on NFC tags) from
+one
+device to another (a process also known as “NDEF Push”). The data transfer is initiated when two
+Android-powered devices that support Android Beam are in close proximity (about 4 cm), usually with
+their backs touching. The data inside the NDEF message can contain any data that you wish to share
+between devices. For example, the People app shares contacts, YouTube shares videos, and Browser
+shares URLs using Android Beam.</p>
+
+<p>To transmit data between devices using Android Beam, you need to create an {@link
+android.nfc.NdefMessage} that contains the information you want to share while your activity is in
+the foreground. You must then pass the
+{@link android.nfc.NdefMessage} to the system in one of two ways:</p>
+
+<ul>
+<li>Define a single {@link android.nfc.NdefMessage} to use from the activity:
+<p>Call {@link android.nfc.NfcAdapter#setNdefPushMessage setNdefPushMessage()} at any time to set
+the
+message you want to send. For instance, you might call this method and pass it your {@link
+android.nfc.NdefMessage} during your activity’s {@link android.app.Activity#onCreate onCreate()}
+method. Then, whenever Android Beam is activated with another device while your activity is in the
+foreground, the system sends that {@link android.nfc.NdefMessage} to the other device.</p></li>
+
+<li>Define the {@link android.nfc.NdefMessage} depending on the current context:
+<p>Implement {@link android.nfc.NfcAdapter.CreateNdefMessageCallback}, in which the {@link
+android.nfc.NfcAdapter.CreateNdefMessageCallback#createNdefMessage createNdefMessage()} callback
+method returns the {@link android.nfc.NdefMessage} you want to send. Then pass the {@link
+android.nfc.NfcAdapter.CreateNdefMessageCallback} to {@link
+android.nfc.NfcAdapter#setNdefPushMessageCallback setNdefPushMessageCallback()}. In this case, when
+Android Beam is activated with another device while your activity is in the foreground, the system
+calls {@link android.nfc.NfcAdapter.CreateNdefMessageCallback#createNdefMessage createNdefMessage()}
+to retrieve the {@link android.nfc.NdefMessage} you want to send. This allows you to create a
+different {@link android.nfc.NdefMessage} for each occurrence, depending on the user context (such
+as which contact in the People app is currently visible).</p></li>
+</ul>
+
+<p>In case you want to run some specific code once the system has successfully delivered your NDEF
+message to the other device, you can implement {@link
+android.nfc.NfcAdapter.OnNdefPushCompleteCallback} and set it with {@link
+android.nfc.NfcAdapter#setOnNdefPushCompleteCallback setNdefPushCompleteCallback()}. The system will
+then call {@link android.nfc.NfcAdapter.OnNdefPushCompleteCallback#onNdefPushComplete
+onNdefPushComplete()} when the message is delivered.</p>
+
+<p>On the receiving device, the system dispatches NDEF Push messages in a similar way to regular NFC
+tags. The system invokes an intent with the {@link android.nfc.NfcAdapter#ACTION_NDEF_DISCOVERED}
+action to start an activity, with either a URL or a MIME type set according to the first {@link
+android.nfc.NdefRecord} in the {@link android.nfc.NdefMessage}. For the activity you want to
+respond, you can set intent filters for the URLs or MIME types your app cares about. For more
+information about Tag Dispatch see the <a
+href=”{@docRoot}guide/topics/nfc/index.html#dispatch”>NFC</a> developer guide.</p>
+
+<p>If you want your {@link android.nfc.NdefMessage} to carry a URI, you can now use the convenience
+method {@link android.nfc.NdefRecord#createUri createUri} to construct a new {@link
+android.nfc.NdefRecord} based on either a string or a {@link android.net.Uri} object. If the URI is
+a special format that you want your application to also receive during an Android Beam event, you
+should create an intent filter for your activity using the same URI scheme in order to receive the
+incoming NDEF message.</p>
+
+<p>You may also want to pass an “Android application record” with your {@link
+android.nfc.NdefMessage}
+in order to guarantee a specific application handles an NDEF message, regardless of whether other
+applications filter for the same intent. You can create an Android application record by calling
+{@link android.nfc.NdefRecord#createApplicationRecord createApplicationRecord()}, passing it the
+application’s package name. When the other device receives the NDEF message with this record, the
+system automatically starts the application matching the package name. If the target device does not
+currently have the application installed, the system uses the Android application record to launch
+Android Market and take the user to the application to install it.</p>
+
+<p>If your application doesn’t use NFC APIs to perform NDEF Push messaging, then Android provides a
+default behavior: When your application is in the foreground on one device and Android Beam is
+invoked with another Android-powered device, then the other device receives an NDEF message with an
+Android application record that identifies your application. If the receiving device has the
+application installed, the system launches it; if it’s not installed, Android Market opens and takes
+the user to your application so they can install it.</p>
+
+
+
+
+
+<h3 id="P2pWiFi">Peer-to-peer Wi-Fi</h3>
+
+<p>Android now supports Wi-Fi Direct&trade; for peer-to-peer (P2P) connections between
+Android-powered
+devices and other device types without a hotspot or Internet connection. The Android framework
+provides a set of Wi-Fi P2P APIs that allow you to discover and connect to other devices when each
+device supports Wi-Fi Direct&trade;, then communicate over a speedy connection across distances much
+longer than a Bluetooth connection.</p>
+
+<p>A new package, {@link android.net.wifi.p2p}, contains all the APIs for performing peer-to-peer
+connections with Wi-Fi. The primary class you need to work with is {@link
+android.net.wifi.p2p.WifiP2pManager}, for which you can get an instance by calling {@link
+android.app.Activity#getSystemService getSystemService(WIFI_P2P_SERVICE)}. The {@link
+android.net.wifi.p2p.WifiP2pManager} provides methods that allow you to:</p>
+<ul>
+<li>Initialize your application for P2P connections by calling {@link
+android.net.wifi.p2p.WifiP2pManager#initialize initialize()}</li>
+<li>Discover nearby devices by calling {@link android.net.wifi.p2p.WifiP2pManager#discoverPeers
+discoverPeers()}</li>
+<li>Start a P2P connection by calling {@link android.net.wifi.p2p.WifiP2pManager#connect
+connect()}</li>
+<li>And more</li>
+</ul>
+
+<p>Several other interfaces and classes are necessary as well, such as:</p>
+<ul>
+<li>The {@link android.net.wifi.p2p.WifiP2pManager.ActionListener} interface allows you to receive
+callbacks when an operation such as discovering peers or connecting to them succeeds or fails.</li>
+<li>{@link android.net.wifi.p2p.WifiP2pManager.PeerListListener} interface allows you to receive
+information about discovered peers. The callback provides a {@link
+android.net.wifi.p2p.WifiP2pDeviceList}, from which you can retrieve a {@link
+android.net.wifi.p2p.WifiP2pDevice} object for each device within range and get information such as
+the device name, address, device type, the WPS configurations the device supports, and more.</li>
+<li>The {@link android.net.wifi.p2p.WifiP2pManager.GroupInfoListener} interface allows you to
+receive
+information about a P2P group. The callback provides a {@link android.net.wifi.p2p.WifiP2pGroup}
+object, which provides group information such as the owner, the network name, and passphrase.</li>
+<li>{@link android.net.wifi.p2p.WifiP2pManager.ConnectionInfoListener} interface allows you to
+receive
+information about the current connection. The callback provides a {@link
+android.net.wifi.p2p.WifiP2pInfo} object, which has information such as whether a group has been
+formed and who is the group owner.</li>
+</ul>
+
+<p>In order to use the Wi-Fi P2P APIs, your app must request the following user permissions:</p>
+<ul>
+<li>{@link android.Manifest.permission#ACCESS_WIFI_STATE}</li>
+<li>{@link android.Manifest.permission#CHANGE_WIFI_STATE}</li>
+<li>{@link android.Manifest.permission#INTERNET} (even though your app doesn’t technically connect
+to
+the Internet, the WiFi Direct implementation uses traditional sockets that do require Internet
+permission to work).</li>
+</ul>
+
+<p>The Android system also broadcasts several different actions during certain Wi-Fi P2P events:</p>
+<ul>
+<li>{@link android.net.wifi.p2p.WifiP2pManager#WIFI_P2P_CONNECTION_CHANGED_ACTION}: The P2P
+connection
+state has changed. This carries {@link android.net.wifi.p2p.WifiP2pManager#EXTRA_WIFI_P2P_INFO} with
+a {@link android.net.wifi.p2p.WifiP2pInfo} object and {@link
+android.net.wifi.p2p.WifiP2pManager#EXTRA_NETWORK_INFO} with a {@link android.net.NetworkInfo}
+object.</li>
+<li>{@link android.net.wifi.p2p.WifiP2pManager#WIFI_P2P_STATE_CHANGED_ACTION}: The P2P state has
+changed
+between enabled and disabled. It carries {@link
+android.net.wifi.p2p.WifiP2pManager#EXTRA_WIFI_STATE} with either {@link
+android.net.wifi.p2p.WifiP2pManager#WIFI_P2P_STATE_DISABLED} or {@link
+android.net.wifi.p2p.WifiP2pManager#WIFI_P2P_STATE_ENABLED}</li>
+<li>{@link android.net.wifi.p2p.WifiP2pManager#WIFI_P2P_PEERS_CHANGED_ACTION}: The list of peer
+devices
+has changed.</li>
+<li>{@link android.net.wifi.p2p.WifiP2pManager#WIFI_P2P_THIS_DEVICE_CHANGED_ACTION}: The details for
+this device have changed.</li>
+</ul>
+
+<p>See the  {@link android.net.wifi.p2p.WifiP2pManager} documentation for more information. Also
+look
+at the <a href=”{@docRoot}resources/samples/WiFiDirectDemo/index.html”>Wi-Fi Direct</a> sample
+application for example code.</p>
+
+
+
+
+
+<h3 id="NetworkData">Network Data</h3>
+
+<p>Android 4.0 gives users precise visibility of how much network data applications are using. The
+Settings app provides controls that allow users to manage set limits for network data usage and even
+disable the use of background data for individual apps. In order to avoid users disabling your app’s
+access to data from the background, you should develop strategies to use use the data connection
+efficiently and vary your usage depending on the type of connection available.</p>
+
+<p>If your application performs a lot of network transactions, you should provide user settings that
+allow users to control your app’s data habits, such as how often your app syncs data, whether to
+perform uploads/downloads only when on Wi-Fi, whether to use data while roaming, etc. With these
+controls available to them, users are much less likely to disable your app’s access to data when
+they approach their limits, because they can instead precisely control how much data your app uses.
+When you provide an activity with these settings, you should include in its manifest declaration an
+intent filter for the {@link android.content.Intent#ACTION_MANAGE_NETWORK_USAGE} action. For
+example:</p>
+
+<pre>
+&lt;activity android:name="DataPreferences" android:label="@string/title_preferences">
+    &lt;intent-filter>
+       &lt;action android:name="android.intent.action.MANAGE_NETWORK_USAGE" />
+       &lt;category android:name="android.intent.category.DEFAULT" />
+    &lt;/intent-filter>
+&lt;/activity>
+</pre>
+
+<p>This intent filter indicates to the system that this is the application that controls your
+application’s data usage. Thus, when the user inspects how much data your app is using from the
+Settings app, a “View application settings” button is available that launches your activity so the
+user can refine how much data your app uses.</p>
+
+<p>Also beware that {@link android.net.ConnectivityManager#getBackgroundDataSetting()} is now
+deprecated and always returns true&mdash;use  {@link
+android.net.ConnectivityManager#getActiveNetworkInfo()} instead. Before you attempt any network
+transactions, you should always call {@link android.net.ConnectivityManager#getActiveNetworkInfo()}
+to get the {@link android.net.NetworkInfo} that represents the current network and query {@link
+android.net.NetworkInfo#isConnected()} to check whether the device has a
+connection. You can then check various other connection properties, such as whether the device is
+roaming or connected to Wi-Fi.</p>
+
+
+
+
+
+
+
+<h3 id="Sensors">Device Sensors</h3>
+
+<p>Two new sensor types have been added in Android 4.0: {@link
+android.hardware.Sensor#TYPE_AMBIENT_TEMPERATURE} and {@link
+android.hardware.Sensor#TYPE_RELATIVE_HUMIDITY}. </p>
+
+<p>{@link android.hardware.Sensor#TYPE_AMBIENT_TEMPERATURE} is a temperature sensor that provides
+the ambient (room) temperature near a device. This sensor reports data in degrees Celsius. {@link
+android.hardware.Sensor#TYPE_RELATIVE_HUMIDITY} is a humidity sensor that provides the relative
+ambient (room) humidity. The sensor reports data as a percentage. If a device has both {@link
+android.hardware.Sensor#TYPE_AMBIENT_TEMPERATURE} and  {@link
+android.hardware.Sensor#TYPE_RELATIVE_HUMIDITY} sensors, you can use them to calculate the dew point
+and the absolute humidity.</p>
+
+<p>The existing temperature sensor ({@link android.hardware.Sensor#TYPE_TEMPERATURE}) has been
+deprecated. You should use the {@link android.hardware.Sensor#TYPE_AMBIENT_TEMPERATURE} sensor
+instead.</p>
+
+<p>Additionally, Android’s three synthetic sensors have been improved so they now have lower latency
+and smoother output. These sensors include the gravity sensor ({@link
+android.hardware.Sensor#TYPE_GRAVITY}), rotation vector sensor ({@link
+android.hardware.Sensor#TYPE_ROTATION_VECTOR}), and linear acceleration sensor ({@link
+android.hardware.Sensor#TYPE_LINEAR_ACCELERATION}). The improved sensors rely on the gyroscope
+sensor to improve their output so the sensors appear only on devices that have a gyroscope. If a
+device already provides one of the sensors, then that sensor appears as a second sensor on the
+device. The three improved sensors have a version number of 2.</p>
+
+
+
+
+
+
+
+
+<h3 id="Renderscript">Renderscript</h3>
+
+<p>Three major features have been added to Renderscript:</p>
+
+<ul>
+  <li>Off-screen rendering to a framebuffer object</li>
+  <li>Rendering inside a view</li>
+  <li>RS for each from the framework APIs</li>
+</ul>
+
+<p>The {@link android.renderscript.Allocation} class now supports a {@link
+android.renderscript.Allocation#USAGE_GRAPHICS_RENDER_TARGET} memory space, which allows you to
+render things directly into the {@link android.renderscript.Allocation} and use it as a framebuffer
+object.  </p>
+
+<p>{@link android.renderscript.RSTextureView} provides a means to display Renderscript graphics
+inside
+of a normal View,  unlike {@link android.renderscript.RSSurfaceView}, which creates a separate
+window. This key difference allows you to do things such as move, transform, or animate an {@link
+android.renderscript.RSTextureView} as well as draw Renderscript graphics inside the View alongside
+other traditional View widgets.</p>
+
+<p>The {@link android.renderscript.Script#forEach forEach()} method allows you to call Renderscript
+compute scripts from the VM level and have them automatically delegated to available cores on the
+device. You do not use this method directly, but any compute Renderscript that you write will have a
+{@link android.renderscript.Script#forEach forEach()}  method that you can call in the reflected
+Renderscript class. You can call the reflected {@link android.renderscript.Script#forEach forEach()}
+method by passing in an input {@link android.renderscript.Allocation} to process, an output {@link
+android.renderscript.Allocation} to write the result to, and a data structure if the Renderscript
+needs more information in addition to the {@link android.renderscript.Allocation}s to. Only one of
+the {@link android.renderscript.Allocation}s is necessary and the data structure is optional.</p>
+
+
+
+
+
+
+<h3 id="A11y">Accessibility</h3>
+
+<p>Android 4.0 improves accessibility for users with disabilities with the Touch Exploration service
+and provides extended APIs for developers of new accessibility services.</p>
+
+<h4>Touch Exploration</h4>
+
+<p>Users with vision loss can now explore applications by touching areas of the screen and hearing
+voice descriptions of the content. The “Explore by Touch” feature works like a virtual cursor as the
+user drags a finger across the screen.</p>
+
+<p>You don’t have to use any new APIs to enhance touch exploration in your application, because the
+existing {@link android.R.attr#contentDescription android:contentDescription}
+attribute and {@link android.view.View#setContentDescription setContentDescription()} method is all
+you need. Because touch exploration works like a virtual cursor, it allows screen readers to
+identify the descriptive the same way that screen readers can when navigating with a d-pad or
+trackball. So this is a reminder to provide descriptive text for the views in your application,
+especially for {@link android.widget.ImageButton}, {@link android.widget.EditText}, {@link
+android.widget.CheckBox} and other interactive widgets that might not contain text information by
+default.</p>
+
+<h4>Accessibility for Custom Views</h4>
+
+<p>Developers of custom Views, ViewGroups and widgets can make their components compatible with
+accessibility services like Touch Exploration. For custom views and widgets targeted for Android 4.0
+and later, developers should implement the following accessibility API methods in their classes:</p>
+<ul>
+<li>These two methods initiate the accessibility event generation process and must be implemented by
+your custom view class.
+  <ul>
+  <li>{@link android.view.View#sendAccessibilityEvent(int) sendAccessibilityEvent()} If
+accessibility
+  is
+  not enabled, this call has no effect.</li>
+  <li>{@link
+  android.view.View#sendAccessibilityEventUnchecked(android.view.accessibility.AccessibilityEvent)
+  sendAccessibilityEventUnchecked()} - This method executes regardless of whether accessibility is
+  enabled or not.</li>
+  </ul>
+</li>
+
+<li>These methods are called in order by the sendAccessibilityEvent methods listed above to collect
+accessibility information about the view, and its child views.
+  <ul>
+  <li>{@link
+  android.view.View#onInitializeAccessibilityEvent(android.view.accessibility.AccessibilityEvent)
+  onInitializeAccessibilityEvent()} - This method collects information about the view. If your
+  application has specific requirements for accessibility, you should extend this method to add that
+  information to the {@link android.view.accessibility.AccessibilityEvent}.</li>
+  
+  <li>{@link
+ 
+android.view.View#dispatchPopulateAccessibilityEvent(android.view.accessibility.AccessibilityEvent)
+  dispatchPopulateAccessibilityEvent()} is called by the framework to request text information for
+  this view and its children. This method calls {@link
+  android.view.View#onPopulateAccessibilityEvent(android.view.accessibility.AccessibilityEvent)
+  onPopulateAccessibilityEvent()} first on the current view and then on its children.</li>
+  </ul>
+</li>
+
+<li>The {@link
+android.view.View#onInitializeAccessibilityNodeInfo onInitializeAccessibilityNodeInfo()} method
+provides additional context information for
+accessibility services. You should implement or override this method to provide improved information
+for accessibility services investigating your custom view.</li>
+
+<li>Custom {@link android.view.ViewGroup} classes should also implement {@link
+android.view.ViewGroup#onRequestSendAccessibilityEvent(android.view.View,
+android.view.accessibility.AccessibilityEvent) onRequestSendAccessibilityEvent()}  </li>
+</ul>
+
+<p>Developers who want to maintain compatibility with Android versions prior to 4.0, while still
+providing support for new the accessibility APIs, can use the {@link
+android.view.View#setAccessibilityDelegate(android.view.View.AccessibilityDelegate)
+setAccessibilityDelegate()} method to provide an {@link android.view.View.AccessibilityDelegate}
+containing implementations of the new accessibility API methods while maintaining compatibility with
+prior releases.</p>
+
+
+
+<h4>Accessibility Service APIs</h4>
+
+<p>Accessibility events have been significantly improved to provide better information for
+accessibility services. In particular, events are generated based on view composition, providing
+better context information and allowing accessibility service developers to traverse view
+hierarchies to get additional view information and deal with special cases.</p>
+
+<p>To access additional content information and traverse view hierarchies, accessibility service
+application developers should use the following procedure.</p>
+<ol>
+<li>Upon receiving an {@link android.view.accessibility.AccessibilityEvent} from an application,
+call
+the {@link android.view.accessibility.AccessibilityEvent#getRecord(int)
+AccessibilityEvent.getRecord()} to retrieve new accessibility information about the state of the
+view.</li>
+<li>From the {@link android.view.accessibility.AccessibilityRecord}, call {@link 
+android.view.accessibility.AccessibilityRecord#getSource() getSource()} to retrieve a {@link
+android.view.accessibility.AccessibilityNodeInfo} object.</li>
+<li>With the {@link android.view.accessibility.AccessibilityNodeInfo}, call {@link
+android.view.accessibility.AccessibilityNodeInfo#getParent getParent()} or {@link
+android.view.accessibility.AccessibilityNodeInfo#getChild getChild()} to traverse the view
+hierarchy and get additional context information.</li>
+</ol>
+
+<p>In order to retrieve {@link android.view.accessibility.AccessibilityNodeInfo} information, your
+application must request permission to retrieve application window content through a manifest
+declaration that includes a new, separate xml configuration file, which supercedes {@link
+android.accessibilityservice.AccessibilityServiceInfo}. For more information, see {@link
+android.accessibilityservice.AccessibilityService} and {@link
+android.accessibilityservice.AccessibilityService#SERVICE_META_DATA
+AccessibilityService.SERVICE_META_DATA}.</p>
+
+
+
+
+
+
+<h3 id="Enterprise">Enterprise</h3>
+
+<p>Android 4.0 expands the capabilities for enterprise application with the following features.</p>
+
+<h4>VPN Services</h4>
+
+<p>The new {@link android.net.VpnService} allows applications to build their own VPN (Virtual
+Private
+Network), running as a {@link android.app.Service}. A VPN service creates an interface for a virtual
+network with its own address and routing rules and performs all reading and writing with a file
+descriptor.</p>
+
+<p>To create a VPN service, use {@link android.net.VpnService.Builder}, which allows you to specify
+the network address, DNS server, network route, and more. When complete, you can establish the
+interface by calling {@link android.net.VpnService.Builder#establish()}, which returns a {@link
+android.os.ParcelFileDescriptor}. </p>
+
+<p>Because  a VPN service can intercept packets, there are security implications.  As such, if you
+implement {@link android.net.VpnService}, then your service must require the {@link
+android.Manifest.permission#BIND_VPN_SERVICE} to ensure that only the system can bind to it (only
+the system is granted this permission&mdash;apps cannot request it). To then use your VPN service,
+users must manually enable it in the system settings.</p>
+
+
+<h4>Device Restrictions</h4>
+
+<p>Applications that manage the device restrictions can now disable the camera using {@link
+android.app.admin.DevicePolicyManager#setCameraDisabled setCameraDisabled()} and the {@link
+android.app.admin.DeviceAdminInfo#USES_POLICY_DISABLE_CAMERA} property (applied with a {@code
+&lt;disable-camera /&gt;} element in the policy configuration file).</p>
+
+
+<h4>Certificate Management</h4>
+
+<p>The new {@link android.security.KeyChain} class provides APIs that allow you to import and access
+certificates and key stores in credential storage.  See the {@link android.security.KeyChain}
+documentation for more information.</p>
+
+
+
+
+<h3 id="Voicemail">Voicemail</h3>
+
+<p>A new voicemail APIs allows applications to add voicemails to the system. Because the APIs
+currently
+do not allow third party apps to read all the voicemails from the system, the only third-party apps
+that should use the voicemail APIs are those that have voicemail to deliver to the user. For
+instance, it’s possible that a users have multiple voicemail sources, such as one provided by their
+phone’s service provider and others from VoIP or other alternative services. These kinds of apps can
+use the APIs to add voicemail to the system. The built-in Phone application can then present all
+voicemails to the user with a single list. Although the system’s Phone application is the only
+application that can read all the voicemails, each application that provides voicemails can read
+those that it has added to the system.</p>
+
+<p>The {@link android.provider.VoicemailContract} class defines the content provider for the
+voicemail
+APIs. The subclasses {@link android.provider.VoicemailContract.Voicemails} and {@link
+android.provider.VoicemailContract.Status} provide tables in which the voicemail providers can
+insert voicemail data for storage on the device. For an example of a voicemail provider app, see the
+<a href=”{@docRoot}resources/samples/VoicemailProviderDemo/index.html”>Voicemail Provider
+Demo</a>.</p>
+
+
+
+
+<h3 id="SpellChecker">Spell Checker Services</h3>
+
+<p>The new spell checker framework allows apps to create spell checkers in a manner similar to the
+input method framework. To create a new spell checker, you must override the {@link
+android.service.textservice.SpellCheckerService.Session} class to provide spelling suggestions based
+on text provided by the interface callback methods, returning suggestions as a {@link
+android.view.textservice.SuggestionsInfo} object. </p>
+
+<p>Applications with a spell checker service must declare the {@link
+android.Manifest.permission#BIND_TEXT_SERVICE} permission as required by the service, such that
+other services must have this permission in order for them to bind with the spell checker service.
+The service must also declare an intent filter with <action
+android:name="android.service.textservice.SpellCheckerService" /> as the intent’s action and should
+include a {@code &lt;meta-data&gt;} element that declares configuration information for the spell
+checker. </p>
+
+
+
+
+
+<h3 id="TTS">Text-to-speech Engines</h3>
+
+<p>Android’s text-to-speech (TTS) APIs have been greatly extended to allow applications to more
+easily
+implement custom TTS engines, while applications that want to use a TTS engine have a couple new
+APIs for selecting the engine.</p>
+
+
+<h4>Using text-to-speech engines</h4>
+
+<p>In previous versions of Android, you could use the {@link android.speech.tts.TextToSpeech} class
+to
+perform text-to-speech (TTS) operations using the TTS engine provided by the system or set a custom
+engine using {@link android.speech.tts.TextToSpeech#setEngineByPackageName
+setEngineByPackageName()}.
+In Android 4.0, the {@link android.speech.tts.TextToSpeech#setEngineByPackageName
+setEngineByPackageName()} method has been deprecated and you can now specify the engine to use with
+a new {@link android.speech.tts.TextToSpeech} that accepts the package name of a TTS engine.</p>
+
+<p>You can also query the available TTS engines with {@link
+android.speech.tts.TextToSpeech#getEngines()}. This method returns a list of {@link
+android.speech.tts.TextToSpeech.EngineInfo} objects, which include meta data such as the engine’s
+icon, label, and package name.</p>
+
+
+<h4>Building text-to-speech engines</h4>
+
+<p>Previously, custom engines required that the engine be built using native code, based on a TTS
+engine header file. In Android 4.0, there is a framework API for building TTS engines. </p>
+
+<p>The basic setup requires an implementation of {@link android.speech.tts.TextToSpeechService} that
+responds to the {@link android.speech.tts.TextToSpeech.Engine#INTENT_ACTION_TTS_SERVICE} intent. The
+primary work for a TTS engine happens during the {@link
+android.speech.tts.TextToSpeechService#onSynthesizeText onSynthesizeText()} callback in the {@link
+android.speech.tts.TextToSpeechService}. The system delivers this method two objects:</p>
+<ul>
+<li>{@link android.speech.tts.SynthesisRequest}: This contains various data including the text to
+synthesize, the locale, the speech rate, and voice pitch.</li>
+<li>{@link android.speech.tts.SynthesisCallback}: This is the interface by which your TTS engine
+delivers the resulting speech data as streaming audio, by calling {@link
+android.speech.tts.SynthesisCallback#start start()} to indicate that the engine is ready to deliver
+the
+audio, then call {@link android.speech.tts.SynthesisCallback#audioAvailable audioAvailable()},
+passing it the audio
+data in a byte buffer. Once your engine has passed all audio through the buffer, call {@link
+android.speech.tts.SynthesisCallback#done()}.</li>
+</ul>
+
+<p>Now that the framework supports a true API for creating TTS engines, support for the previous
+technique using native code has been removed. Watch for a blog post about the compatibility layer
+that you can use to convert TTS engines built using the previous technique to the new framework.</p>
+
+<p>For an example TTS engine using the new APIs, see the <a
+href=”{@docRoot}resources/samples/TtsEngine/index.html”>Text To Speech Engine</a> sample app.</p>
+
+
+
+
+
+
+
+
+
+
+
+<h3 id="ActionBar">Action Bar</h3>
+
+<p>The {@link android.app.ActionBar} has been updated to support several new behaviors. Most
+importantly, the system gracefully manages the action bar’s size and configuration when running on
+smaller screens in order to provide an optimal user experience. For example, when the screen is
+narrow (such as when a handset is in portrait orientation), the action bar’s navigation tabs appear
+in a “stacked bar,” which appears directly below the main action bar. You can also opt-in to a
+“split action bar,” which will place all action items in a separate bar at the bottom of the screen
+when the screen is narrow.</p>
+
+
+<h4>Split Action Bar</h4>
+
+<p>If your action bar includes several action items, not all of them will fit into the action bar
+when on a narrow screen, so the system will place them into the overflow menu. However, Android 4.0
+allows you to enable “split action bar” so that more action items can appear on the screen in a
+separate bar at the bottom of the screen. To enable split action bar, add {@link
+android.R.attr#uiOptions android:uiOptions} with {@code ”splitActionBarWhenNarrow”} to either your
+{@code &lt;application&gt;} tag or individual {@code &lt;activity&gt;} tags in your manifest file.
+When enabled, the system will enable the additional bar for action items when the screen is narrow
+and add all action items to the new bar (no action items will appear in the primary action bar).</p>
+
+<p>If you want to use the navigation tabs provided by the {@link android.app.ActionBar.Tab} APIs,
+but
+don’t want the stacked bar&mdash;you want only the tabs to appear, then enable the split action bar
+as described above and also call {@link android.app.ActionBar#setDisplayShowHomeEnabled
+setDisplayShowHomeEnabled(false)} to disable the application icon in the action bar. With nothing
+left in the main action bar, it disappears&mdash;all that’s left are the navigation tabs at the top
+and the action items at the bottom of the screen.</p>
+
+
+<h4>Action Bar Styles</h4>
+
+<p>If you want to apply custom styling to the action bar, you can use new style properties {@link
+android.R.attr#backgroundStacked} and {@link android.R.attr#backgroundSplit} to apply a background
+drawable or color to the stacked bar and split bar, respectively. You can also set these styles at
+runtime with {@link android.app.ActionBar#setStackedBackgroundDrawable
+setStackedBackgroundDrawable()} and {@link android.app.ActionBar#setSplitBackgroundDrawable
+setSplitBackgroundDrawable()}.</p>
+
+
+<h4>Action Provider</h4>
+
+<p>The new {@link android.view.ActionProvider} class facilitates user actions to which several
+different applications may respond. For example, a “share” action in your application might invoke
+several different apps that can handle the {@link android.content.Intent#ACTION_SEND} intent and the
+associated data. In this case, you can use the {@link android.widget.ShareActionProvider} (an
+extension of {@link android.view.ActionProvider}) in your action bar, instead of a traditional menu
+item that invokes the intent. The {@link android.widget.ShareActionProvider} populates a drop-down
+menu with all the available apps that can handle the intent.</p>
+
+<p>To declare an action provider for an action item, include the {@code android:actionProviderClass}
+attribute in the {@code &lt;item&gt;} element for your activity’s options menu, with the class name
+of the action provider as the attribute value. For example:</p>
+
+<pre>
+&lt;item android:id="@+id/menu_share"
+      android:title="Share"
+      android:icon="@drawable/ic_share"
+      android:showAsAction="ifRoom"
+      android:actionProviderClass="android.widget.ShareActionProvider" /&gt;
+</pre>
+
+<p>In your activity’s {@link android.app.Activity#onCreateOptionsMenu onCreateOptionsMenu()}
+callback
+method, retrieve an instance of the action provider from the menu item and set the intent:</p>
+
+<pre>
+public boolean onCreateOptionsMenu(Menu menu) {
+    getMenuInflater().inflate(R.menu.options, menu);
+    ShareActionProvider shareActionProvider =
+          (ShareActionProvider) menu.findItem(R.id.menu_share).getActionProvider();
+    // Set the share intent of the share action provider.
+    shareActionProvider.setShareIntent(createShareIntent());
+    ...
+    return super.onCreateOptionsMenu(menu);
+}
+</pre>
+
+<p>For an example using the {@link android.widget.ShareActionProvider}, see the <a
+href=”{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/ActionBarActionProviderActivity.html”>ActionBarActionProviderActivity</a>
+class in ApiDemos.</p>
+
+
+<h4>Collapsible Action Views</h4>
+
+<p>Menu items that appear as action items can now toggle between their action view state and
+traditional action item state. Previously only the {@link android.widget.SearchView} supported
+collapsing when used as an action view, but now you can add an action view for any action item and
+switch between the expanded state (action view is visible) and collapsed state (action item is
+visible).</p>
+
+<p>To declare that an action item that contains an action view be collapsible, include the {@code
+“collapseActionView”} flag in the {@code android:showAsAction} attribute for the {@code
+&lt;item&gt;} element in the menu’s XML file.</p>
+
+<p>To receive callbacks when an action view switches between expanded and collapsed, register an
+instance of {@link android.view.MenuItem.OnActionExpandListener} with the respective {@link
+android.view.MenuItem} by calling {@link android.view.MenuItem#setOnActionExpandListener
+setOnActionExpandListener()}. Typically, you should do so during the {@link
+android.app.Activity#onCreateOptionsMenu onCreateOptionsMenu()} callback.</p>
+
+<p>To control a collapsible action view, you can call {@link
+android.view.MenuItem#collapseActionView()} and {@link android.view.MenuItem#expandActionView()} on
+the respective {@link android.view.MenuItem}.</p>
+
+<p>When creating a custom action view, you can also implement the new {@link
+android.view.CollapsibleActionView} interface to receive callbacks when the view is expanded and
+collapsed.</p>
+
+
+<h4>Other APIs for Action Bar</h4>
+<ul>
+<li>{@link android.app.ActionBar#setHomeButtonEnabled setHomeButtonEnabled()} allows you to disable
+the
+default behavior in which the application icon/logo behaves as a button (pass “false” to disable it
+as a button).</li>
+<li>{@link android.app.ActionBar#setIcon setIcon()} and {@link android.app.ActionBar#setLogo
+setLogo()}
+to define the action bar icon or logo at runtime.</li>
+<li>{@link android.app.Fragment#setMenuVisibility Fragment.setMenuVisibility()} allows you to enable
+or
+disable the visibility of the options menu items declared by the fragment. This is useful if the
+fragment has been added to the activity, but is not visible, so the menu items should be
+hidden.</li>
+<li>{@link android.app.FragmentManager#invalidateOptionsMenu
+FragmentManager.invalidateOptionsMenu()}
+allows you to invalidate the activity options menu during various states of the fragment lifecycle
+in which using the equivalent method from {@link android.app.Activity} might not be available.</li>
+</ul>
+
+
+
+
+
+
+
+
+<h3 id="UI">User Interface and Views</h3>
+
+<p>Android 4.0 introduces a variety of new views and other UI components.</p>
+
+<h4>System UI</h4>
+
+<p>Since the early days of Android, the system has managed a UI component known as the <em>status
+bar</em>, which resides at the top of handset devices to deliver information such as the carrier
+signal, time, notifications, and so on. Android 3.0 added the <em>system bar</em> for tablet
+devices, which resides at the bottom of the screen to provide system navigation controls (Home,
+Back, and so forth) and also an interface for elements traditionally provided by the status bar.  In
+Android 4.0, the system provides a new type of system UI called the <em>navigation bar</em>. The
+navigation bar shares some qualities with the system bar, because it provides navigation controls
+for devices that don’t have hardware counterparts for navigating the system, but the navigation
+controls is all that it provides (a device with the navigation bar, thus, also includes the status
+bar at the top of the screen).</p>
+
+<p>To this day, you can hide the status bar on handsets using the {@link
+android.view.WindowManager.LayoutParams#FLAG_FULLSCREEN} flag. In Android 4.0, the APIs that control
+the system bar’s visibility have been updated to better reflect the behavior of both the system bar
+and navigation bar:</p>
+<ul>
+<li>The {@link android.view.View#SYSTEM_UI_FLAG_LOW_PROFILE} flag replaces View.STATUS_BAR_HIDDEN
+flag
+(now deprecated). When set, this flag enables “low profile” mode for the system bar or navigation
+bar. Navigation buttons dim and other elements in the system bar also hide.</li>
+<li>The {@link android.view.View#SYSTEM_UI_FLAG_VISIBLE} flag replaces the {@code
+STATUS_BAR_VISIBLE}
+flag to request the system bar or navigation bar be visible.</li>
+<li>The {@link android.view.View#SYSTEM_UI_FLAG_HIDE_NAVIGATION} is a new flag that requests that
+the
+navigation bar hide completely. Take note that this works only for the <em>navigation bar</em> used
+by some handsets (it does <strong>not</strong> hide the system bar on tablets). The navigation bar
+returns as soon as the system receives user input. As such, this mode is generally used for video
+playback or other cases in which user input is not required.</li>
+</ul>
+
+<p>You can set each of these flags for the system bar by calling {@link
+android.view.View#setSystemUiVisibility setSystemUiVisibility()} on any view in your activity
+window. The window manager will combine (OR-together) all flags from all views in your window and
+apply them to the system UI as long as your window has input focus. When your window loses input
+focus (the user navigates away from your app, or a dialog appears), your flags cease to have effect.
+Similarly, if you remove those views from the view hierarchy their flags no longer apply.</p>
+
+<p>To synchronize other events in your activity with visibility changes to the system UI (for
+example,
+hide the action bar or other UI controls when the system UI hides), you can register a {@link
+android.view.View.OnSystemUiVisibilityChangeListener} to get a callback when the visibility
+changes.</p>
+
+<p>See the <a
+href=”{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/view/OverscanActivity.html”>
+OverscanActivity</a> class for a demonstration of different system UI options.</p>
+
+
+<h4>GridLayout</h4>
+
+<p>{@link android.widget.GridLayout} is a new view group that places child views in a rectangular
+grid.
+Unlike {@link android.widget.TableLayout}, {@link android.widget.GridLayout} relies on a flat
+hierarchy and does not make use of intermediate views such as table rows for providing structure.
+Instead, children specify which row(s) and column(s) they should occupy (cells can span multiple
+rows and/or columns), and by default are laid out sequentially across the grid’s rows and columns.
+The {@link android.widget.GridLayout} orientation determines whether sequential children are by
+default laid out horizontally or vertically. Space between children may be specified either by using
+instances of the new {@link android.widget.Space} view or by setting the relevant margin parameters
+on children.</p>
+
+<p>See <a
+href=”{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/view/index.html”>ApiDemos</a>
+for samples using {@link android.widget.GridLayout}.</p>
+
+
+
+<h4>TextureView</h4>
+
+<p>{@link android.view.TextureView} is a new view that allows you to display a content stream, such
+as
+a video or an OpenGL scene. Although similar to {@link android.view.SurfaceView}, {@link
+android.view.TextureView} is unique in that it behaves like a regular view, rather than creating a
+separate window, so you can treat it like any other {@link android.view.View} object. For example,
+you can apply transforms, animate it using {@link android.view.ViewPropertyAnimator}, or easily
+adjust its opacity with {@link android.view.View#setAlpha setAlpha()}.</p>
+
+<p>Beware that {@link android.view.TextureView} works only within a hardware accelerated window.</p>
+
+<p>For more information, see the {@link android.view.TextureView} documentation.</p>
+
+
+<h4>Switch Widget</h4>
+
+<p>The new {@link android.widget.Switch} widget is a two-state toggle that users can drag to one
+side
+or the other (or simply tap) to toggle an option between two states.</p>
+
+<p>You can declare a switch in your layout with the {@code &lt;Switch&gt;} element. You can use the
+{@code android:textOn} and {@code android:textOff} attributes to specify the text to appear on the
+switch when in the on and off setting. The {@code android:text} attribute also allows you to place a
+label alongside the switch.</p>
+
+<p>For a sample using switches, see the <a
+href=”{@docRoot}resources/samples/ApiDemos/res/layout/switches.html”>switches.xml</a> layout file
+and respective <a
+href=”{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/view/Switches.html”>Switches
+</a> activity.</p>
+
+
+<h4>Popup Menus</h4>
+
+<p>Android 3.0 introduced {@link android.widget.PopupMenu} to create short contextual menus that pop
+up
+at an anchor point you specify (usually at the point of the item selected). Android 4.0 extends the
+{@link android.widget.PopupMenu} with a couple useful features:</p>
+<ul>
+<li>You can now easily inflate the contents of a popup menu from an XML <a
+href=”{@docRoot}guide/topics/resources/menu-resource.html”>menu resource</a> with {@link
+android.widget.PopupMenu#inflate inflate()}, passing it the menu resource ID.</li>
+<li>You can also now create a {@link android.widget.PopupMenu.OnDismissListener} that receives a
+callback when the menu is dismissed.</li>
+</ul>
+
+<h4>Preferences</h4>
+
+<p>A new {@link android.preference.TwoStatePreference} abstract class serves as the basis for
+preferences that provide a two-state selection option. The new {@link
+android.preference.SwitchPreference} is an extension of {@link
+android.preference.TwoStatePreference} that provides a {@link android.widget.Switch} widget in the
+preference view to allow users to toggle a setting on or off without the need to open an additional
+preference screen or dialog. For example, the Settings application uses a {@link
+android.preference.SwitchPreference} for the Wi-Fi and Bluetooth settings.</p>
+
+
+<h4>Hover Events</h4>
+
+<p>The {@link android.view.View} class now supports “hover” events to enable richer interactions
+through the use of pointer devices (such as a mouse or other device that drives an on-screen
+cursor).</p>
+
+<p>To receive hover events on a view, implement the {@link android.view.View.OnHoverListener} and
+register it with {@link android.view.View#setOnHoverListener setOnHoverListener()}. When a hover
+event occurs on the view, your listener receives a call to {@link
+android.view.View.OnHoverListener#onHover onHover()}, providing the {@link android.view.View} that
+received the event and a {@link android.view.MotionEvent} that describes the type of hover event
+that occurred. The hover event can be one of the following:</p>
+<ul>
+<li>{@link android.view.MotionEvent#ACTION_HOVER_ENTER}</li>
+<li>{@link android.view.MotionEvent#ACTION_HOVER_EXIT}</li>
+<li>{@link android.view.MotionEvent#ACTION_HOVER_MOVE}</li>
+</ul>
+
+<p>Your {@link android.view.View.OnHoverListener} should return true from {@link
+android.view.View.OnHoverListener#onHover onHover()} if it handles the hover event.  If your
+listener returns false, then the hover event will be dispatched to the parent view as usual.</p>
+
+<p>If your application uses buttons or other widgets that change their appearance based on the
+current
+state, you can now use the {@code android:state_hovered} attribute in a <a
+href=”{@docRoot}guide/topics/resources/drawable-resource.html#StateList”>state list drawable</a> to
+provide a different background drawable when a cursor hovers over the view.</p>
+
+<p>For a demonstration of the new hover events, see the <a
+href=”{@docRoot}samples/ApiDemos/src/com/example/android/apis/view/Hover.html”>Hover</a> class in
+ApiDemos.</p>
+
+
+<h4>Stylus and Mouse Button Input Events</h4>
+
+<p>Android now provides APIs for receiving input from a stylus input device such as a digitizer
+tablet
+peripheral or a stylus-enabled touch screen.</p>
+
+<p>Stylus input operates in a similar manner to touch or mouse input.  When the stylus is in contact
+with the digitizer, applications receive touch events just like they would when a finger is used to
+touch the display.  When the stylus is hovering above the digitizer, applications receive hover
+events just like they would when a mouse pointer was being moved across the display when no buttons
+are pressed.</p>
+
+<p>Your application can distinguish between finger, mouse, stylus and eraser input by querying the
+“tool type” associated with each pointer in a {@link android.view.MotionEvent} using {@link
+android.view.MotionEvent#getToolType getToolType()}.  The currently defined tool types are: {@link
+android.view.MotionEvent#TOOL_TYPE_UNKNOWN}, {@link android.view.MotionEvent#TOOL_TYPE_FINGER},
+{@link android.view.MotionEvent#TOOL_TYPE_MOUSE}, {@link android.view.MotionEvent#TOOL_TYPE_STYLUS},
+and {@link android.view.MotionEvent#TOOL_TYPE_ERASER}.  By querying the tool type, your application
+can choose to handle stylus input in different ways from finger or mouse input.</p>
+
+<p>Your application can also query which mouse or stylus buttons are pressed by querying the “button
+state” of a {@link android.view.MotionEvent} using {@link android.view.MotionEvent#getButtonState
+getButtonState()}.  The currently defined button states are: {@link
+android.view.MotionEvent#BUTTON_PRIMARY}, {@link
+android.view.MotionEvent#BUTTON_SECONDARY}, {@link
+android.view.MotionEvent#BUTTON_TERTIARY}, {@link android.view.MotionEvent#BUTTON_BACK},
+and {@link android.view.MotionEvent#BUTTON_FORWARD}.
+For convenience, the back and forward mouse buttons are automatically mapped to the {@link
+android.view.KeyEvent#KEYCODE_BACK} and {@link android.view.KeyEvent#KEYCODE_FORWARD} keys.  Your
+application can handle these keys to support mouse button based back and forward navigation.</p>
+
+<p>In addition to precisely measuring the position and pressure of a contact, some stylus input
+devices
+also report the distance between the stylus tip and the digitizer, the stylus tilt angle, and the
+stylus orientation angle.  Your application can query this information using {@link
+android.view.MotionEvent#getAxisValue getAxisValue()} with the axis codes {@link
+android.view.MotionEvent#AXIS_DISTANCE}, {@link android.view.MotionEvent#AXIS_TILT}, and {@link
+android.view.MotionEvent#AXIS_ORIENTATION}.</p>
+
+<p>For a demonstration of tool types, button states and the new axis codes, see the <a
+href=”{@docRoot}samples/ApiDemos/src/com/example/android/apis/graphics/TouchPaint.html”>TouchPaint
+</a> class in ApiDemos.</p>
+
+
+
+
+
+
+<h3 id="Properties">Properties</h3>
+
+<p>The new {@link android.util.Property} class provides a fast, efficient, and easy way to specify a
+property on any object that allows callers to generically set/get values on target objects. It also
+allows the functionality of passing around field/method references and allows code to set/get values
+of the property without knowing the details of what the fields/methods are.</p>
+
+<p>For example, if you want to set the value of field {@code bar} on object {@code foo}, you would
+previously do this:</p>
+<pre>
+foo.bar = value;
+</pre>
+
+<p>If you want to call the setter for an underlying private field {@code bar}, you would previously
+do this:</p>
+<pre>
+foo.setBar(value);
+</pre>
+
+<p>However, if you want to pass around the {@code foo} instance and have some other code set the
+{@code bar} value, there is really no way to do it prior to Android 4.0.</p>
+
+<p>Using the {@link android.util.Property} class, you can declare a {@link android.util.Property}
+object {@code BAR} on class {@code Foo} so that you can set the field on instance {@code foo} of
+class {@code Foo} like this:</p>
+<pre>
+BAR.set(foo, value);
+</pre>
+
+<p>The {@link android.view.View} class now leverages the {@link android.util.Property} class to
+allow you to set various fields, such as transform properties that were added in Android 3.0 ({@link
+android.view.View#ROTATION}, {@link android.view.View#ROTATION_X}, {@link
+android.view.View#TRANSLATION_X}, etc.).</p>
+
+<p>The {@link android.animation.ObjectAnimator} class also uses the {@link android.util.Property}
+class, so you can create an {@link android.animation.ObjectAnimator} with a {@link
+android.util.Property}, which is faster, more efficient, and more type-safe than the string-based
+approach.</p>
+
+
+
+
+
+
+<h3 id="HwAccel">Hardware Acceleration</h3>
+
+<p>Beginning with Android 4.0, hardware acceleration for all windows is enabled by default if your
+application has set either <a
+href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code targetSdkVersion}</a> or
+<a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#min">{@code minSdkVersion}</a> to
+{@code “14”} or higher. Hardware acceleration generally results in smoother animations, smoother
+scrolling, and overall better performance and response to user interaction.</p>
+
+<p>If necessary, you can manually disable hardware acceleration with the <a
+href=”{@docRoot}guide/topics/manifest/activity-element.html#hwaccel”>{@code hardwareAccelerated}</a>
+attribute for individual <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code
+&lt;activity&gt;}</a> elements or the <a
+href="{@docRoot}guide/topics/manifest/application-element.html">{@code &lt;application&gt;}</a>
+element. You can alternatively disable hardware acceleration for individual views by calling {@link
+android.view.View#setLayerType setLayerType(LAYER_TYPE_SOFTWARE)}.</p>
+
+
+<h3 id="Jni">JNI Changes</h3>
+
+<p>In previous versions of Android, JNI local references weren’t indirect handles; we used direct
+pointers. This didn’t seem like a problem as long as we didn’t have a garbage collector that moves
+objects, but it was because it meant that it was possible to write buggy code that still seemed to
+work. In Android 4.0, we’ve moved to using indirect references so we can detect these bugs before we
+need third-party native code to be correct.</p>
+
+<p>The ins and outs of JNI local references are described in “Local and Global References” in
+<a href="{@docRoot}guide/practices/design/jni.html">JNI Tips</a>. In Android 4.0, <a
+href="http://android-developers.blogspot.com/2011/07/debugging-android-jni-with-checkjni.html">CheckJNI</a>
+has been
+enhanced to detect these errors. Watch the <a href=”http://android-developers.blogspot.com/”>Android
+Developers Blog</a> for an upcoming post about common errors with JNI references and how you can fix
+them.</p>
+
+<p>This change in the JNI implementation only affects apps that target Android 4.0 by setting either
+the <a
+href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code targetSdkVersion}</a> or
+<a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#min">{@code minSdkVersion}</a> to
+{@code “14”} or higher. If you’ve set these attributes to any lower
+value, then JNI local references will behave the same as in previous versions.</p>
+
+
+
+
+
+<h3 id="WebKit">WebKit</h3>
+<ul>
+<li>WebKit updated to version 534.30</li>
+<li>Support for Indic fonts (Devanagari, Bengali, and Tamil, including the complex character support
+needed for combining glyphs) in {@link android.webkit.WebView} and the built-in Browser</li>
+<li>Support for Ethiopic, Georgian, and Armenian fonts in {@link android.webkit.WebView} and the
+built-in Browser</li>
+<li>Support for <a
+href="http://google-opensource.blogspot.com/2009/05/introducing-webdriver.html">WebDriver</a> makes
+it easier for you to test apps that use {@link android.webkit.WebView}</li>
+</ul>
+
+
+<h4>Android Browser</h4>
+
+<p>The Browser application adds the following features to support web applications:</p>
+<ul>
+<li>Updated V8 JavaScript compiler for faster performance</li>
+<li>Plus other notable enhancements carried over from <a
+href=”{@docRoot}sdk/android-3.0.html”>Android
+3.0</a> are now available for handsets:
+<ul>
+<li>Support for fixed position elements on all pages</li>
+<li><a href="http://dev.w3.org/2009/dap/camera/">HTML media capture</a></li>
+<li><a href="http://dev.w3.org/geo/api/spec-source-orientation.html">Device orientation
+events</a></li>
+<li><a href="http://www.w3.org/TR/css3-3d-transforms/">CSS 3D transformations</a></li>
+</ul>
+</li>
+</ul>
+
+
+
+<h3 id="Permissions">Permissions</h3>
+
+<p>The following are new permissions:</p>
+<ul>
+<li>{@link android.Manifest.permission#ADD_VOICEMAIL}: Allows a voicemail service to add voicemail
+messages to the device.</li>
+<li>{@link android.Manifest.permission#BIND_TEXT_SERVICE}: A service that implements {@link
+android.service.textservice.SpellCheckerService} must require this permission for itself.</li>
+<li>{@link android.Manifest.permission#BIND_VPN_SERVICE}: A service that implements {@link
+android.net.VpnService} must require this permission for itself.</li>
+<li>{@link android.Manifest.permission#READ_PROFILE}: Provides read access to the {@link
+android.provider.ContactsContract.Profile} provider.</li>
+<li>{@link android.Manifest.permission#WRITE_PROFILE}: Provides write access to the {@link
+android.provider.ContactsContract.Profile} provider.</li>
+</ul>
+
+
+
+<h3 id="DeviceFeatures">Device Features</h3>
+
+<p>The following are new device features:</p>
+<ul>
+<li>{@link android.content.pm.PackageManager#FEATURE_WIFI_DIRECT}: Declares that the application
+uses
+Wi-Fi for peer-to-peer communications.</li>
+</ul>
+
+
+
+
+
+
+
+
+
+
+
+<h2 id="api-diff">API Differences Report</h2>
+
+<p>For a detailed view of all API changes in Android {@sdkPlatformVersion} (API
+Level
+{@sdkPlatformApiLevel}), see the <a
+href="{@docRoot}sdk/api_diff/{@sdkPlatformApiLevel}/changes.html">API
+Differences Report</a>.</p>
+
+
+
+
+
+<h2 id="api-level">API Level</h2>
+
+<p>The Android {@sdkPlatformVersion} platform delivers an updated version of the framework API. The
+Android {@sdkPlatformVersion} API is assigned an integer identifier &mdash;
+<strong>{@sdkPlatformApiLevel}</strong> &mdash; that is stored in the system itself. This
+identifier, called the "API Level", allows the system to correctly determine whether an application
+is compatible with the system, prior to installing the application. </p>
+
+<p>To use APIs introduced in Android {@sdkPlatformVersion} in your application, you need compile the
+application against the Android library that is provided in the Android {@sdkPlatformVersion} SDK
+platform. Depending on your needs, you might also need to add an
+<code>android:minSdkVersion="{@sdkPlatformApiLevel}"</code> attribute to the
+<code>&lt;uses-sdk&gt;</code> element in the application's manifest.</p>
+
+<p>For more information about how to use API Level, see the <a
+href="{@docRoot}guide/appendix/api-levels.html">API Levels</a> document. </p>
+
+
+<h2 id="apps">Built-in Applications</h2>
+
+<p>The system image included in the downloadable platform provides these
+built-in applications:</p>
+
+<table style="border:0;padding-bottom:0;margin-bottom:0;">
+<tr>
+<td style="border:0;padding-bottom:0;margin-bottom:0;">
+<ul>
+<li>API Demos</li>
+<li>Browser</li>
+<li>Calculator</li>
+<li>Camera</li>
+<li>Clock</li>
+<li>Custom Locale</li>
+<li>Dev Tools</li>
+<li>Downloads</li>
+<li>Email</li>
+<li>Gallery</li>
+</ul>
+</td>
+<td style="border:0;padding-bottom:0;margin-bottom:0;padding-left:5em;">
+<ul>
+<li>Gestures Builder</li>
+<li>Messaging</li>
+<li>Music</li>
+<li>People</li>
+<li>Phone</li>
+<li>Search</li>
+<li>Settings</li>
+<li>Spare Parts</li>
+<li>Speech Recorder</li>
+<li>Widget Preview</li>
+</ul>
+</td>
+</tr>
+</table>
+
+
+<h2 id="locs" style="margin-top:.75em;">Locales</h2>
+
+<p>The system image included in the downloadable SDK platform provides a variety
+of
+built-in locales. In some cases, region-specific strings are available for the
+locales. In other cases, a default version of the language is used. The
+languages that are available in the Android 3.0 system
+image are listed below (with <em>language</em>_<em>country/region</em> locale
+descriptor).</p>
+
+<table style="border:0;padding-bottom:0;margin-bottom:0;">
+<tr>
+<td style="border:0;padding-bottom:0;margin-bottom:0;">
+<ul>
+<li>Arabic, Egypt (ar_EG)</li>
+<li>Arabic, Israel (ar_IL)</li>
+<li>Bulgarian, Bulgaria (bg_BG)</li>
+<li>Catalan, Spain (ca_ES)</li>
+<li>Czech, Czech Republic (cs_CZ)</li>
+<li>Danish, Denmark(da_DK)</li>
+<li>German, Austria (de_AT)</li>
+<li>German, Switzerland (de_CH)</li>
+<li>German, Germany (de_DE)</li>
+<li>German, Liechtenstein (de_LI)</li>
+<li>Greek, Greece (el_GR)</li>
+<li>English, Australia (en_AU)</li>
+<li>English, Canada (en_CA)</li>
+<li>English, Britain (en_GB)</li>
+<li>English, Ireland (en_IE)</li>
+<li>English, India (en_IN)</li>
+<li>English, New Zealand (en_NZ)</li>
+<li>English, Singapore(en_SG)</li>
+<li>English, US (en_US)</li>
+<li>English, Zimbabwe (en_ZA)</li>
+<li>Spanish (es_ES)</li>
+<li>Spanish, US (es_US)</li>
+<li>Finnish, Finland (fi_FI)</li>
+<li>French, Belgium (fr_BE)</li>
+<li>French, Canada (fr_CA)</li>
+<li>French, Switzerland (fr_CH)</li>
+<li>French, France (fr_FR)</li>
+<li>Hebrew, Israel (he_IL)</li>
+<li>Hindi, India (hi_IN)</li>
+</ul>
+</td>
+<td style="border:0;padding-bottom:0;margin-bottom:0;padding-left:5em;">
+<li>Croatian, Croatia (hr_HR)</li>
+<li>Hungarian, Hungary (hu_HU)</li>
+<li>Indonesian, Indonesia (id_ID)</li>
+<li>Italian, Switzerland (it_CH)</li>
+<li>Italian, Italy (it_IT)</li>
+<li>Japanese (ja_JP)</li>
+<li>Korean (ko_KR)</li>
+<li>Lithuanian, Lithuania (lt_LT)</li>
+<li>Latvian, Latvia (lv_LV)</li>
+<li>Norwegian bokmål, Norway (nb_NO)</li>
+<li>Dutch, Belgium (nl_BE)</li>
+<li>Dutch, Netherlands (nl_NL)</li>
+<li>Polish (pl_PL)</li>
+<li>Portuguese, Brazil (pt_BR)</li>
+<li>Portuguese, Portugal (pt_PT)</li>
+<li>Romanian, Romania (ro_RO)</li>
+<li>Russian (ru_RU)</li></li>
+<li>Slovak, Slovakia (sk_SK)</li>
+<li>Slovenian, Slovenia (sl_SI)</li>
+<li>Serbian (sr_RS)</li>
+<li>Swedish, Sweden (sv_SE)</li>
+<li>Thai, Thailand (th_TH)</li>
+<li>Tagalog, Philippines (tl_PH)</li>
+<li>Turkish, Turkey (tr_TR)</li>
+<li>Ukrainian, Ukraine (uk_UA)</li>
+<li>Vietnamese, Vietnam (vi_VN)</li>
+<li>Chinese, PRC (zh_CN)</li>
+<li>Chinese, Taiwan (zh_TW)</li>
+</td>
+</tr>
+</table>
+
+<p class="note"><strong>Note:</strong> The Android platform may support more
+locales than are included in the SDK system image. All of the supported locales
+are available in the <a href="http://source.android.com/">Android Open Source
+Project</a>.</p>
+
+<h2 id="skins">Emulator Skins</h2>
+
+<p>The downloadable platform includes the following emulator skin:</p>
+
+<ul>
+  <li>
+    WVGA800 (1280x800, extra high density, normal screen)
+  </li>
+</ul>
+
+<p>For more information about how to develop an application that displays
+and functions properly on all Android-powered devices, see <a
+href="{@docRoot}guide/practices/screens_support.html">Supporting Multiple
+Screens</a>.</p>
diff --git a/docs/html/sdk/api_diff/14/changes.html b/docs/html/sdk/api_diff/14/changes.html
index 40016d1..1ae5204 100644
--- a/docs/html/sdk/api_diff/14/changes.html
+++ b/docs/html/sdk/api_diff/14/changes.html
@@ -4,7 +4,7 @@
 <meta name="generator" content="JDiff v1.1.0">
 <!-- Generated by the JDiff Javadoc doclet -->
 <!-- (http://www.jdiff.org) -->
-<!-- on Tue Oct 04 17:12:08 PDT 2011 -->
+<!-- on Thu Oct 06 23:19:50 PDT 2011 -->
 <meta name="description" content="JDiff is a Javadoc doclet which generates an HTML report of all the packages, classes, constructors, methods, and fields which have been removed, added or changed in any way, including their documentation, when two APIs are compared.">
 <meta name="keywords" content="diff, jdiff, javadiff, java diff, java difference, API difference, difference between two APIs, API diff, Javadoc, doclet">
 <TITLE>
diff --git a/docs/html/sdk/api_diff/14/changes/alldiffs_index_additions.html b/docs/html/sdk/api_diff/14/changes/alldiffs_index_additions.html
index d63c137..a1dff53 100644
--- a/docs/html/sdk/api_diff/14/changes/alldiffs_index_additions.html
+++ b/docs/html/sdk/api_diff/14/changes/alldiffs_index_additions.html
@@ -780,9 +780,6 @@
 <!-- Method getActionProvider -->
 <nobr><A HREF="android.view.MenuItem.html#android.view.MenuItem.getActionProvider_added()" class="hiddenlink" target="rightframe"><b>getActionProvider</b>
 ()</A></nobr><br>
-<!-- Method getActiveNetworkQuotaInfo -->
-<nobr><A HREF="android.net.ConnectivityManager.html#android.net.ConnectivityManager.getActiveNetworkQuotaInfo_added()" class="hiddenlink" target="rightframe"><b>getActiveNetworkQuotaInfo</b>
-()</A></nobr><br>
 <!-- Method getAnnotation -->
 <i>getAnnotation</i><br>
 &nbsp;&nbsp;<nobr><A HREF="java.lang.reflect.Constructor.html#java.lang.reflect.Constructor.getAnnotation_added(java.lang.Class<A>)" class="hiddenlink" target="rightframe">type&nbsp;<b>
@@ -1402,7 +1399,7 @@
 </nobr><br>
 <!-- Class MotionEvent.PointerProperties -->
 <A HREF="pkg_android.view.html#MotionEvent.PointerProperties" class="hiddenlink" target="rightframe"><b>MotionEvent.PointerProperties</b></A><br>
-<!-- Class NetworkQuotaInfo -->
+<!-- Method newChooseAccountIntent -->
 <A NAME="N"></A>
 <br><font size="+2">N</font>&nbsp;
 <a href="#A"><font size="-2">A</font></a> 
@@ -1429,8 +1426,6 @@
 <a href="#Y"><font size="-2">Y</font></a> 
  <a href="#topheader"><font size="-2">TOP</font></a>
 <p><div style="line-height:1.5em;color:black">
-<A HREF="pkg_android.net.html#NetworkQuotaInfo" class="hiddenlink" target="rightframe"><b>NetworkQuotaInfo</b></A><br>
-<!-- Method newChooseAccountIntent -->
 <nobr><A HREF="android.accounts.AccountManager.html#android.accounts.AccountManager.newChooseAccountIntent_added(android.accounts.Account, java.util.ArrayList<android.accounts.Account>, java.lang.String[], boolean, java.lang.String, java.lang.String, java.lang.String[], android.os.Bundle)" class="hiddenlink" target="rightframe"><b>newChooseAccountIntent</b>
 (<code>Account, ArrayList&lt;Account&gt;, String[], boolean, String, String, String[], Bundle</code>)</A></nobr><br>
 <!-- Class NfcAdapter.CreateNdefMessageCallback -->
diff --git a/docs/html/sdk/api_diff/14/changes/alldiffs_index_all.html b/docs/html/sdk/api_diff/14/changes/alldiffs_index_all.html
index b218b52..7958b99 100644
--- a/docs/html/sdk/api_diff/14/changes/alldiffs_index_all.html
+++ b/docs/html/sdk/api_diff/14/changes/alldiffs_index_all.html
@@ -1106,9 +1106,6 @@
 <!-- Method getActionProvider -->
 <nobr><A HREF="android.view.MenuItem.html#android.view.MenuItem.getActionProvider_added()" class="hiddenlink" target="rightframe"><b>getActionProvider</b>
 ()</A></nobr><br>
-<!-- Method getActiveNetworkQuotaInfo -->
-<nobr><A HREF="android.net.ConnectivityManager.html#android.net.ConnectivityManager.getActiveNetworkQuotaInfo_added()" class="hiddenlink" target="rightframe"><b>getActiveNetworkQuotaInfo</b>
-()</A></nobr><br>
 <!-- Method getAddedCount -->
 <nobr><A HREF="android.view.accessibility.AccessibilityEvent.html#android.view.accessibility.AccessibilityEvent.getAddedCount_changed()" class="hiddenlink" target="rightframe">getAddedCount
 ()</A></nobr><br>
@@ -2039,8 +2036,6 @@
  <a href="#topheader"><font size="-2">TOP</font></a>
 <p><div style="line-height:1.5em;color:black">
 <A HREF="android.nfc.NdefRecord.html" class="hiddenlink" target="rightframe">NdefRecord</A><br>
-<!-- Class NetworkQuotaInfo -->
-<A HREF="pkg_android.net.html#NetworkQuotaInfo" class="hiddenlink" target="rightframe"><b>NetworkQuotaInfo</b></A><br>
 <!-- Method newChooseAccountIntent -->
 <nobr><A HREF="android.accounts.AccountManager.html#android.accounts.AccountManager.newChooseAccountIntent_added(android.accounts.Account, java.util.ArrayList<android.accounts.Account>, java.lang.String[], boolean, java.lang.String, java.lang.String, java.lang.String[], android.os.Bundle)" class="hiddenlink" target="rightframe"><b>newChooseAccountIntent</b>
 (<code>Account, ArrayList&lt;Account&gt;, String[], boolean, String, String, String[], Bundle</code>)</A></nobr><br>
diff --git a/docs/html/sdk/api_diff/14/changes/android.Manifest.permission.html b/docs/html/sdk/api_diff/14/changes/android.Manifest.permission.html
index 24386cf..542b3c8 100644
--- a/docs/html/sdk/api_diff/14/changes/android.Manifest.permission.html
+++ b/docs/html/sdk/api_diff/14/changes/android.Manifest.permission.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.R.attr.html b/docs/html/sdk/api_diff/14/changes/android.R.attr.html
index 2944036..d7adadb 100644
--- a/docs/html/sdk/api_diff/14/changes/android.R.attr.html
+++ b/docs/html/sdk/api_diff/14/changes/android.R.attr.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.R.color.html b/docs/html/sdk/api_diff/14/changes/android.R.color.html
index 3c13cc6..2fa2703 100644
--- a/docs/html/sdk/api_diff/14/changes/android.R.color.html
+++ b/docs/html/sdk/api_diff/14/changes/android.R.color.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.R.integer.html b/docs/html/sdk/api_diff/14/changes/android.R.integer.html
index 9d10a83..8218ee4 100644
--- a/docs/html/sdk/api_diff/14/changes/android.R.integer.html
+++ b/docs/html/sdk/api_diff/14/changes/android.R.integer.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.R.string.html b/docs/html/sdk/api_diff/14/changes/android.R.string.html
index d9deb00..942e97b 100644
--- a/docs/html/sdk/api_diff/14/changes/android.R.string.html
+++ b/docs/html/sdk/api_diff/14/changes/android.R.string.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.R.style.html b/docs/html/sdk/api_diff/14/changes/android.R.style.html
index 857d9d7..e4692cc 100644
--- a/docs/html/sdk/api_diff/14/changes/android.R.style.html
+++ b/docs/html/sdk/api_diff/14/changes/android.R.style.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.accessibilityservice.AccessibilityService.html b/docs/html/sdk/api_diff/14/changes/android.accessibilityservice.AccessibilityService.html
index 9428a21..7cae772 100644
--- a/docs/html/sdk/api_diff/14/changes/android.accessibilityservice.AccessibilityService.html
+++ b/docs/html/sdk/api_diff/14/changes/android.accessibilityservice.AccessibilityService.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.accessibilityservice.AccessibilityServiceInfo.html b/docs/html/sdk/api_diff/14/changes/android.accessibilityservice.AccessibilityServiceInfo.html
index e27d5d0..8e775a4 100644
--- a/docs/html/sdk/api_diff/14/changes/android.accessibilityservice.AccessibilityServiceInfo.html
+++ b/docs/html/sdk/api_diff/14/changes/android.accessibilityservice.AccessibilityServiceInfo.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.accounts.AccountManager.html b/docs/html/sdk/api_diff/14/changes/android.accounts.AccountManager.html
index eead88c..8adef37 100644
--- a/docs/html/sdk/api_diff/14/changes/android.accounts.AccountManager.html
+++ b/docs/html/sdk/api_diff/14/changes/android.accounts.AccountManager.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.animation.Animator.html b/docs/html/sdk/api_diff/14/changes/android.animation.Animator.html
index 43836a1..1448825 100644
--- a/docs/html/sdk/api_diff/14/changes/android.animation.Animator.html
+++ b/docs/html/sdk/api_diff/14/changes/android.animation.Animator.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.animation.FloatEvaluator.html b/docs/html/sdk/api_diff/14/changes/android.animation.FloatEvaluator.html
index 0a62369..faedf88 100644
--- a/docs/html/sdk/api_diff/14/changes/android.animation.FloatEvaluator.html
+++ b/docs/html/sdk/api_diff/14/changes/android.animation.FloatEvaluator.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.animation.IntEvaluator.html b/docs/html/sdk/api_diff/14/changes/android.animation.IntEvaluator.html
index aabb197..91388bd 100644
--- a/docs/html/sdk/api_diff/14/changes/android.animation.IntEvaluator.html
+++ b/docs/html/sdk/api_diff/14/changes/android.animation.IntEvaluator.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.animation.LayoutTransition.html b/docs/html/sdk/api_diff/14/changes/android.animation.LayoutTransition.html
index 2bf33a0..ed6b3e7 100644
--- a/docs/html/sdk/api_diff/14/changes/android.animation.LayoutTransition.html
+++ b/docs/html/sdk/api_diff/14/changes/android.animation.LayoutTransition.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.animation.ObjectAnimator.html b/docs/html/sdk/api_diff/14/changes/android.animation.ObjectAnimator.html
index 4231d3e..872ffff 100644
--- a/docs/html/sdk/api_diff/14/changes/android.animation.ObjectAnimator.html
+++ b/docs/html/sdk/api_diff/14/changes/android.animation.ObjectAnimator.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.animation.PropertyValuesHolder.html b/docs/html/sdk/api_diff/14/changes/android.animation.PropertyValuesHolder.html
index d054258..543d91f 100644
--- a/docs/html/sdk/api_diff/14/changes/android.animation.PropertyValuesHolder.html
+++ b/docs/html/sdk/api_diff/14/changes/android.animation.PropertyValuesHolder.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.animation.TypeEvaluator.html b/docs/html/sdk/api_diff/14/changes/android.animation.TypeEvaluator.html
index aa31f1f..1e95066 100644
--- a/docs/html/sdk/api_diff/14/changes/android.animation.TypeEvaluator.html
+++ b/docs/html/sdk/api_diff/14/changes/android.animation.TypeEvaluator.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.app.ActionBar.Tab.html b/docs/html/sdk/api_diff/14/changes/android.app.ActionBar.Tab.html
index 558ef44..22eed31 100644
--- a/docs/html/sdk/api_diff/14/changes/android.app.ActionBar.Tab.html
+++ b/docs/html/sdk/api_diff/14/changes/android.app.ActionBar.Tab.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.app.ActionBar.html b/docs/html/sdk/api_diff/14/changes/android.app.ActionBar.html
index a0c8f1f..0ca869c 100644
--- a/docs/html/sdk/api_diff/14/changes/android.app.ActionBar.html
+++ b/docs/html/sdk/api_diff/14/changes/android.app.ActionBar.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.app.Activity.html b/docs/html/sdk/api_diff/14/changes/android.app.Activity.html
index 9e57853..7e5e032 100644
--- a/docs/html/sdk/api_diff/14/changes/android.app.Activity.html
+++ b/docs/html/sdk/api_diff/14/changes/android.app.Activity.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.app.AlertDialog.html b/docs/html/sdk/api_diff/14/changes/android.app.AlertDialog.html
index e6e692c..b3786dea 100644
--- a/docs/html/sdk/api_diff/14/changes/android.app.AlertDialog.html
+++ b/docs/html/sdk/api_diff/14/changes/android.app.AlertDialog.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.app.Application.html b/docs/html/sdk/api_diff/14/changes/android.app.Application.html
index b89ba8a..da105de 100644
--- a/docs/html/sdk/api_diff/14/changes/android.app.Application.html
+++ b/docs/html/sdk/api_diff/14/changes/android.app.Application.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.app.Fragment.html b/docs/html/sdk/api_diff/14/changes/android.app.Fragment.html
index f6e57b1..2d85f0c 100644
--- a/docs/html/sdk/api_diff/14/changes/android.app.Fragment.html
+++ b/docs/html/sdk/api_diff/14/changes/android.app.Fragment.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.app.FragmentManager.BackStackEntry.html b/docs/html/sdk/api_diff/14/changes/android.app.FragmentManager.BackStackEntry.html
index 5f4a0d0..6db6763 100644
--- a/docs/html/sdk/api_diff/14/changes/android.app.FragmentManager.BackStackEntry.html
+++ b/docs/html/sdk/api_diff/14/changes/android.app.FragmentManager.BackStackEntry.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.app.FragmentManager.html b/docs/html/sdk/api_diff/14/changes/android.app.FragmentManager.html
index 95d763c..bb11aba 100644
--- a/docs/html/sdk/api_diff/14/changes/android.app.FragmentManager.html
+++ b/docs/html/sdk/api_diff/14/changes/android.app.FragmentManager.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.app.Notification.Builder.html b/docs/html/sdk/api_diff/14/changes/android.app.Notification.Builder.html
index 5218ca1..d9fc7f4 100644
--- a/docs/html/sdk/api_diff/14/changes/android.app.Notification.Builder.html
+++ b/docs/html/sdk/api_diff/14/changes/android.app.Notification.Builder.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.app.PendingIntent.html b/docs/html/sdk/api_diff/14/changes/android.app.PendingIntent.html
index 6660be4..e1ac14b 100644
--- a/docs/html/sdk/api_diff/14/changes/android.app.PendingIntent.html
+++ b/docs/html/sdk/api_diff/14/changes/android.app.PendingIntent.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.app.SearchManager.html b/docs/html/sdk/api_diff/14/changes/android.app.SearchManager.html
index eff008b..c2ad438 100644
--- a/docs/html/sdk/api_diff/14/changes/android.app.SearchManager.html
+++ b/docs/html/sdk/api_diff/14/changes/android.app.SearchManager.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.app.Service.html b/docs/html/sdk/api_diff/14/changes/android.app.Service.html
index de90b36..a56592b 100644
--- a/docs/html/sdk/api_diff/14/changes/android.app.Service.html
+++ b/docs/html/sdk/api_diff/14/changes/android.app.Service.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.app.WallpaperManager.html b/docs/html/sdk/api_diff/14/changes/android.app.WallpaperManager.html
index 7cccebe..dbe8e9f 100644
--- a/docs/html/sdk/api_diff/14/changes/android.app.WallpaperManager.html
+++ b/docs/html/sdk/api_diff/14/changes/android.app.WallpaperManager.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.app.admin.DeviceAdminInfo.html b/docs/html/sdk/api_diff/14/changes/android.app.admin.DeviceAdminInfo.html
index 6064e1c..73a430d 100644
--- a/docs/html/sdk/api_diff/14/changes/android.app.admin.DeviceAdminInfo.html
+++ b/docs/html/sdk/api_diff/14/changes/android.app.admin.DeviceAdminInfo.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.app.admin.DevicePolicyManager.html b/docs/html/sdk/api_diff/14/changes/android.app.admin.DevicePolicyManager.html
index 1dff802..03febd7 100644
--- a/docs/html/sdk/api_diff/14/changes/android.app.admin.DevicePolicyManager.html
+++ b/docs/html/sdk/api_diff/14/changes/android.app.admin.DevicePolicyManager.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.app.backup.BackupAgent.html b/docs/html/sdk/api_diff/14/changes/android.app.backup.BackupAgent.html
index f5edb3f..ff28b33 100644
--- a/docs/html/sdk/api_diff/14/changes/android.app.backup.BackupAgent.html
+++ b/docs/html/sdk/api_diff/14/changes/android.app.backup.BackupAgent.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.appwidget.AppWidgetProviderInfo.html b/docs/html/sdk/api_diff/14/changes/android.appwidget.AppWidgetProviderInfo.html
index 196696a..0e93fa5 100644
--- a/docs/html/sdk/api_diff/14/changes/android.appwidget.AppWidgetProviderInfo.html
+++ b/docs/html/sdk/api_diff/14/changes/android.appwidget.AppWidgetProviderInfo.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.bluetooth.BluetoothAdapter.html b/docs/html/sdk/api_diff/14/changes/android.bluetooth.BluetoothAdapter.html
index ddd9b46..7785223 100644
--- a/docs/html/sdk/api_diff/14/changes/android.bluetooth.BluetoothAdapter.html
+++ b/docs/html/sdk/api_diff/14/changes/android.bluetooth.BluetoothAdapter.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.bluetooth.BluetoothProfile.html b/docs/html/sdk/api_diff/14/changes/android.bluetooth.BluetoothProfile.html
index 7bf16cf..0d25fb1 100644
--- a/docs/html/sdk/api_diff/14/changes/android.bluetooth.BluetoothProfile.html
+++ b/docs/html/sdk/api_diff/14/changes/android.bluetooth.BluetoothProfile.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.bluetooth.BluetoothSocket.html b/docs/html/sdk/api_diff/14/changes/android.bluetooth.BluetoothSocket.html
index ce4e0a8..d4f827b 100644
--- a/docs/html/sdk/api_diff/14/changes/android.bluetooth.BluetoothSocket.html
+++ b/docs/html/sdk/api_diff/14/changes/android.bluetooth.BluetoothSocket.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.content.ContentProvider.html b/docs/html/sdk/api_diff/14/changes/android.content.ContentProvider.html
index 87a24e6..48176b5 100644
--- a/docs/html/sdk/api_diff/14/changes/android.content.ContentProvider.html
+++ b/docs/html/sdk/api_diff/14/changes/android.content.ContentProvider.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.content.Context.html b/docs/html/sdk/api_diff/14/changes/android.content.Context.html
index 34c71ca..641b64e 100644
--- a/docs/html/sdk/api_diff/14/changes/android.content.Context.html
+++ b/docs/html/sdk/api_diff/14/changes/android.content.Context.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.content.Intent.html b/docs/html/sdk/api_diff/14/changes/android.content.Intent.html
index 3115dee..068fb3f 100644
--- a/docs/html/sdk/api_diff/14/changes/android.content.Intent.html
+++ b/docs/html/sdk/api_diff/14/changes/android.content.Intent.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.content.IntentSender.html b/docs/html/sdk/api_diff/14/changes/android.content.IntentSender.html
index a6b51dd..a6e751b 100644
--- a/docs/html/sdk/api_diff/14/changes/android.content.IntentSender.html
+++ b/docs/html/sdk/api_diff/14/changes/android.content.IntentSender.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.content.SyncAdapterType.html b/docs/html/sdk/api_diff/14/changes/android.content.SyncAdapterType.html
index 0116101..030de82 100644
--- a/docs/html/sdk/api_diff/14/changes/android.content.SyncAdapterType.html
+++ b/docs/html/sdk/api_diff/14/changes/android.content.SyncAdapterType.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.content.pm.ActivityInfo.html b/docs/html/sdk/api_diff/14/changes/android.content.pm.ActivityInfo.html
index 6bd00a2..95d4f9b 100644
--- a/docs/html/sdk/api_diff/14/changes/android.content.pm.ActivityInfo.html
+++ b/docs/html/sdk/api_diff/14/changes/android.content.pm.ActivityInfo.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.content.pm.ApplicationInfo.html b/docs/html/sdk/api_diff/14/changes/android.content.pm.ApplicationInfo.html
index 7ca9e93..cd3c18d 100644
--- a/docs/html/sdk/api_diff/14/changes/android.content.pm.ApplicationInfo.html
+++ b/docs/html/sdk/api_diff/14/changes/android.content.pm.ApplicationInfo.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.content.pm.PackageManager.html b/docs/html/sdk/api_diff/14/changes/android.content.pm.PackageManager.html
index 9a1d983..62f35f4 100644
--- a/docs/html/sdk/api_diff/14/changes/android.content.pm.PackageManager.html
+++ b/docs/html/sdk/api_diff/14/changes/android.content.pm.PackageManager.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.content.pm.PackageStats.html b/docs/html/sdk/api_diff/14/changes/android.content.pm.PackageStats.html
index 948eb59..faac19e 100644
--- a/docs/html/sdk/api_diff/14/changes/android.content.pm.PackageStats.html
+++ b/docs/html/sdk/api_diff/14/changes/android.content.pm.PackageStats.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.content.pm.ServiceInfo.html b/docs/html/sdk/api_diff/14/changes/android.content.pm.ServiceInfo.html
index 34bd7e7..6b9f78a 100644
--- a/docs/html/sdk/api_diff/14/changes/android.content.pm.ServiceInfo.html
+++ b/docs/html/sdk/api_diff/14/changes/android.content.pm.ServiceInfo.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.database.sqlite.SQLiteOpenHelper.html b/docs/html/sdk/api_diff/14/changes/android.database.sqlite.SQLiteOpenHelper.html
index b50e75c..d7b09f3 100644
--- a/docs/html/sdk/api_diff/14/changes/android.database.sqlite.SQLiteOpenHelper.html
+++ b/docs/html/sdk/api_diff/14/changes/android.database.sqlite.SQLiteOpenHelper.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.database.sqlite.SQLiteQueryBuilder.html b/docs/html/sdk/api_diff/14/changes/android.database.sqlite.SQLiteQueryBuilder.html
index 06c12c4e..02bdeee 100644
--- a/docs/html/sdk/api_diff/14/changes/android.database.sqlite.SQLiteQueryBuilder.html
+++ b/docs/html/sdk/api_diff/14/changes/android.database.sqlite.SQLiteQueryBuilder.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.graphics.Canvas.html b/docs/html/sdk/api_diff/14/changes/android.graphics.Canvas.html
index a065efe..8f90381 100644
--- a/docs/html/sdk/api_diff/14/changes/android.graphics.Canvas.html
+++ b/docs/html/sdk/api_diff/14/changes/android.graphics.Canvas.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.graphics.Paint.html b/docs/html/sdk/api_diff/14/changes/android.graphics.Paint.html
index dce7e75..1cc467f 100644
--- a/docs/html/sdk/api_diff/14/changes/android.graphics.Paint.html
+++ b/docs/html/sdk/api_diff/14/changes/android.graphics.Paint.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.graphics.RectF.html b/docs/html/sdk/api_diff/14/changes/android.graphics.RectF.html
index 869b542..62d6a96 100644
--- a/docs/html/sdk/api_diff/14/changes/android.graphics.RectF.html
+++ b/docs/html/sdk/api_diff/14/changes/android.graphics.RectF.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.graphics.SurfaceTexture.html b/docs/html/sdk/api_diff/14/changes/android.graphics.SurfaceTexture.html
index 0c8c3dc..8df17da80 100644
--- a/docs/html/sdk/api_diff/14/changes/android.graphics.SurfaceTexture.html
+++ b/docs/html/sdk/api_diff/14/changes/android.graphics.SurfaceTexture.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.hardware.Camera.Parameters.html b/docs/html/sdk/api_diff/14/changes/android.hardware.Camera.Parameters.html
index e14b081..890a4aa 100644
--- a/docs/html/sdk/api_diff/14/changes/android.hardware.Camera.Parameters.html
+++ b/docs/html/sdk/api_diff/14/changes/android.hardware.Camera.Parameters.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.hardware.Camera.html b/docs/html/sdk/api_diff/14/changes/android.hardware.Camera.html
index 56b8392..1d6907d 100644
--- a/docs/html/sdk/api_diff/14/changes/android.hardware.Camera.html
+++ b/docs/html/sdk/api_diff/14/changes/android.hardware.Camera.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.hardware.Sensor.html b/docs/html/sdk/api_diff/14/changes/android.hardware.Sensor.html
index 0b3e1a9..b56e11c 100644
--- a/docs/html/sdk/api_diff/14/changes/android.hardware.Sensor.html
+++ b/docs/html/sdk/api_diff/14/changes/android.hardware.Sensor.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.inputmethodservice.InputMethodService.InputMethodSessionImpl.html b/docs/html/sdk/api_diff/14/changes/android.inputmethodservice.InputMethodService.InputMethodSessionImpl.html
index 51c2afb..d2b2a7a 100644
--- a/docs/html/sdk/api_diff/14/changes/android.inputmethodservice.InputMethodService.InputMethodSessionImpl.html
+++ b/docs/html/sdk/api_diff/14/changes/android.inputmethodservice.InputMethodService.InputMethodSessionImpl.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.inputmethodservice.InputMethodService.html b/docs/html/sdk/api_diff/14/changes/android.inputmethodservice.InputMethodService.html
index 7d22e59..c3dcdc5 100644
--- a/docs/html/sdk/api_diff/14/changes/android.inputmethodservice.InputMethodService.html
+++ b/docs/html/sdk/api_diff/14/changes/android.inputmethodservice.InputMethodService.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.media.AudioManager.html b/docs/html/sdk/api_diff/14/changes/android.media.AudioManager.html
index b6131f3..7b68d0c 100644
--- a/docs/html/sdk/api_diff/14/changes/android.media.AudioManager.html
+++ b/docs/html/sdk/api_diff/14/changes/android.media.AudioManager.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.media.MediaMetadataRetriever.html b/docs/html/sdk/api_diff/14/changes/android.media.MediaMetadataRetriever.html
index 39147db..5f589b9 100644
--- a/docs/html/sdk/api_diff/14/changes/android.media.MediaMetadataRetriever.html
+++ b/docs/html/sdk/api_diff/14/changes/android.media.MediaMetadataRetriever.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.media.MediaPlayer.html b/docs/html/sdk/api_diff/14/changes/android.media.MediaPlayer.html
index 40b9abd..ebdab5c 100644
--- a/docs/html/sdk/api_diff/14/changes/android.media.MediaPlayer.html
+++ b/docs/html/sdk/api_diff/14/changes/android.media.MediaPlayer.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.media.MediaRecorder.html b/docs/html/sdk/api_diff/14/changes/android.media.MediaRecorder.html
index 6f59ec4..6f2405f 100644
--- a/docs/html/sdk/api_diff/14/changes/android.media.MediaRecorder.html
+++ b/docs/html/sdk/api_diff/14/changes/android.media.MediaRecorder.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.net.ConnectivityManager.html b/docs/html/sdk/api_diff/14/changes/android.net.ConnectivityManager.html
index 56a89cd1..f1aaddc 100644
--- a/docs/html/sdk/api_diff/14/changes/android.net.ConnectivityManager.html
+++ b/docs/html/sdk/api_diff/14/changes/android.net.ConnectivityManager.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
@@ -76,21 +76,6 @@
 <a NAME="constructors"></a>
 <a NAME="methods"></a>
 <p>
-<a NAME="Added"></a>
-<TABLE summary="Added Methods" WIDTH="100%">
-<TR>
-  <TH VALIGN="TOP" COLSPAN=2>Added Methods</FONT></TD>
-</TH>
-<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
-  <TD VALIGN="TOP" WIDTH="25%">
-  <A NAME="android.net.ConnectivityManager.getActiveNetworkQuotaInfo_added()"></A>
-  <nobr><code>NetworkQuotaInfo</code>&nbsp;<A HREF="../../../../reference/android/net/ConnectivityManager.html#getActiveNetworkQuotaInfo()" target="_top"><code>getActiveNetworkQuotaInfo</code></A>()</nobr>
-  </TD>
-  <TD>&nbsp;</TD>
-</TR>
-</TABLE>
-&nbsp;
-<p>
 <a NAME="Changed"></a>
 <TABLE summary="Changed Methods" WIDTH="100%">
 <TR>
diff --git a/docs/html/sdk/api_diff/14/changes/android.net.SSLCertificateSocketFactory.html b/docs/html/sdk/api_diff/14/changes/android.net.SSLCertificateSocketFactory.html
index be155fa..b57b309 100644
--- a/docs/html/sdk/api_diff/14/changes/android.net.SSLCertificateSocketFactory.html
+++ b/docs/html/sdk/api_diff/14/changes/android.net.SSLCertificateSocketFactory.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.net.TrafficStats.html b/docs/html/sdk/api_diff/14/changes/android.net.TrafficStats.html
index 28543ca..55c729a 100644
--- a/docs/html/sdk/api_diff/14/changes/android.net.TrafficStats.html
+++ b/docs/html/sdk/api_diff/14/changes/android.net.TrafficStats.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.net.http.SslError.html b/docs/html/sdk/api_diff/14/changes/android.net.http.SslError.html
index e6504b9..6b9c440 100644
--- a/docs/html/sdk/api_diff/14/changes/android.net.http.SslError.html
+++ b/docs/html/sdk/api_diff/14/changes/android.net.http.SslError.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.net.wifi.WifiManager.html b/docs/html/sdk/api_diff/14/changes/android.net.wifi.WifiManager.html
index 3d38034..d4e2168 100644
--- a/docs/html/sdk/api_diff/14/changes/android.net.wifi.WifiManager.html
+++ b/docs/html/sdk/api_diff/14/changes/android.net.wifi.WifiManager.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.nfc.NdefRecord.html b/docs/html/sdk/api_diff/14/changes/android.nfc.NdefRecord.html
index 55fd1cb..8fea7bb 100644
--- a/docs/html/sdk/api_diff/14/changes/android.nfc.NdefRecord.html
+++ b/docs/html/sdk/api_diff/14/changes/android.nfc.NdefRecord.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.nfc.NfcAdapter.html b/docs/html/sdk/api_diff/14/changes/android.nfc.NfcAdapter.html
index 57f958b..ef09aa0 100644
--- a/docs/html/sdk/api_diff/14/changes/android.nfc.NfcAdapter.html
+++ b/docs/html/sdk/api_diff/14/changes/android.nfc.NfcAdapter.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.nfc.tech.IsoDep.html b/docs/html/sdk/api_diff/14/changes/android.nfc.tech.IsoDep.html
index 8b6cb25..2966854 100644
--- a/docs/html/sdk/api_diff/14/changes/android.nfc.tech.IsoDep.html
+++ b/docs/html/sdk/api_diff/14/changes/android.nfc.tech.IsoDep.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.nfc.tech.MifareClassic.html b/docs/html/sdk/api_diff/14/changes/android.nfc.tech.MifareClassic.html
index 511c63d..c682df0 100644
--- a/docs/html/sdk/api_diff/14/changes/android.nfc.tech.MifareClassic.html
+++ b/docs/html/sdk/api_diff/14/changes/android.nfc.tech.MifareClassic.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.nfc.tech.MifareUltralight.html b/docs/html/sdk/api_diff/14/changes/android.nfc.tech.MifareUltralight.html
index 296b9c1..31e0903 100644
--- a/docs/html/sdk/api_diff/14/changes/android.nfc.tech.MifareUltralight.html
+++ b/docs/html/sdk/api_diff/14/changes/android.nfc.tech.MifareUltralight.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.nfc.tech.NfcA.html b/docs/html/sdk/api_diff/14/changes/android.nfc.tech.NfcA.html
index e153132..7213d86 100644
--- a/docs/html/sdk/api_diff/14/changes/android.nfc.tech.NfcA.html
+++ b/docs/html/sdk/api_diff/14/changes/android.nfc.tech.NfcA.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.nfc.tech.NfcB.html b/docs/html/sdk/api_diff/14/changes/android.nfc.tech.NfcB.html
index 5dcc0c2..188e4ff 100644
--- a/docs/html/sdk/api_diff/14/changes/android.nfc.tech.NfcB.html
+++ b/docs/html/sdk/api_diff/14/changes/android.nfc.tech.NfcB.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.nfc.tech.NfcF.html b/docs/html/sdk/api_diff/14/changes/android.nfc.tech.NfcF.html
index fd6b045..0b4cd91 100644
--- a/docs/html/sdk/api_diff/14/changes/android.nfc.tech.NfcF.html
+++ b/docs/html/sdk/api_diff/14/changes/android.nfc.tech.NfcF.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.nfc.tech.NfcV.html b/docs/html/sdk/api_diff/14/changes/android.nfc.tech.NfcV.html
index cdbc4c5..d7cc5b8 100644
--- a/docs/html/sdk/api_diff/14/changes/android.nfc.tech.NfcV.html
+++ b/docs/html/sdk/api_diff/14/changes/android.nfc.tech.NfcV.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.opengl.GLUtils.html b/docs/html/sdk/api_diff/14/changes/android.opengl.GLUtils.html
index a9613c9..def8913 100644
--- a/docs/html/sdk/api_diff/14/changes/android.opengl.GLUtils.html
+++ b/docs/html/sdk/api_diff/14/changes/android.opengl.GLUtils.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.opengl.Matrix.html b/docs/html/sdk/api_diff/14/changes/android.opengl.Matrix.html
index d112afa..82d7990 100644
--- a/docs/html/sdk/api_diff/14/changes/android.opengl.Matrix.html
+++ b/docs/html/sdk/api_diff/14/changes/android.opengl.Matrix.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.os.Build.VERSION_CODES.html b/docs/html/sdk/api_diff/14/changes/android.os.Build.VERSION_CODES.html
index 5d3e92b..79e8983 100644
--- a/docs/html/sdk/api_diff/14/changes/android.os.Build.VERSION_CODES.html
+++ b/docs/html/sdk/api_diff/14/changes/android.os.Build.VERSION_CODES.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.os.Build.html b/docs/html/sdk/api_diff/14/changes/android.os.Build.html
index 08a487d..6b5d7e3 100644
--- a/docs/html/sdk/api_diff/14/changes/android.os.Build.html
+++ b/docs/html/sdk/api_diff/14/changes/android.os.Build.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.os.Debug.MemoryInfo.html b/docs/html/sdk/api_diff/14/changes/android.os.Debug.MemoryInfo.html
index b429b0c3..0b13977 100644
--- a/docs/html/sdk/api_diff/14/changes/android.os.Debug.MemoryInfo.html
+++ b/docs/html/sdk/api_diff/14/changes/android.os.Debug.MemoryInfo.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.os.Debug.html b/docs/html/sdk/api_diff/14/changes/android.os.Debug.html
index b75dee3..24e8933 100644
--- a/docs/html/sdk/api_diff/14/changes/android.os.Debug.html
+++ b/docs/html/sdk/api_diff/14/changes/android.os.Debug.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.os.Handler.html b/docs/html/sdk/api_diff/14/changes/android.os.Handler.html
index 745334b..6dbd8d8 100644
--- a/docs/html/sdk/api_diff/14/changes/android.os.Handler.html
+++ b/docs/html/sdk/api_diff/14/changes/android.os.Handler.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.os.Looper.html b/docs/html/sdk/api_diff/14/changes/android.os.Looper.html
index 181c541..fb617b2 100644
--- a/docs/html/sdk/api_diff/14/changes/android.os.Looper.html
+++ b/docs/html/sdk/api_diff/14/changes/android.os.Looper.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.os.ParcelFileDescriptor.html b/docs/html/sdk/api_diff/14/changes/android.os.ParcelFileDescriptor.html
index d0556d7..aec382d 100644
--- a/docs/html/sdk/api_diff/14/changes/android.os.ParcelFileDescriptor.html
+++ b/docs/html/sdk/api_diff/14/changes/android.os.ParcelFileDescriptor.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.os.Process.html b/docs/html/sdk/api_diff/14/changes/android.os.Process.html
index 2a6f87c..e3a0add 100644
--- a/docs/html/sdk/api_diff/14/changes/android.os.Process.html
+++ b/docs/html/sdk/api_diff/14/changes/android.os.Process.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.os.RecoverySystem.html b/docs/html/sdk/api_diff/14/changes/android.os.RecoverySystem.html
index e857ebf..38a5f5d 100644
--- a/docs/html/sdk/api_diff/14/changes/android.os.RecoverySystem.html
+++ b/docs/html/sdk/api_diff/14/changes/android.os.RecoverySystem.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.preference.CheckBoxPreference.html b/docs/html/sdk/api_diff/14/changes/android.preference.CheckBoxPreference.html
index a213df5..70f62de 100644
--- a/docs/html/sdk/api_diff/14/changes/android.preference.CheckBoxPreference.html
+++ b/docs/html/sdk/api_diff/14/changes/android.preference.CheckBoxPreference.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.preference.Preference.html b/docs/html/sdk/api_diff/14/changes/android.preference.Preference.html
index 2d2a88a..28f0b436 100644
--- a/docs/html/sdk/api_diff/14/changes/android.preference.Preference.html
+++ b/docs/html/sdk/api_diff/14/changes/android.preference.Preference.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.preference.PreferenceActivity.html b/docs/html/sdk/api_diff/14/changes/android.preference.PreferenceActivity.html
index 1bfb447..e1938cb 100644
--- a/docs/html/sdk/api_diff/14/changes/android.preference.PreferenceActivity.html
+++ b/docs/html/sdk/api_diff/14/changes/android.preference.PreferenceActivity.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.provider.CallLog.Calls.html b/docs/html/sdk/api_diff/14/changes/android.provider.CallLog.Calls.html
index a6ff6a7..a0223f8 100644
--- a/docs/html/sdk/api_diff/14/changes/android.provider.CallLog.Calls.html
+++ b/docs/html/sdk/api_diff/14/changes/android.provider.CallLog.Calls.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.provider.ContactsContract.CommonDataKinds.Photo.html b/docs/html/sdk/api_diff/14/changes/android.provider.ContactsContract.CommonDataKinds.Photo.html
index bef23cc..5e4921a 100644
--- a/docs/html/sdk/api_diff/14/changes/android.provider.ContactsContract.CommonDataKinds.Photo.html
+++ b/docs/html/sdk/api_diff/14/changes/android.provider.ContactsContract.CommonDataKinds.Photo.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.provider.ContactsContract.Contacts.Photo.html b/docs/html/sdk/api_diff/14/changes/android.provider.ContactsContract.Contacts.Photo.html
index 25f3b83..e94ed8c 100644
--- a/docs/html/sdk/api_diff/14/changes/android.provider.ContactsContract.Contacts.Photo.html
+++ b/docs/html/sdk/api_diff/14/changes/android.provider.ContactsContract.Contacts.Photo.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.provider.ContactsContract.Contacts.html b/docs/html/sdk/api_diff/14/changes/android.provider.ContactsContract.Contacts.html
index cb84233..08d7c36 100644
--- a/docs/html/sdk/api_diff/14/changes/android.provider.ContactsContract.Contacts.html
+++ b/docs/html/sdk/api_diff/14/changes/android.provider.ContactsContract.Contacts.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.provider.ContactsContract.ContactsColumns.html b/docs/html/sdk/api_diff/14/changes/android.provider.ContactsContract.ContactsColumns.html
index de60368..ab4775b 100644
--- a/docs/html/sdk/api_diff/14/changes/android.provider.ContactsContract.ContactsColumns.html
+++ b/docs/html/sdk/api_diff/14/changes/android.provider.ContactsContract.ContactsColumns.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.provider.ContactsContract.GroupsColumns.html b/docs/html/sdk/api_diff/14/changes/android.provider.ContactsContract.GroupsColumns.html
index ac74e71..58381c2 100644
--- a/docs/html/sdk/api_diff/14/changes/android.provider.ContactsContract.GroupsColumns.html
+++ b/docs/html/sdk/api_diff/14/changes/android.provider.ContactsContract.GroupsColumns.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.provider.ContactsContract.Intents.html b/docs/html/sdk/api_diff/14/changes/android.provider.ContactsContract.Intents.html
index 6ef8d49..aef0030 100644
--- a/docs/html/sdk/api_diff/14/changes/android.provider.ContactsContract.Intents.html
+++ b/docs/html/sdk/api_diff/14/changes/android.provider.ContactsContract.Intents.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.provider.ContactsContract.RawContactsColumns.html b/docs/html/sdk/api_diff/14/changes/android.provider.ContactsContract.RawContactsColumns.html
index 4ff53b7..b98d1b1 100644
--- a/docs/html/sdk/api_diff/14/changes/android.provider.ContactsContract.RawContactsColumns.html
+++ b/docs/html/sdk/api_diff/14/changes/android.provider.ContactsContract.RawContactsColumns.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.provider.ContactsContract.RawContactsEntity.html b/docs/html/sdk/api_diff/14/changes/android.provider.ContactsContract.RawContactsEntity.html
index dcfe079..a63d728 100644
--- a/docs/html/sdk/api_diff/14/changes/android.provider.ContactsContract.RawContactsEntity.html
+++ b/docs/html/sdk/api_diff/14/changes/android.provider.ContactsContract.RawContactsEntity.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.provider.ContactsContract.SettingsColumns.html b/docs/html/sdk/api_diff/14/changes/android.provider.ContactsContract.SettingsColumns.html
index 0b571a0..3f02f5f2 100644
--- a/docs/html/sdk/api_diff/14/changes/android.provider.ContactsContract.SettingsColumns.html
+++ b/docs/html/sdk/api_diff/14/changes/android.provider.ContactsContract.SettingsColumns.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.provider.ContactsContract.StatusUpdates.html b/docs/html/sdk/api_diff/14/changes/android.provider.ContactsContract.StatusUpdates.html
index 84ec049..ff069b0 100644
--- a/docs/html/sdk/api_diff/14/changes/android.provider.ContactsContract.StatusUpdates.html
+++ b/docs/html/sdk/api_diff/14/changes/android.provider.ContactsContract.StatusUpdates.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.provider.ContactsContract.html b/docs/html/sdk/api_diff/14/changes/android.provider.ContactsContract.html
index 2ae870c..f635b59 100644
--- a/docs/html/sdk/api_diff/14/changes/android.provider.ContactsContract.html
+++ b/docs/html/sdk/api_diff/14/changes/android.provider.ContactsContract.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.provider.LiveFolders.html b/docs/html/sdk/api_diff/14/changes/android.provider.LiveFolders.html
index 232171d..3db447e 100644
--- a/docs/html/sdk/api_diff/14/changes/android.provider.LiveFolders.html
+++ b/docs/html/sdk/api_diff/14/changes/android.provider.LiveFolders.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.provider.MediaStore.Audio.AudioColumns.html b/docs/html/sdk/api_diff/14/changes/android.provider.MediaStore.Audio.AudioColumns.html
index 99c3797..765bdb7 100644
--- a/docs/html/sdk/api_diff/14/changes/android.provider.MediaStore.Audio.AudioColumns.html
+++ b/docs/html/sdk/api_diff/14/changes/android.provider.MediaStore.Audio.AudioColumns.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.provider.Settings.Secure.html b/docs/html/sdk/api_diff/14/changes/android.provider.Settings.Secure.html
index 529f9e0..7cf1983 100644
--- a/docs/html/sdk/api_diff/14/changes/android.provider.Settings.Secure.html
+++ b/docs/html/sdk/api_diff/14/changes/android.provider.Settings.Secure.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.provider.Settings.System.html b/docs/html/sdk/api_diff/14/changes/android.provider.Settings.System.html
index 72bdb4f..4705790 100644
--- a/docs/html/sdk/api_diff/14/changes/android.provider.Settings.System.html
+++ b/docs/html/sdk/api_diff/14/changes/android.provider.Settings.System.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.provider.Settings.html b/docs/html/sdk/api_diff/14/changes/android.provider.Settings.html
index fb377f4..7ff39a8 100644
--- a/docs/html/sdk/api_diff/14/changes/android.provider.Settings.html
+++ b/docs/html/sdk/api_diff/14/changes/android.provider.Settings.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.renderscript.Allocation.html b/docs/html/sdk/api_diff/14/changes/android.renderscript.Allocation.html
index edff730..4a3f6e3 100644
--- a/docs/html/sdk/api_diff/14/changes/android.renderscript.Allocation.html
+++ b/docs/html/sdk/api_diff/14/changes/android.renderscript.Allocation.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.renderscript.AllocationAdapter.html b/docs/html/sdk/api_diff/14/changes/android.renderscript.AllocationAdapter.html
index 55f81f1..74682a6 100644
--- a/docs/html/sdk/api_diff/14/changes/android.renderscript.AllocationAdapter.html
+++ b/docs/html/sdk/api_diff/14/changes/android.renderscript.AllocationAdapter.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.renderscript.BaseObj.html b/docs/html/sdk/api_diff/14/changes/android.renderscript.BaseObj.html
index 073a080..67c4380 100644
--- a/docs/html/sdk/api_diff/14/changes/android.renderscript.BaseObj.html
+++ b/docs/html/sdk/api_diff/14/changes/android.renderscript.BaseObj.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.renderscript.Byte2.html b/docs/html/sdk/api_diff/14/changes/android.renderscript.Byte2.html
index c5b2fb3..bf81390 100644
--- a/docs/html/sdk/api_diff/14/changes/android.renderscript.Byte2.html
+++ b/docs/html/sdk/api_diff/14/changes/android.renderscript.Byte2.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.renderscript.Byte3.html b/docs/html/sdk/api_diff/14/changes/android.renderscript.Byte3.html
index 1821474..89988ac 100644
--- a/docs/html/sdk/api_diff/14/changes/android.renderscript.Byte3.html
+++ b/docs/html/sdk/api_diff/14/changes/android.renderscript.Byte3.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.renderscript.Byte4.html b/docs/html/sdk/api_diff/14/changes/android.renderscript.Byte4.html
index a218354..0317a2a 100644
--- a/docs/html/sdk/api_diff/14/changes/android.renderscript.Byte4.html
+++ b/docs/html/sdk/api_diff/14/changes/android.renderscript.Byte4.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.renderscript.Element.html b/docs/html/sdk/api_diff/14/changes/android.renderscript.Element.html
index 3d78923..b2bb1a0 100644
--- a/docs/html/sdk/api_diff/14/changes/android.renderscript.Element.html
+++ b/docs/html/sdk/api_diff/14/changes/android.renderscript.Element.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.renderscript.FieldPacker.html b/docs/html/sdk/api_diff/14/changes/android.renderscript.FieldPacker.html
index fa36797..b770687 100644
--- a/docs/html/sdk/api_diff/14/changes/android.renderscript.FieldPacker.html
+++ b/docs/html/sdk/api_diff/14/changes/android.renderscript.FieldPacker.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.renderscript.Int2.html b/docs/html/sdk/api_diff/14/changes/android.renderscript.Int2.html
index e0ec645..9338626 100644
--- a/docs/html/sdk/api_diff/14/changes/android.renderscript.Int2.html
+++ b/docs/html/sdk/api_diff/14/changes/android.renderscript.Int2.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.renderscript.Int3.html b/docs/html/sdk/api_diff/14/changes/android.renderscript.Int3.html
index dce2940..dd2929d 100644
--- a/docs/html/sdk/api_diff/14/changes/android.renderscript.Int3.html
+++ b/docs/html/sdk/api_diff/14/changes/android.renderscript.Int3.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.renderscript.Int4.html b/docs/html/sdk/api_diff/14/changes/android.renderscript.Int4.html
index 8013990..c7feb7c 100644
--- a/docs/html/sdk/api_diff/14/changes/android.renderscript.Int4.html
+++ b/docs/html/sdk/api_diff/14/changes/android.renderscript.Int4.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.renderscript.Long2.html b/docs/html/sdk/api_diff/14/changes/android.renderscript.Long2.html
index 464424d..b70a7b9 100644
--- a/docs/html/sdk/api_diff/14/changes/android.renderscript.Long2.html
+++ b/docs/html/sdk/api_diff/14/changes/android.renderscript.Long2.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.renderscript.Long3.html b/docs/html/sdk/api_diff/14/changes/android.renderscript.Long3.html
index 2bb7027..8f79513 100644
--- a/docs/html/sdk/api_diff/14/changes/android.renderscript.Long3.html
+++ b/docs/html/sdk/api_diff/14/changes/android.renderscript.Long3.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.renderscript.Long4.html b/docs/html/sdk/api_diff/14/changes/android.renderscript.Long4.html
index 4daaaee..75e5c1c 100644
--- a/docs/html/sdk/api_diff/14/changes/android.renderscript.Long4.html
+++ b/docs/html/sdk/api_diff/14/changes/android.renderscript.Long4.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.renderscript.RenderScriptGL.html b/docs/html/sdk/api_diff/14/changes/android.renderscript.RenderScriptGL.html
index b45d036..c95df17 100644
--- a/docs/html/sdk/api_diff/14/changes/android.renderscript.RenderScriptGL.html
+++ b/docs/html/sdk/api_diff/14/changes/android.renderscript.RenderScriptGL.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.renderscript.Script.html b/docs/html/sdk/api_diff/14/changes/android.renderscript.Script.html
index 6543d24..e758f56 100644
--- a/docs/html/sdk/api_diff/14/changes/android.renderscript.Script.html
+++ b/docs/html/sdk/api_diff/14/changes/android.renderscript.Script.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.renderscript.Short2.html b/docs/html/sdk/api_diff/14/changes/android.renderscript.Short2.html
index 26ce27e..29bcabc 100644
--- a/docs/html/sdk/api_diff/14/changes/android.renderscript.Short2.html
+++ b/docs/html/sdk/api_diff/14/changes/android.renderscript.Short2.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.renderscript.Short3.html b/docs/html/sdk/api_diff/14/changes/android.renderscript.Short3.html
index 5accbc7..b2c0790 100644
--- a/docs/html/sdk/api_diff/14/changes/android.renderscript.Short3.html
+++ b/docs/html/sdk/api_diff/14/changes/android.renderscript.Short3.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.renderscript.Short4.html b/docs/html/sdk/api_diff/14/changes/android.renderscript.Short4.html
index 51caf08..1b295f9 100644
--- a/docs/html/sdk/api_diff/14/changes/android.renderscript.Short4.html
+++ b/docs/html/sdk/api_diff/14/changes/android.renderscript.Short4.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.service.wallpaper.WallpaperService.Engine.html b/docs/html/sdk/api_diff/14/changes/android.service.wallpaper.WallpaperService.Engine.html
index c510522..16d0d11 100644
--- a/docs/html/sdk/api_diff/14/changes/android.service.wallpaper.WallpaperService.Engine.html
+++ b/docs/html/sdk/api_diff/14/changes/android.service.wallpaper.WallpaperService.Engine.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.speech.RecognizerIntent.html b/docs/html/sdk/api_diff/14/changes/android.speech.RecognizerIntent.html
index ba94bc2..11ec629 100644
--- a/docs/html/sdk/api_diff/14/changes/android.speech.RecognizerIntent.html
+++ b/docs/html/sdk/api_diff/14/changes/android.speech.RecognizerIntent.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.speech.SpeechRecognizer.html b/docs/html/sdk/api_diff/14/changes/android.speech.SpeechRecognizer.html
index b609702..b668613 100644
--- a/docs/html/sdk/api_diff/14/changes/android.speech.SpeechRecognizer.html
+++ b/docs/html/sdk/api_diff/14/changes/android.speech.SpeechRecognizer.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.speech.tts.TextToSpeech.Engine.html b/docs/html/sdk/api_diff/14/changes/android.speech.tts.TextToSpeech.Engine.html
index d348b69..bb0b4ac 100644
--- a/docs/html/sdk/api_diff/14/changes/android.speech.tts.TextToSpeech.Engine.html
+++ b/docs/html/sdk/api_diff/14/changes/android.speech.tts.TextToSpeech.Engine.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.speech.tts.TextToSpeech.html b/docs/html/sdk/api_diff/14/changes/android.speech.tts.TextToSpeech.html
index 66dbe94..24de846 100644
--- a/docs/html/sdk/api_diff/14/changes/android.speech.tts.TextToSpeech.html
+++ b/docs/html/sdk/api_diff/14/changes/android.speech.tts.TextToSpeech.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.test.mock.MockPackageManager.html b/docs/html/sdk/api_diff/14/changes/android.test.mock.MockPackageManager.html
index f09c1fd..5dcf841 100644
--- a/docs/html/sdk/api_diff/14/changes/android.test.mock.MockPackageManager.html
+++ b/docs/html/sdk/api_diff/14/changes/android.test.mock.MockPackageManager.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.text.Layout.html b/docs/html/sdk/api_diff/14/changes/android.text.Layout.html
index d4df05b..81cc608 100644
--- a/docs/html/sdk/api_diff/14/changes/android.text.Layout.html
+++ b/docs/html/sdk/api_diff/14/changes/android.text.Layout.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.util.Config.html b/docs/html/sdk/api_diff/14/changes/android.util.Config.html
index 908fb76..4d1cfe4 100644
--- a/docs/html/sdk/api_diff/14/changes/android.util.Config.html
+++ b/docs/html/sdk/api_diff/14/changes/android.util.Config.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.util.Patterns.html b/docs/html/sdk/api_diff/14/changes/android.util.Patterns.html
index 0c8824f..c5c0367 100644
--- a/docs/html/sdk/api_diff/14/changes/android.util.Patterns.html
+++ b/docs/html/sdk/api_diff/14/changes/android.util.Patterns.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.util.SparseArray.html b/docs/html/sdk/api_diff/14/changes/android.util.SparseArray.html
index 66f1b3b..be509fa 100644
--- a/docs/html/sdk/api_diff/14/changes/android.util.SparseArray.html
+++ b/docs/html/sdk/api_diff/14/changes/android.util.SparseArray.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.util.SparseBooleanArray.html b/docs/html/sdk/api_diff/14/changes/android.util.SparseBooleanArray.html
index b440bfc5..3b6a853 100644
--- a/docs/html/sdk/api_diff/14/changes/android.util.SparseBooleanArray.html
+++ b/docs/html/sdk/api_diff/14/changes/android.util.SparseBooleanArray.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.util.SparseIntArray.html b/docs/html/sdk/api_diff/14/changes/android.util.SparseIntArray.html
index 6c431b2..63577a3 100644
--- a/docs/html/sdk/api_diff/14/changes/android.util.SparseIntArray.html
+++ b/docs/html/sdk/api_diff/14/changes/android.util.SparseIntArray.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.view.ActionMode.html b/docs/html/sdk/api_diff/14/changes/android.view.ActionMode.html
index d93a89b..f0b1252 100644
--- a/docs/html/sdk/api_diff/14/changes/android.view.ActionMode.html
+++ b/docs/html/sdk/api_diff/14/changes/android.view.ActionMode.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.view.Gravity.html b/docs/html/sdk/api_diff/14/changes/android.view.Gravity.html
index 497302d..12aa839 100644
--- a/docs/html/sdk/api_diff/14/changes/android.view.Gravity.html
+++ b/docs/html/sdk/api_diff/14/changes/android.view.Gravity.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.view.InputDevice.html b/docs/html/sdk/api_diff/14/changes/android.view.InputDevice.html
index c53af0ad..4636c47 100644
--- a/docs/html/sdk/api_diff/14/changes/android.view.InputDevice.html
+++ b/docs/html/sdk/api_diff/14/changes/android.view.InputDevice.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.view.KeyEvent.html b/docs/html/sdk/api_diff/14/changes/android.view.KeyEvent.html
index 1d43fee..df18feb 100644
--- a/docs/html/sdk/api_diff/14/changes/android.view.KeyEvent.html
+++ b/docs/html/sdk/api_diff/14/changes/android.view.KeyEvent.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.view.MenuItem.html b/docs/html/sdk/api_diff/14/changes/android.view.MenuItem.html
index d87eee3..4b72464 100644
--- a/docs/html/sdk/api_diff/14/changes/android.view.MenuItem.html
+++ b/docs/html/sdk/api_diff/14/changes/android.view.MenuItem.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.view.MotionEvent.html b/docs/html/sdk/api_diff/14/changes/android.view.MotionEvent.html
index 4ae540d..1ab1946 100644
--- a/docs/html/sdk/api_diff/14/changes/android.view.MotionEvent.html
+++ b/docs/html/sdk/api_diff/14/changes/android.view.MotionEvent.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.view.Surface.html b/docs/html/sdk/api_diff/14/changes/android.view.Surface.html
index dd671ad..d6d496b 100644
--- a/docs/html/sdk/api_diff/14/changes/android.view.Surface.html
+++ b/docs/html/sdk/api_diff/14/changes/android.view.Surface.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.view.View.html b/docs/html/sdk/api_diff/14/changes/android.view.View.html
index 13d1dbe..38a21f7 100644
--- a/docs/html/sdk/api_diff/14/changes/android.view.View.html
+++ b/docs/html/sdk/api_diff/14/changes/android.view.View.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.view.ViewConfiguration.html b/docs/html/sdk/api_diff/14/changes/android.view.ViewConfiguration.html
index b8e87e5..18025b0 100644
--- a/docs/html/sdk/api_diff/14/changes/android.view.ViewConfiguration.html
+++ b/docs/html/sdk/api_diff/14/changes/android.view.ViewConfiguration.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.view.ViewGroup.html b/docs/html/sdk/api_diff/14/changes/android.view.ViewGroup.html
index 4bcf46b..b869fb4 100644
--- a/docs/html/sdk/api_diff/14/changes/android.view.ViewGroup.html
+++ b/docs/html/sdk/api_diff/14/changes/android.view.ViewGroup.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.view.ViewParent.html b/docs/html/sdk/api_diff/14/changes/android.view.ViewParent.html
index 63ca614..6cb3c63 100644
--- a/docs/html/sdk/api_diff/14/changes/android.view.ViewParent.html
+++ b/docs/html/sdk/api_diff/14/changes/android.view.ViewParent.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.view.ViewPropertyAnimator.html b/docs/html/sdk/api_diff/14/changes/android.view.ViewPropertyAnimator.html
index 4cd2465..30e0734 100644
--- a/docs/html/sdk/api_diff/14/changes/android.view.ViewPropertyAnimator.html
+++ b/docs/html/sdk/api_diff/14/changes/android.view.ViewPropertyAnimator.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.view.Window.html b/docs/html/sdk/api_diff/14/changes/android.view.Window.html
index f7b4624..5c044fe 100644
--- a/docs/html/sdk/api_diff/14/changes/android.view.Window.html
+++ b/docs/html/sdk/api_diff/14/changes/android.view.Window.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.view.WindowManager.LayoutParams.html b/docs/html/sdk/api_diff/14/changes/android.view.WindowManager.LayoutParams.html
index 99e8db6..ef0bf07 100644
--- a/docs/html/sdk/api_diff/14/changes/android.view.WindowManager.LayoutParams.html
+++ b/docs/html/sdk/api_diff/14/changes/android.view.WindowManager.LayoutParams.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.view.accessibility.AccessibilityEvent.html b/docs/html/sdk/api_diff/14/changes/android.view.accessibility.AccessibilityEvent.html
index bd5261a..1b712e3 100644
--- a/docs/html/sdk/api_diff/14/changes/android.view.accessibility.AccessibilityEvent.html
+++ b/docs/html/sdk/api_diff/14/changes/android.view.accessibility.AccessibilityEvent.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.view.accessibility.AccessibilityManager.html b/docs/html/sdk/api_diff/14/changes/android.view.accessibility.AccessibilityManager.html
index f49bd69..6a072f7 100644
--- a/docs/html/sdk/api_diff/14/changes/android.view.accessibility.AccessibilityManager.html
+++ b/docs/html/sdk/api_diff/14/changes/android.view.accessibility.AccessibilityManager.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.view.inputmethod.InputMethodManager.html b/docs/html/sdk/api_diff/14/changes/android.view.inputmethod.InputMethodManager.html
index 7741ecd..ae39429 100644
--- a/docs/html/sdk/api_diff/14/changes/android.view.inputmethod.InputMethodManager.html
+++ b/docs/html/sdk/api_diff/14/changes/android.view.inputmethod.InputMethodManager.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.view.inputmethod.InputMethodSession.html b/docs/html/sdk/api_diff/14/changes/android.view.inputmethod.InputMethodSession.html
index f497962..c1ff358 100644
--- a/docs/html/sdk/api_diff/14/changes/android.view.inputmethod.InputMethodSession.html
+++ b/docs/html/sdk/api_diff/14/changes/android.view.inputmethod.InputMethodSession.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.view.inputmethod.InputMethodSubtype.html b/docs/html/sdk/api_diff/14/changes/android.view.inputmethod.InputMethodSubtype.html
index 37208cb..f8e18fa 100644
--- a/docs/html/sdk/api_diff/14/changes/android.view.inputmethod.InputMethodSubtype.html
+++ b/docs/html/sdk/api_diff/14/changes/android.view.inputmethod.InputMethodSubtype.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.webkit.WebChromeClient.html b/docs/html/sdk/api_diff/14/changes/android.webkit.WebChromeClient.html
index e3aafad..d88e6c9 100644
--- a/docs/html/sdk/api_diff/14/changes/android.webkit.WebChromeClient.html
+++ b/docs/html/sdk/api_diff/14/changes/android.webkit.WebChromeClient.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.webkit.WebSettings.TextSize.html b/docs/html/sdk/api_diff/14/changes/android.webkit.WebSettings.TextSize.html
index c587f5c..5555034 100644
--- a/docs/html/sdk/api_diff/14/changes/android.webkit.WebSettings.TextSize.html
+++ b/docs/html/sdk/api_diff/14/changes/android.webkit.WebSettings.TextSize.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.webkit.WebSettings.html b/docs/html/sdk/api_diff/14/changes/android.webkit.WebSettings.html
index c092747..2966bb8 100644
--- a/docs/html/sdk/api_diff/14/changes/android.webkit.WebSettings.html
+++ b/docs/html/sdk/api_diff/14/changes/android.webkit.WebSettings.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.webkit.WebView.HitTestResult.html b/docs/html/sdk/api_diff/14/changes/android.webkit.WebView.HitTestResult.html
index 004b885..7778856 100644
--- a/docs/html/sdk/api_diff/14/changes/android.webkit.WebView.HitTestResult.html
+++ b/docs/html/sdk/api_diff/14/changes/android.webkit.WebView.HitTestResult.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.widget.AbsListView.html b/docs/html/sdk/api_diff/14/changes/android.widget.AbsListView.html
index b55e613..c11c111 100644
--- a/docs/html/sdk/api_diff/14/changes/android.widget.AbsListView.html
+++ b/docs/html/sdk/api_diff/14/changes/android.widget.AbsListView.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.widget.AdapterViewAnimator.html b/docs/html/sdk/api_diff/14/changes/android.widget.AdapterViewAnimator.html
index 429c0b4..0d1bccd 100644
--- a/docs/html/sdk/api_diff/14/changes/android.widget.AdapterViewAnimator.html
+++ b/docs/html/sdk/api_diff/14/changes/android.widget.AdapterViewAnimator.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.widget.ExpandableListView.html b/docs/html/sdk/api_diff/14/changes/android.widget.ExpandableListView.html
index 4442c15..71b928a 100644
--- a/docs/html/sdk/api_diff/14/changes/android.widget.ExpandableListView.html
+++ b/docs/html/sdk/api_diff/14/changes/android.widget.ExpandableListView.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.widget.FrameLayout.html b/docs/html/sdk/api_diff/14/changes/android.widget.FrameLayout.html
index 03df5a7..be62cbfc 100644
--- a/docs/html/sdk/api_diff/14/changes/android.widget.FrameLayout.html
+++ b/docs/html/sdk/api_diff/14/changes/android.widget.FrameLayout.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.widget.LinearLayout.html b/docs/html/sdk/api_diff/14/changes/android.widget.LinearLayout.html
index 4a7e999..33de5d1 100644
--- a/docs/html/sdk/api_diff/14/changes/android.widget.LinearLayout.html
+++ b/docs/html/sdk/api_diff/14/changes/android.widget.LinearLayout.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.widget.OverScroller.html b/docs/html/sdk/api_diff/14/changes/android.widget.OverScroller.html
index 2de63b9..3c902cf 100644
--- a/docs/html/sdk/api_diff/14/changes/android.widget.OverScroller.html
+++ b/docs/html/sdk/api_diff/14/changes/android.widget.OverScroller.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.widget.PopupMenu.html b/docs/html/sdk/api_diff/14/changes/android.widget.PopupMenu.html
index c85ca0f..5a82801 100644
--- a/docs/html/sdk/api_diff/14/changes/android.widget.PopupMenu.html
+++ b/docs/html/sdk/api_diff/14/changes/android.widget.PopupMenu.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.widget.RemoteViews.html b/docs/html/sdk/api_diff/14/changes/android.widget.RemoteViews.html
index 6d905d1..2750719 100644
--- a/docs/html/sdk/api_diff/14/changes/android.widget.RemoteViews.html
+++ b/docs/html/sdk/api_diff/14/changes/android.widget.RemoteViews.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.widget.Scroller.html b/docs/html/sdk/api_diff/14/changes/android.widget.Scroller.html
index fc3fb39..d586513 100644
--- a/docs/html/sdk/api_diff/14/changes/android.widget.Scroller.html
+++ b/docs/html/sdk/api_diff/14/changes/android.widget.Scroller.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.widget.SearchView.html b/docs/html/sdk/api_diff/14/changes/android.widget.SearchView.html
index fb49499..1116d30 100644
--- a/docs/html/sdk/api_diff/14/changes/android.widget.SearchView.html
+++ b/docs/html/sdk/api_diff/14/changes/android.widget.SearchView.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.widget.StackView.html b/docs/html/sdk/api_diff/14/changes/android.widget.StackView.html
index 0c524a5..6b491d0 100644
--- a/docs/html/sdk/api_diff/14/changes/android.widget.StackView.html
+++ b/docs/html/sdk/api_diff/14/changes/android.widget.StackView.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/android.widget.TextView.html b/docs/html/sdk/api_diff/14/changes/android.widget.TextView.html
index 54eb708..a2909ac 100644
--- a/docs/html/sdk/api_diff/14/changes/android.widget.TextView.html
+++ b/docs/html/sdk/api_diff/14/changes/android.widget.TextView.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/changes-summary.html b/docs/html/sdk/api_diff/14/changes/changes-summary.html
index 57e565e..ccb5d26 100644
--- a/docs/html/sdk/api_diff/14/changes/changes-summary.html
+++ b/docs/html/sdk/api_diff/14/changes/changes-summary.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/classes_index_additions.html b/docs/html/sdk/api_diff/14/changes/classes_index_additions.html
index 915fb4d..72461ce 100644
--- a/docs/html/sdk/api_diff/14/changes/classes_index_additions.html
+++ b/docs/html/sdk/api_diff/14/changes/classes_index_additions.html
@@ -269,7 +269,6 @@
 <a href="#W"><font size="-2">W</font></a> 
  <a href="#topheader"><font size="-2">TOP</font></a>
 <p><div style="line-height:1.5em;color:black">
-<A HREF="pkg_android.net.html#NetworkQuotaInfo" class="hiddenlink" target="rightframe"><b>NetworkQuotaInfo</b></A><br>
 <A HREF="pkg_android.nfc.html#NfcAdapter.CreateNdefMessageCallback" class="hiddenlink" target="rightframe"><b><i>NfcAdapter.CreateNdefMessageCallback</i></b></A><br>
 <A HREF="pkg_android.nfc.html#NfcAdapter.OnNdefPushCompleteCallback" class="hiddenlink" target="rightframe"><b><i>NfcAdapter.OnNdefPushCompleteCallback</i></b></A><br>
 <A HREF="pkg_android.nfc.html#NfcEvent" class="hiddenlink" target="rightframe"><b>NfcEvent</b></A><br>
diff --git a/docs/html/sdk/api_diff/14/changes/classes_index_all.html b/docs/html/sdk/api_diff/14/changes/classes_index_all.html
index 97f0d9d..ef8ccca 100644
--- a/docs/html/sdk/api_diff/14/changes/classes_index_all.html
+++ b/docs/html/sdk/api_diff/14/changes/classes_index_all.html
@@ -529,7 +529,6 @@
  <a href="#topheader"><font size="-2">TOP</font></a>
 <p><div style="line-height:1.5em;color:black">
 <A HREF="android.nfc.NdefRecord.html" class="hiddenlink" target="rightframe">NdefRecord</A><br>
-<A HREF="pkg_android.net.html#NetworkQuotaInfo" class="hiddenlink" target="rightframe"><b>NetworkQuotaInfo</b></A><br>
 <A HREF="android.nfc.tech.NfcA.html" class="hiddenlink" target="rightframe">NfcA</A><br>
 <A HREF="android.nfc.NfcAdapter.html" class="hiddenlink" target="rightframe">NfcAdapter</A><br>
 <A HREF="pkg_android.nfc.html#NfcAdapter.CreateNdefMessageCallback" class="hiddenlink" target="rightframe"><b><i>NfcAdapter.CreateNdefMessageCallback</i></b></A><br>
diff --git a/docs/html/sdk/api_diff/14/changes/dalvik.annotation.TestTarget.html b/docs/html/sdk/api_diff/14/changes/dalvik.annotation.TestTarget.html
index 7f684b5..d931d2e 100644
--- a/docs/html/sdk/api_diff/14/changes/dalvik.annotation.TestTarget.html
+++ b/docs/html/sdk/api_diff/14/changes/dalvik.annotation.TestTarget.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/dalvik.annotation.TestTargetClass.html b/docs/html/sdk/api_diff/14/changes/dalvik.annotation.TestTargetClass.html
index 015e9b7..eee755b 100644
--- a/docs/html/sdk/api_diff/14/changes/dalvik.annotation.TestTargetClass.html
+++ b/docs/html/sdk/api_diff/14/changes/dalvik.annotation.TestTargetClass.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/dalvik.system.DexClassLoader.html b/docs/html/sdk/api_diff/14/changes/dalvik.system.DexClassLoader.html
index fdcf5f9..a932a23 100644
--- a/docs/html/sdk/api_diff/14/changes/dalvik.system.DexClassLoader.html
+++ b/docs/html/sdk/api_diff/14/changes/dalvik.system.DexClassLoader.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/dalvik.system.PathClassLoader.html b/docs/html/sdk/api_diff/14/changes/dalvik.system.PathClassLoader.html
index 770e144..030cef9 100644
--- a/docs/html/sdk/api_diff/14/changes/dalvik.system.PathClassLoader.html
+++ b/docs/html/sdk/api_diff/14/changes/dalvik.system.PathClassLoader.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/java.io.FilePermission.html b/docs/html/sdk/api_diff/14/changes/java.io.FilePermission.html
index 6f1f043..07432bf 100644
--- a/docs/html/sdk/api_diff/14/changes/java.io.FilePermission.html
+++ b/docs/html/sdk/api_diff/14/changes/java.io.FilePermission.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/java.io.ObjectInputStream.html b/docs/html/sdk/api_diff/14/changes/java.io.ObjectInputStream.html
index 56a49fe..21b48ec 100644
--- a/docs/html/sdk/api_diff/14/changes/java.io.ObjectInputStream.html
+++ b/docs/html/sdk/api_diff/14/changes/java.io.ObjectInputStream.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/java.io.ObjectOutputStream.html b/docs/html/sdk/api_diff/14/changes/java.io.ObjectOutputStream.html
index 0a320e2..0ab0ed26 100644
--- a/docs/html/sdk/api_diff/14/changes/java.io.ObjectOutputStream.html
+++ b/docs/html/sdk/api_diff/14/changes/java.io.ObjectOutputStream.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/java.lang.Class.html b/docs/html/sdk/api_diff/14/changes/java.lang.Class.html
index cec7515..394b440 100644
--- a/docs/html/sdk/api_diff/14/changes/java.lang.Class.html
+++ b/docs/html/sdk/api_diff/14/changes/java.lang.Class.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/java.lang.ref.ReferenceQueue.html b/docs/html/sdk/api_diff/14/changes/java.lang.ref.ReferenceQueue.html
index 7127f60..000481c 100644
--- a/docs/html/sdk/api_diff/14/changes/java.lang.ref.ReferenceQueue.html
+++ b/docs/html/sdk/api_diff/14/changes/java.lang.ref.ReferenceQueue.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/java.lang.reflect.AccessibleObject.html b/docs/html/sdk/api_diff/14/changes/java.lang.reflect.AccessibleObject.html
index 8b9ef71..f90f9e5 100644
--- a/docs/html/sdk/api_diff/14/changes/java.lang.reflect.AccessibleObject.html
+++ b/docs/html/sdk/api_diff/14/changes/java.lang.reflect.AccessibleObject.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/java.lang.reflect.Constructor.html b/docs/html/sdk/api_diff/14/changes/java.lang.reflect.Constructor.html
index 7aba794..acb83ef 100644
--- a/docs/html/sdk/api_diff/14/changes/java.lang.reflect.Constructor.html
+++ b/docs/html/sdk/api_diff/14/changes/java.lang.reflect.Constructor.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/java.lang.reflect.Field.html b/docs/html/sdk/api_diff/14/changes/java.lang.reflect.Field.html
index 911b74f..19f58eb 100644
--- a/docs/html/sdk/api_diff/14/changes/java.lang.reflect.Field.html
+++ b/docs/html/sdk/api_diff/14/changes/java.lang.reflect.Field.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/java.lang.reflect.Method.html b/docs/html/sdk/api_diff/14/changes/java.lang.reflect.Method.html
index 71b7148..2226260 100644
--- a/docs/html/sdk/api_diff/14/changes/java.lang.reflect.Method.html
+++ b/docs/html/sdk/api_diff/14/changes/java.lang.reflect.Method.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/java.net.SocketPermission.html b/docs/html/sdk/api_diff/14/changes/java.net.SocketPermission.html
index e0e97f7..0c386f0 100644
--- a/docs/html/sdk/api_diff/14/changes/java.net.SocketPermission.html
+++ b/docs/html/sdk/api_diff/14/changes/java.net.SocketPermission.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/java.security.AllPermission.html b/docs/html/sdk/api_diff/14/changes/java.security.AllPermission.html
index e7b6c69..25c745b 100644
--- a/docs/html/sdk/api_diff/14/changes/java.security.AllPermission.html
+++ b/docs/html/sdk/api_diff/14/changes/java.security.AllPermission.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/java.security.BasicPermission.html b/docs/html/sdk/api_diff/14/changes/java.security.BasicPermission.html
index e1635b2..24c047e 100644
--- a/docs/html/sdk/api_diff/14/changes/java.security.BasicPermission.html
+++ b/docs/html/sdk/api_diff/14/changes/java.security.BasicPermission.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/java.security.Permission.html b/docs/html/sdk/api_diff/14/changes/java.security.Permission.html
index 3d588cd..6356059 100644
--- a/docs/html/sdk/api_diff/14/changes/java.security.Permission.html
+++ b/docs/html/sdk/api_diff/14/changes/java.security.Permission.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/java.security.UnresolvedPermission.html b/docs/html/sdk/api_diff/14/changes/java.security.UnresolvedPermission.html
index 73628f6..8d90dc8 100644
--- a/docs/html/sdk/api_diff/14/changes/java.security.UnresolvedPermission.html
+++ b/docs/html/sdk/api_diff/14/changes/java.security.UnresolvedPermission.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/java.util.logging.Handler.html b/docs/html/sdk/api_diff/14/changes/java.util.logging.Handler.html
index 1eeee00..3a33e6e 100644
--- a/docs/html/sdk/api_diff/14/changes/java.util.logging.Handler.html
+++ b/docs/html/sdk/api_diff/14/changes/java.util.logging.Handler.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/javax.security.auth.PrivateCredentialPermission.html b/docs/html/sdk/api_diff/14/changes/javax.security.auth.PrivateCredentialPermission.html
index 86774e0..cf64e41 100644
--- a/docs/html/sdk/api_diff/14/changes/javax.security.auth.PrivateCredentialPermission.html
+++ b/docs/html/sdk/api_diff/14/changes/javax.security.auth.PrivateCredentialPermission.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/jdiff_statistics.html b/docs/html/sdk/api_diff/14/changes/jdiff_statistics.html
index 038cd2d..6729816 100644
--- a/docs/html/sdk/api_diff/14/changes/jdiff_statistics.html
+++ b/docs/html/sdk/api_diff/14/changes/jdiff_statistics.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
@@ -71,7 +71,7 @@
 <div id="doc-content" style="position:relative;">
 <div id="mainBodyFluid">
 <h1>API&nbsp;Change&nbsp;Statistics</h1>
-<p>The overall difference between API Levels 13 and 14 is approximately <span style="color:222;font-weight:bold;">3.96%</span>.
+<p>The overall difference between API Levels 13 and 14 is approximately <span style="color:222;font-weight:bold;">3.95%</span>.
 </p>
 <br>
 <a name="numbers"></a>
@@ -96,10 +96,10 @@
 </TR>
 <TR>
   <TD>Classes and <i>Interfaces</i></TD>
-  <TD ALIGN="right">91</TD>
+  <TD ALIGN="right">90</TD>
   <TD ALIGN="right">192</TD>
   <TD ALIGN="right">0</TD>
-  <TD ALIGN="right">283</TD>
+  <TD ALIGN="right">282</TD>
 </TR>
 <TR>
   <TD>Constructors</TD>
@@ -110,10 +110,10 @@
 </TR>
 <TR>
   <TD>Methods</TD>
-  <TD ALIGN="right">286</TD>
+  <TD ALIGN="right">285</TD>
   <TD ALIGN="right">94</TD>
   <TD ALIGN="right">29</TD>
-  <TD ALIGN="right">409</TD>
+  <TD ALIGN="right">408</TD>
 </TR>
 <TR>
   <TD>Fields</TD>
@@ -124,10 +124,10 @@
 </TR>
 <TR>
   <TD style="background-color:#FAFAFA"><b>Total</b></TD>
-  <TD  style="background-color:#FAFAFA" ALIGN="right"><strong>806</strong></TD>
+  <TD  style="background-color:#FAFAFA" ALIGN="right"><strong>804</strong></TD>
   <TD  style="background-color:#FAFAFA" ALIGN="right"><strong>370</strong></TD>
   <TD  style="background-color:#FAFAFA" ALIGN="right"><strong>45</strong></TD>
-  <TD  style="background-color:#FAFAFA" ALIGN="right"><strong>1221</strong></TD>
+  <TD  style="background-color:#FAFAFA" ALIGN="right"><strong>1219</strong></TD>
 </TR>
 </TABLE>
 <br>
@@ -188,10 +188,6 @@
 </TR>
 <TR>
   <TD ALIGN="center">7</TD>
-  <TD><A HREF="pkg_android.net.html">android.net</A></TD>
-</TR>
-<TR>
-  <TD ALIGN="center">7</TD>
   <TD><A HREF="pkg_android.net.http.html">android.net.http</A></TD>
 </TR>
 <TR>
@@ -204,6 +200,10 @@
 </TR>
 <TR>
   <TD ALIGN="center">5</TD>
+  <TD><A HREF="pkg_android.net.html">android.net</A></TD>
+</TR>
+<TR>
+  <TD ALIGN="center">5</TD>
   <TD><A HREF="pkg_android.view.html">android.view</A></TD>
 </TR>
 <TR>
@@ -772,11 +772,6 @@
 </TR>
 <TR>
   <TD ALIGN="center">6</TD>
-  <TD><A HREF="android.net.ConnectivityManager.html">
-android.net.ConnectivityManager</A></TD>
-</TR>
-<TR>
-  <TD ALIGN="center">6</TD>
   <TD><A HREF="android.media.MediaRecorder.html">
 android.media.MediaRecorder</A></TD>
 </TR>
@@ -837,6 +832,11 @@
 </TR>
 <TR>
   <TD ALIGN="center">5</TD>
+  <TD><A HREF="android.net.ConnectivityManager.html">
+android.net.ConnectivityManager</A></TD>
+</TR>
+<TR>
+  <TD ALIGN="center">5</TD>
   <TD><A HREF="android.view.inputmethod.InputMethodSession.html">
 <i>android.view.inputmethod.InputMethodSession</i></A></TD>
 </TR>
diff --git a/docs/html/sdk/api_diff/14/changes/methods_index_additions.html b/docs/html/sdk/api_diff/14/changes/methods_index_additions.html
index 1fd9649..58dd0bf 100644
--- a/docs/html/sdk/api_diff/14/changes/methods_index_additions.html
+++ b/docs/html/sdk/api_diff/14/changes/methods_index_additions.html
@@ -271,8 +271,6 @@
 (<code>int, int</code>)</A></nobr><br>
 <nobr><A HREF="android.view.MenuItem.html#android.view.MenuItem.getActionProvider_added()" class="hiddenlink" target="rightframe"><b>getActionProvider</b>
 ()</A></nobr><br>
-<nobr><A HREF="android.net.ConnectivityManager.html#android.net.ConnectivityManager.getActiveNetworkQuotaInfo_added()" class="hiddenlink" target="rightframe"><b>getActiveNetworkQuotaInfo</b>
-()</A></nobr><br>
 <i>getAnnotation</i><br>
 &nbsp;&nbsp;<nobr><A HREF="java.lang.reflect.Constructor.html#java.lang.reflect.Constructor.getAnnotation_added(java.lang.Class<A>)" class="hiddenlink" target="rightframe">type&nbsp;<b>
 (<code>Class&lt;A&gt;</code>)</b>&nbsp;in&nbsp;java.lang.reflect.Constructor
diff --git a/docs/html/sdk/api_diff/14/changes/methods_index_all.html b/docs/html/sdk/api_diff/14/changes/methods_index_all.html
index 38c2f86..3ba8441 100644
--- a/docs/html/sdk/api_diff/14/changes/methods_index_all.html
+++ b/docs/html/sdk/api_diff/14/changes/methods_index_all.html
@@ -339,8 +339,6 @@
 ()</A></nobr><br>
 <nobr><A HREF="android.view.MenuItem.html#android.view.MenuItem.getActionProvider_added()" class="hiddenlink" target="rightframe"><b>getActionProvider</b>
 ()</A></nobr><br>
-<nobr><A HREF="android.net.ConnectivityManager.html#android.net.ConnectivityManager.getActiveNetworkQuotaInfo_added()" class="hiddenlink" target="rightframe"><b>getActiveNetworkQuotaInfo</b>
-()</A></nobr><br>
 <nobr><A HREF="android.view.accessibility.AccessibilityEvent.html#android.view.accessibility.AccessibilityEvent.getAddedCount_changed()" class="hiddenlink" target="rightframe">getAddedCount
 ()</A></nobr><br>
 <i>getAnnotation</i><br>
diff --git a/docs/html/sdk/api_diff/14/changes/pkg_android.accessibilityservice.html b/docs/html/sdk/api_diff/14/changes/pkg_android.accessibilityservice.html
index 30f61f3..0ab9feb 100644
--- a/docs/html/sdk/api_diff/14/changes/pkg_android.accessibilityservice.html
+++ b/docs/html/sdk/api_diff/14/changes/pkg_android.accessibilityservice.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/pkg_android.accounts.html b/docs/html/sdk/api_diff/14/changes/pkg_android.accounts.html
index d424a2c..b19da2d 100644
--- a/docs/html/sdk/api_diff/14/changes/pkg_android.accounts.html
+++ b/docs/html/sdk/api_diff/14/changes/pkg_android.accounts.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/pkg_android.animation.html b/docs/html/sdk/api_diff/14/changes/pkg_android.animation.html
index 0e095e9..21148bf 100644
--- a/docs/html/sdk/api_diff/14/changes/pkg_android.animation.html
+++ b/docs/html/sdk/api_diff/14/changes/pkg_android.animation.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/pkg_android.app.admin.html b/docs/html/sdk/api_diff/14/changes/pkg_android.app.admin.html
index 2923068..4dfa032 100644
--- a/docs/html/sdk/api_diff/14/changes/pkg_android.app.admin.html
+++ b/docs/html/sdk/api_diff/14/changes/pkg_android.app.admin.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/pkg_android.app.backup.html b/docs/html/sdk/api_diff/14/changes/pkg_android.app.backup.html
index 731eb34..dd5324b 100644
--- a/docs/html/sdk/api_diff/14/changes/pkg_android.app.backup.html
+++ b/docs/html/sdk/api_diff/14/changes/pkg_android.app.backup.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/pkg_android.app.html b/docs/html/sdk/api_diff/14/changes/pkg_android.app.html
index 4713e89..8e6d724 100644
--- a/docs/html/sdk/api_diff/14/changes/pkg_android.app.html
+++ b/docs/html/sdk/api_diff/14/changes/pkg_android.app.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/pkg_android.appwidget.html b/docs/html/sdk/api_diff/14/changes/pkg_android.appwidget.html
index c25b084..a8651f3 100644
--- a/docs/html/sdk/api_diff/14/changes/pkg_android.appwidget.html
+++ b/docs/html/sdk/api_diff/14/changes/pkg_android.appwidget.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/pkg_android.bluetooth.html b/docs/html/sdk/api_diff/14/changes/pkg_android.bluetooth.html
index 3f4a707..1a5556c 100644
--- a/docs/html/sdk/api_diff/14/changes/pkg_android.bluetooth.html
+++ b/docs/html/sdk/api_diff/14/changes/pkg_android.bluetooth.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/pkg_android.content.html b/docs/html/sdk/api_diff/14/changes/pkg_android.content.html
index 54804d3..60d7c7e 100644
--- a/docs/html/sdk/api_diff/14/changes/pkg_android.content.html
+++ b/docs/html/sdk/api_diff/14/changes/pkg_android.content.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/pkg_android.content.pm.html b/docs/html/sdk/api_diff/14/changes/pkg_android.content.pm.html
index 2f04eab..81ac942 100644
--- a/docs/html/sdk/api_diff/14/changes/pkg_android.content.pm.html
+++ b/docs/html/sdk/api_diff/14/changes/pkg_android.content.pm.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/pkg_android.database.sqlite.html b/docs/html/sdk/api_diff/14/changes/pkg_android.database.sqlite.html
index 3b28f3b..39291b9 100644
--- a/docs/html/sdk/api_diff/14/changes/pkg_android.database.sqlite.html
+++ b/docs/html/sdk/api_diff/14/changes/pkg_android.database.sqlite.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/pkg_android.graphics.html b/docs/html/sdk/api_diff/14/changes/pkg_android.graphics.html
index 10b7d8f..b4b1517 100644
--- a/docs/html/sdk/api_diff/14/changes/pkg_android.graphics.html
+++ b/docs/html/sdk/api_diff/14/changes/pkg_android.graphics.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/pkg_android.hardware.html b/docs/html/sdk/api_diff/14/changes/pkg_android.hardware.html
index 93bd316..6e6d40e 100644
--- a/docs/html/sdk/api_diff/14/changes/pkg_android.hardware.html
+++ b/docs/html/sdk/api_diff/14/changes/pkg_android.hardware.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/pkg_android.html b/docs/html/sdk/api_diff/14/changes/pkg_android.html
index 818391c..7f15e82 100644
--- a/docs/html/sdk/api_diff/14/changes/pkg_android.html
+++ b/docs/html/sdk/api_diff/14/changes/pkg_android.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/pkg_android.inputmethodservice.html b/docs/html/sdk/api_diff/14/changes/pkg_android.inputmethodservice.html
index 18503bf..c020347 100644
--- a/docs/html/sdk/api_diff/14/changes/pkg_android.inputmethodservice.html
+++ b/docs/html/sdk/api_diff/14/changes/pkg_android.inputmethodservice.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/pkg_android.media.html b/docs/html/sdk/api_diff/14/changes/pkg_android.media.html
index d92e8b4..6269a65 100644
--- a/docs/html/sdk/api_diff/14/changes/pkg_android.media.html
+++ b/docs/html/sdk/api_diff/14/changes/pkg_android.media.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/pkg_android.net.html b/docs/html/sdk/api_diff/14/changes/pkg_android.net.html
index 9ffb210..3deb6bd 100644
--- a/docs/html/sdk/api_diff/14/changes/pkg_android.net.html
+++ b/docs/html/sdk/api_diff/14/changes/pkg_android.net.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
@@ -81,13 +81,6 @@
 </TH>
 <TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
   <TD VALIGN="TOP" WIDTH="25%">
-  <A NAME="NetworkQuotaInfo"></A>
-  <nobr><A HREF="../../../../reference/android/net/NetworkQuotaInfo.html" target="_top"><code>NetworkQuotaInfo</code></A></nobr>
-  </TD>
-  <TD>&nbsp;</TD>
-</TR>
-<TR BGCOLOR="#FFFFFF" CLASS="TableRowColor">
-  <TD VALIGN="TOP" WIDTH="25%">
   <A NAME="VpnService"></A>
   <nobr><A HREF="../../../../reference/android/net/VpnService.html" target="_top"><code>VpnService</code></A></nobr>
   </TD>
diff --git a/docs/html/sdk/api_diff/14/changes/pkg_android.net.http.html b/docs/html/sdk/api_diff/14/changes/pkg_android.net.http.html
index 43c77e3..cd51c20 100644
--- a/docs/html/sdk/api_diff/14/changes/pkg_android.net.http.html
+++ b/docs/html/sdk/api_diff/14/changes/pkg_android.net.http.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/pkg_android.net.wifi.html b/docs/html/sdk/api_diff/14/changes/pkg_android.net.wifi.html
index 5dcc18b..5ae5932 100644
--- a/docs/html/sdk/api_diff/14/changes/pkg_android.net.wifi.html
+++ b/docs/html/sdk/api_diff/14/changes/pkg_android.net.wifi.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/pkg_android.nfc.html b/docs/html/sdk/api_diff/14/changes/pkg_android.nfc.html
index edeb544..a044e01 100644
--- a/docs/html/sdk/api_diff/14/changes/pkg_android.nfc.html
+++ b/docs/html/sdk/api_diff/14/changes/pkg_android.nfc.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/pkg_android.nfc.tech.html b/docs/html/sdk/api_diff/14/changes/pkg_android.nfc.tech.html
index f23ff0a..c7e562d 100644
--- a/docs/html/sdk/api_diff/14/changes/pkg_android.nfc.tech.html
+++ b/docs/html/sdk/api_diff/14/changes/pkg_android.nfc.tech.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/pkg_android.opengl.html b/docs/html/sdk/api_diff/14/changes/pkg_android.opengl.html
index eb5a078..0d66ed8 100644
--- a/docs/html/sdk/api_diff/14/changes/pkg_android.opengl.html
+++ b/docs/html/sdk/api_diff/14/changes/pkg_android.opengl.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/pkg_android.os.html b/docs/html/sdk/api_diff/14/changes/pkg_android.os.html
index 527abea..1a56e37 100644
--- a/docs/html/sdk/api_diff/14/changes/pkg_android.os.html
+++ b/docs/html/sdk/api_diff/14/changes/pkg_android.os.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/pkg_android.preference.html b/docs/html/sdk/api_diff/14/changes/pkg_android.preference.html
index 1a513f0..ded1274 100644
--- a/docs/html/sdk/api_diff/14/changes/pkg_android.preference.html
+++ b/docs/html/sdk/api_diff/14/changes/pkg_android.preference.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/pkg_android.provider.html b/docs/html/sdk/api_diff/14/changes/pkg_android.provider.html
index 02522f1..23a6407 100644
--- a/docs/html/sdk/api_diff/14/changes/pkg_android.provider.html
+++ b/docs/html/sdk/api_diff/14/changes/pkg_android.provider.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/pkg_android.renderscript.html b/docs/html/sdk/api_diff/14/changes/pkg_android.renderscript.html
index 5038418..03563af 100644
--- a/docs/html/sdk/api_diff/14/changes/pkg_android.renderscript.html
+++ b/docs/html/sdk/api_diff/14/changes/pkg_android.renderscript.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/pkg_android.service.wallpaper.html b/docs/html/sdk/api_diff/14/changes/pkg_android.service.wallpaper.html
index cb1fcc9..c1bdfb1 100644
--- a/docs/html/sdk/api_diff/14/changes/pkg_android.service.wallpaper.html
+++ b/docs/html/sdk/api_diff/14/changes/pkg_android.service.wallpaper.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/pkg_android.speech.html b/docs/html/sdk/api_diff/14/changes/pkg_android.speech.html
index 346474e..bfbe14e 100644
--- a/docs/html/sdk/api_diff/14/changes/pkg_android.speech.html
+++ b/docs/html/sdk/api_diff/14/changes/pkg_android.speech.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/pkg_android.speech.tts.html b/docs/html/sdk/api_diff/14/changes/pkg_android.speech.tts.html
index 3f35de3..21fca52 100644
--- a/docs/html/sdk/api_diff/14/changes/pkg_android.speech.tts.html
+++ b/docs/html/sdk/api_diff/14/changes/pkg_android.speech.tts.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/pkg_android.test.mock.html b/docs/html/sdk/api_diff/14/changes/pkg_android.test.mock.html
index 161e278..169b498 100644
--- a/docs/html/sdk/api_diff/14/changes/pkg_android.test.mock.html
+++ b/docs/html/sdk/api_diff/14/changes/pkg_android.test.mock.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/pkg_android.text.html b/docs/html/sdk/api_diff/14/changes/pkg_android.text.html
index 345d90d..b286fa1 100644
--- a/docs/html/sdk/api_diff/14/changes/pkg_android.text.html
+++ b/docs/html/sdk/api_diff/14/changes/pkg_android.text.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/pkg_android.text.style.html b/docs/html/sdk/api_diff/14/changes/pkg_android.text.style.html
index 2423fc4..dfda61e 100644
--- a/docs/html/sdk/api_diff/14/changes/pkg_android.text.style.html
+++ b/docs/html/sdk/api_diff/14/changes/pkg_android.text.style.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/pkg_android.util.html b/docs/html/sdk/api_diff/14/changes/pkg_android.util.html
index f776a86..6b9a20b 100644
--- a/docs/html/sdk/api_diff/14/changes/pkg_android.util.html
+++ b/docs/html/sdk/api_diff/14/changes/pkg_android.util.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/pkg_android.view.accessibility.html b/docs/html/sdk/api_diff/14/changes/pkg_android.view.accessibility.html
index c731a5e..c78a800 100644
--- a/docs/html/sdk/api_diff/14/changes/pkg_android.view.accessibility.html
+++ b/docs/html/sdk/api_diff/14/changes/pkg_android.view.accessibility.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/pkg_android.view.html b/docs/html/sdk/api_diff/14/changes/pkg_android.view.html
index d963b18..58e2441 100644
--- a/docs/html/sdk/api_diff/14/changes/pkg_android.view.html
+++ b/docs/html/sdk/api_diff/14/changes/pkg_android.view.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/pkg_android.view.inputmethod.html b/docs/html/sdk/api_diff/14/changes/pkg_android.view.inputmethod.html
index b04df04..d422a5d 100644
--- a/docs/html/sdk/api_diff/14/changes/pkg_android.view.inputmethod.html
+++ b/docs/html/sdk/api_diff/14/changes/pkg_android.view.inputmethod.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/pkg_android.webkit.html b/docs/html/sdk/api_diff/14/changes/pkg_android.webkit.html
index 4671eea..8d52055 100644
--- a/docs/html/sdk/api_diff/14/changes/pkg_android.webkit.html
+++ b/docs/html/sdk/api_diff/14/changes/pkg_android.webkit.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/pkg_android.widget.html b/docs/html/sdk/api_diff/14/changes/pkg_android.widget.html
index bff12a8..f5a9ede 100644
--- a/docs/html/sdk/api_diff/14/changes/pkg_android.widget.html
+++ b/docs/html/sdk/api_diff/14/changes/pkg_android.widget.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/pkg_dalvik.annotation.html b/docs/html/sdk/api_diff/14/changes/pkg_dalvik.annotation.html
index 209eadc..5d6987a 100644
--- a/docs/html/sdk/api_diff/14/changes/pkg_dalvik.annotation.html
+++ b/docs/html/sdk/api_diff/14/changes/pkg_dalvik.annotation.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/pkg_dalvik.system.html b/docs/html/sdk/api_diff/14/changes/pkg_dalvik.system.html
index 9b876d4..246b8dd 100644
--- a/docs/html/sdk/api_diff/14/changes/pkg_dalvik.system.html
+++ b/docs/html/sdk/api_diff/14/changes/pkg_dalvik.system.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/pkg_java.io.html b/docs/html/sdk/api_diff/14/changes/pkg_java.io.html
index 9c4ca29..4291f38 100644
--- a/docs/html/sdk/api_diff/14/changes/pkg_java.io.html
+++ b/docs/html/sdk/api_diff/14/changes/pkg_java.io.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/pkg_java.lang.html b/docs/html/sdk/api_diff/14/changes/pkg_java.lang.html
index 91c9c1c..fcf6b25 100644
--- a/docs/html/sdk/api_diff/14/changes/pkg_java.lang.html
+++ b/docs/html/sdk/api_diff/14/changes/pkg_java.lang.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/pkg_java.lang.ref.html b/docs/html/sdk/api_diff/14/changes/pkg_java.lang.ref.html
index 73fbd22..1aabf82 100644
--- a/docs/html/sdk/api_diff/14/changes/pkg_java.lang.ref.html
+++ b/docs/html/sdk/api_diff/14/changes/pkg_java.lang.ref.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/pkg_java.lang.reflect.html b/docs/html/sdk/api_diff/14/changes/pkg_java.lang.reflect.html
index 81a73a7..ca050ee 100644
--- a/docs/html/sdk/api_diff/14/changes/pkg_java.lang.reflect.html
+++ b/docs/html/sdk/api_diff/14/changes/pkg_java.lang.reflect.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/pkg_java.net.html b/docs/html/sdk/api_diff/14/changes/pkg_java.net.html
index 6d16c39..37a8105 100644
--- a/docs/html/sdk/api_diff/14/changes/pkg_java.net.html
+++ b/docs/html/sdk/api_diff/14/changes/pkg_java.net.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/pkg_java.security.html b/docs/html/sdk/api_diff/14/changes/pkg_java.security.html
index 8173cfc..38d8f1f 100644
--- a/docs/html/sdk/api_diff/14/changes/pkg_java.security.html
+++ b/docs/html/sdk/api_diff/14/changes/pkg_java.security.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/pkg_java.util.logging.html b/docs/html/sdk/api_diff/14/changes/pkg_java.util.logging.html
index 2944111..cac83f2 100644
--- a/docs/html/sdk/api_diff/14/changes/pkg_java.util.logging.html
+++ b/docs/html/sdk/api_diff/14/changes/pkg_java.util.logging.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/api_diff/14/changes/pkg_javax.security.auth.html b/docs/html/sdk/api_diff/14/changes/pkg_javax.security.auth.html
index d321d86..9c134cf 100644
--- a/docs/html/sdk/api_diff/14/changes/pkg_javax.security.auth.html
+++ b/docs/html/sdk/api_diff/14/changes/pkg_javax.security.auth.html
@@ -54,7 +54,7 @@
       </tr>
       <tr>
         <td class="diffspec">Generated</td>
-        <td class="diffvalue">2011.10.04 17:12</td>
+        <td class="diffvalue">2011.10.06 23:19</td>
       </tr>
     </table>
     </div><!-- End and-diff-id -->
diff --git a/docs/html/sdk/eclipse-adt.jd b/docs/html/sdk/eclipse-adt.jd
index bbf7cbe..333efa2 100644
--- a/docs/html/sdk/eclipse-adt.jd
+++ b/docs/html/sdk/eclipse-adt.jd
@@ -1,8 +1,8 @@
 page.title=ADT Plugin for Eclipse
-adt.zip.version=12.0.0
-adt.zip.download=ADT-12.0.0.zip
-adt.zip.bytes=5651973
-adt.zip.checksum=8ad85d0f3da4a2b8dadfddcc2d66dbcb
+adt.zip.version=14.0.0
+adt.zip.download=ADT-14.0.0.zip
+adt.zip.bytes=6745584
+adt.zip.checksum=a645330d90fd9dae6187662bb1c3c644
 
 @jd:body
 
@@ -22,7 +22,7 @@
     </li>
     <li><a href="#updating">Updating the ADT Plugin</a></li>
   </ol>
-  
+
   <h2>See also</h2>
   <ol>
     <li><a href="{@docRoot}guide/developing/tools/adt.html">Android Developer Tools</a></li>
@@ -110,6 +110,124 @@
   <a href="#" onclick="return toggleDiv(this)">
         <img src="{@docRoot}assets/images/triangle-opened.png" class="toggle-img" height="9px"
 width="9px" />
+ADT 14.0.0</a> <em>(October 2011)</em>
+  <div class="toggleme">
+<dl>
+
+<dt>Dependencies:</dt>
+
+<dd>ADT 14.0.0 is designed for use with <a href="{@docRoot}sdk/tools-notes.html">SDK Tools r14</a>.
+If you haven't already installed SDK Tools r14 into your SDK, use the Android SDK and AVD Manager to
+do so.</dd>
+
+<dt>Build system</dt>
+<dd>
+  <ul>
+    <li>Changed <code>default.properties</code> to <code>project.properties</code> and
+    <code>build.properties</code> to <code>ant.properties</code>. ADT automatically
+    renames these files, if necessary, when you open a project in Eclipse.</li>
+    <li>Changed how library projects are built in Eclipse.</a></li>
+    <li>Changed output of <code>javac</code> from <code>bin/</code> to <code>bin/classes</code>
+    in Eclipse.</li>
+    <li>Improved incremental builds so that resource compilation runs less frequently. Builds no
+    longer run when you edit strings or layouts (unless you add a new <code>id</code>) and no longer
+    run once for each library project.</li>
+    <li>Introduced a "PNG crunch cache" that only runs on modified PNG files, instead of
+    crunching all existing PNG files, all the time.</li>
+    <li>Modified resource compilation so it no longer happens for normal save operations. It only
+    happens when running or debugging (the build option that lets you disable the packaging
+    step, which was introduced in ADT 12, is now on by default.)</li>
+  </ul>
+<p>For a complete overview of the build system changes and what you need to do to support them,
+see the <a href="http://tools.android.com/recent/buildchangesinrevision14">Android Tools Project
+site</a>.</p>
+</dd>
+
+<dt>General improvements</dt>
+<dd>
+  <ul>
+
+
+<li>Added a Welcome Wizard to help with the initial setup of the Android
+development environment (<a href="http://tools.android.com/recent/welcomewizard">more
+info</a>).</li>
+<li>Integrated the Android Asset Studio, which helps you create icons for things
+like the launcher, menus, and tabs. (<a
+href="http://tools.android.com/recent/assetstudiointegration">more
+info</a>).</li>
+<li>Revamped the Logcat view and added support to display and filter logs by
+   application names as well as PIDs (<a
+   href="http://tools.android.com/recent/updatedlogcatviewer">more info</a>).</li>
+<li>Revamped the SDK Manager UI (<a href="http://tools.android.com/recent/newsdkmanager">more
+info</a>).</li>
+<li>Revamped the New Project and the New XML File wizards to have
+multiple pages. Sample projects are now copied into the workspace such that they can be modified
+and deleted without affecting the master copy
+(<a href="http://tools.android.com/recent/revampedwizards">more info</a>).</li>
+<li>Removed the dependency on Eclipse GEF.</li>
+</ul>
+</dd>
+
+<dt>XML and Java editors</dt>
+<dd>
+  <ul>
+    <li>Added a new XML formatter that formats all XML files according to the
+   standard Android coding style. The formatter can also reorder
+   attributes to follow a recommended order and processes any changes made in the Layout editor.
+(<a href="http://tools.android.com/recent/xmlformatter">more info</a>).</li>
+  <li>Added the "Go to Matching" (Ctrl-Shift-P) feature, which lets you jump
+between opening and closing tags in XML files.</li>
+  <li>Added support for the "Select Enclosing Element" feature on Mac.</li>
+  <li>Added a Quickfix for extracting Strings when the caret is inside a String (<a href="">see
+more</a>).</li>
+  <li>Improved "smart indent", which allows automatic indentation and un-indentation
+   when pressing the Return key in XML editors (<a
+href="http://tools.android.com/recent/xmleditingimprovements">more info</a>).</li>
+
+  </ul>
+</dd>
+
+<dt>Layout editor</dt>
+<dd>
+  <ul>
+    <li>Added tooltip feedback for dragging and resizing operations. For
+    example, when dragging in a relative layout, the proposed
+    constraints are shown. When resizing, the new dimensions are
+    shown (<a href="http://tools.android.com/recent/layouteditorfeedbacktooltips">more
+info</a>).</li>
+    <li>Added the ability to suppress rendering fidelity warnings (<a
+href="http://tools.android.com/recent/suppressrenderwarnings">more info</a>).</li>
+    <li>Added "Remove Container" visual refactoring that removes the
+    children of a container up to the top level and transfers
+    namespace and layout attributes if necessary (<a
+href="http://tools.android.com/recent/removecontainervisualrefactoring">more info</a>).</li>
+    <li>Added pull-right menus to the context menu for accessing
+    properties of the parents, which is useful when the children fully
+    cover the parent and make it hard to select on their own.</li>
+     <li>Improved access to properties in the context menu. The most
+    frequently set attributes for each view are listed at the top of
+    the menu. The Properties menu offers access to the most
+    recently set attributes, attributes organized by their defining
+    view, and layout attributes only or all attributes alphabetically (<a
+href="http://tools.android.com/recent/layouteditorcontextmenuimprovements">more info</a>).</li>
+  </ul>
+</dd>
+
+<dt>Bug fixes</dt>
+<dd>Fixed many bugs and added <a
+href="http://tools.android.com/recent/miscellaneousrecentfixes">minor improvements</a>, in
+particular some <a href="http://tools.android.com/recent/linuxfixes">critical bug fixes on
+Linux</a>.</dd>
+
+</div>
+</div>
+
+
+
+<div class="toggleable closed">
+  <a href="#" onclick="return toggleDiv(this)">
+        <img src="{@docRoot}assets/images/triangle-closed.png" class="toggle-img" height="9px"
+width="9px" />
 ADT 12.0.0</a> <em>(July 2011)</em>
   <div class="toggleme">
 <dl>
@@ -141,7 +259,7 @@
 <dt>Build system</dt>
 <dd>
 <ul>
-  <li>A new option lets you disable the packaging step in the automatic
+  <li id="build-option">A new option lets you disable the packaging step in the automatic
   builders. This improves performance when saving files by not
   performing a full build, which can take a long time for large projects.
   If the option is enabled, the APK is packaged when the
@@ -225,7 +343,7 @@
 href="http://tools.android.com/recent/customviewsinthepalette">more info</a>).</li>
     <li>Fragments are available in the palette for placement in your layout. In the tool, you can
 choose which layout to show rendered for a given fragment tag. Go to declaration works for fragment
-classes (<a href="http://tools.android.com/recent/fragmentsupport">more info</a>).</li> 
+classes (<a href="http://tools.android.com/recent/fragmentsupport">more info</a>).</li>
     <li>The layout editor automatically applies a "zoom to fit" for newly
     opened files as well as on device size and orientation changes to
     ensure that large layouts are always fully visible unless you
@@ -253,7 +371,7 @@
 
 <dt>XML editors:</dt>
 <dd>
-<ul>  
+<ul>
   <li>Code completion has been significantly improved. It now works
   with {@code &lt;style&gt;} elements, completes dimensional units,
   sorts resource paths in values based on the attribute name, and more. There are also many fixes to
@@ -270,7 +388,7 @@
 
 <dt>DDMS:</dt>
 <dd>
-<ul>  
+<ul>
   <li>"New Folder" action in the File Explorer.</li>
   <li>The screenshot dialog will add timestamps to the filenames and preserve the orientation on
 snapshot refresh.</li>
@@ -367,7 +485,7 @@
         (<a href="http://tools.android.com/recent/improvedsupportformergetags">details</a>).</li>
         <li>Improved rendering error diagnostics.</li>
       </ul>
-    </li>    
+    </li>
   </ul>
 </dd>
 </dl>
@@ -391,14 +509,14 @@
 
 <dt>General notes:</dt>
 <dd>
-  <ul>    
+  <ul>
     <li>"Go To Declaration" hyperlink support: You can jump directly from code references (such as
     <code>R.id.main</code>) to the corresponding XML declaration, or from XML attributes (such as
     <code>@string</code>) to the corresponding resource definition, or from manifest XML
     registrations to activities and services.</li>
     <li>Improvements were made to name refactoring.</li>
     <li>AVDs now automatically save their state, so they can restart almost instantly. You can enable this feature when
-    creating an AVD or by editing an AVD with the AVD Manager.</li> 
+    creating an AVD or by editing an AVD with the AVD Manager.</li>
     <li>Improvements to the Visual Layout Editor:
       <ul>
         <li>Support for rendering targets: You can now choose an arbitrary Android platform to
@@ -436,10 +554,10 @@
         into an {@link android.widget.AdapterView}.</li>
         <li>Outline reordering: Reordering your views in the Outline tab is much easier
         (<a href="http://tools.android.com/recent/outlineimprovements">Details</a>).</li>
-        <li>Fix for keybinding bug where keyboard shortcuts did not work (Issues 
-        <a href="http://code.google.com/p/android/issues/detail?id=13231">13231</a> and 
+        <li>Fix for keybinding bug where keyboard shortcuts did not work (Issues
+        <a href="http://code.google.com/p/android/issues/detail?id=13231">13231</a> and
         <a href="http://code.google.com/p/android/issues/detail?id=13134">13134</a>).</li>
-        <li>Fix for problems with Custom layout attribute menu (Issue 
+        <li>Fix for problems with Custom layout attribute menu (Issue
         <a href="http://code.google.com/p/android/issues/detail?id=13134">13134</a>).</li>
         <li>Automatic configuration for various view types: Certain views have properties configured
         by default. For example, the width of an {@link android.widget.EditText} object is set to
@@ -455,7 +573,7 @@
         and <a href="http://code.google.com/p/android/issues/detail?id=13092">13092</a>).</li>
         <li>Included layouts can be rendered and edited in the context of the layouts that include
         them. From a layout using an <a href="{@docRoot}guide/topics/resources/layout-resource.html#include-element">
-        <code>&lt;include&gt;</code></a> tag, double-clicking on the 
+        <code>&lt;include&gt;</code></a> tag, double-clicking on the
         <a href="{@docRoot}guide/topics/resources/layout-resource.html#include-element">
         <code>&lt;include&gt;</code></a> element edits the referenced layout in the context of the
         current layout. Additionally, when editing a layout that is included by other layouts,
@@ -466,12 +584,12 @@
     <li>This release fixes many other bugs, but the most important ones are listed below:
   <ul>
    <li>Fixed issue that prevented launching debug builds on productions devices when
-    <code>debuggable=true</code> was not set in the Android manifest.</li>    
+    <code>debuggable=true</code> was not set in the Android manifest.</li>
     <li>The LogCat view in DDMS properly handles UTF-8 characters.</li>
     <li>The SDK Manager is more reliable on Windows
     (<a href="http://tools.android.com/recent/sdkmanagerfixes">Details</a>).</li>
-    <li>A JUnit initialization bug that prevented you from working with JUnit tests was fixed 
-    (Issue <a href="http://code.google.com/p/android/issues/detail?id=12411">12411</a>).</li>   
+    <li>A JUnit initialization bug that prevented you from working with JUnit tests was fixed
+    (Issue <a href="http://code.google.com/p/android/issues/detail?id=12411">12411</a>).</li>
   </ul>
 </li>
   </ul>
@@ -828,7 +946,7 @@
 
 <ul>
 <li>If Eclipse is already installed on your computer, make sure that it is
-a version that is compatible with ADT and the Android SDK. 
+a version that is compatible with ADT and the Android SDK.
 
 <li>If you need to install or update Eclipse, you can download it from this
 location:
diff --git a/docs/html/sdk/index.jd b/docs/html/sdk/index.jd
index 105c868..065f41b 100644
--- a/docs/html/sdk/index.jd
+++ b/docs/html/sdk/index.jd
@@ -1,21 +1,21 @@
 page.title=Android SDK
 sdk.redirect=0
 
-sdk.win_installer=installer_r13-windows.exe
-sdk.win_installer_bytes=36533357
-sdk.win_installer_checksum=cd3a76fe2b8ed62b2d03cf1851692e2d
+sdk.win_installer=installer_r14-windows.exe
+sdk.win_installer_bytes=33860145
+sdk.win_installer_checksum=7a563491bf4671d09b9da0dcde85f212
 
-sdk.win_download=android-sdk_r13-windows.zip
-sdk.win_bytes=36487911
-sdk.win_checksum=de8a039891e5e65b7742f188f07b992d
+sdk.win_download=android-sdk_r14-windows.zip
+sdk.win_bytes=33852972
+sdk.win_checksum=d1381a0cc8e6f9358174aa6d051ba379
 
-sdk.mac_download=android-sdk_r13-mac_x86.zip
-sdk.mac_bytes=30233944
-sdk.mac_checksum=f4002a0344b48856c09dec796acecd4d
+sdk.mac_download=android-sdk_r14-macosx.zip
+sdk.mac_bytes=30426052
+sdk.mac_checksum=df0a5c5b5327ffcaf256ce735998e12a
 
-sdk.linux_download=android-sdk_r13-linux_x86.tgz
-sdk.linux_bytes=30034328
-sdk.linux_checksum=d80d7530a46c665644ae76084a9a0dc4
+sdk.linux_download=android-sdk_r14-linux.tgz
+sdk.linux_bytes=26083315
+sdk.linux_checksum=2049d5c1a164fcae47a5e93c52200752
 
 @jd:body
 
@@ -39,7 +39,7 @@
 <style type="text/css">
   .offline-message { display:none; }
 </style>
-      
+
 <p class="offline-message">For more information about how to set up your
 development environment, read the guide to <a href="installing.html">Installing the SDK</a>.</p>
 
diff --git a/docs/html/sdk/sdk_toc.cs b/docs/html/sdk/sdk_toc.cs
index 8a57312..9bc9b9a 100644
--- a/docs/html/sdk/sdk_toc.cs
+++ b/docs/html/sdk/sdk_toc.cs
@@ -22,7 +22,7 @@
           <span style="display:none" class="ja">ダウンロード</span>
           <span style="display:none" class="zh-CN">下载</span>
           <span style="display:none" class="zh-TW">下載</span>
-        </a></li><?cs 
+        </a></li><?cs
   /if ?>
       <li><a href="<?cs var:toroot ?>sdk/installing.html">
           <span class="en">Installing the SDK</span>
@@ -76,6 +76,14 @@
     </ul>
     <ul>
       <li class="toggle-list">
+        <div><a href="<?cs var:toroot ?>sdk/android-4.0.html">
+        <span class="en">Android 4.0 Platform</span></a> <span class="new">new!</span></div>
+        <ul>
+          <!-- <li><a href="<?cs var:toroot ?>sdk/android-4.0-highlights.html">Platform Highlights</a></li> -->
+          <li><a href="<?cs var:toroot ?>sdk/api_diff/14/changes.html">API Differences Report &raquo;</a></li>
+        </ul>
+      </li>
+      <li class="toggle-list">
         <div><a href="<?cs var:toroot ?>sdk/android-3.2.html">
         <span class="en">Android 3.2 Platform</span></a></div>
         <ul>
@@ -87,7 +95,7 @@
         <div><a href="<?cs var:toroot ?>sdk/android-3.1.html">
         <span class="en">Android 3.1 Platform</span></a></div>
         <ul>
-          <li><a href="<?cs var:toroot ?>sdk/android-3.1-highlights.html">Platform Highlights</a></li> 
+          <li><a href="<?cs var:toroot ?>sdk/android-3.1-highlights.html">Platform Highlights</a></li>
           <li><a href="<?cs var:toroot ?>sdk/api_diff/12/changes.html">API Differences Report &raquo;</a></li>
         </ul>
       </li>
@@ -95,7 +103,7 @@
         <div><a href="<?cs var:toroot ?>sdk/android-3.0.html">
         <span class="en">Android 3.0 Platform</span></a></div>
         <ul>
-          <li><a href="<?cs var:toroot ?>sdk/android-3.0-highlights.html">Platform Highlights</a></li> 
+          <li><a href="<?cs var:toroot ?>sdk/android-3.0-highlights.html">Platform Highlights</a></li>
           <li><a href="<?cs var:toroot ?>sdk/api_diff/11/changes.html">API Differences Report &raquo;</a></li>
         </ul>
       </li>
@@ -104,14 +112,14 @@
       <div><a href="<?cs var:toroot ?>sdk/android-2.3.3.html">
       <span class="en">Android 2.3.3 Platform</span></a></div>
         <ul>
-          <li><a href="<?cs var:toroot ?>sdk/api_diff/10/changes.html">API Differences Report &raquo;</a></li> 
+          <li><a href="<?cs var:toroot ?>sdk/api_diff/10/changes.html">API Differences Report &raquo;</a></li>
         </ul>
       </li>
       <li class="toggle-list">
         <div><a href="<?cs var:toroot ?>sdk/android-2.2.html">
         <span class="en">Android 2.2 Platform</span></a></div>
         <ul>
-          <li><a href="<?cs var:toroot ?>sdk/android-2.2-highlights.html">Platform Highlights</a></li> 
+          <li><a href="<?cs var:toroot ?>sdk/android-2.2-highlights.html">Platform Highlights</a></li>
           <li><a href="<?cs var:toroot ?>sdk/api_diff/8/changes.html">API Differences Report &raquo;</a></li>
         </ul>
       </li>
@@ -129,8 +137,8 @@
             <div><a href="<?cs var:toroot ?>sdk/android-2.3.html">
             <span class="en">Android 2.3 Platform</span></a></div>
               <ul>
-                <li><a href="<?cs var:toroot ?>sdk/android-2.3-highlights.html">Platform Highlights</a></li> 
-                <li><a href="<?cs var:toroot ?>sdk/api_diff/9/changes.html">API Differences Report &raquo;</a></li> 
+                <li><a href="<?cs var:toroot ?>sdk/android-2.3-highlights.html">Platform Highlights</a></li>
+                <li><a href="<?cs var:toroot ?>sdk/api_diff/9/changes.html">API Differences Report &raquo;</a></li>
               </ul>
           </li>
           <li><a href="<?cs var:toroot ?>sdk/android-2.0.1.html">Android 2.0.1 Platform</a></li>
@@ -142,7 +150,7 @@
       </li>
     </ul>
     <ul>
-      <li><a href="<?cs var:toroot ?>sdk/tools-notes.html">SDK Tools, r13</a> <span
+      <li><a href="<?cs var:toroot ?>sdk/tools-notes.html">SDK Tools, r14</a> <span
 class="new">new!</span></li>
       <li><a href="<?cs var:toroot ?>sdk/win-usb.html">Google USB Driver, r4</a></li>
       <li><a href="<?cs var:toroot ?>sdk/compatibility-library.html">Compatibility Package,
@@ -161,14 +169,15 @@
       <span style="display:none" class="zh-TW"></span>
       </h2>
     <ul>
-      <li><a href="<?cs var:toroot ?>sdk/eclipse-adt.html">ADT 12.0.0
+      <li><a href="<?cs var:toroot ?>sdk/eclipse-adt.html">ADT 14.0.0
       <span style="display:none" class="de"></span>
       <span style="display:none" class="es"></span>
       <span style="display:none" class="fr"></span>
       <span style="display:none" class="it"></span>
       <span style="display:none" class="ja"></span>
       <span style="display:none" class="zh-CN"></span>
-      <span style="display:none" class="zh-TW"></span></a>
+      <span style="display:none" class="zh-TW"></span></a> <span
+class="new">new!</span>
       </li>
     </ul>
   </li>
diff --git a/docs/html/sdk/tools-notes.jd b/docs/html/sdk/tools-notes.jd
index 2179cec..2d044ed 100644
--- a/docs/html/sdk/tools-notes.jd
+++ b/docs/html/sdk/tools-notes.jd
@@ -2,7 +2,7 @@
 @jd:body
 
 <p>SDK Tools is a downloadable component for the Android SDK. It includes the
-complete set of development and debugging tools for the Android SDK. </p>
+complete set of development and debugging tools for the Android SDK.</p>
 
 <p>If you are new to the Android SDK, the <a
 href="{@docRoot}sdk/index.html">SDK starter package</a> installs the
@@ -13,7 +13,7 @@
 update, rather than downloading a new SDK starter package. For more information
 about how to update, see <a
 href="{@docRoot}sdk/adding-components.html#UpdatingComponents">Updating SDK
-Components</a>. </p>
+Components</a>.</p>
 
 
 <h2 id="notes">Revisions</h2>
@@ -62,10 +62,56 @@
 }
 </style>
 
-
 <div class="toggleable opened">
   <a href="#" onclick="return toggleDiv(this)">
-        <img src="{@docRoot}assets/images/triangle-opened.png" class="toggle-img" height="9px" width="9px" />
+    <img src="{@docRoot}assets/images/triangle-opened.png" class="toggle-img" height="9px"
+    width="9px" />SDK Tools, Revision 14</a> <em>(October 2011)</em>
+  <div class="toggleme">
+  <dl>
+<dt>Dependencies:</dt>
+<dd>
+  <ul><li>Android SDK Platform-tools revision 8 or later.</li>
+  <li>If you are developing in Eclipse with ADT, note that the SDK Tools r14 is designed for use
+  with ADT 14.0.0 and later. If you haven't already, we highly recommend updating your <a
+  href="{@docRoot}sdk/eclipse-adt.html">ADT Plugin</a> to 14.0.0.</li>
+  <li>If you are developing outside Eclipse, you must have <a href="http://ant.apache.org/">Apache
+  Ant</a> 1.8 or later.</li>
+</ul>
+
+<dt>General notes:</dt>
+<dd>
+  <ul>
+     <li>Changed <code>default.properties</code> to <code>project.properties</code> and
+    <code>build.properties</code> to <code>ant.properties</code>. Any existing
+    projects that you build with Ant must be updated with the <code>android update project</code>
+    command.</li>
+    <li>Changed Ant <code>build.xml</code> file to support improvements to the
+    build system and added and modified Ant commands to support these changes. For a list of Ant
+commands, see the
+<a href="{@docRoot}guide/developing/building/building-cmdline.html#AntReference">Ant Command
+Reference</a>.</li>
+
+    <li>Changed how library projects are built.</a></li>
+    <li>Improved incremental builds, so that resource compilation runs less frequently. Builds no
+    longer run when you edit strings or layouts (unless you add a new <code>id</code>) and no longer
+    run once for each library project.</li>
+    <li>Introduced a "PNG crunch cache" that only runs on modified PNG files, instead of
+    crunching all existing PNG files, all the time.</li>
+    <li>Revamped the SDK Manager UI (<a href="http://tools.android.com/recent/newsdkmanager">more
+info</a>).</li>
+  </ul>
+  <p>For a complete overview of the build system changes and what you need to do to support them,
+see the <a href="http://tools.android.com/recent/buildchangesinrevision14">Android Tools Project
+site</a>.</p>
+</dd>
+</dl>
+</div>
+</div>
+
+<div class="toggleable closed">
+  <a href="#" onclick="return toggleDiv(this)">
+        <img src="{@docRoot}assets/images/triangle-closed.png" class="toggle-img" height="9px"
+        width="9px" />
 SDK Tools, Revision 13</a> <em>(September 2011)</em>
   <div class="toggleme">
   <dl>
diff --git a/graphics/java/android/renderscript/RenderScript.java b/graphics/java/android/renderscript/RenderScript.java
index e2950d5e..d3d65a3 100644
--- a/graphics/java/android/renderscript/RenderScript.java
+++ b/graphics/java/android/renderscript/RenderScript.java
@@ -865,13 +865,7 @@
     }
 
     static int getTargetSdkVersion(Context ctx) {
-        try {
-            PackageManager pm = ctx.getPackageManager();
-            ApplicationInfo app = pm.getApplicationInfo(ctx.getPackageName(), 0);
-            return app.targetSdkVersion;
-        } catch (Exception e) {
-            throw new RSDriverException("Error calculating target SDK version for RS.");
-        }
+        return ctx.getApplicationInfo().targetSdkVersion;
     }
 
     /**
diff --git a/include/android_runtime/AndroidRuntime.h b/include/android_runtime/AndroidRuntime.h
index 32cd4f5..fd33d59 100644
--- a/include/android_runtime/AndroidRuntime.h
+++ b/include/android_runtime/AndroidRuntime.h
@@ -31,8 +31,6 @@
 
 namespace android {
 
-class CursorWindow;
-
 class AndroidRuntime
 {
 public:
@@ -133,8 +131,6 @@
     static int javaThreadShell(void* args);
 };
 
-extern CursorWindow * get_window_from_object(JNIEnv * env, jobject javaWindow);
-
 }
 
 #endif
diff --git a/include/binder/CursorWindow.h b/include/binder/CursorWindow.h
index f0b2909..d227244 100644
--- a/include/binder/CursorWindow.h
+++ b/include/binder/CursorWindow.h
@@ -143,8 +143,6 @@
                          */
     uint32_t            alloc(size_t size, bool aligned = false);
 
-    uint32_t            read_field_slot(int row, int column, field_slot_t * slot);
-
                         /**
                          * Copy data into the window at the given offset.
                          */
@@ -181,6 +179,32 @@
                                 return ((field_slot_t *)offsetToPtr(fieldDirOffset)) + column;
                             }
 
+    int64_t getFieldSlotValueLong(field_slot_t* fieldSlot) {
+#if WINDOW_STORAGE_INLINE_NUMERICS
+        return fieldSlot->data.l;
+#else
+        return copyOutLong(fieldSlot->data.buffer.offset);
+#endif
+    }
+
+    double getFieldSlotValueDouble(field_slot_t* fieldSlot) {
+#if WINDOW_STORAGE_INLINE_NUMERICS
+        return fieldSlot->data.d;
+#else
+        return copyOutDouble(fieldSlot->data.buffer.offset);
+#endif
+    }
+
+#if WINDOW_STORAGE_UTF8
+    char* getFieldSlotValueString(field_slot_t* fieldSlot) {
+        return reinterpret_cast<char*>(offsetToPtr(fieldSlot->data.buffer.offset));
+    }
+#else
+    char16_t* getFieldSlotValueString(field_slot_t* fieldSlot) {
+        return reinterpret_cast<char16_t*>(offsetToPtr(fieldSlot->data.buffer.offset));
+    }
+#endif
+
 private:
     uint8_t * mData;
     size_t mSize;
diff --git a/libs/binder/CursorWindow.cpp b/libs/binder/CursorWindow.cpp
index 47bbd04..b02374f 100644
--- a/libs/binder/CursorWindow.cpp
+++ b/libs/binder/CursorWindow.cpp
@@ -236,33 +236,6 @@
   return ((field_slot_t *)offsetToPtr(fieldDirOffset)) + column;  
 }
 
-uint32_t CursorWindow::read_field_slot(int row, int column, field_slot_t * slotOut)
-{
-    if (row < 0 || row >= mHeader->numRows || column < 0 || column >= mHeader->numColumns) {
-        LOGE("Can't read row# %d, col# %d from CursorWindow. Make sure your Cursor is initialized correctly.",
-                row, column);
-        return -1;
-    }        
-    row_slot_t * rowSlot = getRowSlot(row);
-    if (!rowSlot) {
-        LOGE("Failed to find rowSlot for row %d", row);
-        return -1;
-    }
-    if (rowSlot->offset == 0 || rowSlot->offset >= mSize) {
-        LOGE("Invalid rowSlot, offset = %d", rowSlot->offset);
-        return -1;
-    }
-LOG_WINDOW("Found field directory for %d,%d at rowSlot %d, offset %d", row, column, (uint8_t *)rowSlot - mData, rowSlot->offset);
-    field_slot_t * fieldDir = (field_slot_t *)offsetToPtr(rowSlot->offset);
-LOG_WINDOW("Read field_slot_t %d,%d: offset = %d, size = %d, type = %d", row, column, fieldDir[column].data.buffer.offset, fieldDir[column].data.buffer.size, fieldDir[column].type);
-
-    // Copy the data to the out param
-    slotOut->data.buffer.offset = fieldDir[column].data.buffer.offset;
-    slotOut->data.buffer.size = fieldDir[column].data.buffer.size;
-    slotOut->type = fieldDir[column].type;
-    return 0;
-}
-
 void CursorWindow::copyIn(uint32_t offset, uint8_t const * data, size_t size)
 {
     assert(offset + size <= mSize);    
@@ -370,12 +343,8 @@
     if (!fieldSlot || fieldSlot->type != FIELD_TYPE_INTEGER) {
         return false;
     }
-    
-#if WINDOW_STORAGE_INLINE_NUMERICS
-    *valueOut = fieldSlot->data.l;
-#else
-    *valueOut = copyOutLong(fieldSlot->data.buffer.offset);
-#endif
+
+    *valueOut = getFieldSlotValueLong(fieldSlot);
     return true;
 }
 
@@ -386,11 +355,7 @@
         return false;
     }
 
-#if WINDOW_STORAGE_INLINE_NUMERICS
-    *valueOut = fieldSlot->data.d;
-#else
-    *valueOut = copyOutDouble(fieldSlot->data.buffer.offset);
-#endif
+    *valueOut = getFieldSlotValueDouble(fieldSlot);
     return true;
 }
 
diff --git a/media/libmediaplayerservice/StagefrightRecorder.cpp b/media/libmediaplayerservice/StagefrightRecorder.cpp
index 6fdb726..6981668 100644
--- a/media/libmediaplayerservice/StagefrightRecorder.cpp
+++ b/media/libmediaplayerservice/StagefrightRecorder.cpp
@@ -554,7 +554,7 @@
 }
 
 status_t StagefrightRecorder::setParamGeoDataLongitude(
-    int32_t longitudex10000) {
+    int64_t longitudex10000) {
 
     if (longitudex10000 > 1800000 || longitudex10000 < -1800000) {
         return BAD_VALUE;
@@ -564,7 +564,7 @@
 }
 
 status_t StagefrightRecorder::setParamGeoDataLatitude(
-    int32_t latitudex10000) {
+    int64_t latitudex10000) {
 
     if (latitudex10000 > 900000 || latitudex10000 < -900000) {
         return BAD_VALUE;
@@ -602,13 +602,13 @@
             return setParam64BitFileOffset(use64BitOffset != 0);
         }
     } else if (key == "param-geotag-longitude") {
-        int32_t longitudex10000;
-        if (safe_strtoi32(value.string(), &longitudex10000)) {
+        int64_t longitudex10000;
+        if (safe_strtoi64(value.string(), &longitudex10000)) {
             return setParamGeoDataLongitude(longitudex10000);
         }
     } else if (key == "param-geotag-latitude") {
-        int32_t latitudex10000;
-        if (safe_strtoi32(value.string(), &latitudex10000)) {
+        int64_t latitudex10000;
+        if (safe_strtoi64(value.string(), &latitudex10000)) {
             return setParamGeoDataLatitude(latitudex10000);
         }
     } else if (key == "param-track-time-status") {
diff --git a/media/libmediaplayerservice/StagefrightRecorder.h b/media/libmediaplayerservice/StagefrightRecorder.h
index 5c5f05c..ec5ce7e 100644
--- a/media/libmediaplayerservice/StagefrightRecorder.h
+++ b/media/libmediaplayerservice/StagefrightRecorder.h
@@ -173,8 +173,8 @@
     status_t setParamMaxFileDurationUs(int64_t timeUs);
     status_t setParamMaxFileSizeBytes(int64_t bytes);
     status_t setParamMovieTimeScale(int32_t timeScale);
-    status_t setParamGeoDataLongitude(int32_t longitudex10000);
-    status_t setParamGeoDataLatitude(int32_t latitudex10000);
+    status_t setParamGeoDataLongitude(int64_t longitudex10000);
+    status_t setParamGeoDataLatitude(int64_t latitudex10000);
     void clipVideoBitRate();
     void clipVideoFrameRate();
     void clipVideoFrameWidth();
diff --git a/media/libstagefright/NuCachedSource2.cpp b/media/libstagefright/NuCachedSource2.cpp
index 4edb613..9adb841 100644
--- a/media/libstagefright/NuCachedSource2.cpp
+++ b/media/libstagefright/NuCachedSource2.cpp
@@ -21,6 +21,7 @@
 #include "include/NuCachedSource2.h"
 #include "include/HTTPBase.h"
 
+#include <cutils/properties.h>
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/foundation/AMessage.h>
 #include <media/stagefright/MediaErrors.h>
@@ -186,7 +187,12 @@
       mLastAccessPos(0),
       mFetching(true),
       mLastFetchTimeUs(-1),
-      mNumRetriesLeft(kMaxNumRetries) {
+      mNumRetriesLeft(kMaxNumRetries),
+      mHighwaterThresholdBytes(kDefaultHighWaterThreshold),
+      mLowwaterThresholdBytes(kDefaultLowWaterThreshold),
+      mKeepAliveIntervalUs(kDefaultKeepAliveIntervalUs) {
+    updateCacheParamsFromSystemProperty();
+
     mLooper->setName("NuCachedSource2");
     mLooper->registerHandler(mReflector);
     mLooper->start();
@@ -318,7 +324,8 @@
     bool keepAlive =
         !mFetching
             && mFinalStatus == OK
-            && ALooper::GetNowUs() >= mLastFetchTimeUs + kKeepAliveIntervalUs;
+            && mKeepAliveIntervalUs > 0
+            && ALooper::GetNowUs() >= mLastFetchTimeUs + mKeepAliveIntervalUs;
 
     if (mFetching || keepAlive) {
         if (keepAlive) {
@@ -329,7 +336,7 @@
 
         mLastFetchTimeUs = ALooper::GetNowUs();
 
-        if (mFetching && mCache->totalSize() >= kHighWaterThreshold) {
+        if (mFetching && mCache->totalSize() >= mHighwaterThresholdBytes) {
             LOGI("Cache full, done prefetching for now");
             mFetching = false;
         }
@@ -392,7 +399,7 @@
 
     if (!ignoreLowWaterThreshold && !force
             && mCacheOffset + mCache->totalSize() - mLastAccessPos
-                >= kLowWaterThreshold) {
+                >= mLowwaterThresholdBytes) {
         return;
     }
 
@@ -482,7 +489,7 @@
 }
 
 ssize_t NuCachedSource2::readInternal(off64_t offset, void *data, size_t size) {
-    CHECK_LE(size, (size_t)kHighWaterThreshold);
+    CHECK_LE(size, (size_t)mHighwaterThresholdBytes);
 
     LOGV("readInternal offset %lld size %d", offset, size);
 
@@ -580,4 +587,54 @@
     return mSource->getMIMEType();
 }
 
+void NuCachedSource2::updateCacheParamsFromSystemProperty() {
+    char value[PROPERTY_VALUE_MAX];
+    if (!property_get("media.stagefright.cache-params", value, NULL)) {
+        return;
+    }
+
+    updateCacheParamsFromString(value);
+}
+
+void NuCachedSource2::updateCacheParamsFromString(const char *s) {
+    ssize_t lowwaterMarkKb, highwaterMarkKb;
+    int keepAliveSecs;
+
+    if (sscanf(s, "%ld/%ld/%d",
+               &lowwaterMarkKb, &highwaterMarkKb, &keepAliveSecs) != 3) {
+        LOGE("Failed to parse cache parameters from '%s'.", s);
+        return;
+    }
+
+    if (lowwaterMarkKb >= 0) {
+        mLowwaterThresholdBytes = lowwaterMarkKb * 1024;
+    } else {
+        mLowwaterThresholdBytes = kDefaultLowWaterThreshold;
+    }
+
+    if (highwaterMarkKb >= 0) {
+        mHighwaterThresholdBytes = highwaterMarkKb * 1024;
+    } else {
+        mHighwaterThresholdBytes = kDefaultHighWaterThreshold;
+    }
+
+    if (mLowwaterThresholdBytes >= mHighwaterThresholdBytes) {
+        LOGE("Illegal low/highwater marks specified, reverting to defaults.");
+
+        mLowwaterThresholdBytes = kDefaultLowWaterThreshold;
+        mHighwaterThresholdBytes = kDefaultHighWaterThreshold;
+    }
+
+    if (keepAliveSecs >= 0) {
+        mKeepAliveIntervalUs = keepAliveSecs * 1000000ll;
+    } else {
+        mKeepAliveIntervalUs = kDefaultKeepAliveIntervalUs;
+    }
+
+    LOGV("lowwater = %d bytes, highwater = %d bytes, keepalive = %lld us",
+         mLowwaterThresholdBytes,
+         mHighwaterThresholdBytes,
+         mKeepAliveIntervalUs);
+}
+
 }  // namespace android
diff --git a/media/libstagefright/include/NuCachedSource2.h b/media/libstagefright/include/NuCachedSource2.h
index 22b2855..f04c566 100644
--- a/media/libstagefright/include/NuCachedSource2.h
+++ b/media/libstagefright/include/NuCachedSource2.h
@@ -63,13 +63,13 @@
     friend struct AHandlerReflector<NuCachedSource2>;
 
     enum {
-        kPageSize            = 65536,
-        kHighWaterThreshold  = 20 * 1024 * 1024,
-        kLowWaterThreshold   = 4 * 1024 * 1024,
+        kPageSize                       = 65536,
+        kDefaultHighWaterThreshold      = 20 * 1024 * 1024,
+        kDefaultLowWaterThreshold       = 4 * 1024 * 1024,
 
         // Read data after a 15 sec timeout whether we're actively
         // fetching or not.
-        kKeepAliveIntervalUs = 15000000,
+        kDefaultKeepAliveIntervalUs     = 15000000,
     };
 
     enum {
@@ -99,6 +99,12 @@
 
     int32_t mNumRetriesLeft;
 
+    size_t mHighwaterThresholdBytes;
+    size_t mLowwaterThresholdBytes;
+
+    // If the keep-alive interval is 0, keep-alives are disabled.
+    int64_t mKeepAliveIntervalUs;
+
     void onMessageReceived(const sp<AMessage> &msg);
     void onFetch();
     void onRead(const sp<AMessage> &msg);
@@ -112,6 +118,9 @@
     void restartPrefetcherIfNecessary_l(
             bool ignoreLowWaterThreshold = false, bool force = false);
 
+    void updateCacheParamsFromSystemProperty();
+    void updateCacheParamsFromString(const char *s);
+
     DISALLOW_EVIL_CONSTRUCTORS(NuCachedSource2);
 };
 
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index 989ccf7..9e1dec7 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -3497,8 +3497,7 @@
         // If there is no window focused, there will be nobody to handle the events
         // anyway, so just hang on in whatever state we're in until things settle down.
         if (mFocusedWindow != null) {
-            final WindowManager.LayoutParams params = mFocusedWindow.getAttrs();
-            final int visibility = params.systemUiVisibility | params.subtreeSystemUiVisibility;
+            final int visibility = mFocusedWindow.getSystemUiVisibility();
             mHandler.post(new Runnable() {
                     public void run() {
                         if (mStatusBarService == null) {
diff --git a/services/camera/libcameraservice/CameraHardwareInterface.h b/services/camera/libcameraservice/CameraHardwareInterface.h
index 31544b3..c3ced4c2 100644
--- a/services/camera/libcameraservice/CameraHardwareInterface.h
+++ b/services/camera/libcameraservice/CameraHardwareInterface.h
@@ -80,24 +80,33 @@
 
 class CameraHardwareInterface : public virtual RefBase {
 public:
-    CameraHardwareInterface(hw_module_t *module, const char *name)
+    CameraHardwareInterface(const char *name)
     {
         mDevice = 0;
         mName = name;
-        LOGI("Opening camera %s, this %p", name, this);
-        int rc = module->methods->open(module, name,
-                                       (hw_device_t **)&mDevice);
-        if (rc != OK)
-            LOGE("Could not open camera %s: %d", name, rc);
-        initHalPreviewWindow();
     }
 
     ~CameraHardwareInterface()
     {
         LOGI("Destroying camera %s", mName.string());
-        int rc = mDevice->common.close(&mDevice->common);
-        if (rc != OK)
-            LOGE("Could not close camera %s: %d", mName.string(), rc);
+        if(mDevice) {
+            int rc = mDevice->common.close(&mDevice->common);
+            if (rc != OK)
+                LOGE("Could not close camera %s: %d", mName.string(), rc);
+        }
+    }
+
+    status_t initialize(hw_module_t *module)
+    {
+        LOGI("Opening camera %s", mName.string());
+        int rc = module->methods->open(module, mName.string(),
+                                       (hw_device_t **)&mDevice);
+        if (rc != OK) {
+            LOGE("Could not open camera %s: %d", mName.string(), rc);
+            return rc;
+        }
+        initHalPreviewWindow();
+        return rc;
     }
 
     /** Set the ANativeWindow to which preview frames are sent */
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index b178fd9..f306e4a 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -133,6 +133,8 @@
 sp<ICamera> CameraService::connect(
         const sp<ICameraClient>& cameraClient, int cameraId) {
     int callingPid = getCallingPid();
+    sp<CameraHardwareInterface> hardware = NULL;
+
     LOG1("CameraService::connect E (pid %d, id %d)", callingPid, cameraId);
 
     if (!mModule) {
@@ -187,10 +189,13 @@
     char camera_device_name[10];
     snprintf(camera_device_name, sizeof(camera_device_name), "%d", cameraId);
 
-    client = new Client(this, cameraClient,
-                new CameraHardwareInterface(&mModule->common,
-                                            camera_device_name),
-                cameraId, info.facing, callingPid);
+    hardware = new CameraHardwareInterface(camera_device_name);
+    if (hardware->initialize(&mModule->common) != OK) {
+        hardware.clear();
+        return NULL;
+    }
+
+    client = new Client(this, cameraClient, hardware, cameraId, info.facing, callingPid);
     mClient[cameraId] = client;
     LOG1("CameraService::connect X");
     return client;
@@ -278,9 +283,20 @@
 // media players.
 
 static MediaPlayer* newMediaPlayer(const char *file) {
+    // Read the system property to determine if we have need to use the
+    // AUDIO_STREAM_ENFORCED_AUDIBLE type.
+    char value[PROPERTY_VALUE_MAX];
+    property_get("ro.camera.sound.forced", value, "0");
+    int audioStreamType;
+    if (strcmp(value, "0") != 0) {
+        audioStreamType = AUDIO_STREAM_ENFORCED_AUDIBLE;
+    } else {
+        audioStreamType = AUDIO_STREAM_MUSIC;
+    }
+
     MediaPlayer* mp = new MediaPlayer();
     if (mp->setDataSource(file, NULL) == NO_ERROR) {
-        mp->setAudioStreamType(AUDIO_STREAM_ENFORCED_AUDIBLE);
+        mp->setAudioStreamType(audioStreamType);
         mp->prepare();
     } else {
         LOGE("Failed to load CameraService sounds: %s", file);
@@ -849,16 +865,16 @@
     if (result != NO_ERROR) return result;
 
     if (cmd == CAMERA_CMD_SET_DISPLAY_ORIENTATION) {
-        // The orientation cannot be set during preview.
-        if (mHardware->previewEnabled()) {
-            return INVALID_OPERATION;
-        }
         // Mirror the preview if the camera is front-facing.
         orientation = getOrientation(arg1, mCameraFacing == CAMERA_FACING_FRONT);
         if (orientation == -1) return BAD_VALUE;
 
         if (mOrientation != orientation) {
             mOrientation = orientation;
+            if (mPreviewWindow != 0) {
+                native_window_set_buffers_transform(mPreviewWindow.get(),
+                        mOrientation);
+            }
         }
         return OK;
     } else if (cmd == CAMERA_CMD_ENABLE_SHUTTER_SOUND) {
diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java
index 8112b1d..ce31474 100644
--- a/services/java/com/android/server/ConnectivityService.java
+++ b/services/java/com/android/server/ConnectivityService.java
@@ -284,6 +284,9 @@
 
     // track the current default http proxy - tell the world if we get a new one (real change)
     private ProxyProperties mDefaultProxy = null;
+    private Object mDefaultProxyLock = new Object();
+    private boolean mDefaultProxyDisabled = false;
+
     // track the global proxy.
     private ProxyProperties mGlobalProxy = null;
     private final Object mGlobalProxyLock = new Object();
@@ -1770,7 +1773,7 @@
                 }
             }
             if (mNetConfigs[netType].isDefault()) {
-                handleApplyDefaultProxy(netType);
+                handleApplyDefaultProxy(newLp.getHttpProxy());
             }
         } else {
             if (VDBG) {
@@ -2549,10 +2552,10 @@
         return;
     }
 
-    public synchronized ProxyProperties getProxy() {
-        if (mGlobalProxy != null) return mGlobalProxy;
-        if (mDefaultProxy != null) return mDefaultProxy;
-        return null;
+    public ProxyProperties getProxy() {
+        synchronized (mDefaultProxyLock) {
+            return mDefaultProxyDisabled ? null : mDefaultProxy;
+        }
     }
 
     public void setGlobalProxy(ProxyProperties proxyProperties) {
@@ -2583,7 +2586,7 @@
         if (mGlobalProxy == null) {
             proxyProperties = mDefaultProxy;
         }
-        sendProxyBroadcast(proxyProperties);
+        //sendProxyBroadcast(proxyProperties);
     }
 
     private void loadGlobalProxy() {
@@ -2606,23 +2609,19 @@
         }
     }
 
-    private void handleApplyDefaultProxy(int type) {
-        // check if new default - push it out to all VM if so
-        ProxyProperties proxy = mNetTrackers[type].getLinkProperties().getHttpProxy();
-        synchronized (this) {
+    private void handleApplyDefaultProxy(ProxyProperties proxy) {
+        if (proxy != null && TextUtils.isEmpty(proxy.getHost())) {
+            proxy = null;
+        }
+        synchronized (mDefaultProxyLock) {
             if (mDefaultProxy != null && mDefaultProxy.equals(proxy)) return;
             if (mDefaultProxy == proxy) return;
-            if (proxy != null && !TextUtils.isEmpty(proxy.getHost())) {
-                mDefaultProxy = proxy;
-            } else {
-                mDefaultProxy = null;
+            mDefaultProxy = proxy;
+
+            if (!mDefaultProxyDisabled) {
+                sendProxyBroadcast(proxy);
             }
         }
-        if (VDBG) log("changing default proxy to " + proxy);
-
-        // global trumps default, if set, ignore this.
-        if (mGlobalProxy != null) return;
-        sendProxyBroadcast(proxy);
     }
 
     private void handleDeprecatedGlobalHttpProxy() {
@@ -2850,17 +2849,30 @@
                 bumpDns();
             }
 
-            // TODO: temporarily remove http proxy?
+            // Temporarily disable the default proxy.
+            synchronized (mDefaultProxyLock) {
+                mDefaultProxyDisabled = true;
+                if (mDefaultProxy != null) {
+                    sendProxyBroadcast(null);
+                }
+            }
+
+            // TODO: support proxy per network.
         }
 
         public void restore() {
             synchronized (mDnsLock) {
-                if (!mDnsOverridden) {
-                    return;
+                if (mDnsOverridden) {
+                    mDnsOverridden = false;
+                    mHandler.sendEmptyMessage(EVENT_RESTORE_DNS);
                 }
-                mDnsOverridden = false;
             }
-            mHandler.sendEmptyMessage(EVENT_RESTORE_DNS);
+            synchronized (mDefaultProxyLock) {
+                mDefaultProxyDisabled = false;
+                if (mDefaultProxy != null) {
+                    sendProxyBroadcast(mDefaultProxy);
+                }
+            }
         }
     }
 }
diff --git a/services/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/java/com/android/server/accessibility/AccessibilityManagerService.java
index ed8fa40..fd528cc 100644
--- a/services/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -298,16 +298,7 @@
                     super.onChange(selfChange);
 
                     synchronized (mLock) {
-                        mIsAccessibilityEnabled = Settings.Secure.getInt(
-                                mContext.getContentResolver(),
-                                Settings.Secure.ACCESSIBILITY_ENABLED, 0) == 1;
-                        if (mIsAccessibilityEnabled) {
-                            manageServicesLocked();
-                        } else {
-                            unbindAllServicesLocked();
-                        }
-                        updateInputFilterLocked();
-                        sendStateToClientsLocked();
+                        handleAccessibilityEnabledSettingChangedLocked();
                     }
                 }
             });
@@ -354,6 +345,7 @@
             client.asBinder().linkToDeath(new DeathRecipient() {
                 public void binderDied() {
                     synchronized (mLock) {
+                        addedClient.asBinder().unlinkToDeath(this, 0);
                         mClients.remove(addedClient);
                     }
                 }
@@ -445,10 +437,12 @@
             IAccessibilityInteractionConnection connection) throws RemoteException {
         synchronized (mLock) {
             final IWindow addedWindowToken = windowToken;
+            final IAccessibilityInteractionConnection addedConnection = connection;
             final int windowId = sNextWindowId++;
-            connection.asBinder().linkToDeath(new DeathRecipient() {
+            addedConnection.asBinder().linkToDeath(new DeathRecipient() {
                 public void binderDied() {
                     synchronized (mLock) {
+                        addedConnection.asBinder().unlinkToDeath(this, 0);
                         removeAccessibilityInteractionConnection(addedWindowToken);
                     }
                 }
@@ -485,21 +479,23 @@
         ComponentName componentName = new ComponentName("foo.bar",
                 "AutomationAccessibilityService");
         synchronized (mLock) {
-            Service oldService = mComponentNameToServiceMap.get(componentName);
-            if (oldService != null) {
-                tryRemoveServiceLocked(oldService);
+            // If an automation services is connected to the system all services are stopped
+            // so the automation one is the only one running. Settings are not changed so when
+            // the automation service goes away the state is restored from the settings.
+
+            // Disable all services.
+            final int runningServiceCount = mServices.size();
+            for (int i = 0; i < runningServiceCount; i++) {
+                Service runningService = mServices.get(i);
+                runningService.unbind();
             }
-            // Now this service is enabled.
-            mEnabledServices.add(componentName);
-            // Also make sure this service is the only one.
-            Settings.Secure.putString(mContext.getContentResolver(),
-                    Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
-                    componentName.flattenToString());
-            // This API is intended for testing so enable accessibility to make
-            // sure clients can start poking with the window content.
-            Settings.Secure.putInt(mContext.getContentResolver(),
-                    Settings.Secure.ACCESSIBILITY_ENABLED, 1);
+            // If necessary enable accessibility and announce that.
+            if (!mIsAccessibilityEnabled) {
+                mIsAccessibilityEnabled = true;
+                sendStateToClientsLocked();
+            }
         }
+        // Hook the automation service up.
         AccessibilityServiceInfo accessibilityServiceInfo = new AccessibilityServiceInfo();
         accessibilityServiceInfo.eventTypes = AccessibilityEvent.TYPES_ALL_MASK;
         accessibilityServiceInfo.feedbackType = AccessibilityServiceInfo.FEEDBACK_GENERIC;
@@ -717,11 +713,12 @@
      * Manages services by starting enabled ones and stopping disabled ones.
      */
     private void manageServicesLocked() {
+        unbindAutomationService();
         populateEnabledServicesLocked(mEnabledServices);
         final int enabledInstalledServicesCount = updateServicesStateLocked(mInstalledServices,
                 mEnabledServices);
         // No enabled installed services => disable accessibility to avoid
-        // sending accessibility events with no recipient across processes. 
+        // sending accessibility events with no recipient across processes.
         if (mIsAccessibilityEnabled && enabledInstalledServicesCount == 0) {
             Settings.Secure.putInt(mContext.getContentResolver(),
                     Settings.Secure.ACCESSIBILITY_ENABLED, 0);
@@ -744,6 +741,21 @@
     }
 
     /**
+     * Unbinds the automation service if such is running.
+     */
+    private void unbindAutomationService() {
+        List<Service> runningServices = mServices;
+        int runningServiceCount = mServices.size();
+        for (int i = 0; i < runningServiceCount; i++) {
+            Service service = runningServices.get(i);
+            if (service.mIsAutomation) {
+                 service.unbind();
+                 return;
+            }
+        }
+    }
+
+    /**
      * Populates a list with the {@link ComponentName}s of all enabled
      * {@link AccessibilityService}s.
      *
@@ -868,6 +880,22 @@
     }
 
     /**
+     * Updated the state based on the accessibility enabled setting.
+     */
+    private void handleAccessibilityEnabledSettingChangedLocked() {
+        mIsAccessibilityEnabled = Settings.Secure.getInt(
+                mContext.getContentResolver(),
+                Settings.Secure.ACCESSIBILITY_ENABLED, 0) == 1;
+        if (mIsAccessibilityEnabled) {
+            manageServicesLocked();
+        } else {
+            unbindAllServicesLocked();
+        }
+        updateInputFilterLocked();
+        sendStateToClientsLocked();
+    }
+
+    /**
      * This class represents an accessibility service. It stores all per service
      * data required for the service management, provides API for starting/stopping the
      * service and is responsible for adding/removing the service in the data structures
@@ -1171,7 +1199,13 @@
 
         public void binderDied() {
             synchronized (mLock) {
+                mService.unlinkToDeath(this, 0);
                 tryRemoveServiceLocked(this);
+                // We no longer have an automation service, so restore
+                // the state based on values in the settings database.
+                if (mIsAutomation) {
+                    handleAccessibilityEnabledSettingChangedLocked();
+                }
             }
         }
 
diff --git a/services/java/com/android/server/wm/Session.java b/services/java/com/android/server/wm/Session.java
index 2e0c9ab..10882f9 100644
--- a/services/java/com/android/server/wm/Session.java
+++ b/services/java/com/android/server/wm/Session.java
@@ -134,28 +134,28 @@
         }
     }
 
-    public int add(IWindow window, WindowManager.LayoutParams attrs,
+    public int add(IWindow window, int seq, WindowManager.LayoutParams attrs,
             int viewVisibility, Rect outContentInsets, InputChannel outInputChannel) {
-        return mService.addWindow(this, window, attrs, viewVisibility, outContentInsets,
+        return mService.addWindow(this, window, seq, attrs, viewVisibility, outContentInsets,
                 outInputChannel);
     }
     
-    public int addWithoutInputChannel(IWindow window, WindowManager.LayoutParams attrs,
+    public int addWithoutInputChannel(IWindow window, int seq, WindowManager.LayoutParams attrs,
             int viewVisibility, Rect outContentInsets) {
-        return mService.addWindow(this, window, attrs, viewVisibility, outContentInsets, null);
+        return mService.addWindow(this, window, seq, attrs, viewVisibility, outContentInsets, null);
     }
 
     public void remove(IWindow window) {
         mService.removeWindow(this, window);
     }
 
-    public int relayout(IWindow window, WindowManager.LayoutParams attrs,
+    public int relayout(IWindow window, int seq, WindowManager.LayoutParams attrs,
             int requestedWidth, int requestedHeight, int viewFlags,
             boolean insetsPending, Rect outFrame, Rect outContentInsets,
             Rect outVisibleInsets, Configuration outConfig, Surface outSurface) {
         if (false) Slog.d(WindowManagerService.TAG, ">>>>>> ENTERED relayout from "
                 + Binder.getCallingPid());
-        int res = mService.relayoutWindow(this, window, attrs,
+        int res = mService.relayoutWindow(this, window, seq, attrs,
                 requestedWidth, requestedHeight, viewFlags, insetsPending,
                 outFrame, outContentInsets, outVisibleInsets, outConfig, outSurface);
         if (false) Slog.d(WindowManagerService.TAG, "<<<<<< EXITING relayout to "
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index f1994d1..540c518 100644
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -1948,7 +1948,7 @@
         }
     }
     
-    public int addWindow(Session session, IWindow client,
+    public int addWindow(Session session, IWindow client, int seq,
             WindowManager.LayoutParams attrs, int viewVisibility,
             Rect outContentInsets, InputChannel outInputChannel) {
         int res = mPolicy.checkAddPermission(attrs);
@@ -2040,7 +2040,7 @@
             }
 
             win = new WindowState(this, session, client, token,
-                    attachedWindow, attrs, viewVisibility);
+                    attachedWindow, seq, attrs, viewVisibility);
             if (win.mDeathRecipient == null) {
                 // Client has apparently died, so there is no reason to
                 // continue.
@@ -2467,7 +2467,7 @@
         return null;
     }
 
-    public int relayoutWindow(Session session, IWindow client,
+    public int relayoutWindow(Session session, IWindow client, int seq,
             WindowManager.LayoutParams attrs, int requestedWidth,
             int requestedHeight, int viewVisibility, boolean insetsPending,
             Rect outFrame, Rect outContentInsets, Rect outVisibleInsets,
@@ -2477,13 +2477,13 @@
         boolean configChanged;
 
         // if they don't have this permission, mask out the status bar bits
+        int systemUiVisibility = 0;
         if (attrs != null) {
-            if (((attrs.systemUiVisibility|attrs.subtreeSystemUiVisibility)
-                    & StatusBarManager.DISABLE_MASK) != 0) {
+            systemUiVisibility = (attrs.systemUiVisibility|attrs.subtreeSystemUiVisibility);
+            if ((systemUiVisibility & StatusBarManager.DISABLE_MASK) != 0) {
                 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR)
                         != PackageManager.PERMISSION_GRANTED) {
-                    attrs.systemUiVisibility &= ~StatusBarManager.DISABLE_MASK;
-                    attrs.subtreeSystemUiVisibility &= ~StatusBarManager.DISABLE_MASK;
+                    systemUiVisibility &= ~StatusBarManager.DISABLE_MASK;
                 }
             }
         }
@@ -2496,6 +2496,9 @@
             }
             win.mRequestedWidth = requestedWidth;
             win.mRequestedHeight = requestedHeight;
+            if (attrs != null && seq == win.mSeq) {
+                win.mSystemUiVisibility = systemUiVisibility;
+            }
 
             if (attrs != null) {
                 mPolicy.adjustWindowParamsLw(attrs);
@@ -9095,13 +9098,27 @@
     @Override
     public void statusBarVisibilityChanged(int visibility) {
         mInputManager.setSystemUiVisibility(visibility);
+
         synchronized (mWindowMap) {
             final int N = mWindows.size();
             for (int i = 0; i < N; i++) {
                 WindowState ws = mWindows.get(i);
                 try {
-                    if (ws.getAttrs().hasSystemUiListeners) {
-                        ws.mClient.dispatchSystemUiVisibilityChanged(visibility);
+                    int curValue = ws.mSystemUiVisibility;
+                    int diff = curValue ^ visibility;
+                    // We are only interested in differences of one of the
+                    // clearable flags...
+                    diff &= View.SYSTEM_UI_CLEARABLE_FLAGS;
+                    // ...if it has actually been cleared.
+                    diff &= ~visibility;
+                    int newValue = (curValue&~diff) | (visibility&diff);
+                    if (newValue != curValue) {
+                        ws.mSeq++;
+                        ws.mSystemUiVisibility = newValue;
+                    }
+                    if (newValue != curValue || ws.mAttrs.hasSystemUiListeners) {
+                        ws.mClient.dispatchSystemUiVisibilityChanged(ws.mSeq,
+                                visibility, newValue, diff);
                     }
                 } catch (RemoteException e) {
                     // so sorry
diff --git a/services/java/com/android/server/wm/WindowState.java b/services/java/com/android/server/wm/WindowState.java
index 3640a15..47f74fb 100644
--- a/services/java/com/android/server/wm/WindowState.java
+++ b/services/java/com/android/server/wm/WindowState.java
@@ -76,8 +76,10 @@
     final boolean mIsImWindow;
     final boolean mIsWallpaper;
     final boolean mIsFloatingLayer;
+    int mSeq;
     boolean mEnforceSizeCompat;
     int mViewVisibility;
+    int mSystemUiVisibility;
     boolean mPolicyVisibility = true;
     boolean mPolicyVisibilityAfterAnim = true;
     boolean mAppFreezing;
@@ -282,7 +284,7 @@
     boolean mWasPaused;
 
     WindowState(WindowManagerService service, Session s, IWindow c, WindowToken token,
-           WindowState attachedWindow, WindowManager.LayoutParams a,
+           WindowState attachedWindow, int seq, WindowManager.LayoutParams a,
            int viewVisibility) {
         mService = service;
         mSession = s;
@@ -292,6 +294,7 @@
         mViewVisibility = viewVisibility;
         DeathRecipient deathRecipient = new DeathRecipient();
         mAlpha = a.alpha;
+        mSeq = seq;
         mEnforceSizeCompat = (mAttrs.flags & FLAG_COMPATIBLE_WINDOW) != 0;
         if (WindowManagerService.localLOGV) Slog.v(
             WindowManagerService.TAG, "Window " + this + " client=" + c.asBinder()
@@ -551,6 +554,10 @@
         return mAttrs;
     }
 
+    public int getSystemUiVisibility() {
+        return mSystemUiVisibility;
+    }
+
     public int getSurfaceLayer() {
         return mLayer;
     }
@@ -1597,6 +1604,9 @@
             pw.print(" mLastHidden="); pw.print(mLastHidden);
             pw.print(" mHaveFrame="); pw.print(mHaveFrame);
             pw.print(" mObscured="); pw.println(mObscured);
+            pw.print(prefix); pw.print("mSeq="); pw.print(mSeq);
+            pw.print(" mSystemUiVisibility=0x");
+            pw.println(Integer.toHexString(mSystemUiVisibility));
         }
         if (!mPolicyVisibility || !mPolicyVisibilityAfterAnim || mAttachedHidden) {
             pw.print(prefix); pw.print("mPolicyVisibility=");
diff --git a/telephony/java/android/telephony/SmsManager.java b/telephony/java/android/telephony/SmsManager.java
index 5bdc146..44bdaeb 100644
--- a/telephony/java/android/telephony/SmsManager.java
+++ b/telephony/java/android/telephony/SmsManager.java
@@ -325,7 +325,7 @@
      *
      * {@hide}
      */
-    public ArrayList<SmsMessage> getAllMessagesFromIcc() {
+    public static ArrayList<SmsMessage> getAllMessagesFromIcc() {
         List<SmsRawData> records = null;
 
         try {
@@ -470,7 +470,7 @@
      *   <code>getAllMessagesFromIcc</code>
      * @return <code>ArrayList</code> of <code>SmsMessage</code> objects.
      */
-    private ArrayList<SmsMessage> createMessageListFromRawRecords(List<SmsRawData> records) {
+    private static ArrayList<SmsMessage> createMessageListFromRawRecords(List<SmsRawData> records) {
         ArrayList<SmsMessage> messages = new ArrayList<SmsMessage>();
         if (records != null) {
             int count = records.size();
diff --git a/telephony/java/android/telephony/SmsMessage.java b/telephony/java/android/telephony/SmsMessage.java
index e75d96d..fc8a145 100644
--- a/telephony/java/android/telephony/SmsMessage.java
+++ b/telephony/java/android/telephony/SmsMessage.java
@@ -36,7 +36,6 @@
  * A Short Message Service message.
  */
 public class SmsMessage {
-    private static final boolean LOCAL_DEBUG = true;
     private static final String LOG_TAG = "SMS";
 
     /**
@@ -78,6 +77,18 @@
      */
     public static final int MAX_USER_DATA_SEPTETS_WITH_HEADER = 153;
 
+    /**
+     * Indicates a 3GPP format SMS message.
+     * @hide pending API council approval
+     */
+    public static final String FORMAT_3GPP = "3gpp";
+
+    /**
+     * Indicates a 3GPP2 format SMS message.
+     * @hide pending API council approval
+     */
+    public static final String FORMAT_3GPP2 = "3gpp2";
+
     /** Contains actual SmsMessage. Only public for debugging and for framework layer.
      *
      * @hide
@@ -106,30 +117,47 @@
 
     }
 
-    /**
-     * Constructor
-     *
-     * @hide
-     */
-    public SmsMessage() {
-        this(getSmsFacility());
-    }
-
     private SmsMessage(SmsMessageBase smb) {
         mWrappedSmsMessage = smb;
     }
 
     /**
      * Create an SmsMessage from a raw PDU.
+     *
+     * <p><b>This method will soon be deprecated</b> and all applications which handle
+     * incoming SMS messages by processing the {@code SMS_RECEIVED_ACTION} broadcast
+     * intent <b>must</b> now pass the new {@code format} String extra from the intent
+     * into the new method {@code createFromPdu(byte[], String)} which takes an
+     * extra format parameter. This is required in order to correctly decode the PDU on
+     * devices that require support for both 3GPP and 3GPP2 formats at the same time,
+     * such as dual-mode GSM/CDMA and CDMA/LTE phones.
      */
     public static SmsMessage createFromPdu(byte[] pdu) {
-        SmsMessageBase wrappedMessage;
         int activePhone = TelephonyManager.getDefault().getCurrentPhoneType();
+        String format = (PHONE_TYPE_CDMA == activePhone) ? FORMAT_3GPP2 : FORMAT_3GPP;
+        return createFromPdu(pdu, format);
+    }
 
-        if (PHONE_TYPE_CDMA == activePhone) {
+    /**
+     * Create an SmsMessage from a raw PDU with the specified message format. The
+     * message format is passed in the {@code SMS_RECEIVED_ACTION} as the {@code format}
+     * String extra, and will be either "3gpp" for GSM/UMTS/LTE messages in 3GPP format
+     * or "3gpp2" for CDMA/LTE messages in 3GPP2 format.
+     *
+     * @param pdu the message PDU from the SMS_RECEIVED_ACTION intent
+     * @param format the format extra from the SMS_RECEIVED_ACTION intent
+     * @hide pending API council approval
+     */
+    public static SmsMessage createFromPdu(byte[] pdu, String format) {
+        SmsMessageBase wrappedMessage;
+
+        if (FORMAT_3GPP2.equals(format)) {
             wrappedMessage = com.android.internal.telephony.cdma.SmsMessage.createFromPdu(pdu);
-        } else {
+        } else if (FORMAT_3GPP.equals(format)) {
             wrappedMessage = com.android.internal.telephony.gsm.SmsMessage.createFromPdu(pdu);
+        } else {
+            Log.e(LOG_TAG, "createFromPdu(): unsupported message format " + format);
+            return null;
         }
 
         return new SmsMessage(wrappedMessage);
@@ -144,57 +172,19 @@
      *
      * {@hide}
      */
-    public static SmsMessage newFromCMT(String[] lines){
-        SmsMessageBase wrappedMessage;
-        int activePhone = TelephonyManager.getDefault().getCurrentPhoneType();
-
-        if (PHONE_TYPE_CDMA == activePhone) {
-            wrappedMessage = com.android.internal.telephony.cdma.SmsMessage.newFromCMT(lines);
-        } else {
-            wrappedMessage = com.android.internal.telephony.gsm.SmsMessage.newFromCMT(lines);
-        }
-
-        return new SmsMessage(wrappedMessage);
-    }
-
-    /** @hide */
-    protected static SmsMessage newFromCMTI(String line) {
-        SmsMessageBase wrappedMessage;
-        int activePhone = TelephonyManager.getDefault().getCurrentPhoneType();
-
-        if (PHONE_TYPE_CDMA == activePhone) {
-            wrappedMessage = com.android.internal.telephony.cdma.SmsMessage.newFromCMTI(line);
-        } else {
-            wrappedMessage = com.android.internal.telephony.gsm.SmsMessage.newFromCMTI(line);
-        }
-
-        return new SmsMessage(wrappedMessage);
-    }
-
-    /** @hide */
-    public static SmsMessage newFromCDS(String line) {
-        SmsMessageBase wrappedMessage;
-        int activePhone = TelephonyManager.getDefault().getCurrentPhoneType();
-
-        if (PHONE_TYPE_CDMA == activePhone) {
-            wrappedMessage = com.android.internal.telephony.cdma.SmsMessage.newFromCDS(line);
-        } else {
-            wrappedMessage = com.android.internal.telephony.gsm.SmsMessage.newFromCDS(line);
-        }
+    public static SmsMessage newFromCMT(String[] lines) {
+        // received SMS in 3GPP format
+        SmsMessageBase wrappedMessage =
+                com.android.internal.telephony.gsm.SmsMessage.newFromCMT(lines);
 
         return new SmsMessage(wrappedMessage);
     }
 
     /** @hide */
     public static SmsMessage newFromParcel(Parcel p) {
-        SmsMessageBase wrappedMessage;
-        int activePhone = TelephonyManager.getDefault().getCurrentPhoneType();
-
-        if (PHONE_TYPE_CDMA == activePhone) {
-            wrappedMessage = com.android.internal.telephony.cdma.SmsMessage.newFromParcel(p);
-        } else {
-            wrappedMessage = com.android.internal.telephony.gsm.SmsMessage.newFromParcel(p);
-        }
+        // received SMS in 3GPP2 format
+        SmsMessageBase wrappedMessage =
+                com.android.internal.telephony.cdma.SmsMessage.newFromParcel(p);
 
         return new SmsMessage(wrappedMessage);
     }
@@ -227,6 +217,9 @@
     /**
      * Get the TP-Layer-Length for the given SMS-SUBMIT PDU Basically, the
      * length in bytes (not hex chars) less the SMSC header
+     *
+     * FIXME: This method is only used by a CTS test case that isn't run on CDMA devices.
+     * We should probably deprecate it and remove the obsolete test case.
      */
     public static int getTPLayerLengthForPDU(String pdu) {
         int activePhone = TelephonyManager.getDefault().getCurrentPhoneType();
@@ -381,34 +374,6 @@
      * @return a <code>SubmitPdu</code> containing the encoded SC
      *         address, if applicable, and the encoded message.
      *         Returns null on encode error.
-     * @hide
-     */
-    public static SubmitPdu getSubmitPdu(String scAddress,
-            String destinationAddress, String message,
-            boolean statusReportRequested, byte[] header) {
-        SubmitPduBase spb;
-        int activePhone = TelephonyManager.getDefault().getCurrentPhoneType();
-
-        if (PHONE_TYPE_CDMA == activePhone) {
-            spb = com.android.internal.telephony.cdma.SmsMessage.getSubmitPdu(scAddress,
-                    destinationAddress, message, statusReportRequested,
-                    SmsHeader.fromByteArray(header));
-        } else {
-            spb = com.android.internal.telephony.gsm.SmsMessage.getSubmitPdu(scAddress,
-                    destinationAddress, message, statusReportRequested, header);
-        }
-
-        return new SubmitPdu(spb);
-    }
-
-    /**
-     * Get an SMS-SUBMIT PDU for a destination address and a message.
-     * This method will not attempt to use any GSM national language 7 bit encodings.
-     *
-     * @param scAddress Service Centre address.  Null means use default.
-     * @return a <code>SubmitPdu</code> containing the encoded SC
-     *         address, if applicable, and the encoded message.
-     *         Returns null on encode error.
      */
     public static SubmitPdu getSubmitPdu(String scAddress,
             String destinationAddress, String message, boolean statusReportRequested) {
@@ -603,15 +568,6 @@
     }
 
     /**
-     * Return the user data header (UDH).
-     *
-     * @hide
-     */
-    public SmsHeader getUserDataHeader() {
-        return mWrappedSmsMessage.getUserDataHeader();
-    }
-
-    /**
      * Returns the raw PDU for the message.
      *
      * @return the raw PDU for the message.
@@ -646,7 +602,6 @@
      *         SmsManager.STATUS_ON_ICC_UNSENT
      */
     public int getStatusOnIcc() {
-
         return mWrappedSmsMessage.getStatusOnIcc();
     }
 
@@ -666,7 +621,6 @@
      *         SmsMessage was not created from a ICC SMS EF record.
      */
     public int getIndexOnIcc() {
-
         return mWrappedSmsMessage.getIndexOnIcc();
     }
 
@@ -704,19 +658,4 @@
     public boolean isReplyPathPresent() {
         return mWrappedSmsMessage.isReplyPathPresent();
     }
-
-    /** This method returns the reference to a specific
-     *  SmsMessage object, which is used for accessing its static methods.
-     * @return Specific SmsMessage.
-     *
-     * @hide
-     */
-    private static final SmsMessageBase getSmsFacility(){
-        int activePhone = TelephonyManager.getDefault().getCurrentPhoneType();
-        if (PHONE_TYPE_CDMA == activePhone) {
-            return new com.android.internal.telephony.cdma.SmsMessage();
-        } else {
-            return new com.android.internal.telephony.gsm.SmsMessage();
-        }
-    }
 }
diff --git a/telephony/java/android/telephony/gsm/SmsMessage.java b/telephony/java/android/telephony/gsm/SmsMessage.java
index 4af99a6..8d86ec2 100644
--- a/telephony/java/android/telephony/gsm/SmsMessage.java
+++ b/telephony/java/android/telephony/gsm/SmsMessage.java
@@ -166,104 +166,6 @@
     }
 
     /**
-     * TS 27.005 3.4.1 lines[0] and lines[1] are the two lines read from the
-     * +CMT unsolicited response (PDU mode, of course)
-     *  +CMT: [&lt;alpha>],<length><CR><LF><pdu>
-     *
-     * Only public for debugging and for RIL
-     * @deprecated Use android.telephony.SmsMessage.
-     * {@hide}
-     */
-    @Deprecated
-    public static SmsMessage newFromCMT(String[] lines){
-        SmsMessageBase wrappedMessage;
-        int activePhone = TelephonyManager.getDefault().getCurrentPhoneType();
-
-        if (PHONE_TYPE_CDMA == activePhone) {
-            wrappedMessage = com.android.internal.telephony.cdma.SmsMessage.newFromCMT(lines);
-        } else {
-            wrappedMessage = com.android.internal.telephony.gsm.SmsMessage.newFromCMT(lines);
-        }
-
-        return new SmsMessage(wrappedMessage);
-    }
-
-    /** @deprecated Use android.telephony.SmsMessage.
-     *  @hide */
-    @Deprecated
-    protected static SmsMessage newFromCMTI(String line) {
-        SmsMessageBase wrappedMessage;
-        int activePhone = TelephonyManager.getDefault().getCurrentPhoneType();
-
-        if (PHONE_TYPE_CDMA == activePhone) {
-            wrappedMessage = com.android.internal.telephony.cdma.SmsMessage.newFromCMTI(line);
-        } else {
-            wrappedMessage = com.android.internal.telephony.gsm.SmsMessage.newFromCMTI(line);
-        }
-
-        return new SmsMessage(wrappedMessage);
-    }
-
-    /** @deprecated Use android.telephony.SmsMessage.
-     *  @hide */
-    @Deprecated
-    public static SmsMessage newFromCDS(String line) {
-        SmsMessageBase wrappedMessage;
-        int activePhone = TelephonyManager.getDefault().getCurrentPhoneType();
-
-        if (PHONE_TYPE_CDMA == activePhone) {
-            wrappedMessage = com.android.internal.telephony.cdma.SmsMessage.newFromCDS(line);
-        } else {
-            wrappedMessage = com.android.internal.telephony.gsm.SmsMessage.newFromCDS(line);
-        }
-
-        return new SmsMessage(wrappedMessage);
-    }
-
-    /** @deprecated Use android.telephony.SmsMessage.
-     *  @hide */
-    @Deprecated
-    public static SmsMessage newFromParcel(Parcel p) {
-        SmsMessageBase wrappedMessage;
-        int activePhone = TelephonyManager.getDefault().getCurrentPhoneType();
-
-        if (PHONE_TYPE_CDMA == activePhone) {
-            wrappedMessage = com.android.internal.telephony.cdma.SmsMessage.newFromParcel(p);
-        } else {
-            wrappedMessage = com.android.internal.telephony.gsm.SmsMessage.newFromParcel(p);
-        }
-
-        return new SmsMessage(wrappedMessage);
-    }
-
-    /**
-     * Create an SmsMessage from an SMS EF record.
-     *
-     * @param index Index of SMS record. This should be index in ArrayList
-     *              returned by SmsManager.getAllMessagesFromSim + 1.
-     * @param data Record data.
-     * @return An SmsMessage representing the record.
-     *
-     * @deprecated Use android.telephony.SmsMessage.
-     * @hide
-     */
-    @Deprecated
-    public static SmsMessage createFromEfRecord(int index, byte[] data) {
-        SmsMessageBase wrappedMessage;
-        int activePhone = TelephonyManager.getDefault().getCurrentPhoneType();
-
-        if (PHONE_TYPE_CDMA == activePhone) {
-            wrappedMessage = com.android.internal.telephony.cdma.SmsMessage.createFromEfRecord(
-                    index, data);
-        } else {
-            wrappedMessage = com.android.internal.telephony.gsm.SmsMessage.createFromEfRecord(
-                    index, data);
-        }
-
-        return new SmsMessage(wrappedMessage);
-    }
-
-    /**
      * Get the TP-Layer-Length for the given SMS-SUBMIT PDU Basically, the
      * length in bytes (not hex chars) less the SMSC header
      * @deprecated Use android.telephony.SmsMessage.
diff --git a/telephony/java/com/android/internal/telephony/BaseCommands.java b/telephony/java/com/android/internal/telephony/BaseCommands.java
index f0d2fba..f111dd6 100644
--- a/telephony/java/com/android/internal/telephony/BaseCommands.java
+++ b/telephony/java/com/android/internal/telephony/BaseCommands.java
@@ -79,7 +79,8 @@
     protected RegistrantList mRilConnectedRegistrants = new RegistrantList();
     protected RegistrantList mIccRefreshRegistrants = new RegistrantList();
 
-    protected Registrant mSMSRegistrant;
+    protected Registrant mGsmSmsRegistrant;
+    protected Registrant mCdmaSmsRegistrant;
     protected Registrant mNITZTimeRegistrant;
     protected Registrant mSignalStrengthRegistrant;
     protected Registrant mUSSDRegistrant;
@@ -358,12 +359,20 @@
         mIccStatusChangedRegistrants.remove(h);
     }
 
-    public void setOnNewSMS(Handler h, int what, Object obj) {
-        mSMSRegistrant = new Registrant (h, what, obj);
+    public void setOnNewGsmSms(Handler h, int what, Object obj) {
+        mGsmSmsRegistrant = new Registrant (h, what, obj);
     }
 
-    public void unSetOnNewSMS(Handler h) {
-        mSMSRegistrant.clear();
+    public void unSetOnNewGsmSms(Handler h) {
+        mGsmSmsRegistrant.clear();
+    }
+
+    public void setOnNewCdmaSms(Handler h, int what, Object obj) {
+        mCdmaSmsRegistrant = new Registrant (h, what, obj);
+    }
+
+    public void unSetOnNewCdmaSms(Handler h) {
+        mCdmaSmsRegistrant.clear();
     }
 
     public void setOnNewGsmBroadcastSms(Handler h, int what, Object obj) {
diff --git a/telephony/java/com/android/internal/telephony/CommandsInterface.java b/telephony/java/com/android/internal/telephony/CommandsInterface.java
index 1caea70..33eed38 100644
--- a/telephony/java/com/android/internal/telephony/CommandsInterface.java
+++ b/telephony/java/com/android/internal/telephony/CommandsInterface.java
@@ -20,8 +20,6 @@
 
 import android.os.Message;
 import android.os.Handler;
-import android.os.SystemProperties;
-
 
 /**
  * {@hide}
@@ -267,14 +265,32 @@
     void unregisterForRUIMReady(Handler h);
 
     /**
-     * unlike the register* methods, there's only one new SMS handler
+     * unlike the register* methods, there's only one new 3GPP format SMS handler.
      * if you need to unregister, you should also tell the radio to stop
      * sending SMS's to you (via AT+CNMI)
      *
      * AsyncResult.result is a String containing the SMS PDU
      */
-    void setOnNewSMS(Handler h, int what, Object obj);
-    void unSetOnNewSMS(Handler h);
+    void setOnNewGsmSms(Handler h, int what, Object obj);
+    void unSetOnNewGsmSms(Handler h);
+
+    /**
+     * unlike the register* methods, there's only one new 3GPP2 format SMS handler.
+     * if you need to unregister, you should also tell the radio to stop
+     * sending SMS's to you (via AT+CNMI)
+     *
+     * AsyncResult.result is a String containing the SMS PDU
+     */
+    void setOnNewCdmaSms(Handler h, int what, Object obj);
+    void unSetOnNewCdmaSms(Handler h);
+
+    /**
+     * Set the handler for SMS Cell Broadcast messages.
+     *
+     * AsyncResult.result is a byte array containing the SMS-CB PDU
+     */
+    void setOnNewGsmBroadcastSms(Handler h, int what, Object obj);
+    void unSetOnNewGsmBroadcastSms(Handler h);
 
    /**
      * Register for NEW_SMS_ON_SIM unsolicited message
diff --git a/telephony/java/com/android/internal/telephony/Phone.java b/telephony/java/com/android/internal/telephony/Phone.java
index 444f0d2..ca04eb2 100644
--- a/telephony/java/com/android/internal/telephony/Phone.java
+++ b/telephony/java/com/android/internal/telephony/Phone.java
@@ -1394,7 +1394,7 @@
     String getDeviceSvn();
 
     /**
-     * Retrieves the unique sbuscriber ID, e.g., IMSI for GSM phones.
+     * Retrieves the unique subscriber ID, e.g., IMSI for GSM phones.
      */
     String getSubscriberId();
 
@@ -1756,4 +1756,13 @@
      * @param response a callback message with the String response in the obj field
      */
     void requestIsimAuthentication(String nonce, Message response);
+
+    /**
+     * Sets the SIM voice message waiting indicator records.
+     * @param line GSM Subscriber Profile Number, one-based. Only '1' is supported
+     * @param countWaiting The number of messages waiting, if known. Use
+     *                     -1 to indicate that an unknown number of
+     *                      messages are waiting
+     */
+    void setVoiceMessageWaiting(int line, int countWaiting);
 }
diff --git a/telephony/java/com/android/internal/telephony/PhoneBase.java b/telephony/java/com/android/internal/telephony/PhoneBase.java
index 82f3955..a7a4908 100644
--- a/telephony/java/com/android/internal/telephony/PhoneBase.java
+++ b/telephony/java/com/android/internal/telephony/PhoneBase.java
@@ -112,15 +112,17 @@
     /* Instance Variables */
     public CommandsInterface mCM;
     protected IccFileHandler mIccFileHandler;
-    boolean mDnsCheckDisabled = false;
+    boolean mDnsCheckDisabled;
     public DataConnectionTracker mDataConnectionTracker;
     boolean mDoesRilSendMultipleCallRing;
-    int mCallRingContinueToken = 0;
+    int mCallRingContinueToken;
     int mCallRingDelay;
     public boolean mIsTheCurrentActivePhone = true;
     boolean mIsVoiceCapable = true;
     public IccRecords mIccRecords;
     public IccCard mIccCard;
+    public SmsStorageMonitor mSmsStorageMonitor;
+    public SmsUsageMonitor mSmsUsageMonitor;
     public SMSDispatcher mSMS;
 
     /**
@@ -164,7 +166,7 @@
 
     protected Looper mLooper; /* to insure registrants are in correct thread*/
 
-    protected Context mContext;
+    protected final Context mContext;
 
     /**
      * PhoneNotifier is an abstraction for all system-wide
@@ -238,6 +240,10 @@
         mCallRingDelay = SystemProperties.getInt(
                 TelephonyProperties.PROPERTY_CALL_RING_DELAY, 3000);
         Log.d(LOG_TAG, "mCallRingDelay=" + mCallRingDelay);
+
+        // Initialize device storage and outgoing SMS usage monitors for SMSDispatchers.
+        mSmsStorageMonitor = new SmsStorageMonitor(this);
+        mSmsUsageMonitor = new SmsUsageMonitor(context.getContentResolver());
     }
 
     public void dispose() {
@@ -246,9 +252,17 @@
             // Must cleanup all connectionS and needs to use sendMessage!
             mDataConnectionTracker.cleanUpAllConnections(null);
             mIsTheCurrentActivePhone = false;
+            // Dispose the SMS usage and storage monitors
+            mSmsStorageMonitor.dispose();
+            mSmsUsageMonitor.dispose();
         }
     }
 
+    public void removeReferences() {
+        mSmsStorageMonitor = null;
+        mSmsUsageMonitor = null;
+    }
+
     /**
      * When overridden the derived class needs to call
      * super.handleMessage(msg) so this method has a
@@ -1037,37 +1051,6 @@
     }
 
     /**
-     * simulateDataConnection
-     *
-     * simulates various data connection states. This messes with
-     * DataConnectionTracker's internal states, but doesn't actually change
-     * the underlying radio connection states.
-     *
-     * @param state Phone.DataState enum.
-     */
-    public void simulateDataConnection(Phone.DataState state) {
-        DataConnectionTracker.State dcState;
-
-        switch (state) {
-            case CONNECTED:
-                dcState = DataConnectionTracker.State.CONNECTED;
-                break;
-            case SUSPENDED:
-                dcState = DataConnectionTracker.State.CONNECTED;
-                break;
-            case DISCONNECTED:
-                dcState = DataConnectionTracker.State.FAILED;
-                break;
-            default:
-                dcState = DataConnectionTracker.State.CONNECTING;
-                break;
-        }
-
-        mDataConnectionTracker.setState(dcState);
-        notifyDataConnection(null, Phone.APN_TYPE_DEFAULT);
-    }
-
-    /**
      * Notify registrants of a new ringing Connection.
      * Subclasses of Phone probably want to replace this with a
      * version scoped to their packages
@@ -1132,7 +1115,7 @@
     /**
      * Common error logger method for unexpected calls to CDMA-only methods.
      */
-    private void logUnexpectedCdmaMethodCall(String name)
+    private static void logUnexpectedCdmaMethodCall(String name)
     {
         Log.e(LOG_TAG, "Error! " + name + "() in PhoneBase should not be " +
                 "called, CDMAPhone inactive.");
@@ -1145,7 +1128,7 @@
     /**
      * Common error logger method for unexpected calls to GSM/WCDMA-only methods.
      */
-    private void logUnexpectedGsmMethodCall(String name) {
+    private static void logUnexpectedGsmMethodCall(String name) {
         Log.e(LOG_TAG, "Error! " + name + "() in PhoneBase should not be " +
                 "called, GSMPhone inactive.");
     }
@@ -1167,4 +1150,16 @@
     public int getLteOnCdmaMode() {
         return mCM.getLteOnCdmaMode();
     }
+
+    /**
+     * Sets the SIM voice message waiting indicator records.
+     * @param line GSM Subscriber Profile Number, one-based. Only '1' is supported
+     * @param countWaiting The number of messages waiting, if known. Use
+     *                     -1 to indicate that an unknown number of
+     *                      messages are waiting
+     */
+    @Override
+    public void setVoiceMessageWaiting(int line, int countWaiting) {
+        mIccRecords.setVoiceMessageWaiting(line, countWaiting);
+    }
 }
diff --git a/telephony/java/com/android/internal/telephony/PhoneProxy.java b/telephony/java/com/android/internal/telephony/PhoneProxy.java
index e0e8d49..b497ec8 100644
--- a/telephony/java/com/android/internal/telephony/PhoneProxy.java
+++ b/telephony/java/com/android/internal/telephony/PhoneProxy.java
@@ -72,7 +72,7 @@
         switch(msg.what) {
         case EVENT_RADIO_TECHNOLOGY_CHANGED:
             //switch Phone from CDMA to GSM or vice versa
-            mOutgoingPhone = ((PhoneBase)mActivePhone).getPhoneName();
+            mOutgoingPhone = mActivePhone.getPhoneName();
             logd("Switching phone from " + mOutgoingPhone + "Phone to " +
                     (mOutgoingPhone.equals("GSM") ? "CDMAPhone" : "GSMPhone") );
             boolean oldPowerState = false; // old power state to off
@@ -144,23 +144,10 @@
         super.handleMessage(msg);
     }
 
-    private void logv(String msg) {
-        Log.v(LOG_TAG, "[PhoneProxy] " + msg);
-    }
-
-    private void logd(String msg) {
+    private static void logd(String msg) {
         Log.d(LOG_TAG, "[PhoneProxy] " + msg);
     }
 
-    private void logw(String msg) {
-        Log.w(LOG_TAG, "[PhoneProxy] " + msg);
-    }
-
-    private void loge(String msg) {
-        Log.e(LOG_TAG, "[PhoneProxy] " + msg);
-    }
-
-
     public ServiceState getServiceState() {
         return mActivePhone.getServiceState();
     }
@@ -739,19 +726,19 @@
     }
 
     public int getCdmaEriIconIndex() {
-         return mActivePhone.getCdmaEriIconIndex();
+        return mActivePhone.getCdmaEriIconIndex();
     }
 
-     public String getCdmaEriText() {
-         return mActivePhone.getCdmaEriText();
-     }
+    public String getCdmaEriText() {
+        return mActivePhone.getCdmaEriText();
+    }
 
     public int getCdmaEriIconMode() {
-         return mActivePhone.getCdmaEriIconMode();
+        return mActivePhone.getCdmaEriIconMode();
     }
 
     public Phone getActivePhone() {
-         return mActivePhone;
+        return mActivePhone;
     }
 
     public void sendBurstDtmf(String dtmfString, int on, int off, Message onComplete){
@@ -861,4 +848,9 @@
     public int getLteOnCdmaMode() {
         return mActivePhone.getLteOnCdmaMode();
     }
+
+    @Override
+    public void setVoiceMessageWaiting(int line, int countWaiting) {
+        mActivePhone.setVoiceMessageWaiting(line, countWaiting);
+    }
 }
diff --git a/telephony/java/com/android/internal/telephony/RIL.java b/telephony/java/com/android/internal/telephony/RIL.java
index bd35058..8aae0d4 100644
--- a/telephony/java/com/android/internal/telephony/RIL.java
+++ b/telephony/java/com/android/internal/telephony/RIL.java
@@ -2434,8 +2434,8 @@
                 SmsMessage sms;
 
                 sms = SmsMessage.newFromCMT(a);
-                if (mSMSRegistrant != null) {
-                    mSMSRegistrant
+                if (mGsmSmsRegistrant != null) {
+                    mGsmSmsRegistrant
                         .notifyRegistrant(new AsyncResult(null, sms, null));
                 }
             break;
@@ -2607,8 +2607,8 @@
 
                 SmsMessage sms = (SmsMessage) ret;
 
-                if (mSMSRegistrant != null) {
-                    mSMSRegistrant
+                if (mCdmaSmsRegistrant != null) {
+                    mCdmaSmsRegistrant
                         .notifyRegistrant(new AsyncResult(null, sms, null));
                 }
                 break;
diff --git a/telephony/java/com/android/internal/telephony/SMSDispatcher.java b/telephony/java/com/android/internal/telephony/SMSDispatcher.java
index 76e719c..e4c6028 100644
--- a/telephony/java/com/android/internal/telephony/SMSDispatcher.java
+++ b/telephony/java/com/android/internal/telephony/SMSDispatcher.java
@@ -44,10 +44,12 @@
 import android.util.Log;
 import android.view.WindowManager;
 
+import com.android.internal.telephony.SmsMessageBase.TextEncodingDetails;
 import com.android.internal.util.HexDump;
 
 import java.io.ByteArrayOutputStream;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.HashMap;
 import java.util.Random;
 
@@ -60,68 +62,66 @@
 import static android.telephony.SmsManager.RESULT_ERROR_LIMIT_EXCEEDED;
 import static android.telephony.SmsManager.RESULT_ERROR_FDN_CHECK_FAILURE;
 
-
 public abstract class SMSDispatcher extends Handler {
-    private static final String TAG = "SMS";
+    static final String TAG = "SMS";    // accessed from inner class
     private static final String SEND_NEXT_MSG_EXTRA = "SendNextMsg";
 
-    /** Default checking period for SMS sent without user permit */
-    private static final int DEFAULT_SMS_CHECK_PERIOD = 3600000;
-
-    /** Default number of SMS sent in checking period without user permit */
-    private static final int DEFAULT_SMS_MAX_COUNT = 100;
-
     /** Default timeout for SMS sent query */
     private static final int DEFAULT_SMS_TIMEOUT = 6000;
 
-    protected static final String[] RAW_PROJECTION = new String[] {
-        "pdu",
-        "sequence",
-        "destination_port",
+    /** Permission required to receive SMS and SMS-CB messages. */
+    public static final String RECEIVE_SMS_PERMISSION = "android.permission.RECEIVE_SMS";
+
+    /** Permission required to receive ETWS and CMAS emergency broadcasts. */
+    public static final String RECEIVE_EMERGENCY_BROADCAST_PERMISSION =
+            "android.permission.RECEIVE_EMERGENCY_BROADCAST";
+
+    /** Query projection for checking for duplicate message segments. */
+    private static final String[] PDU_PROJECTION = new String[] {
+            "pdu"
     };
 
-    static final protected int EVENT_NEW_SMS = 1;
+    /** Query projection for combining concatenated message segments. */
+    private static final String[] PDU_SEQUENCE_PORT_PROJECTION = new String[] {
+            "pdu",
+            "sequence",
+            "destination_port"
+    };
 
-    static final protected int EVENT_SEND_SMS_COMPLETE = 2;
+    private static final int PDU_COLUMN = 0;
+    private static final int SEQUENCE_COLUMN = 1;
+    private static final int DESTINATION_PORT_COLUMN = 2;
+
+    /** New SMS received. */
+    protected static final int EVENT_NEW_SMS = 1;
+
+    /** SMS send complete. */
+    protected static final int EVENT_SEND_SMS_COMPLETE = 2;
 
     /** Retry sending a previously failed SMS message */
-    static final protected int EVENT_SEND_RETRY = 3;
-
-    /** Status report received */
-    static final protected int EVENT_NEW_SMS_STATUS_REPORT = 5;
-
-    /** SIM/RUIM storage is full */
-    static final protected int EVENT_ICC_FULL = 6;
+    private static final int EVENT_SEND_RETRY = 3;
 
     /** SMS confirm required */
-    static final protected int EVENT_POST_ALERT = 7;
+    private static final int EVENT_POST_ALERT = 4;
 
     /** Send the user confirmed SMS */
-    static final protected int EVENT_SEND_CONFIRMED_SMS = 8;
+    static final int EVENT_SEND_CONFIRMED_SMS = 5;  // accessed from inner class
 
     /** Alert is timeout */
-    static final protected int EVENT_ALERT_TIMEOUT = 9;
+    private static final int EVENT_ALERT_TIMEOUT = 6;
 
     /** Stop the sending */
-    static final protected int EVENT_STOP_SENDING = 10;
+    static final int EVENT_STOP_SENDING = 7;        // accessed from inner class
 
-    /** Memory status reporting is acknowledged by RIL */
-    static final protected int EVENT_REPORT_MEMORY_STATUS_DONE = 11;
-
-    /** Radio is ON */
-    static final protected int EVENT_RADIO_ON = 12;
-
-    /** New broadcast SMS */
-    static final protected int EVENT_NEW_BROADCAST_SMS = 13;
-
-    protected Phone mPhone;
-    protected Context mContext;
-    protected ContentResolver mResolver;
-    protected CommandsInterface mCm;
+    protected final Phone mPhone;
+    protected final Context mContext;
+    protected final ContentResolver mResolver;
+    protected final CommandsInterface mCm;
+    protected final SmsStorageMonitor mStorageMonitor;
 
     protected final WapPushOverSms mWapPush;
 
-    protected final Uri mRawUri = Uri.withAppendedPath(Telephony.Sms.CONTENT_URI, "raw");
+    protected static final Uri mRawUri = Uri.withAppendedPath(Telephony.Sms.CONTENT_URI, "raw");
 
     /** Maximum number of times to retry sending a failed SMS. */
     private static final int MAX_SEND_RETRIES = 3;
@@ -136,12 +136,14 @@
      * Message reference for a CONCATENATED_8_BIT_REFERENCE or
      * CONCATENATED_16_BIT_REFERENCE message set.  Should be
      * incremented for each set of concatenated messages.
+     * Static field shared by all dispatcher objects.
      */
-    private static int sConcatenatedRef;
+    private static int sConcatenatedRef = new Random().nextInt(256);
 
-    private SmsCounter mCounter;
+    /** Outgoing message counter. Shared by all dispatchers. */
+    private final SmsUsageMonitor mUsageMonitor;
 
-    private ArrayList<SmsTracker> mSTrackers = new ArrayList<SmsTracker>(MO_MSG_QUEUE_LIMIT);
+    private final ArrayList<SmsTracker> mSTrackers = new ArrayList<SmsTracker>(MO_MSG_QUEUE_LIMIT);
 
     /** Wake lock to ensure device stays awake while dispatching the SMS intent. */
     private PowerManager.WakeLock mWakeLock;
@@ -150,17 +152,14 @@
      * Hold the wake lock for 5 seconds, which should be enough time for
      * any receiver(s) to grab its own wake lock.
      */
-    private final int WAKE_LOCK_TIMEOUT = 5000;
-
-    protected boolean mStorageAvailable = true;
-    protected boolean mReportMemoryStatusPending = false;
+    private static final int WAKE_LOCK_TIMEOUT = 5000;
 
     /* Flags indicating whether the current device allows sms service */
     protected boolean mSmsCapable = true;
     protected boolean mSmsReceiveDisabled;
     protected boolean mSmsSendDisabled;
 
-    protected static int mRemainingMessages = -1;
+    protected int mRemainingMessages = -1;
 
     protected static int getNextConcatenatedRef() {
         sConcatenatedRef += 1;
@@ -168,111 +167,52 @@
     }
 
     /**
-     *  Implement the per-application based SMS control, which only allows
-     *  a limit on the number of SMS/MMS messages an app can send in checking
-     *  period.
+     * Create a new SMS dispatcher.
+     * @param phone the Phone to use
+     * @param storageMonitor the SmsStorageMonitor to use
+     * @param usageMonitor the SmsUsageMonitor to use
      */
-    private class SmsCounter {
-        private int mCheckPeriod;
-        private int mMaxAllowed;
-        private HashMap<String, ArrayList<Long>> mSmsStamp;
-
-        /**
-         * Create SmsCounter
-         * @param mMax is the number of SMS allowed without user permit
-         * @param mPeriod is the checking period
-         */
-        SmsCounter(int mMax, int mPeriod) {
-            mMaxAllowed = mMax;
-            mCheckPeriod = mPeriod;
-            mSmsStamp = new HashMap<String, ArrayList<Long>> ();
-        }
-
-        /**
-         * Check to see if an application allow to send new SMS messages
-         *
-         * @param appName is the application sending sms
-         * @param smsWaiting is the number of new sms wants to be sent
-         * @return true if application is allowed to send the requested number
-         *         of new sms messages
-         */
-        boolean check(String appName, int smsWaiting) {
-            if (!mSmsStamp.containsKey(appName)) {
-                mSmsStamp.put(appName, new ArrayList<Long>());
-            }
-
-            return isUnderLimit(mSmsStamp.get(appName), smsWaiting);
-        }
-
-        private boolean isUnderLimit(ArrayList<Long> sent, int smsWaiting) {
-            Long ct =  System.currentTimeMillis();
-
-            Log.d(TAG, "SMS send size=" + sent.size() + "time=" + ct);
-
-            while (sent.size() > 0 && (ct - sent.get(0)) > mCheckPeriod ) {
-                    sent.remove(0);
-            }
-
-
-            if ( (sent.size() + smsWaiting) <= mMaxAllowed) {
-                for (int i = 0; i < smsWaiting; i++ ) {
-                    sent.add(ct);
-                }
-                return true;
-            }
-            return false;
-        }
-    }
-
-    protected SMSDispatcher(PhoneBase phone) {
+    protected SMSDispatcher(PhoneBase phone, SmsStorageMonitor storageMonitor,
+            SmsUsageMonitor usageMonitor) {
         mPhone = phone;
         mWapPush = new WapPushOverSms(phone, this);
         mContext = phone.getContext();
         mResolver = mContext.getContentResolver();
         mCm = phone.mCM;
+        mStorageMonitor = storageMonitor;
+        mUsageMonitor = usageMonitor;
 
         createWakelock();
 
-        int check_period = Settings.Secure.getInt(mResolver,
-                Settings.Secure.SMS_OUTGOING_CHECK_INTERVAL_MS,
-                DEFAULT_SMS_CHECK_PERIOD);
-        int max_count = Settings.Secure.getInt(mResolver,
-                Settings.Secure.SMS_OUTGOING_CHECK_MAX_COUNT,
-                DEFAULT_SMS_MAX_COUNT);
-        mCounter = new SmsCounter(max_count, check_period);
-
-        mCm.setOnNewSMS(this, EVENT_NEW_SMS, null);
-        mCm.setOnSmsStatus(this, EVENT_NEW_SMS_STATUS_REPORT, null);
-        mCm.setOnIccSmsFull(this, EVENT_ICC_FULL, null);
-        mCm.registerForOn(this, EVENT_RADIO_ON, null);
-
-        // Don't always start message ref at 0.
-        sConcatenatedRef = new Random().nextInt(256);
-
-        // Register for device storage intents.  Use these to notify the RIL
-        // that storage for SMS is or is not available.
-        IntentFilter filter = new IntentFilter();
-        filter.addAction(Intent.ACTION_DEVICE_STORAGE_FULL);
-        filter.addAction(Intent.ACTION_DEVICE_STORAGE_NOT_FULL);
-        mContext.registerReceiver(mResultReceiver, filter);
-
         mSmsCapable = mContext.getResources().getBoolean(
                 com.android.internal.R.bool.config_sms_capable);
         mSmsReceiveDisabled = !SystemProperties.getBoolean(
                                 TelephonyProperties.PROPERTY_SMS_RECEIVE, mSmsCapable);
         mSmsSendDisabled = !SystemProperties.getBoolean(
                                 TelephonyProperties.PROPERTY_SMS_SEND, mSmsCapable);
-        Log.d(TAG, "SMSDispatcher: ctor mSmsCapable=" + mSmsCapable
+        Log.d(TAG, "SMSDispatcher: ctor mSmsCapable=" + mSmsCapable + " format=" + getFormat()
                 + " mSmsReceiveDisabled=" + mSmsReceiveDisabled
                 + " mSmsSendDisabled=" + mSmsSendDisabled);
     }
 
-    public void dispose() {
-        mCm.unSetOnNewSMS(this);
-        mCm.unSetOnSmsStatus(this);
-        mCm.unSetOnIccSmsFull(this);
-        mCm.unregisterForOn(this);
-    }
+    /** Unregister for incoming SMS events. */
+    public abstract void dispose();
+
+    /**
+     * The format of the message PDU in the associated broadcast intent.
+     * This will be either "3gpp" for GSM/UMTS/LTE messages in 3GPP format
+     * or "3gpp2" for CDMA/LTE messages in 3GPP2 format.
+     *
+     * Note: All applications which handle incoming SMS messages by processing the
+     * SMS_RECEIVED_ACTION broadcast intent MUST pass the "format" extra from the intent
+     * into the new methods in {@link android.telephony.SmsMessage} which take an
+     * extra format parameter. This is required in order to correctly decode the PDU on
+     * devices which require support for both 3GPP and 3GPP2 formats at the same time,
+     * such as CDMA/LTE devices and GSM/CDMA world phones.
+     *
+     * @return the format of the message PDU
+     */
+    protected abstract String getFormat();
 
     @Override
     protected void finalize() {
@@ -338,14 +278,6 @@
             sendSms((SmsTracker) msg.obj);
             break;
 
-        case EVENT_NEW_SMS_STATUS_REPORT:
-            handleStatusReport((AsyncResult)msg.obj);
-            break;
-
-        case EVENT_ICC_FULL:
-            handleIccFull();
-            break;
-
         case EVENT_POST_ALERT:
             handleReachSentLimit((SmsTracker)(msg.obj));
             break;
@@ -369,7 +301,7 @@
         case EVENT_SEND_CONFIRMED_SMS:
             if (mSTrackers.isEmpty() == false) {
                 SmsTracker sTracker = mSTrackers.remove(mSTrackers.size() - 1);
-                if (isMultipartTracker(sTracker)) {
+                if (sTracker.isMultipart()) {
                     sendMultipartSms(sTracker);
                 } else {
                     sendSms(sTracker);
@@ -390,30 +322,6 @@
                 removeMessages(EVENT_ALERT_TIMEOUT, msg.obj);
             }
             break;
-
-        case EVENT_REPORT_MEMORY_STATUS_DONE:
-            ar = (AsyncResult)msg.obj;
-            if (ar.exception != null) {
-                mReportMemoryStatusPending = true;
-                Log.v(TAG, "Memory status report to modem pending : mStorageAvailable = "
-                        + mStorageAvailable);
-            } else {
-                mReportMemoryStatusPending = false;
-            }
-            break;
-
-        case EVENT_RADIO_ON:
-            if (mReportMemoryStatusPending) {
-                Log.v(TAG, "Sending pending memory status report : mStorageAvailable = "
-                        + mStorageAvailable);
-                mCm.reportSmsMemoryStatus(mStorageAvailable,
-                        obtainMessage(EVENT_REPORT_MEMORY_STATUS_DONE));
-            }
-            break;
-
-        case EVENT_NEW_BROADCAST_SMS:
-            handleBroadcastSms((AsyncResult)msg.obj);
-            break;
         }
     }
 
@@ -440,26 +348,6 @@
     }
 
     /**
-     * Called when SIM_FULL message is received from the RIL.  Notifies interested
-     * parties that SIM storage for SMS messages is full.
-     */
-    private void handleIccFull(){
-        // broadcast SIM_FULL intent
-        Intent intent = new Intent(Intents.SIM_FULL_ACTION);
-        mWakeLock.acquire(WAKE_LOCK_TIMEOUT);
-        mContext.sendBroadcast(intent, "android.permission.RECEIVE_SMS");
-    }
-
-    /**
-     * Called when a status report is received.  This should correspond to
-     * a previously successful SEND.
-     *
-     * @param ar AsyncResult passed into the message handler.  ar.result should
-     *           be a String representing the status report PDU, as ASCII hex.
-     */
-    protected abstract void handleStatusReport(AsyncResult ar);
-
-    /**
      * Called when SMS send completes. Broadcasts a sentIntent on success.
      * On failure, either sets up retries or broadcasts a sentIntent with
      * the failure in the result code.
@@ -559,7 +447,7 @@
      *                  POWER_OFF
      * @param tracker   An SmsTracker for the current message.
      */
-    protected void handleNotInService(int ss, SmsTracker tracker) {
+    protected static void handleNotInService(int ss, SmsTracker tracker) {
         if (tracker.mSentIntent != null) {
             try {
                 if (ss == ServiceState.STATE_POWER_OFF) {
@@ -581,86 +469,171 @@
      */
     public abstract int dispatchMessage(SmsMessageBase sms);
 
+    /**
+     * Dispatch a normal incoming SMS. This is called from the format-specific
+     * {@link #dispatchMessage(SmsMessageBase)} if no format-specific handling is required.
+     *
+     * @param sms
+     * @return
+     */
+    protected int dispatchNormalMessage(SmsMessageBase sms) {
+        SmsHeader smsHeader = sms.getUserDataHeader();
+
+        // See if message is partial or port addressed.
+        if ((smsHeader == null) || (smsHeader.concatRef == null)) {
+            // Message is not partial (not part of concatenated sequence).
+            byte[][] pdus = new byte[1][];
+            pdus[0] = sms.getPdu();
+
+            if (smsHeader != null && smsHeader.portAddrs != null) {
+                if (smsHeader.portAddrs.destPort == SmsHeader.PORT_WAP_PUSH) {
+                    // GSM-style WAP indication
+                    return mWapPush.dispatchWapPdu(sms.getUserData());
+                } else {
+                    // The message was sent to a port, so concoct a URI for it.
+                    dispatchPortAddressedPdus(pdus, smsHeader.portAddrs.destPort);
+                }
+            } else {
+                // Normal short and non-port-addressed message, dispatch it.
+                dispatchPdus(pdus);
+            }
+            return Activity.RESULT_OK;
+        } else {
+            // Process the message part.
+            SmsHeader.ConcatRef concatRef = smsHeader.concatRef;
+            SmsHeader.PortAddrs portAddrs = smsHeader.portAddrs;
+            return processMessagePart(sms.getPdu(), sms.getOriginatingAddress(),
+                    concatRef.refNumber, concatRef.seqNumber, concatRef.msgCount,
+                    sms.getTimestampMillis(), (portAddrs != null ? portAddrs.destPort : -1), false);
+        }
+    }
 
     /**
      * If this is the last part send the parts out to the application, otherwise
-     * the part is stored for later processing.
+     * the part is stored for later processing. Handles both 3GPP concatenated messages
+     * as well as 3GPP2 format WAP push messages processed by
+     * {@link com.android.internal.telephony.cdma.CdmaSMSDispatcher#processCdmaWapPdu}.
      *
-     * NOTE: concatRef (naturally) needs to be non-null, but portAddrs can be null.
+     * @param pdu the message PDU, or the datagram portion of a CDMA WDP datagram segment
+     * @param address the originating address
+     * @param referenceNumber distinguishes concatenated messages from the same sender
+     * @param sequenceNumber the order of this segment in the message
+     * @param messageCount the number of segments in the message
+     * @param timestamp the service center timestamp in millis
+     * @param destPort the destination port for the message, or -1 for no destination port
+     * @param isCdmaWapPush true if pdu is a CDMA WDP datagram segment and not an SM PDU
+     *
      * @return a result code from {@link Telephony.Sms.Intents}, or
      *         {@link Activity#RESULT_OK} if the message has been broadcast
      *         to applications
      */
-    protected int processMessagePart(SmsMessageBase sms,
-            SmsHeader.ConcatRef concatRef, SmsHeader.PortAddrs portAddrs) {
-
-        // Lookup all other related parts
-        StringBuilder where = new StringBuilder("reference_number =");
-        where.append(concatRef.refNumber);
-        where.append(" AND address = ?");
-        String[] whereArgs = new String[] {sms.getOriginatingAddress()};
-
+    protected int processMessagePart(byte[] pdu, String address, int referenceNumber,
+            int sequenceNumber, int messageCount, long timestamp, int destPort,
+            boolean isCdmaWapPush) {
         byte[][] pdus = null;
         Cursor cursor = null;
         try {
-            cursor = mResolver.query(mRawUri, RAW_PROJECTION, where.toString(), whereArgs, null);
+            // used by several query selection arguments
+            String refNumber = Integer.toString(referenceNumber);
+            String seqNumber = Integer.toString(sequenceNumber);
+
+            // Check for duplicate message segment
+            cursor = mResolver.query(mRawUri, PDU_PROJECTION,
+                    "address=? AND reference_number=? AND sequence=?",
+                    new String[] {address, refNumber, seqNumber}, null);
+
+            // moveToNext() returns false if no duplicates were found
+            if (cursor.moveToNext()) {
+                Log.w(TAG, "Discarding duplicate message segment from address=" + address
+                        + " refNumber=" + refNumber + " seqNumber=" + seqNumber);
+                String oldPduString = cursor.getString(PDU_COLUMN);
+                byte[] oldPdu = HexDump.hexStringToByteArray(oldPduString);
+                if (!Arrays.equals(oldPdu, pdu)) {
+                    Log.e(TAG, "Warning: dup message segment PDU of length " + pdu.length
+                            + " is different from existing PDU of length " + oldPdu.length);
+                }
+                return Intents.RESULT_SMS_HANDLED;
+            }
+            cursor.close();
+
+            // not a dup, query for all other segments of this concatenated message
+            String where = "address=? AND reference_number=?";
+            String[] whereArgs = new String[] {address, refNumber};
+            cursor = mResolver.query(mRawUri, PDU_SEQUENCE_PORT_PROJECTION, where, whereArgs, null);
+
             int cursorCount = cursor.getCount();
-            if (cursorCount != concatRef.msgCount - 1) {
+            if (cursorCount != messageCount - 1) {
                 // We don't have all the parts yet, store this one away
                 ContentValues values = new ContentValues();
-                values.put("date", new Long(sms.getTimestampMillis()));
-                values.put("pdu", HexDump.toHexString(sms.getPdu()));
-                values.put("address", sms.getOriginatingAddress());
-                values.put("reference_number", concatRef.refNumber);
-                values.put("count", concatRef.msgCount);
-                values.put("sequence", concatRef.seqNumber);
-                if (portAddrs != null) {
-                    values.put("destination_port", portAddrs.destPort);
+                values.put("date", timestamp);
+                values.put("pdu", HexDump.toHexString(pdu));
+                values.put("address", address);
+                values.put("reference_number", referenceNumber);
+                values.put("count", messageCount);
+                values.put("sequence", sequenceNumber);
+                if (destPort != -1) {
+                    values.put("destination_port", destPort);
                 }
                 mResolver.insert(mRawUri, values);
                 return Intents.RESULT_SMS_HANDLED;
             }
 
             // All the parts are in place, deal with them
-            int pduColumn = cursor.getColumnIndex("pdu");
-            int sequenceColumn = cursor.getColumnIndex("sequence");
-
-            pdus = new byte[concatRef.msgCount][];
+            pdus = new byte[messageCount][];
             for (int i = 0; i < cursorCount; i++) {
                 cursor.moveToNext();
-                int cursorSequence = (int)cursor.getLong(sequenceColumn);
+                int cursorSequence = cursor.getInt(SEQUENCE_COLUMN);
                 pdus[cursorSequence - 1] = HexDump.hexStringToByteArray(
-                        cursor.getString(pduColumn));
+                        cursor.getString(PDU_COLUMN));
+
+                // Read the destination port from the first segment (needed for CDMA WAP PDU).
+                // It's not a bad idea to prefer the port from the first segment for 3GPP as well.
+                if (cursorSequence == 0 && !cursor.isNull(DESTINATION_PORT_COLUMN)) {
+                    destPort = cursor.getInt(DESTINATION_PORT_COLUMN);
+                }
             }
             // This one isn't in the DB, so add it
-            pdus[concatRef.seqNumber - 1] = sms.getPdu();
+            pdus[sequenceNumber - 1] = pdu;
 
             // Remove the parts from the database
-            mResolver.delete(mRawUri, where.toString(), whereArgs);
+            mResolver.delete(mRawUri, where, whereArgs);
         } catch (SQLException e) {
             Log.e(TAG, "Can't access multipart SMS database", e);
-            // TODO:  Would OUT_OF_MEMORY be more appropriate?
             return Intents.RESULT_SMS_GENERIC_ERROR;
         } finally {
             if (cursor != null) cursor.close();
         }
 
-        /**
-         * TODO(cleanup): The following code has duplicated logic with
-         * the radio-specific dispatchMessage code, which is fragile,
-         * in addition to being redundant.  Instead, if this method
-         * maybe returned the reassembled message (or just contents),
-         * the following code (which is not really related to
-         * reconstruction) could be better consolidated.
-         */
+        // Special handling for CDMA WDP datagrams
+        if (isCdmaWapPush) {
+            // Build up the data stream
+            ByteArrayOutputStream output = new ByteArrayOutputStream();
+            for (int i = 0; i < messageCount; i++) {
+                // reassemble the (WSP-)pdu
+                output.write(pdus[i], 0, pdus[i].length);
+            }
+            byte[] datagram = output.toByteArray();
+
+            // Dispatch the PDU to applications
+            if (destPort == SmsHeader.PORT_WAP_PUSH) {
+                // Handle the PUSH
+                return mWapPush.dispatchWapPdu(datagram);
+            } else {
+                pdus = new byte[1][];
+                pdus[0] = datagram;
+                // The messages were sent to any other WAP port
+                dispatchPortAddressedPdus(pdus, destPort);
+                return Activity.RESULT_OK;
+            }
+        }
 
         // Dispatch the PDUs to applications
-        if (portAddrs != null) {
-            if (portAddrs.destPort == SmsHeader.PORT_WAP_PUSH) {
+        if (destPort != -1) {
+            if (destPort == SmsHeader.PORT_WAP_PUSH) {
                 // Build up the data stream
                 ByteArrayOutputStream output = new ByteArrayOutputStream();
-                for (int i = 0; i < concatRef.msgCount; i++) {
-                    SmsMessage msg = SmsMessage.createFromPdu(pdus[i]);
+                for (int i = 0; i < messageCount; i++) {
+                    SmsMessage msg = SmsMessage.createFromPdu(pdus[i], getFormat());
                     byte[] data = msg.getUserData();
                     output.write(data, 0, data.length);
                 }
@@ -668,7 +641,7 @@
                 return mWapPush.dispatchWapPdu(output.toByteArray());
             } else {
                 // The messages were sent to a port, so concoct a URI for it
-                dispatchPortAddressedPdus(pdus, portAddrs.destPort);
+                dispatchPortAddressedPdus(pdus, destPort);
             }
         } else {
             // The messages were not sent to a port
@@ -685,7 +658,8 @@
     protected void dispatchPdus(byte[][] pdus) {
         Intent intent = new Intent(Intents.SMS_RECEIVED_ACTION);
         intent.putExtra("pdus", pdus);
-        dispatch(intent, "android.permission.RECEIVE_SMS");
+        intent.putExtra("format", getFormat());
+        dispatch(intent, RECEIVE_SMS_PERMISSION);
     }
 
     /**
@@ -698,7 +672,8 @@
         Uri uri = Uri.parse("sms://localhost:" + port);
         Intent intent = new Intent(Intents.DATA_SMS_RECEIVED_ACTION, uri);
         intent.putExtra("pdus", pdus);
-        dispatch(intent, "android.permission.RECEIVE_SMS");
+        intent.putExtra("format", getFormat());
+        dispatch(intent, RECEIVE_SMS_PERMISSION);
     }
 
     /**
@@ -759,6 +734,16 @@
             String text, PendingIntent sentIntent, PendingIntent deliveryIntent);
 
     /**
+     * Calculate the number of septets needed to encode the message.
+     *
+     * @param messageBody the message to encode
+     * @param use7bitOnly ignore (but still count) illegal characters if true
+     * @return TextEncodingDetails
+     */
+    protected abstract TextEncodingDetails calculateLength(CharSequence messageBody,
+            boolean use7bitOnly);
+
+    /**
      * Send a multi-part text based SMS.
      *
      * @param destAddr the address to send the message to
@@ -784,9 +769,70 @@
      *   to the recipient.  The raw pdu of the status report is in the
      *   extended data ("pdu").
      */
-    protected abstract void sendMultipartText(String destAddr, String scAddr,
+    protected void sendMultipartText(String destAddr, String scAddr,
             ArrayList<String> parts, ArrayList<PendingIntent> sentIntents,
-            ArrayList<PendingIntent> deliveryIntents);
+            ArrayList<PendingIntent> deliveryIntents) {
+
+        int refNumber = getNextConcatenatedRef() & 0x00FF;
+        int msgCount = parts.size();
+        int encoding = android.telephony.SmsMessage.ENCODING_UNKNOWN;
+
+        mRemainingMessages = msgCount;
+
+        TextEncodingDetails[] encodingForParts = new TextEncodingDetails[msgCount];
+        for (int i = 0; i < msgCount; i++) {
+            TextEncodingDetails details = calculateLength(parts.get(i), false);
+            if (encoding != details.codeUnitSize
+                    && (encoding == android.telephony.SmsMessage.ENCODING_UNKNOWN
+                            || encoding == android.telephony.SmsMessage.ENCODING_7BIT)) {
+                encoding = details.codeUnitSize;
+            }
+            encodingForParts[i] = details;
+        }
+
+        for (int i = 0; i < msgCount; i++) {
+            SmsHeader.ConcatRef concatRef = new SmsHeader.ConcatRef();
+            concatRef.refNumber = refNumber;
+            concatRef.seqNumber = i + 1;  // 1-based sequence
+            concatRef.msgCount = msgCount;
+            // TODO: We currently set this to true since our messaging app will never
+            // send more than 255 parts (it converts the message to MMS well before that).
+            // However, we should support 3rd party messaging apps that might need 16-bit
+            // references
+            // Note:  It's not sufficient to just flip this bit to true; it will have
+            // ripple effects (several calculations assume 8-bit ref).
+            concatRef.isEightBits = true;
+            SmsHeader smsHeader = new SmsHeader();
+            smsHeader.concatRef = concatRef;
+
+            // Set the national language tables for 3GPP 7-bit encoding, if enabled.
+            if (encoding == android.telephony.SmsMessage.ENCODING_7BIT) {
+                smsHeader.languageTable = encodingForParts[i].languageTable;
+                smsHeader.languageShiftTable = encodingForParts[i].languageShiftTable;
+            }
+
+            PendingIntent sentIntent = null;
+            if (sentIntents != null && sentIntents.size() > i) {
+                sentIntent = sentIntents.get(i);
+            }
+
+            PendingIntent deliveryIntent = null;
+            if (deliveryIntents != null && deliveryIntents.size() > i) {
+                deliveryIntent = deliveryIntents.get(i);
+            }
+
+            sendNewSubmitPdu(destAddr, scAddr, parts.get(i), smsHeader, encoding,
+                    sentIntent, deliveryIntent, (i == (msgCount - 1)));
+        }
+
+    }
+
+    /**
+     * Create a new SubmitPdu and send it.
+     */
+    protected abstract void sendNewSubmitPdu(String destinationAddress, String scAddress,
+            String message, SmsHeader smsHeader, int encoding,
+            PendingIntent sentIntent, PendingIntent deliveryIntent, boolean lastPart);
 
     /**
      * Send a SMS
@@ -842,7 +888,7 @@
             handleNotInService(ss, tracker);
         } else {
             String appName = getAppNameByIntent(sentIntent);
-            if (mCounter.check(appName, SINGLE_PART_SMS)) {
+            if (mUsageMonitor.check(appName, SINGLE_PART_SMS)) {
                 sendSms(tracker);
             } else {
                 sendMessage(obtainMessage(EVENT_POST_ALERT, tracker));
@@ -885,7 +931,7 @@
                 DEFAULT_SMS_TIMEOUT);
     }
 
-    protected String getAppNameByIntent(PendingIntent intent) {
+    protected static String getAppNameByIntent(PendingIntent intent) {
         Resources r = Resources.getSystem();
         return (intent != null) ? intent.getTargetPackage()
             : r.getString(R.string.sms_control_default_app_name);
@@ -903,7 +949,35 @@
      *
      * @param tracker holds the multipart Sms tracker ready to be sent
      */
-    protected abstract void sendMultipartSms (SmsTracker tracker);
+    private void sendMultipartSms(SmsTracker tracker) {
+        ArrayList<String> parts;
+        ArrayList<PendingIntent> sentIntents;
+        ArrayList<PendingIntent> deliveryIntents;
+
+        HashMap<String, Object> map = tracker.mData;
+
+        String destinationAddress = (String) map.get("destination");
+        String scAddress = (String) map.get("scaddress");
+
+        parts = (ArrayList<String>) map.get("parts");
+        sentIntents = (ArrayList<PendingIntent>) map.get("sentIntents");
+        deliveryIntents = (ArrayList<PendingIntent>) map.get("deliveryIntents");
+
+        // check if in service
+        int ss = mPhone.getServiceState().getState();
+        if (ss != ServiceState.STATE_IN_SERVICE) {
+            for (int i = 0, count = parts.size(); i < count; i++) {
+                PendingIntent sentIntent = null;
+                if (sentIntents != null && sentIntents.size() > i) {
+                    sentIntent = sentIntents.get(i);
+                }
+                handleNotInService(ss, new SmsTracker(null, sentIntent, null));
+            }
+            return;
+        }
+
+        sendMultipartText(destinationAddress, scAddress, parts, sentIntents, deliveryIntents);
+    }
 
     /**
      * Send an acknowledge message.
@@ -934,66 +1008,38 @@
     }
 
     /**
-     * Check if a SmsTracker holds multi-part Sms
-     *
-     * @param tracker a SmsTracker could hold a multi-part Sms
-     * @return true for tracker holds Multi-parts Sms
-     */
-    private boolean isMultipartTracker (SmsTracker tracker) {
-        HashMap map = tracker.mData;
-        return ( map.get("parts") != null);
-    }
-
-    /**
      * Keeps track of an SMS that has been sent to the RIL, until it has
      * successfully been sent, or we're done trying.
      *
      */
-    static protected class SmsTracker {
+    protected static final class SmsTracker {
         // fields need to be public for derived SmsDispatchers
-        public HashMap<String, Object> mData;
+        public final HashMap<String, Object> mData;
         public int mRetryCount;
         public int mMessageRef;
 
-        public PendingIntent mSentIntent;
-        public PendingIntent mDeliveryIntent;
+        public final PendingIntent mSentIntent;
+        public final PendingIntent mDeliveryIntent;
 
-        SmsTracker(HashMap<String, Object> data, PendingIntent sentIntent,
+        public SmsTracker(HashMap<String, Object> data, PendingIntent sentIntent,
                 PendingIntent deliveryIntent) {
             mData = data;
             mSentIntent = sentIntent;
             mDeliveryIntent = deliveryIntent;
             mRetryCount = 0;
         }
+
+        /**
+         * Returns whether this tracker holds a multi-part SMS.
+         * @return true if the tracker holds a multi-part SMS; false otherwise
+         */
+        protected boolean isMultipart() {
+            HashMap map = mData;
+            return map.containsKey("parts");
+        }
     }
 
-    protected SmsTracker SmsTrackerFactory(HashMap<String, Object> data, PendingIntent sentIntent,
-            PendingIntent deliveryIntent) {
-        return new SmsTracker(data, sentIntent, deliveryIntent);
-    }
-
-    public void initSipStack(boolean isObg) {
-        // This function should be overridden by the classes that support
-        // switching modes such as the CdmaSMSDispatcher.
-        // Not implemented in GsmSMSDispatcher.
-        Log.e(TAG, "Error! This function should never be executed.");
-    }
-
-    public void switchToCdma() {
-        // This function should be overridden by the classes that support
-        // switching modes such as the CdmaSMSDispatcher.
-        // Not implemented in GsmSMSDispatcher.
-        Log.e(TAG, "Error! This function should never be executed.");
-    }
-
-    public void switchToGsm() {
-        // This function should be overridden by the classes that support
-        // switching modes such as the CdmaSMSDispatcher.
-        // Not implemented in GsmSMSDispatcher.
-        Log.e(TAG, "Error! This function should never be executed.");
-    }
-
-    private DialogInterface.OnClickListener mListener =
+    private final DialogInterface.OnClickListener mListener =
         new DialogInterface.OnClickListener() {
 
             public void onClick(DialogInterface dialog, int which) {
@@ -1007,42 +1053,32 @@
             }
         };
 
-    private BroadcastReceiver mResultReceiver = new BroadcastReceiver() {
+    private final BroadcastReceiver mResultReceiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
-            if (intent.getAction().equals(Intent.ACTION_DEVICE_STORAGE_FULL)) {
-                mStorageAvailable = false;
-                mCm.reportSmsMemoryStatus(false, obtainMessage(EVENT_REPORT_MEMORY_STATUS_DONE));
-            } else if (intent.getAction().equals(Intent.ACTION_DEVICE_STORAGE_NOT_FULL)) {
-                mStorageAvailable = true;
-                mCm.reportSmsMemoryStatus(true, obtainMessage(EVENT_REPORT_MEMORY_STATUS_DONE));
-            } else {
-                // Assume the intent is one of the SMS receive intents that
-                // was sent as an ordered broadcast.  Check result and ACK.
-                int rc = getResultCode();
-                boolean success = (rc == Activity.RESULT_OK)
-                        || (rc == Intents.RESULT_SMS_HANDLED);
+            // Assume the intent is one of the SMS receive intents that
+            // was sent as an ordered broadcast.  Check result and ACK.
+            int rc = getResultCode();
+            boolean success = (rc == Activity.RESULT_OK)
+                    || (rc == Intents.RESULT_SMS_HANDLED);
 
-                // For a multi-part message, this only ACKs the last part.
-                // Previous parts were ACK'd as they were received.
-                acknowledgeLastIncomingSms(success, rc, null);
-            }
+            // For a multi-part message, this only ACKs the last part.
+            // Previous parts were ACK'd as they were received.
+            acknowledgeLastIncomingSms(success, rc, null);
         }
     };
 
-    protected abstract void handleBroadcastSms(AsyncResult ar);
-
     protected void dispatchBroadcastPdus(byte[][] pdus, boolean isEmergencyMessage) {
         if (isEmergencyMessage) {
             Intent intent = new Intent(Intents.SMS_EMERGENCY_CB_RECEIVED_ACTION);
             intent.putExtra("pdus", pdus);
             Log.d(TAG, "Dispatching " + pdus.length + " emergency SMS CB pdus");
-            dispatch(intent, "android.permission.RECEIVE_EMERGENCY_BROADCAST");
+            dispatch(intent, RECEIVE_EMERGENCY_BROADCAST_PERMISSION);
         } else {
             Intent intent = new Intent(Intents.SMS_CB_RECEIVED_ACTION);
             intent.putExtra("pdus", pdus);
             Log.d(TAG, "Dispatching " + pdus.length + " SMS CB pdus");
-            dispatch(intent, "android.permission.RECEIVE_SMS");
+            dispatch(intent, RECEIVE_SMS_PERMISSION);
         }
     }
 }
diff --git a/telephony/java/com/android/internal/telephony/SmsStorageMonitor.java b/telephony/java/com/android/internal/telephony/SmsStorageMonitor.java
new file mode 100644
index 0000000..0c06ffc
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/SmsStorageMonitor.java
@@ -0,0 +1,162 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.telephony;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.AsyncResult;
+import android.os.Handler;
+import android.os.Message;
+import android.os.PowerManager;
+import android.provider.Telephony.Sms.Intents;
+import android.util.Log;
+
+/**
+ * Monitors the device and ICC storage, and sends the appropriate events.
+ *
+ * This code was formerly part of {@link SMSDispatcher}, and has been moved
+ * into a separate class to support instantiation of multiple SMSDispatchers on
+ * dual-mode devices that require support for both 3GPP and 3GPP2 format messages.
+ */
+public final class SmsStorageMonitor extends Handler {
+    private static final String TAG = "SmsStorageMonitor";
+
+    /** SIM/RUIM storage is full */
+    private static final int EVENT_ICC_FULL = 1;
+
+    /** Memory status reporting is acknowledged by RIL */
+    private static final int EVENT_REPORT_MEMORY_STATUS_DONE = 2;
+
+    /** Radio is ON */
+    private static final int EVENT_RADIO_ON = 3;
+
+    /** Context from phone object passed to constructor. */
+    private final Context mContext;
+
+    /** Wake lock to ensure device stays awake while dispatching the SMS intent. */
+    private PowerManager.WakeLock mWakeLock;
+
+    private boolean mReportMemoryStatusPending;
+
+    final CommandsInterface mCm;                            // accessed from inner class
+    boolean mStorageAvailable = true;                       // accessed from inner class
+
+    /**
+     * Hold the wake lock for 5 seconds, which should be enough time for
+     * any receiver(s) to grab its own wake lock.
+     */
+    private static final int WAKE_LOCK_TIMEOUT = 5000;
+
+    /**
+     * Creates an SmsStorageMonitor and registers for events.
+     * @param phone the Phone to use
+     */
+    public SmsStorageMonitor(PhoneBase phone) {
+        mContext = phone.getContext();
+        mCm = phone.mCM;
+
+        createWakelock();
+
+        mCm.setOnIccSmsFull(this, EVENT_ICC_FULL, null);
+        mCm.registerForOn(this, EVENT_RADIO_ON, null);
+
+        // Register for device storage intents.  Use these to notify the RIL
+        // that storage for SMS is or is not available.
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(Intent.ACTION_DEVICE_STORAGE_FULL);
+        filter.addAction(Intent.ACTION_DEVICE_STORAGE_NOT_FULL);
+        mContext.registerReceiver(mResultReceiver, filter);
+    }
+
+    public void dispose() {
+        mCm.unSetOnIccSmsFull(this);
+        mCm.unregisterForOn(this);
+        mContext.unregisterReceiver(mResultReceiver);
+    }
+
+    /**
+     * Handles events coming from the phone stack. Overridden from handler.
+     * @param msg the message to handle
+     */
+    @Override
+    public void handleMessage(Message msg) {
+        AsyncResult ar;
+
+        switch (msg.what) {
+            case EVENT_ICC_FULL:
+                handleIccFull();
+                break;
+
+            case EVENT_REPORT_MEMORY_STATUS_DONE:
+                ar = (AsyncResult) msg.obj;
+                if (ar.exception != null) {
+                    mReportMemoryStatusPending = true;
+                    Log.v(TAG, "Memory status report to modem pending : mStorageAvailable = "
+                            + mStorageAvailable);
+                } else {
+                    mReportMemoryStatusPending = false;
+                }
+                break;
+
+            case EVENT_RADIO_ON:
+                if (mReportMemoryStatusPending) {
+                    Log.v(TAG, "Sending pending memory status report : mStorageAvailable = "
+                            + mStorageAvailable);
+                    mCm.reportSmsMemoryStatus(mStorageAvailable,
+                            obtainMessage(EVENT_REPORT_MEMORY_STATUS_DONE));
+                }
+                break;
+        }
+    }
+
+    private void createWakelock() {
+        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
+        mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "SmsStorageMonitor");
+        mWakeLock.setReferenceCounted(true);
+    }
+
+    /**
+     * Called when SIM_FULL message is received from the RIL.  Notifies interested
+     * parties that SIM storage for SMS messages is full.
+     */
+    private void handleIccFull() {
+        // broadcast SIM_FULL intent
+        Intent intent = new Intent(Intents.SIM_FULL_ACTION);
+        mWakeLock.acquire(WAKE_LOCK_TIMEOUT);
+        mContext.sendBroadcast(intent, SMSDispatcher.RECEIVE_SMS_PERMISSION);
+    }
+
+    /** Returns whether or not there is storage available for an incoming SMS. */
+    public boolean isStorageAvailable() {
+        return mStorageAvailable;
+    }
+
+    private final BroadcastReceiver mResultReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (intent.getAction().equals(Intent.ACTION_DEVICE_STORAGE_FULL)) {
+                mStorageAvailable = false;
+                mCm.reportSmsMemoryStatus(false, obtainMessage(EVENT_REPORT_MEMORY_STATUS_DONE));
+            } else if (intent.getAction().equals(Intent.ACTION_DEVICE_STORAGE_NOT_FULL)) {
+                mStorageAvailable = true;
+                mCm.reportSmsMemoryStatus(true, obtainMessage(EVENT_REPORT_MEMORY_STATUS_DONE));
+            }
+        }
+    };
+}
diff --git a/telephony/java/com/android/internal/telephony/SmsUsageMonitor.java b/telephony/java/com/android/internal/telephony/SmsUsageMonitor.java
new file mode 100644
index 0000000..bd2ae8b
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/SmsUsageMonitor.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.telephony;
+
+import android.content.ContentResolver;
+import android.provider.Settings;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+/**
+ * Implement the per-application based SMS control, which limits the number of
+ * SMS/MMS messages an app can send in the checking period.
+ *
+ * This code was formerly part of {@link SMSDispatcher}, and has been moved
+ * into a separate class to support instantiation of multiple SMSDispatchers on
+ * dual-mode devices that require support for both 3GPP and 3GPP2 format messages.
+ */
+public class SmsUsageMonitor {
+    private static final String TAG = "SmsStorageMonitor";
+
+    /** Default checking period for SMS sent without user permission. */
+    private static final int DEFAULT_SMS_CHECK_PERIOD = 3600000;
+
+    /** Default number of SMS sent in checking period without user permission. */
+    private static final int DEFAULT_SMS_MAX_COUNT = 100;
+
+    private final int mCheckPeriod;
+    private final int mMaxAllowed;
+    private final HashMap<String, ArrayList<Long>> mSmsStamp =
+            new HashMap<String, ArrayList<Long>>();
+
+    /**
+     * Create SMS usage monitor.
+     * @param resolver the ContentResolver to use to load from secure settings
+     */
+    public SmsUsageMonitor(ContentResolver resolver) {
+        mMaxAllowed = Settings.Secure.getInt(resolver,
+                Settings.Secure.SMS_OUTGOING_CHECK_MAX_COUNT,
+                DEFAULT_SMS_MAX_COUNT);
+
+        mCheckPeriod = Settings.Secure.getInt(resolver,
+                Settings.Secure.SMS_OUTGOING_CHECK_INTERVAL_MS,
+                DEFAULT_SMS_CHECK_PERIOD);
+    }
+
+    /** Clear the SMS application list for disposal. */
+    void dispose() {
+        mSmsStamp.clear();
+    }
+
+    /**
+     * Check to see if an application is allowed to send new SMS messages.
+     *
+     * @param appName the application sending sms
+     * @param smsWaiting the number of new messages desired to send
+     * @return true if application is allowed to send the requested number
+     *  of new sms messages
+     */
+    public boolean check(String appName, int smsWaiting) {
+        synchronized (mSmsStamp) {
+            removeExpiredTimestamps();
+
+            ArrayList<Long> sentList = mSmsStamp.get(appName);
+            if (sentList == null) {
+                sentList = new ArrayList<Long>();
+                mSmsStamp.put(appName, sentList);
+            }
+
+            return isUnderLimit(sentList, smsWaiting);
+        }
+    }
+
+    /**
+     * Remove keys containing only old timestamps. This can happen if an SMS app is used
+     * to send messages and then uninstalled.
+     */
+    private void removeExpiredTimestamps() {
+        long beginCheckPeriod = System.currentTimeMillis() - mCheckPeriod;
+
+        synchronized (mSmsStamp) {
+            Iterator<Map.Entry<String, ArrayList<Long>>> iter = mSmsStamp.entrySet().iterator();
+            while (iter.hasNext()) {
+                Map.Entry<String, ArrayList<Long>> entry = iter.next();
+                ArrayList<Long> oldList = entry.getValue();
+                if (oldList.isEmpty() || oldList.get(oldList.size() - 1) < beginCheckPeriod) {
+                    iter.remove();
+                }
+            }
+        }
+    }
+
+    private boolean isUnderLimit(ArrayList<Long> sent, int smsWaiting) {
+        Long ct = System.currentTimeMillis();
+        long beginCheckPeriod = ct - mCheckPeriod;
+
+        Log.d(TAG, "SMS send size=" + sent.size() + " time=" + ct);
+
+        while (!sent.isEmpty() && sent.get(0) < beginCheckPeriod) {
+            sent.remove(0);
+        }
+
+        if ((sent.size() + smsWaiting) <= mMaxAllowed) {
+            for (int i = 0; i < smsWaiting; i++ ) {
+                sent.add(ct);
+            }
+            return true;
+        }
+        return false;
+    }
+}
diff --git a/telephony/java/com/android/internal/telephony/cdma/CDMALTEPhone.java b/telephony/java/com/android/internal/telephony/cdma/CDMALTEPhone.java
index 6903025..c2b9e4f 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CDMALTEPhone.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CDMALTEPhone.java
@@ -27,6 +27,9 @@
 import com.android.internal.telephony.CommandsInterface;
 import com.android.internal.telephony.Phone;
 import com.android.internal.telephony.PhoneNotifier;
+import com.android.internal.telephony.PhoneProxy;
+import com.android.internal.telephony.SMSDispatcher;
+import com.android.internal.telephony.gsm.GsmSMSDispatcher;
 import com.android.internal.telephony.gsm.SimCard;
 import com.android.internal.telephony.ims.IsimRecords;
 
@@ -35,14 +38,13 @@
 
     private static final boolean DBG = true;
 
+    /** Secondary SMSDispatcher for 3GPP format messages. */
+    SMSDispatcher m3gppSMS;
+
     // Constructors
     public CDMALTEPhone(Context context, CommandsInterface ci, PhoneNotifier notifier) {
-        this(context, ci, notifier, false);
-    }
-
-    public CDMALTEPhone(Context context, CommandsInterface ci, PhoneNotifier notifier,
-            boolean unitTestMode) {
         super(context, ci, notifier, false);
+        m3gppSMS = new GsmSMSDispatcher(this, mSmsStorageMonitor, mSmsUsageMonitor);
     }
 
     @Override
@@ -54,6 +56,20 @@
     }
 
     @Override
+    public void dispose() {
+        synchronized(PhoneProxy.lockForRadioTechnologyChange) {
+            super.dispose();
+            m3gppSMS.dispose();
+        }
+    }
+
+    @Override
+    public void removeReferences() {
+        super.removeReferences();
+        m3gppSMS = null;
+    }
+
+    @Override
     public DataState getDataConnectionState(String apnType) {
         DataState ret = DataState.DISCONNECTED;
 
@@ -92,13 +108,15 @@
         return ret;
     }
 
+    @Override
     public boolean updateCurrentCarrierInProvider() {
         if (mIccRecords != null) {
             try {
                 Uri uri = Uri.withAppendedPath(Telephony.Carriers.CONTENT_URI, "current");
                 ContentValues map = new ContentValues();
-                map.put(Telephony.Carriers.NUMERIC, mIccRecords.getOperatorNumeric());
-                log("updateCurrentCarrierInProvider insert uri=" + uri);
+                String operatorNumeric = mIccRecords.getOperatorNumeric();
+                map.put(Telephony.Carriers.NUMERIC, operatorNumeric);
+                log("updateCurrentCarrierInProvider from UICC: numeric=" + operatorNumeric);
                 mContext.getContentResolver().insert(uri, map);
                 return true;
             } catch (SQLException e) {
diff --git a/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java b/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java
index 286515e..09ee28c 100755
--- a/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java
@@ -17,10 +17,9 @@
 package com.android.internal.telephony.cdma;
 
 import android.app.ActivityManagerNative;
-import android.content.Context;
 import android.content.ContentValues;
+import android.content.Context;
 import android.content.Intent;
-import android.content.res.Configuration;
 import android.content.SharedPreferences;
 import android.database.SQLException;
 import android.net.Uri;
@@ -31,7 +30,6 @@
 import android.os.PowerManager.WakeLock;
 import android.os.Registrant;
 import android.os.RegistrantList;
-import android.os.RemoteException;
 import android.os.SystemProperties;
 import android.preference.PreferenceManager;
 import android.provider.Telephony;
@@ -42,20 +40,17 @@
 import android.text.TextUtils;
 import android.util.Log;
 
-import com.android.internal.telephony.cat.CatService;
 import com.android.internal.telephony.Call;
 import com.android.internal.telephony.CallStateException;
+import com.android.internal.telephony.CallTracker;
 import com.android.internal.telephony.CommandException;
 import com.android.internal.telephony.CommandsInterface;
 import com.android.internal.telephony.Connection;
-import com.android.internal.telephony.DataConnection;
-import com.android.internal.telephony.IccRecords;
-import com.android.internal.telephony.MccTable;
-import com.android.internal.telephony.IccCard;
 import com.android.internal.telephony.IccException;
 import com.android.internal.telephony.IccFileHandler;
 import com.android.internal.telephony.IccPhoneBookInterfaceManager;
 import com.android.internal.telephony.IccSmsInterfaceManager;
+import com.android.internal.telephony.MccTable;
 import com.android.internal.telephony.MmiCode;
 import com.android.internal.telephony.OperatorInfo;
 import com.android.internal.telephony.Phone;
@@ -67,19 +62,17 @@
 import com.android.internal.telephony.TelephonyIntents;
 import com.android.internal.telephony.TelephonyProperties;
 import com.android.internal.telephony.UUSInfo;
-import com.android.internal.telephony.CallTracker;
-
-import static com.android.internal.telephony.TelephonyProperties.PROPERTY_ICC_OPERATOR_ALPHA;
-import static com.android.internal.telephony.TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC;
-import static com.android.internal.telephony.TelephonyProperties.PROPERTY_ICC_OPERATOR_ISO_COUNTRY;
+import com.android.internal.telephony.cat.CatService;
 
 import java.util.ArrayList;
 import java.util.List;
-
-
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
+import static com.android.internal.telephony.TelephonyProperties.PROPERTY_ICC_OPERATOR_ALPHA;
+import static com.android.internal.telephony.TelephonyProperties.PROPERTY_ICC_OPERATOR_ISO_COUNTRY;
+import static com.android.internal.telephony.TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC;
+
 /**
  * {@hide}
  */
@@ -109,13 +102,13 @@
     CatService mCcatService;
 
     // mNvLoadedRegistrants are informed after the EVENT_NV_READY
-    private RegistrantList mNvLoadedRegistrants = new RegistrantList();
+    private final RegistrantList mNvLoadedRegistrants = new RegistrantList();
 
     // mEriFileLoadedRegistrants are informed after the ERI text has been loaded
-    private RegistrantList mEriFileLoadedRegistrants = new RegistrantList();
+    private final RegistrantList mEriFileLoadedRegistrants = new RegistrantList();
 
     // mEcmTimerResetRegistrants are informed after Ecm timer is canceled or re-started
-    private RegistrantList mEcmTimerResetRegistrants = new RegistrantList();
+    private final RegistrantList mEcmTimerResetRegistrants = new RegistrantList();
 
     // mEcmExitRespRegistrant is informed after the phone has been exited
     //the emergency callback mode
@@ -131,6 +124,7 @@
 
     // A runnable which is used to automatically exit from Ecm after a period of time.
     private Runnable mExitEcmRunnable = new Runnable() {
+        @Override
         public void run() {
             exitEmergencyCallbackMode();
         }
@@ -164,7 +158,7 @@
     protected void init(Context context, PhoneNotifier notifier) {
         mCM.setPhoneType(Phone.PHONE_TYPE_CDMA);
         mCT = new CdmaCallTracker(this);
-        mSMS = new CdmaSMSDispatcher(this);
+        mSMS = new CdmaSMSDispatcher(this, mSmsStorageMonitor, mSmsUsageMonitor);
         mDataConnectionTracker = new CdmaDataConnectionTracker (this);
         mRuimPhoneBookInterfaceManager = new RuimPhoneBookInterfaceManager(this);
         mRuimSmsInterfaceManager = new RuimSmsInterfaceManager(this, mSMS);
@@ -188,7 +182,7 @@
 
         //Change the system setting
         SystemProperties.set(TelephonyProperties.CURRENT_ACTIVE_PHONE,
-                new Integer(Phone.PHONE_TYPE_CDMA).toString());
+                Integer.toString(Phone.PHONE_TYPE_CDMA));
 
         // This is needed to handle phone process crashes
         String inEcm=SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE, "false");
@@ -220,6 +214,7 @@
         notifier.notifyMessageWaitingChanged(this);
     }
 
+    @Override
     public void dispose() {
         synchronized(PhoneProxy.lockForRadioTechnologyChange) {
             super.dispose();
@@ -253,23 +248,26 @@
         }
     }
 
+    @Override
     public void removeReferences() {
-            log("removeReferences");
-            this.mRuimPhoneBookInterfaceManager = null;
-            this.mRuimSmsInterfaceManager = null;
-            this.mSMS = null;
-            this.mSubInfo = null;
-            this.mIccRecords = null;
-            this.mIccFileHandler = null;
-            this.mIccCard = null;
-            this.mDataConnectionTracker = null;
-            this.mCT = null;
-            this.mSST = null;
-            this.mEriManager = null;
-            this.mCcatService = null;
-            this.mExitEcmRunnable = null;
+        log("removeReferences");
+        super.removeReferences();
+        mRuimPhoneBookInterfaceManager = null;
+        mRuimSmsInterfaceManager = null;
+        mSMS = null;
+        mSubInfo = null;
+        mIccRecords = null;
+        mIccFileHandler = null;
+        mIccCard = null;
+        mDataConnectionTracker = null;
+        mCT = null;
+        mSST = null;
+        mEriManager = null;
+        mCcatService = null;
+        mExitEcmRunnable = null;
     }
 
+    @Override
     protected void finalize() {
         if(DBG) Log.d(LOG_TAG, "CDMAPhone finalized");
         if (mWakeLock.isHeld()) {
@@ -813,7 +811,7 @@
         return null;
     }
 
-   /**
+    /**
      * Notify any interested party of a Phone state change  {@link Phone.State}
      */
     /*package*/ void notifyPhoneStateChanged() {
@@ -858,18 +856,6 @@
         if (DBG) Log.d(LOG_TAG, "sendEmergencyCallbackModeChange");
     }
 
-    /*package*/ void
-    updateMessageWaitingIndicator(boolean mwi) {
-        // this also calls notifyMessageWaitingIndicator()
-        mIccRecords.setVoiceMessageWaiting(1, mwi ? -1 : 0);
-    }
-
-    /* This function is overloaded to send number of voicemails instead of sending true/false */
-    /*package*/ void
-    updateMessageWaitingIndicator(int mwi) {
-        mIccRecords.setVoiceMessageWaiting(1, mwi);
-    }
-
     @Override
     public void exitEmergencyCallbackMode() {
         if (mWakeLock.isHeld()) {
@@ -1013,6 +999,7 @@
 
             case EVENT_RUIM_RECORDS_LOADED:{
                 Log.d(LOG_TAG, "Event EVENT_RUIM_RECORDS_LOADED Received");
+                updateCurrentCarrierInProvider();
             }
             break;
 
@@ -1172,7 +1159,7 @@
     private static final int IS683_CONST_1900MHZ_F_BLOCK = 7;
     private static final int INVALID_SYSTEM_SELECTION_CODE = -1;
 
-    private boolean isIs683OtaSpDialStr(String dialStr) {
+    private static boolean isIs683OtaSpDialStr(String dialStr) {
         int sysSelCodeInt;
         boolean isOtaspDialString = false;
         int dialStrLen = dialStr.length();
@@ -1203,7 +1190,7 @@
     /**
      * This function extracts the system selection code from the dial string.
      */
-    private int extractSelCodeFromOtaSpNum(String dialStr) {
+    private static int extractSelCodeFromOtaSpNum(String dialStr) {
         int dialStrLen = dialStr.length();
         int sysSelCodeInt = INVALID_SYSTEM_SELECTION_CODE;
 
@@ -1226,7 +1213,7 @@
      * the dial string "sysSelCodeInt' is the system selection code specified
      * in the carrier ota sp number schema "sch".
      */
-    private boolean
+    private static boolean
     checkOtaSpNumBasedOnSysSelCode (int sysSelCodeInt, String sch[]) {
         boolean isOtaSpNum = false;
         try {
@@ -1414,7 +1401,7 @@
                 Uri uri = Uri.withAppendedPath(Telephony.Carriers.CONTENT_URI, "current");
                 ContentValues map = new ContentValues();
                 map.put(Telephony.Carriers.NUMERIC, operatorNumeric);
-                log("updateCurrentCarrierInProvider insert uri=" + uri);
+                log("updateCurrentCarrierInProvider from system: numeric=" + operatorNumeric);
                 getContext().getContentResolver().insert(uri, map);
 
                 // Updates MCC MNC device configuration information
@@ -1428,6 +1415,16 @@
         return false;
     }
 
+    /**
+     * Sets the "current" field in the telephony provider according to the SIM's operator.
+     * Implemented in {@link CDMALTEPhone} for CDMA/LTE devices.
+     *
+     * @return true for success; false otherwise.
+     */
+    boolean updateCurrentCarrierInProvider() {
+        return true;
+    }
+
     public void prepareEri() {
         mEriManager.loadEriFile();
         if(mEriManager.isEriFileLoaded()) {
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaLteUiccRecords.java b/telephony/java/com/android/internal/telephony/cdma/CdmaLteUiccRecords.java
index 0617fee..47c638f 100755
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaLteUiccRecords.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaLteUiccRecords.java
@@ -26,6 +26,7 @@
 import com.android.internal.telephony.IccUtils;
 import com.android.internal.telephony.MccTable;
 import com.android.internal.telephony.PhoneBase;
+import com.android.internal.telephony.SmsMessageBase;
 import com.android.internal.telephony.cdma.sms.UserData;
 import com.android.internal.telephony.gsm.SIMRecords;
 import com.android.internal.telephony.ims.IsimRecords;
@@ -438,4 +439,13 @@
         }
         return true;
     }
+
+    /**
+     * Dispatch 3GPP format message. For CDMA/LTE phones,
+     * send the message to the secondary 3GPP format SMS dispatcher.
+     */
+    @Override
+    protected int dispatchGsmMessage(SmsMessageBase message) {
+        return ((CDMALTEPhone) phone).m3gppSMS.dispatchMessage(message);
+    }
 }
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java b/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java
index 07b0f4f..dded39e 100755
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java
@@ -25,7 +25,6 @@
 import android.content.SharedPreferences;
 import android.database.Cursor;
 import android.database.SQLException;
-import android.os.AsyncResult;
 import android.os.Message;
 import android.os.SystemProperties;
 import android.preference.PreferenceManager;
@@ -40,6 +39,8 @@
 import com.android.internal.telephony.SmsHeader;
 import com.android.internal.telephony.SmsMessageBase;
 import com.android.internal.telephony.SmsMessageBase.TextEncodingDetails;
+import com.android.internal.telephony.SmsStorageMonitor;
+import com.android.internal.telephony.SmsUsageMonitor;
 import com.android.internal.telephony.TelephonyProperties;
 import com.android.internal.telephony.WspTypeDecoder;
 import com.android.internal.telephony.cdma.sms.SmsEnvelope;
@@ -47,7 +48,6 @@
 import com.android.internal.util.HexDump;
 
 import java.io.ByteArrayOutputStream;
-import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashMap;
 
@@ -60,24 +60,23 @@
     private byte[] mLastDispatchedSmsFingerprint;
     private byte[] mLastAcknowledgedSmsFingerprint;
 
-    private boolean mCheckForDuplicatePortsInOmadmWapPush = Resources.getSystem().getBoolean(
+    private final boolean mCheckForDuplicatePortsInOmadmWapPush = Resources.getSystem().getBoolean(
             com.android.internal.R.bool.config_duplicate_port_omadm_wappush);
 
-    CdmaSMSDispatcher(CDMAPhone phone) {
-        super(phone);
+    CdmaSMSDispatcher(CDMAPhone phone, SmsStorageMonitor storageMonitor,
+            SmsUsageMonitor usageMonitor) {
+        super(phone, storageMonitor, usageMonitor);
+        mCm.setOnNewCdmaSms(this, EVENT_NEW_SMS, null);
     }
 
-    /**
-     * Called when a status report is received.  This should correspond to
-     * a previously successful SEND.
-     * Is a special GSM function, should never be called in CDMA!!
-     *
-     * @param ar AsyncResult passed into the message handler.  ar.result should
-     *           be a String representing the status report PDU, as ASCII hex.
-     */
     @Override
-    protected void handleStatusReport(AsyncResult ar) {
-        Log.d(TAG, "handleStatusReport is a special GSM function, should never be called in CDMA!");
+    public void dispose() {
+        mCm.unSetOnNewCdmaSms(this);
+    }
+
+    @Override
+    protected String getFormat() {
+        return android.telephony.SmsMessage.FORMAT_3GPP2;
     }
 
     private void handleCdmaStatusReport(SmsMessage sms) {
@@ -138,11 +137,11 @@
             Log.d(TAG, "Voicemail count=" + voicemailCount);
             // Store the voicemail count in preferences.
             SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(
-                    mPhone.getContext());
+                    mContext);
             SharedPreferences.Editor editor = sp.edit();
             editor.putInt(CDMAPhone.VM_COUNT_CDMA, voicemailCount);
             editor.apply();
-            ((CDMAPhone) mPhone).updateMessageWaitingIndicator(voicemailCount);
+            mPhone.setVoiceMessageWaiting(1, voicemailCount);
             handled = true;
         } else if (((SmsEnvelope.TELESERVICE_WMT == teleService) ||
                 (SmsEnvelope.TELESERVICE_WEMT == teleService)) &&
@@ -160,7 +159,8 @@
             return Intents.RESULT_SMS_HANDLED;
         }
 
-        if (!mStorageAvailable && (sms.getMessageClass() != MessageClass.CLASS_0)) {
+        if (!mStorageMonitor.isStorageAvailable() &&
+                sms.getMessageClass() != MessageClass.CLASS_0) {
             // It's a storable message and there's no storage available.  Bail.
             // (See C.S0015-B v2.0 for a description of "Immediate Display"
             // messages, which we represent as CLASS_0.)
@@ -181,48 +181,7 @@
             return Intents.RESULT_SMS_UNSUPPORTED;
         }
 
-        /*
-         * TODO(cleanup): Why are we using a getter method for this
-         * (and for so many other sms fields)?  Trivial getters and
-         * setters like this are direct violations of the style guide.
-         * If the purpose is to protect against writes (by not
-         * providing a setter) then any protection is illusory (and
-         * hence bad) for cases where the values are not primitives,
-         * such as this call for the header.  Since this is an issue
-         * with the public API it cannot be changed easily, but maybe
-         * something can be done eventually.
-         */
-        SmsHeader smsHeader = sms.getUserDataHeader();
-
-        /*
-         * TODO(cleanup): Since both CDMA and GSM use the same header
-         * format, this dispatch processing is naturally identical,
-         * and code should probably not be replicated explicitly.
-         */
-
-        // See if message is partial or port addressed.
-        if ((smsHeader == null) || (smsHeader.concatRef == null)) {
-            // Message is not partial (not part of concatenated sequence).
-            byte[][] pdus = new byte[1][];
-            pdus[0] = sms.getPdu();
-
-            if (smsHeader != null && smsHeader.portAddrs != null) {
-                if (smsHeader.portAddrs.destPort == SmsHeader.PORT_WAP_PUSH) {
-                    // GSM-style WAP indication
-                    return mWapPush.dispatchWapPdu(sms.getUserData());
-                } else {
-                    // The message was sent to a port, so concoct a URI for it.
-                    dispatchPortAddressedPdus(pdus, smsHeader.portAddrs.destPort);
-                }
-            } else {
-                // Normal short and non-port-addressed message, dispatch it.
-                dispatchPdus(pdus);
-            }
-            return Activity.RESULT_OK;
-        } else {
-            // Process the message part.
-            return processMessagePart(sms, smsHeader.concatRef, smsHeader.portAddrs);
-        }
+        return dispatchNormalMessage(smsb);
     }
 
     /**
@@ -236,23 +195,19 @@
      *         to applications
      */
     protected int processCdmaWapPdu(byte[] pdu, int referenceNumber, String address) {
-        int segment;
-        int totalSegments;
         int index = 0;
-        int msgType;
 
-        int sourcePort = 0;
-        int destinationPort = 0;
-
-        msgType = pdu[index++];
-        if (msgType != 0){
+        int msgType = pdu[index++];
+        if (msgType != 0) {
             Log.w(TAG, "Received a WAP SMS which is not WDP. Discard.");
             return Intents.RESULT_SMS_HANDLED;
         }
-        totalSegments = pdu[index++]; // >=1
-        segment = pdu[index++]; // >=0
+        int totalSegments = pdu[index++];   // >= 1
+        int segment = pdu[index++];         // >= 0
 
         // Only the first segment contains sourcePort and destination Port
+        int sourcePort = 0;
+        int destinationPort = 0;
         if (segment == 0) {
             //process WDP segment
             sourcePort = (0xFF & pdu[index++]) << 8;
@@ -269,90 +224,16 @@
         }
 
         // Lookup all other related parts
-        StringBuilder where = new StringBuilder("reference_number =");
-        where.append(referenceNumber);
-        where.append(" AND address = ?");
-        String[] whereArgs = new String[] {address};
-
         Log.i(TAG, "Received WAP PDU. Type = " + msgType + ", originator = " + address
                 + ", src-port = " + sourcePort + ", dst-port = " + destinationPort
-                + ", ID = " + referenceNumber + ", segment# = " + segment + "/" + totalSegments);
+                + ", ID = " + referenceNumber + ", segment# = " + segment + '/' + totalSegments);
 
-        byte[][] pdus = null;
-        Cursor cursor = null;
-        try {
-            cursor = mResolver.query(mRawUri, RAW_PROJECTION, where.toString(), whereArgs, null);
-            int cursorCount = cursor.getCount();
-            if (cursorCount != totalSegments - 1) {
-                // We don't have all the parts yet, store this one away
-                ContentValues values = new ContentValues();
-                values.put("date", (long) 0);
-                values.put("pdu", HexDump.toHexString(pdu, index, pdu.length - index));
-                values.put("address", address);
-                values.put("reference_number", referenceNumber);
-                values.put("count", totalSegments);
-                values.put("sequence", segment);
-                values.put("destination_port", destinationPort);
+        // pass the user data portion of the PDU to the shared handler in SMSDispatcher
+        byte[] userData = new byte[pdu.length - index];
+        System.arraycopy(pdu, index, userData, 0, pdu.length - index);
 
-                mResolver.insert(mRawUri, values);
-
-                return Intents.RESULT_SMS_HANDLED;
-            }
-
-            // All the parts are in place, deal with them
-            int pduColumn = cursor.getColumnIndex("pdu");
-            int sequenceColumn = cursor.getColumnIndex("sequence");
-
-            pdus = new byte[totalSegments][];
-            for (int i = 0; i < cursorCount; i++) {
-                cursor.moveToNext();
-                int cursorSequence = (int)cursor.getLong(sequenceColumn);
-                // Read the destination port from the first segment
-                if (cursorSequence == 0) {
-                    int destinationPortColumn = cursor.getColumnIndex("destination_port");
-                    destinationPort = (int)cursor.getLong(destinationPortColumn);
-                }
-                pdus[cursorSequence] = HexDump.hexStringToByteArray(
-                        cursor.getString(pduColumn));
-            }
-            // The last part will be added later
-
-            // Remove the parts from the database
-            mResolver.delete(mRawUri, where.toString(), whereArgs);
-        } catch (SQLException e) {
-            Log.e(TAG, "Can't access multipart SMS database", e);
-            return Intents.RESULT_SMS_GENERIC_ERROR;
-        } finally {
-            if (cursor != null) cursor.close();
-        }
-
-        // Build up the data stream
-        ByteArrayOutputStream output = new ByteArrayOutputStream();
-        for (int i = 0; i < totalSegments; i++) {
-            // reassemble the (WSP-)pdu
-            if (i == segment) {
-                // This one isn't in the DB, so add it
-                output.write(pdu, index, pdu.length - index);
-            } else {
-                output.write(pdus[i], 0, pdus[i].length);
-            }
-        }
-
-        byte[] datagram = output.toByteArray();
-        // Dispatch the PDU to applications
-        switch (destinationPort) {
-        case SmsHeader.PORT_WAP_PUSH:
-            // Handle the PUSH
-            return mWapPush.dispatchWapPdu(datagram);
-
-        default:{
-            pdus = new byte[1][];
-            pdus[0] = datagram;
-            // The messages were sent to any other WAP port
-            dispatchPortAddressedPdus(pdus, destinationPort);
-            return Activity.RESULT_OK;
-        }
-        }
+        return processMessagePart(userData, address, referenceNumber, segment, totalSegments,
+                0L, destinationPort, true);
     }
 
     /** {@inheritDoc} */
@@ -375,68 +256,34 @@
 
     /** {@inheritDoc} */
     @Override
-    protected void sendMultipartText(String destAddr, String scAddr,
-            ArrayList<String> parts, ArrayList<PendingIntent> sentIntents,
-            ArrayList<PendingIntent> deliveryIntents) {
+    protected TextEncodingDetails calculateLength(CharSequence messageBody,
+            boolean use7bitOnly) {
+        return SmsMessage.calculateLength(messageBody, use7bitOnly);
+    }
 
-        /**
-         * TODO(cleanup): There is no real code difference between
-         * this and the GSM version, and hence it should be moved to
-         * the base class or consolidated somehow, provided calling
-         * the proper submit pdu stuff can be arranged.
-         */
-
-        int refNumber = getNextConcatenatedRef() & 0x00FF;
-        int msgCount = parts.size();
-        int encoding = android.telephony.SmsMessage.ENCODING_UNKNOWN;
-
-        for (int i = 0; i < msgCount; i++) {
-            TextEncodingDetails details = SmsMessage.calculateLength(parts.get(i), false);
-            if (encoding != details.codeUnitSize
-                    && (encoding == android.telephony.SmsMessage.ENCODING_UNKNOWN
-                            || encoding == android.telephony.SmsMessage.ENCODING_7BIT)) {
-                encoding = details.codeUnitSize;
-            }
+    /** {@inheritDoc} */
+    @Override
+    protected void sendNewSubmitPdu(String destinationAddress, String scAddress,
+            String message, SmsHeader smsHeader, int encoding,
+            PendingIntent sentIntent, PendingIntent deliveryIntent, boolean lastPart) {
+        UserData uData = new UserData();
+        uData.payloadStr = message;
+        uData.userDataHeader = smsHeader;
+        if (encoding == android.telephony.SmsMessage.ENCODING_7BIT) {
+            uData.msgEncoding = UserData.ENCODING_GSM_7BIT_ALPHABET;
+        } else { // assume UTF-16
+            uData.msgEncoding = UserData.ENCODING_UNICODE_16;
         }
+        uData.msgEncodingSet = true;
 
-        for (int i = 0; i < msgCount; i++) {
-            SmsHeader.ConcatRef concatRef = new SmsHeader.ConcatRef();
-            concatRef.refNumber = refNumber;
-            concatRef.seqNumber = i + 1;  // 1-based sequence
-            concatRef.msgCount = msgCount;
-            concatRef.isEightBits = true;
-            SmsHeader smsHeader = new SmsHeader();
-            smsHeader.concatRef = concatRef;
+        /* By setting the statusReportRequested bit only for the
+         * last message fragment, this will result in only one
+         * callback to the sender when that last fragment delivery
+         * has been acknowledged. */
+        SmsMessage.SubmitPdu submitPdu = SmsMessage.getSubmitPdu(destinationAddress,
+                uData, (deliveryIntent != null) && lastPart);
 
-            PendingIntent sentIntent = null;
-            if (sentIntents != null && sentIntents.size() > i) {
-                sentIntent = sentIntents.get(i);
-            }
-
-            PendingIntent deliveryIntent = null;
-            if (deliveryIntents != null && deliveryIntents.size() > i) {
-                deliveryIntent = deliveryIntents.get(i);
-            }
-
-            UserData uData = new UserData();
-            uData.payloadStr = parts.get(i);
-            uData.userDataHeader = smsHeader;
-            if (encoding == android.telephony.SmsMessage.ENCODING_7BIT) {
-                uData.msgEncoding = UserData.ENCODING_GSM_7BIT_ALPHABET;
-            } else { // assume UTF-16
-                uData.msgEncoding = UserData.ENCODING_UNICODE_16;
-            }
-            uData.msgEncodingSet = true;
-
-            /* By setting the statusReportRequested bit only for the
-             * last message fragment, this will result in only one
-             * callback to the sender when that last fragment delivery
-             * has been acknowledged. */
-            SmsMessage.SubmitPdu submitPdu = SmsMessage.getSubmitPdu(destAddr,
-                    uData, (deliveryIntent != null) && (i == (msgCount - 1)));
-
-            sendSubmitPdu(submitPdu, sentIntent, deliveryIntent);
-        }
+        sendSubmitPdu(submitPdu, sentIntent, deliveryIntent);
     }
 
     protected void sendSubmitPdu(SmsMessage.SubmitPdu pdu,
@@ -464,43 +311,27 @@
         byte pdu[] = (byte[]) map.get("pdu");
 
         Message reply = obtainMessage(EVENT_SEND_SMS_COMPLETE, tracker);
-
         mCm.sendCdmaSms(pdu, reply);
     }
 
-     /** {@inheritDoc} */
-    @Override
-    protected void sendMultipartSms (SmsTracker tracker) {
-        Log.d(TAG, "TODO: CdmaSMSDispatcher.sendMultipartSms not implemented");
-    }
-
     /** {@inheritDoc} */
     @Override
-    protected void acknowledgeLastIncomingSms(boolean success, int result, Message response){
-        // FIXME unit test leaves cm == null. this should change
-
+    protected void acknowledgeLastIncomingSms(boolean success, int result, Message response) {
         String inEcm=SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE, "false");
         if (inEcm.equals("true")) {
             return;
         }
 
-        if (mCm != null) {
-            int causeCode = resultToCause(result);
-            mCm.acknowledgeLastIncomingCdmaSms(success, causeCode, response);
+        int causeCode = resultToCause(result);
+        mCm.acknowledgeLastIncomingCdmaSms(success, causeCode, response);
 
-            if (causeCode == 0) {
-                mLastAcknowledgedSmsFingerprint = mLastDispatchedSmsFingerprint;
-            }
-            mLastDispatchedSmsFingerprint = null;
+        if (causeCode == 0) {
+            mLastAcknowledgedSmsFingerprint = mLastDispatchedSmsFingerprint;
         }
+        mLastDispatchedSmsFingerprint = null;
     }
 
-    protected void handleBroadcastSms(AsyncResult ar) {
-        // Not supported
-        Log.e(TAG, "Error! Not implemented for CDMA.");
-    }
-
-    private int resultToCause(int rc) {
+    private static int resultToCause(int rc) {
         switch (rc) {
         case Activity.RESULT_OK:
         case Intents.RESULT_SMS_HANDLED:
@@ -527,7 +358,7 @@
      * @return True if OrigPdu is OmaDM Push Message which has duplicate ports.
      *         False if OrigPdu is NOT OmaDM Push Message which has duplicate ports.
      */
-    private boolean checkDuplicatePortOmadmWappush(byte[] origPdu, int index) {
+    private static boolean checkDuplicatePortOmadmWappush(byte[] origPdu, int index) {
         index += 4;
         byte[] omaPdu = new byte[origPdu.length - index];
         System.arraycopy(origPdu, index, omaPdu, 0, omaPdu.length);
diff --git a/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java b/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java
index be5c616..1409cab 100644
--- a/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java
+++ b/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java
@@ -114,30 +114,6 @@
     }
 
     /**
-     * Note: This function is a GSM specific functionality which is not supported in CDMA mode.
-     */
-    public static SmsMessage newFromCMT(String[] lines) {
-        Log.w(LOG_TAG, "newFromCMT: is not supported in CDMA mode.");
-        return null;
-    }
-
-    /**
-     * Note: This function is a GSM specific functionality which is not supported in CDMA mode.
-     */
-    public static SmsMessage newFromCMTI(String line) {
-        Log.w(LOG_TAG, "newFromCMTI: is not supported in CDMA mode.");
-        return null;
-    }
-
-    /**
-     * Note: This function is a GSM specific functionality which is not supported in CDMA mode.
-     */
-    public static SmsMessage newFromCDS(String line) {
-        Log.w(LOG_TAG, "newFromCDS: is not supported in CDMA mode.");
-        return null;
-    }
-
-    /**
      *  Create a "raw" CDMA SmsMessage from a Parcel that was forged in ril.cpp.
      *  Note: Only primitive fields are set.
      */
diff --git a/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java b/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java
index d325aaa..e1f4c4b 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java
@@ -56,9 +56,6 @@
 import com.android.internal.telephony.CallStateException;
 import com.android.internal.telephony.CommandsInterface;
 import com.android.internal.telephony.Connection;
-import com.android.internal.telephony.DataConnection;
-import com.android.internal.telephony.DataConnectionTracker;
-import com.android.internal.telephony.IccCard;
 import com.android.internal.telephony.IccFileHandler;
 import com.android.internal.telephony.IccPhoneBookInterfaceManager;
 import com.android.internal.telephony.IccSmsInterfaceManager;
@@ -140,7 +137,7 @@
         mCM.setPhoneType(Phone.PHONE_TYPE_GSM);
         mCT = new GsmCallTracker(this);
         mSST = new GsmServiceStateTracker (this);
-        mSMS = new GsmSMSDispatcher(this);
+        mSMS = new GsmSMSDispatcher(this, mSmsStorageMonitor, mSmsUsageMonitor);
         mIccFileHandler = new SIMFileHandler(this);
         mIccRecords = new SIMRecords(this);
         mDataConnectionTracker = new GsmDataConnectionTracker (this);
@@ -199,6 +196,7 @@
                 new Integer(Phone.PHONE_TYPE_GSM).toString());
     }
 
+    @Override
     public void dispose() {
         synchronized(PhoneProxy.lockForRadioTechnologyChange) {
             super.dispose();
@@ -228,19 +226,22 @@
         }
     }
 
+    @Override
     public void removeReferences() {
-            this.mSimulatedRadioControl = null;
-            this.mStkService = null;
-            this.mSimPhoneBookIntManager = null;
-            this.mSimSmsIntManager = null;
-            this.mSMS = null;
-            this.mSubInfo = null;
-            this.mIccRecords = null;
-            this.mIccFileHandler = null;
-            this.mIccCard = null;
-            this.mDataConnectionTracker = null;
-            this.mCT = null;
-            this.mSST = null;
+        Log.d(LOG_TAG, "removeReferences");
+        super.removeReferences();
+        mSimulatedRadioControl = null;
+        mStkService = null;
+        mSimPhoneBookIntManager = null;
+        mSimSmsIntManager = null;
+        mSMS = null;
+        mSubInfo = null;
+        mIccRecords = null;
+        mIccFileHandler = null;
+        mIccCard = null;
+        mDataConnectionTracker = null;
+        mCT = null;
+        mSST = null;
     }
 
     protected void finalize() {
@@ -406,17 +407,6 @@
     }
 
     public void
-    notifyDataConnectionFailed(String reason, String apnType) {
-        mNotifier.notifyDataConnectionFailed(this, reason, apnType);
-    }
-
-    /*package*/ void
-    updateMessageWaitingIndicator(boolean mwi) {
-        // this also calls notifyMessageWaitingIndicator()
-        mIccRecords.setVoiceMessageWaiting(1, mwi ? -1 : 0);
-    }
-
-    public void
     notifyCallForwardingIndicator() {
         mNotifier.notifyCallForwardingChanged(this);
     }
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java b/telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java
index 52ca453..4e1cc9a 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java
@@ -30,13 +30,15 @@
 import android.telephony.gsm.GsmCellLocation;
 import android.util.Log;
 
-import com.android.internal.telephony.BaseCommands;
 import com.android.internal.telephony.CommandsInterface;
 import com.android.internal.telephony.IccUtils;
+import com.android.internal.telephony.PhoneBase;
 import com.android.internal.telephony.SMSDispatcher;
 import com.android.internal.telephony.SmsHeader;
 import com.android.internal.telephony.SmsMessageBase;
 import com.android.internal.telephony.SmsMessageBase.TextEncodingDetails;
+import com.android.internal.telephony.SmsStorageMonitor;
+import com.android.internal.telephony.SmsUsageMonitor;
 import com.android.internal.telephony.TelephonyProperties;
 
 import java.util.ArrayList;
@@ -45,16 +47,55 @@
 
 import static android.telephony.SmsMessage.MessageClass;
 
-final class GsmSMSDispatcher extends SMSDispatcher {
+public final class GsmSMSDispatcher extends SMSDispatcher {
     private static final String TAG = "GSM";
 
-    private GSMPhone mGsmPhone;
+    /** Status report received */
+    private static final int EVENT_NEW_SMS_STATUS_REPORT = 100;
 
-    GsmSMSDispatcher(GSMPhone phone) {
-        super(phone);
-        mGsmPhone = phone;
+    /** New broadcast SMS */
+    private static final int EVENT_NEW_BROADCAST_SMS = 101;
 
-        ((BaseCommands)mCm).setOnNewGsmBroadcastSms(this, EVENT_NEW_BROADCAST_SMS, null);
+    public GsmSMSDispatcher(PhoneBase phone, SmsStorageMonitor storageMonitor,
+            SmsUsageMonitor usageMonitor) {
+        super(phone, storageMonitor, usageMonitor);
+        mCm.setOnNewGsmSms(this, EVENT_NEW_SMS, null);
+        mCm.setOnSmsStatus(this, EVENT_NEW_SMS_STATUS_REPORT, null);
+        mCm.setOnNewGsmBroadcastSms(this, EVENT_NEW_BROADCAST_SMS, null);
+    }
+
+    @Override
+    public void dispose() {
+        mCm.unSetOnNewGsmSms(this);
+        mCm.unSetOnSmsStatus(this);
+        mCm.unSetOnNewGsmBroadcastSms(this);
+    }
+
+    @Override
+    protected String getFormat() {
+        return android.telephony.SmsMessage.FORMAT_3GPP;
+    }
+
+    /**
+     * Handles 3GPP format-specific events coming from the phone stack.
+     * Other events are handled by {@link SMSDispatcher#handleMessage}.
+     *
+     * @param msg the message to handle
+     */
+    @Override
+    public void handleMessage(Message msg) {
+        switch (msg.what) {
+        case EVENT_NEW_SMS_STATUS_REPORT:
+            handleStatusReport((AsyncResult) msg.obj);
+            break;
+
+        case EVENT_NEW_BROADCAST_SMS:
+            handleBroadcastSms((AsyncResult)msg.obj);
+            break;
+
+        default:
+            super.handleMessage(msg);
+        }
     }
 
     /**
@@ -64,8 +105,7 @@
      * @param ar AsyncResult passed into the message handler.  ar.result should
      *           be a String representing the status report PDU, as ASCII hex.
      */
-    @Override
-    protected void handleStatusReport(AsyncResult ar) {
+    private void handleStatusReport(AsyncResult ar) {
         String pduString = (String) ar.result;
         SmsMessage sms = SmsMessage.newFromCDS(pduString);
 
@@ -94,17 +134,17 @@
         acknowledgeLastIncomingSms(true, Intents.RESULT_SMS_HANDLED, null);
     }
 
-
     /** {@inheritDoc} */
     @Override
     public int dispatchMessage(SmsMessageBase smsb) {
 
         // If sms is null, means there was a parsing error.
         if (smsb == null) {
+            Log.e(TAG, "dispatchMessage: message is null");
             return Intents.RESULT_SMS_GENERIC_ERROR;
         }
+
         SmsMessage sms = (SmsMessage) smsb;
-        boolean handled = false;
 
         if (sms.isTypeZero()) {
             // As per 3GPP TS 23.040 9.2.3.9, Type Zero messages should not be
@@ -121,14 +161,15 @@
         }
 
         // Special case the message waiting indicator messages
+        boolean handled = false;
         if (sms.isMWISetMessage()) {
-            mGsmPhone.updateMessageWaitingIndicator(true);
+            mPhone.setVoiceMessageWaiting(1, -1);  // line 1: unknown number of msgs waiting
             handled = sms.isMwiDontStore();
             if (false) {
                 Log.d(TAG, "Received voice mail indicator set SMS shouldStore=" + !handled);
             }
         } else if (sms.isMWIClearMessage()) {
-            mGsmPhone.updateMessageWaitingIndicator(false);
+            mPhone.setVoiceMessageWaiting(1, 0);   // line 1: no msgs waiting
             handled = sms.isMwiDontStore();
             if (false) {
                 Log.d(TAG, "Received voice mail indicator clear SMS shouldStore=" + !handled);
@@ -139,35 +180,14 @@
             return Intents.RESULT_SMS_HANDLED;
         }
 
-        if (!mStorageAvailable && (sms.getMessageClass() != MessageClass.CLASS_0)) {
+        if (!mStorageMonitor.isStorageAvailable() &&
+                sms.getMessageClass() != MessageClass.CLASS_0) {
             // It's a storable message and there's no storage available.  Bail.
             // (See TS 23.038 for a description of class 0 messages.)
             return Intents.RESULT_SMS_OUT_OF_MEMORY;
         }
 
-        SmsHeader smsHeader = sms.getUserDataHeader();
-         // See if message is partial or port addressed.
-        if ((smsHeader == null) || (smsHeader.concatRef == null)) {
-            // Message is not partial (not part of concatenated sequence).
-            byte[][] pdus = new byte[1][];
-            pdus[0] = sms.getPdu();
-
-            if (smsHeader != null && smsHeader.portAddrs != null) {
-                if (smsHeader.portAddrs.destPort == SmsHeader.PORT_WAP_PUSH) {
-                    return mWapPush.dispatchWapPdu(sms.getUserData());
-                } else {
-                    // The message was sent to a port, so concoct a URI for it.
-                    dispatchPortAddressedPdus(pdus, smsHeader.portAddrs.destPort);
-                }
-            } else {
-                // Normal short and non-port-addressed message, dispatch it.
-                dispatchPdus(pdus);
-            }
-            return Activity.RESULT_OK;
-        } else {
-            // Process the message part.
-            return processMessagePart(sms, smsHeader.concatRef, smsHeader.portAddrs);
-        }
+        return dispatchNormalMessage(smsb);
     }
 
     /** {@inheritDoc} */
@@ -190,158 +210,20 @@
 
     /** {@inheritDoc} */
     @Override
-    protected void sendMultipartText(String destinationAddress, String scAddress,
-            ArrayList<String> parts, ArrayList<PendingIntent> sentIntents,
-            ArrayList<PendingIntent> deliveryIntents) {
-
-        int refNumber = getNextConcatenatedRef() & 0x00FF;
-        int msgCount = parts.size();
-        int encoding = android.telephony.SmsMessage.ENCODING_UNKNOWN;
-
-        mRemainingMessages = msgCount;
-
-        TextEncodingDetails[] encodingForParts = new TextEncodingDetails[msgCount];
-        for (int i = 0; i < msgCount; i++) {
-            TextEncodingDetails details = SmsMessage.calculateLength(parts.get(i), false);
-            if (encoding != details.codeUnitSize
-                    && (encoding == android.telephony.SmsMessage.ENCODING_UNKNOWN
-                            || encoding == android.telephony.SmsMessage.ENCODING_7BIT)) {
-                encoding = details.codeUnitSize;
-            }
-            encodingForParts[i] = details;
-        }
-
-        for (int i = 0; i < msgCount; i++) {
-            SmsHeader.ConcatRef concatRef = new SmsHeader.ConcatRef();
-            concatRef.refNumber = refNumber;
-            concatRef.seqNumber = i + 1;  // 1-based sequence
-            concatRef.msgCount = msgCount;
-            // TODO: We currently set this to true since our messaging app will never
-            // send more than 255 parts (it converts the message to MMS well before that).
-            // However, we should support 3rd party messaging apps that might need 16-bit
-            // references
-            // Note:  It's not sufficient to just flip this bit to true; it will have
-            // ripple effects (several calculations assume 8-bit ref).
-            concatRef.isEightBits = true;
-            SmsHeader smsHeader = new SmsHeader();
-            smsHeader.concatRef = concatRef;
-            if (encoding == android.telephony.SmsMessage.ENCODING_7BIT) {
-                smsHeader.languageTable = encodingForParts[i].languageTable;
-                smsHeader.languageShiftTable = encodingForParts[i].languageShiftTable;
-            }
-
-            PendingIntent sentIntent = null;
-            if (sentIntents != null && sentIntents.size() > i) {
-                sentIntent = sentIntents.get(i);
-            }
-
-            PendingIntent deliveryIntent = null;
-            if (deliveryIntents != null && deliveryIntents.size() > i) {
-                deliveryIntent = deliveryIntents.get(i);
-            }
-
-            SmsMessage.SubmitPdu pdus = SmsMessage.getSubmitPdu(scAddress, destinationAddress,
-                    parts.get(i), deliveryIntent != null, SmsHeader.toByteArray(smsHeader),
-                    encoding, smsHeader.languageTable, smsHeader.languageShiftTable);
-
-            sendRawPdu(pdus.encodedScAddress, pdus.encodedMessage, sentIntent, deliveryIntent);
-        }
+    protected TextEncodingDetails calculateLength(CharSequence messageBody,
+            boolean use7bitOnly) {
+        return SmsMessage.calculateLength(messageBody, use7bitOnly);
     }
 
-    /**
-     * Send a multi-part text based SMS which already passed SMS control check.
-     *
-     * It is the working function for sendMultipartText().
-     *
-     * @param destinationAddress the address to send the message to
-     * @param scAddress is the service center address or null to use
-     *   the current default SMSC
-     * @param parts an <code>ArrayList</code> of strings that, in order,
-     *   comprise the original message
-     * @param sentIntents if not null, an <code>ArrayList</code> of
-     *   <code>PendingIntent</code>s (one for each message part) that is
-     *   broadcast when the corresponding message part has been sent.
-     *   The result code will be <code>Activity.RESULT_OK<code> for success,
-     *   or one of these errors:
-     *   <code>RESULT_ERROR_GENERIC_FAILURE</code>
-     *   <code>RESULT_ERROR_RADIO_OFF</code>
-     *   <code>RESULT_ERROR_NULL_PDU</code>.
-     * @param deliveryIntents if not null, an <code>ArrayList</code> of
-     *   <code>PendingIntent</code>s (one for each message part) that is
-     *   broadcast when the corresponding message part has been delivered
-     *   to the recipient.  The raw pdu of the status report is in the
-     *   extended data ("pdu").
-     */
-    private void sendMultipartTextWithPermit(String destinationAddress,
-            String scAddress, ArrayList<String> parts,
-            ArrayList<PendingIntent> sentIntents,
-            ArrayList<PendingIntent> deliveryIntents) {
-
-        // check if in service
-        int ss = mPhone.getServiceState().getState();
-        if (ss != ServiceState.STATE_IN_SERVICE) {
-            for (int i = 0, count = parts.size(); i < count; i++) {
-                PendingIntent sentIntent = null;
-                if (sentIntents != null && sentIntents.size() > i) {
-                    sentIntent = sentIntents.get(i);
-                }
-                SmsTracker tracker = SmsTrackerFactory(null, sentIntent, null);
-                handleNotInService(ss, tracker);
-            }
-            return;
-        }
-
-        int refNumber = getNextConcatenatedRef() & 0x00FF;
-        int msgCount = parts.size();
-        int encoding = android.telephony.SmsMessage.ENCODING_UNKNOWN;
-
-        mRemainingMessages = msgCount;
-
-        TextEncodingDetails[] encodingForParts = new TextEncodingDetails[msgCount];
-        for (int i = 0; i < msgCount; i++) {
-            TextEncodingDetails details = SmsMessage.calculateLength(parts.get(i), false);
-            if (encoding != details.codeUnitSize
-                    && (encoding == android.telephony.SmsMessage.ENCODING_UNKNOWN
-                            || encoding == android.telephony.SmsMessage.ENCODING_7BIT)) {
-                encoding = details.codeUnitSize;
-            }
-            encodingForParts[i] = details;
-        }
-
-        for (int i = 0; i < msgCount; i++) {
-            SmsHeader.ConcatRef concatRef = new SmsHeader.ConcatRef();
-            concatRef.refNumber = refNumber;
-            concatRef.seqNumber = i + 1;  // 1-based sequence
-            concatRef.msgCount = msgCount;
-            concatRef.isEightBits = false;
-            SmsHeader smsHeader = new SmsHeader();
-            smsHeader.concatRef = concatRef;
-            if (encoding == android.telephony.SmsMessage.ENCODING_7BIT) {
-                smsHeader.languageTable = encodingForParts[i].languageTable;
-                smsHeader.languageShiftTable = encodingForParts[i].languageShiftTable;
-            }
-
-            PendingIntent sentIntent = null;
-            if (sentIntents != null && sentIntents.size() > i) {
-                sentIntent = sentIntents.get(i);
-            }
-
-            PendingIntent deliveryIntent = null;
-            if (deliveryIntents != null && deliveryIntents.size() > i) {
-                deliveryIntent = deliveryIntents.get(i);
-            }
-
-            SmsMessage.SubmitPdu pdus = SmsMessage.getSubmitPdu(scAddress, destinationAddress,
-                    parts.get(i), deliveryIntent != null, SmsHeader.toByteArray(smsHeader),
-                    encoding, smsHeader.languageTable, smsHeader.languageShiftTable);
-
-            HashMap<String, Object> map = new HashMap<String, Object>();
-            map.put("smsc", pdus.encodedScAddress);
-            map.put("pdu", pdus.encodedMessage);
-
-            SmsTracker tracker = SmsTrackerFactory(map, sentIntent, deliveryIntent);
-            sendSms(tracker);
-        }
+    /** {@inheritDoc} */
+    @Override
+    protected void sendNewSubmitPdu(String destinationAddress, String scAddress,
+            String message, SmsHeader smsHeader, int encoding,
+            PendingIntent sentIntent, PendingIntent deliveryIntent, boolean lastPart) {
+        SmsMessage.SubmitPdu pdu = SmsMessage.getSubmitPdu(scAddress, destinationAddress,
+                message, deliveryIntent != null, SmsHeader.toByteArray(smsHeader),
+                encoding, smsHeader.languageTable, smsHeader.languageShiftTable);
+        sendRawPdu(pdu.encodedScAddress, pdu.encodedMessage, sentIntent, deliveryIntent);
     }
 
     /** {@inheritDoc} */
@@ -353,45 +235,16 @@
         byte pdu[] = (byte[]) map.get("pdu");
 
         Message reply = obtainMessage(EVENT_SEND_SMS_COMPLETE, tracker);
-        mCm.sendSMS(IccUtils.bytesToHexString(smsc),
-                IccUtils.bytesToHexString(pdu), reply);
-    }
-
-    /**
-     * Send the multi-part SMS based on multipart Sms tracker
-     *
-     * @param tracker holds the multipart Sms tracker ready to be sent
-     */
-    @Override
-    protected void sendMultipartSms (SmsTracker tracker) {
-        ArrayList<String> parts;
-        ArrayList<PendingIntent> sentIntents;
-        ArrayList<PendingIntent> deliveryIntents;
-
-        HashMap<String, Object> map = tracker.mData;
-
-        String destinationAddress = (String) map.get("destination");
-        String scAddress = (String) map.get("scaddress");
-
-        parts = (ArrayList<String>) map.get("parts");
-        sentIntents = (ArrayList<PendingIntent>) map.get("sentIntents");
-        deliveryIntents = (ArrayList<PendingIntent>) map.get("deliveryIntents");
-
-        sendMultipartTextWithPermit(destinationAddress,
-                scAddress, parts, sentIntents, deliveryIntents);
-
+        mCm.sendSMS(IccUtils.bytesToHexString(smsc), IccUtils.bytesToHexString(pdu), reply);
     }
 
     /** {@inheritDoc} */
     @Override
-    protected void acknowledgeLastIncomingSms(boolean success, int result, Message response){
-        // FIXME unit test leaves cm == null. this should change
-        if (mCm != null) {
-            mCm.acknowledgeLastIncomingGsmSms(success, resultToCause(result), response);
-        }
+    protected void acknowledgeLastIncomingSms(boolean success, int result, Message response) {
+        mCm.acknowledgeLastIncomingGsmSms(success, resultToCause(result), response);
     }
 
-    private int resultToCause(int rc) {
+    private static int resultToCause(int rc) {
         switch (rc) {
             case Activity.RESULT_OK:
             case Intents.RESULT_SMS_HANDLED:
@@ -485,10 +338,12 @@
     private final HashMap<SmsCbConcatInfo, byte[][]> mSmsCbPageMap =
             new HashMap<SmsCbConcatInfo, byte[][]>();
 
-    @Override
-    protected void handleBroadcastSms(AsyncResult ar) {
+    /**
+     * Handle 3GPP format SMS-CB message.
+     * @param ar the AsyncResult containing the received PDUs
+     */
+    private void handleBroadcastSms(AsyncResult ar) {
         try {
-            byte[][] pdus = null;
             byte[] receivedPdu = (byte[])ar.result;
 
             if (false) {
@@ -507,10 +362,11 @@
 
             SmsCbHeader header = new SmsCbHeader(receivedPdu);
             String plmn = SystemProperties.get(TelephonyProperties.PROPERTY_OPERATOR_NUMERIC);
-            GsmCellLocation cellLocation = (GsmCellLocation)mGsmPhone.getCellLocation();
+            GsmCellLocation cellLocation = (GsmCellLocation) mPhone.getCellLocation();
             int lac = cellLocation.getLac();
             int cid = cellLocation.getCid();
 
+            byte[][] pdus;
             if (header.nrOfPages > 1) {
                 // Multi-page message
                 SmsCbConcatInfo concatInfo = new SmsCbConcatInfo(header, plmn, lac, cid);
@@ -563,5 +419,4 @@
             Log.e(TAG, "Error in decoding SMS CB pdu", e);
         }
     }
-
 }
diff --git a/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java b/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java
index 73c319c..5d6f181 100755
--- a/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java
+++ b/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java
@@ -38,6 +38,7 @@
 import com.android.internal.telephony.MccTable;
 import com.android.internal.telephony.Phone;
 import com.android.internal.telephony.PhoneBase;
+import com.android.internal.telephony.SmsMessageBase;
 
 import java.util.ArrayList;
 
@@ -1160,6 +1161,15 @@
         }
     }
 
+    /**
+     * Dispatch 3GPP format message. Overridden for CDMA/LTE phones by
+     * {@link com.android.internal.telephony.cdma.CdmaLteUiccRecords}
+     * to send messages to the secondary 3GPP format SMS dispatcher.
+     */
+    protected int dispatchGsmMessage(SmsMessageBase message) {
+        return phone.mSMS.dispatchMessage(message);
+    }
+
     private void handleSms(byte[] ba) {
         if (ba[0] != 0)
             Log.d("ENF", "status : " + ba[0]);
@@ -1175,7 +1185,7 @@
             System.arraycopy(ba, 1, pdu, 0, n - 1);
             SmsMessage message = SmsMessage.createFromPdu(pdu);
 
-            phone.mSMS.dispatchMessage(message);
+            dispatchGsmMessage(message);
         }
     }
 
@@ -1201,7 +1211,7 @@
                 System.arraycopy(ba, 1, pdu, 0, n - 1);
                 SmsMessage message = SmsMessage.createFromPdu(pdu);
 
-                phone.mSMS.dispatchMessage(message);
+                dispatchGsmMessage(message);
 
                 // 3GPP TS 51.011 v5.0.0 (20011-12)  10.5.3
                 // 1 == "received by MS from network; message read"
diff --git a/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java b/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java
index 3784e7c..ea030e6 100644
--- a/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java
+++ b/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java
@@ -137,14 +137,6 @@
     }
 
     /** @hide */
-    public static SmsMessage newFromCMTI(String line) {
-        // the thinking here is not to read the message immediately
-        // FTA test case
-        Log.e(LOG_TAG, "newFromCMTI: not yet supported");
-        return null;
-    }
-
-    /** @hide */
     public static SmsMessage newFromCDS(String line) {
         try {
             SmsMessage msg = new SmsMessage();
@@ -157,15 +149,6 @@
     }
 
     /**
-     * Note: This functionality is currently not supported in GSM mode.
-     * @hide
-     */
-    public static SmsMessageBase newFromParcel(Parcel p){
-        Log.w(LOG_TAG, "newFromParcel: is not supported in GSM mode.");
-        return null;
-    }
-
-    /**
      * Create an SmsMessage from an SMS EF record.
      *
      * @param index Index of SMS record. This should be index in ArrayList
diff --git a/tests/GridLayoutTest/AndroidManifest.xml b/tests/GridLayoutTest/AndroidManifest.xml
index 1b72357..141e8fa 100644
--- a/tests/GridLayoutTest/AndroidManifest.xml
+++ b/tests/GridLayoutTest/AndroidManifest.xml
@@ -35,20 +35,6 @@
             </intent-filter>
         </activity>
 
-        <activity android:name="Activity2" android:label="Activity2">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN"/>
-                <category android:name="android.intent.category.LAUNCHER"/>
-            </intent-filter>
-        </activity>
-
-        <activity android:name="Activity3" android:label="Activity3">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN"/>
-                <category android:name="android.intent.category.LAUNCHER"/>
-            </intent-filter>
-        </activity>
-
         <activity android:name="Activity4" android:label="Activity4">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN"/>
diff --git a/tests/GridLayoutTest/res/layout/grid3.xml b/tests/GridLayoutTest/res/layout/grid3.xml
deleted file mode 100644
index 0e53613..0000000
--- a/tests/GridLayoutTest/res/layout/grid3.xml
+++ /dev/null
@@ -1,87 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<GridLayout
-        xmlns:android="http://schemas.android.com/apk/res/android"
-
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-
-        android:useDefaultMargins="true"
-        android:alignmentMode="alignBounds"
-        android:rowOrderPreserved="false"
-
-        android:columnCount="4"
-        >
-
-    <TextView
-            android:text="Email setup"
-            android:textSize="32dip"
-
-            android:layout_columnSpan="4"
-            android:layout_gravity="center_horizontal"
-            />
-
-    <TextView
-            android:text="You can configure email in just a few steps:"
-            android:textSize="16dip"
-
-            android:layout_columnSpan="4"
-            android:layout_gravity="left"
-            />
-
-    <TextView
-            android:text="Email address:"
-
-            android:layout_gravity="right"
-            />
-
-    <EditText
-            android:ems="10"
-            />
-
-    <TextView
-            android:text="Password:"
-
-            android:layout_column="0"
-            android:layout_gravity="right"
-            />
-
-    <EditText
-            android:ems="8"
-            />
-
-    <Space
-            android:layout_row="2"
-            android:layout_rowSpan="3"
-            android:layout_column="2"
-            android:layout_gravity="fill"
-            />
-
-    <Button
-            android:text="Manual setup"
-
-            android:layout_row="5"
-            android:layout_column="3"
-            />
-
-    <Button
-            android:text="Next"
-
-            android:layout_column="3"
-            android:layout_gravity="fill_horizontal"
-            />
-</GridLayout>
diff --git a/tests/GridLayoutTest/src/com/android/test/layout/Activity2.java b/tests/GridLayoutTest/src/com/android/test/layout/Activity2.java
deleted file mode 100644
index 8974f37..0000000
--- a/tests/GridLayoutTest/src/com/android/test/layout/Activity2.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.test.layout;
-
-import android.app.Activity;
-import android.content.Context;
-import android.os.Bundle;
-import android.view.View;
-import android.widget.Button;
-import android.widget.EditText;
-import android.widget.GridLayout;
-import android.widget.Space;
-import android.widget.TextView;
-
-import static android.text.InputType.TYPE_CLASS_TEXT;
-import static android.view.inputmethod.EditorInfo.TYPE_TEXT_VARIATION_EMAIL_ADDRESS;
-import static android.view.inputmethod.EditorInfo.TYPE_TEXT_VARIATION_PASSWORD;
-import static android.widget.GridLayout.*;
-
-public class Activity2 extends Activity {
-
-    public static View create(Context context) {
-        GridLayout p = new GridLayout(context);
-        p.setUseDefaultMargins(true);
-        p.setAlignmentMode(ALIGN_BOUNDS);
-        p.setRowOrderPreserved(false);
-
-        Spec row1 = spec(0);
-        Spec row2 = spec(1);
-        Spec row3 = spec(2, BASELINE);
-        Spec row4 = spec(3, BASELINE);
-        Spec row5 = spec(2, 3, FILL); // allow the last two rows to overlap the middle two
-        Spec row6 = spec(5);
-        Spec row7 = spec(6);
-
-        Spec col1a = spec(0, 4, CENTER);
-        Spec col1b = spec(0, 4, LEFT);
-        Spec col1c = spec(0, RIGHT);
-        Spec col2 = spec(1, LEFT);
-        Spec col3 = spec(2, FILL);
-        Spec col4a = spec(3);
-        Spec col4b = spec(3, FILL);
-
-        {
-            TextView c = new TextView(context);
-            c.setTextSize(32);
-            c.setText("Email setup");
-            p.addView(c, new LayoutParams(row1, col1a));
-        }
-        {
-            TextView c = new TextView(context);
-            c.setTextSize(16);
-            c.setText("You can configure email in just a few steps:");
-            p.addView(c, new LayoutParams(row2, col1b));
-        }
-        {
-            TextView c = new TextView(context);
-            c.setText("Email address:");
-            p.addView(c, new LayoutParams(row3, col1c));
-        }
-        {
-            EditText c = new EditText(context);
-            c.setEms(10);
-            c.setInputType(TYPE_CLASS_TEXT | TYPE_TEXT_VARIATION_EMAIL_ADDRESS);
-            p.addView(c, new LayoutParams(row3, col2));
-        }
-        {
-            TextView c = new TextView(context);
-            c.setText("Password:");
-            p.addView(c, new LayoutParams(row4, col1c));
-        }
-        {
-            TextView c = new EditText(context);
-            c.setEms(8);
-            c.setInputType(TYPE_CLASS_TEXT | TYPE_TEXT_VARIATION_PASSWORD);
-            p.addView(c, new LayoutParams(row4, col2));
-        }
-        {
-            Space c = new Space(context);
-            LayoutParams lp = new LayoutParams(row5, col3);
-            p.addView(c, lp);
-        }
-        {
-            Button c = new Button(context);
-            c.setText("Manual setup");
-            p.addView(c, new LayoutParams(row6, col4a));
-        }
-        {
-            Button c = new Button(context);
-            c.setText("Next");
-            p.addView(c, new LayoutParams(row7, col4b));
-        }
-
-        return p;
-    }
-
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        setContentView(create(getBaseContext()));
-    }
-
-}
\ No newline at end of file
diff --git a/tests/GridLayoutTest/src/com/android/test/layout/Activity3.java b/tests/GridLayoutTest/src/com/android/test/layout/Activity3.java
deleted file mode 100644
index fc0b382..0000000
--- a/tests/GridLayoutTest/src/com/android/test/layout/Activity3.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.test.layout;
-
-import android.app.Activity;
-import android.os.Bundle;
-
-public class Activity3 extends Activity {
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        setContentView(R.layout.grid3);
-    }
-}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindow.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindow.java
index 8e673ad..e13380e 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindow.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindow.java
@@ -85,7 +85,8 @@
         // pass for now.
     }
 
-    public void dispatchSystemUiVisibilityChanged(int visibility) {
+    public void dispatchSystemUiVisibilityChanged(int seq, int globalUi,
+            int localValue, int localChanges) {
         // pass for now.
     }
 
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowSession.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowSession.java
index ab8c4ec..1d97e15 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowSession.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowSession.java
@@ -37,14 +37,14 @@
  */
 public final class BridgeWindowSession implements IWindowSession {
 
-    public int add(IWindow arg0, LayoutParams arg1, int arg2, Rect arg3,
+    public int add(IWindow arg0, int seq, LayoutParams arg1, int arg2, Rect arg3,
             InputChannel outInputchannel)
             throws RemoteException {
         // pass for now.
         return 0;
     }
 
-    public int addWithoutInputChannel(IWindow arg0, LayoutParams arg1, int arg2, Rect arg3)
+    public int addWithoutInputChannel(IWindow arg0, int seq, LayoutParams arg1, int arg2, Rect arg3)
             throws RemoteException {
         // pass for now.
         return 0;
@@ -78,7 +78,7 @@
         return null;
     }
 
-    public int relayout(IWindow arg0, LayoutParams arg1, int arg2, int arg3, int arg4,
+    public int relayout(IWindow arg0, int seq, LayoutParams arg1, int arg2, int arg3, int arg4,
             boolean arg4_5, Rect arg5, Rect arg6, Rect arg7, Configuration arg7b, Surface arg8)
             throws RemoteException {
         // pass for now.