Merge "Import translations. DO NOT MERGE"
diff --git a/Android.mk b/Android.mk
index 678ae55..eef900a 100644
--- a/Android.mk
+++ b/Android.mk
@@ -94,7 +94,6 @@
 	core/java/android/bluetooth/IBluetoothHealthCallback.aidl \
 	core/java/android/bluetooth/IBluetoothPbap.aidl \
 	core/java/android/bluetooth/IBluetoothStateChangeCallback.aidl \
-	core/java/android/content/ICancellationSignal.aidl \
 	core/java/android/content/IClipboard.aidl \
 	core/java/android/content/IContentService.aidl \
 	core/java/android/content/IIntentReceiver.aidl \
@@ -126,6 +125,7 @@
 	core/java/android/nfc/INfcAdapter.aidl \
 	core/java/android/nfc/INfcAdapterExtras.aidl \
 	core/java/android/nfc/INfcTag.aidl \
+	core/java/android/os/ICancellationSignal.aidl \
 	core/java/android/os/IHardwareService.aidl \
 	core/java/android/os/IMessenger.aidl \
 	core/java/android/os/INetworkManagementService.aidl \
diff --git a/api/current.txt b/api/current.txt
index 9a349a5..803c149 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -103,7 +103,6 @@
     field public static final java.lang.String SET_ALWAYS_FINISH = "android.permission.SET_ALWAYS_FINISH";
     field public static final java.lang.String SET_ANIMATION_SCALE = "android.permission.SET_ANIMATION_SCALE";
     field public static final java.lang.String SET_DEBUG_APP = "android.permission.SET_DEBUG_APP";
-    field public static final java.lang.String SET_KEYBOARD_LAYOUT = "android.permission.SET_KEYBOARD_LAYOUT";
     field public static final java.lang.String SET_ORIENTATION = "android.permission.SET_ORIENTATION";
     field public static final java.lang.String SET_POINTER_SPEED = "android.permission.SET_POINTER_SPEED";
     field public static final deprecated java.lang.String SET_PREFERRED_APPLICATIONS = "android.permission.SET_PREFERRED_APPLICATIONS";
@@ -2026,6 +2025,7 @@
     method protected void onServiceConnected();
     method public final boolean performGlobalAction(int);
     method public final void setServiceInfo(android.accessibilityservice.AccessibilityServiceInfo);
+    field public static final int GESTURE_DOUBLE_TAP = 17; // 0x11
     field public static final int GESTURE_SWIPE_DOWN = 2; // 0x2
     field public static final int GESTURE_SWIPE_DOWN_AND_LEFT = 15; // 0xf
     field public static final int GESTURE_SWIPE_DOWN_AND_RIGHT = 16; // 0x10
@@ -2042,8 +2042,7 @@
     field public static final int GESTURE_SWIPE_UP_AND_DOWN = 7; // 0x7
     field public static final int GESTURE_SWIPE_UP_AND_LEFT = 13; // 0xd
     field public static final int GESTURE_SWIPE_UP_AND_RIGHT = 14; // 0xe
-    field public static final int GESTURE_TWO_FINGER_LONG_PRESS = 18; // 0x12
-    field public static final int GESTURE_TWO_FINGER_TAP = 17; // 0x11
+    field public static final int GESTURE_TAP_AND_HOLD = 18; // 0x12
     field public static final int GLOBAL_ACTION_BACK = 1; // 0x1
     field public static final int GLOBAL_ACTION_HOME = 2; // 0x2
     field public static final int GLOBAL_ACTION_NOTIFICATIONS = 4; // 0x4
@@ -4918,18 +4917,6 @@
     method public final void setResultExtras(android.os.Bundle);
   }
 
-  public final class CancellationSignal {
-    ctor public CancellationSignal();
-    method public void cancel();
-    method public boolean isCanceled();
-    method public void setOnCancelListener(android.content.CancellationSignal.OnCancelListener);
-    method public void throwIfCanceled();
-  }
-
-  public static abstract interface CancellationSignal.OnCancelListener {
-    method public abstract void onCancel();
-  }
-
   public class ClipData implements android.os.Parcelable {
     ctor public ClipData(java.lang.CharSequence, java.lang.String[], android.content.ClipData.Item);
     ctor public ClipData(android.content.ClipDescription, android.content.ClipData.Item);
@@ -5060,7 +5047,7 @@
     method public android.os.ParcelFileDescriptor openPipeHelper(android.net.Uri, java.lang.String, android.os.Bundle, T, android.content.ContentProvider.PipeDataWriter<T>) throws java.io.FileNotFoundException;
     method public android.content.res.AssetFileDescriptor openTypedAssetFile(android.net.Uri, java.lang.String, android.os.Bundle) throws java.io.FileNotFoundException;
     method public abstract android.database.Cursor query(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String);
-    method public android.database.Cursor query(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String, android.content.CancellationSignal);
+    method public android.database.Cursor query(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String, android.os.CancellationSignal);
     method protected final void setPathPermissions(android.content.pm.PathPermission[]);
     method protected final void setReadPermission(java.lang.String);
     method protected final void setWritePermission(java.lang.String);
@@ -5084,7 +5071,7 @@
     method public android.os.ParcelFileDescriptor openFile(android.net.Uri, java.lang.String) throws java.io.FileNotFoundException, android.os.RemoteException;
     method public final android.content.res.AssetFileDescriptor openTypedAssetFileDescriptor(android.net.Uri, java.lang.String, android.os.Bundle) throws java.io.FileNotFoundException, android.os.RemoteException;
     method public android.database.Cursor query(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String) throws android.os.RemoteException;
-    method public android.database.Cursor query(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String, android.content.CancellationSignal) throws android.os.RemoteException;
+    method public android.database.Cursor query(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String, android.os.CancellationSignal) throws android.os.RemoteException;
     method public boolean release();
     method public int update(android.net.Uri, android.content.ContentValues, java.lang.String, java.lang.String[]) throws android.os.RemoteException;
   }
@@ -5171,7 +5158,7 @@
     method public final java.io.OutputStream openOutputStream(android.net.Uri, java.lang.String) throws java.io.FileNotFoundException;
     method public final android.content.res.AssetFileDescriptor openTypedAssetFileDescriptor(android.net.Uri, java.lang.String, android.os.Bundle) throws java.io.FileNotFoundException;
     method public final android.database.Cursor query(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String);
-    method public final android.database.Cursor query(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String, android.content.CancellationSignal);
+    method public final android.database.Cursor query(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String, android.os.CancellationSignal);
     method public final void registerContentObserver(android.net.Uri, boolean, android.database.ContentObserver);
     method public static void removePeriodicSync(android.accounts.Account, java.lang.String, android.os.Bundle);
     method public static void removeStatusChangeListener(java.lang.Object);
@@ -6048,11 +6035,6 @@
     method public int getNumSuccessfulYieldPoints();
   }
 
-  public class OperationCanceledException extends java.lang.RuntimeException {
-    ctor public OperationCanceledException();
-    ctor public OperationCanceledException(java.lang.String);
-  }
-
   public class PeriodicSync implements android.os.Parcelable {
     ctor public PeriodicSync(android.accounts.Account, java.lang.String, android.os.Bundle, long);
     method public int describeContents();
@@ -7513,15 +7495,15 @@
     method public static android.database.sqlite.SQLiteDatabase openOrCreateDatabase(java.lang.String, android.database.sqlite.SQLiteDatabase.CursorFactory);
     method public static android.database.sqlite.SQLiteDatabase openOrCreateDatabase(java.lang.String, android.database.sqlite.SQLiteDatabase.CursorFactory, android.database.DatabaseErrorHandler);
     method public android.database.Cursor query(boolean, java.lang.String, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String, java.lang.String, java.lang.String, java.lang.String);
-    method public android.database.Cursor query(boolean, java.lang.String, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String, java.lang.String, java.lang.String, java.lang.String, android.content.CancellationSignal);
+    method public android.database.Cursor query(boolean, java.lang.String, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String, java.lang.String, java.lang.String, java.lang.String, android.os.CancellationSignal);
     method public android.database.Cursor query(java.lang.String, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String, java.lang.String, java.lang.String);
     method public android.database.Cursor query(java.lang.String, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String, java.lang.String, java.lang.String, java.lang.String);
     method public android.database.Cursor queryWithFactory(android.database.sqlite.SQLiteDatabase.CursorFactory, boolean, java.lang.String, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String, java.lang.String, java.lang.String, java.lang.String);
-    method public android.database.Cursor queryWithFactory(android.database.sqlite.SQLiteDatabase.CursorFactory, boolean, java.lang.String, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String, java.lang.String, java.lang.String, java.lang.String, android.content.CancellationSignal);
+    method public android.database.Cursor queryWithFactory(android.database.sqlite.SQLiteDatabase.CursorFactory, boolean, java.lang.String, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String, java.lang.String, java.lang.String, java.lang.String, android.os.CancellationSignal);
     method public android.database.Cursor rawQuery(java.lang.String, java.lang.String[]);
-    method public android.database.Cursor rawQuery(java.lang.String, java.lang.String[], android.content.CancellationSignal);
+    method public android.database.Cursor rawQuery(java.lang.String, java.lang.String[], android.os.CancellationSignal);
     method public android.database.Cursor rawQueryWithFactory(android.database.sqlite.SQLiteDatabase.CursorFactory, java.lang.String, java.lang.String[], java.lang.String);
-    method public android.database.Cursor rawQueryWithFactory(android.database.sqlite.SQLiteDatabase.CursorFactory, java.lang.String, java.lang.String[], java.lang.String, android.content.CancellationSignal);
+    method public android.database.Cursor rawQueryWithFactory(android.database.sqlite.SQLiteDatabase.CursorFactory, java.lang.String, java.lang.String[], java.lang.String, android.os.CancellationSignal);
     method public static int releaseMemory();
     method public long replace(java.lang.String, java.lang.String, android.content.ContentValues);
     method public long replaceOrThrow(java.lang.String, java.lang.String, android.content.ContentValues) throws android.database.SQLException;
@@ -7647,7 +7629,7 @@
     method public java.lang.String getTables();
     method public android.database.Cursor query(android.database.sqlite.SQLiteDatabase, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String, java.lang.String, java.lang.String);
     method public android.database.Cursor query(android.database.sqlite.SQLiteDatabase, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String, java.lang.String, java.lang.String, java.lang.String);
-    method public android.database.Cursor query(android.database.sqlite.SQLiteDatabase, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String, java.lang.String, java.lang.String, java.lang.String, android.content.CancellationSignal);
+    method public android.database.Cursor query(android.database.sqlite.SQLiteDatabase, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String, java.lang.String, java.lang.String, java.lang.String, android.os.CancellationSignal);
     method public void setCursorFactory(android.database.sqlite.SQLiteDatabase.CursorFactory);
     method public void setDistinct(boolean);
     method public void setProjectionMap(java.util.Map<java.lang.String, java.lang.String>);
@@ -11269,7 +11251,6 @@
     method public void unselectTrack(int);
     field public static final int SAMPLE_FLAG_ENCRYPTED = 2; // 0x2
     field public static final int SAMPLE_FLAG_SYNC = 1; // 0x1
-    field public static final int SEEK_TO_CLOSEST = 3; // 0x3
     field public static final int SEEK_TO_CLOSEST_SYNC = 2; // 0x2
     field public static final int SEEK_TO_NEXT_SYNC = 1; // 0x1
     field public static final int SEEK_TO_PREVIOUS_SYNC = 0; // 0x0
@@ -12742,21 +12723,6 @@
 
 package android.net.nsd {
 
-  public class DnsSdServiceInfo implements android.os.Parcelable {
-    ctor public DnsSdServiceInfo();
-    method public int describeContents();
-    method public java.net.InetAddress getHost();
-    method public int getPort();
-    method public java.lang.String getServiceName();
-    method public java.lang.String getServiceType();
-    method public void setHost(java.net.InetAddress);
-    method public void setPort(int);
-    method public void setServiceName(java.lang.String);
-    method public void setServiceType(java.lang.String);
-    method public void writeToParcel(android.os.Parcel, int);
-    field public static final android.os.Parcelable.Creator CREATOR;
-  }
-
   public class DnsSdTxtRecord implements android.os.Parcelable {
     ctor public DnsSdTxtRecord();
     ctor public DnsSdTxtRecord(byte[]);
@@ -12773,53 +12739,56 @@
     field public static final android.os.Parcelable.Creator CREATOR;
   }
 
-  public class NsdManager {
-    method public void deinitialize(android.net.nsd.NsdManager.Channel);
-    method public void discoverServices(android.net.nsd.NsdManager.Channel, java.lang.String, android.net.nsd.NsdManager.DnsSdDiscoveryListener);
-    method public void initialize(android.content.Context, android.os.Looper, android.net.nsd.NsdManager.ChannelListener);
-    method public void registerService(android.net.nsd.NsdManager.Channel, java.lang.String, java.lang.String, int, android.net.nsd.NsdManager.DnsSdRegisterListener);
-    method public void resolveService(android.net.nsd.NsdManager.Channel, java.lang.String, java.lang.String, android.net.nsd.NsdManager.DnsSdResolveListener);
-    method public void stopServiceDiscovery(android.net.nsd.NsdManager.Channel, android.net.nsd.NsdManager.ActionListener);
-    method public void unregisterService(android.net.nsd.NsdManager.Channel, int, android.net.nsd.NsdManager.ActionListener);
+  public final class NsdManager {
+    method public void discoverServices(java.lang.String, int, android.net.nsd.NsdManager.DiscoveryListener);
+    method public void registerService(android.net.nsd.NsdServiceInfo, int, android.net.nsd.NsdManager.RegistrationListener);
+    method public void resolveService(android.net.nsd.NsdServiceInfo, android.net.nsd.NsdManager.ResolveListener);
+    method public void stopServiceDiscovery(android.net.nsd.NsdManager.DiscoveryListener);
+    method public void unregisterService(android.net.nsd.NsdManager.RegistrationListener);
     field public static final java.lang.String ACTION_NSD_STATE_CHANGED = "android.net.nsd.STATE_CHANGED";
-    field public static final int ALREADY_ACTIVE = 3; // 0x3
-    field public static final int BUSY = 2; // 0x2
-    field public static final int ERROR = 0; // 0x0
     field public static final java.lang.String EXTRA_NSD_STATE = "nsd_state";
-    field public static final int MAX_REGS_REACHED = 4; // 0x4
+    field public static final int FAILURE_ALREADY_ACTIVE = 3; // 0x3
+    field public static final int FAILURE_INTERNAL_ERROR = 0; // 0x0
+    field public static final int FAILURE_MAX_LIMIT = 4; // 0x4
     field public static final int NSD_STATE_DISABLED = 1; // 0x1
     field public static final int NSD_STATE_ENABLED = 2; // 0x2
-    field public static final int UNSUPPORTED = 1; // 0x1
+    field public static final int PROTOCOL_DNS_SD = 1; // 0x1
   }
 
-  public static abstract interface NsdManager.ActionListener {
-    method public abstract void onFailure(int);
-    method public abstract void onSuccess();
+  public static abstract interface NsdManager.DiscoveryListener {
+    method public abstract void onDiscoveryStarted(java.lang.String);
+    method public abstract void onDiscoveryStopped(java.lang.String);
+    method public abstract void onServiceFound(android.net.nsd.NsdServiceInfo);
+    method public abstract void onServiceLost(android.net.nsd.NsdServiceInfo);
+    method public abstract void onStartDiscoveryFailed(java.lang.String, int);
+    method public abstract void onStopDiscoveryFailed(java.lang.String, int);
   }
 
-  public static class NsdManager.Channel {
+  public static abstract interface NsdManager.RegistrationListener {
+    method public abstract void onRegistrationFailed(android.net.nsd.NsdServiceInfo, int);
+    method public abstract void onServiceRegistered(android.net.nsd.NsdServiceInfo);
+    method public abstract void onServiceUnregistered(android.net.nsd.NsdServiceInfo);
+    method public abstract void onUnregistrationFailed(android.net.nsd.NsdServiceInfo, int);
   }
 
-  public static abstract interface NsdManager.ChannelListener {
-    method public abstract void onChannelConnected(android.net.nsd.NsdManager.Channel);
-    method public abstract void onChannelDisconnected();
+  public static abstract interface NsdManager.ResolveListener {
+    method public abstract void onResolveFailed(android.net.nsd.NsdServiceInfo, int);
+    method public abstract void onServiceResolved(android.net.nsd.NsdServiceInfo);
   }
 
-  public static abstract interface NsdManager.DnsSdDiscoveryListener {
-    method public abstract void onFailure(int);
-    method public abstract void onServiceFound(android.net.nsd.DnsSdServiceInfo);
-    method public abstract void onServiceLost(android.net.nsd.DnsSdServiceInfo);
-    method public abstract void onStarted(java.lang.String);
-  }
-
-  public static abstract interface NsdManager.DnsSdRegisterListener {
-    method public abstract void onFailure(int);
-    method public abstract void onServiceRegistered(int, android.net.nsd.DnsSdServiceInfo);
-  }
-
-  public static abstract interface NsdManager.DnsSdResolveListener {
-    method public abstract void onFailure(int);
-    method public abstract void onServiceResolved(android.net.nsd.DnsSdServiceInfo);
+  public final class NsdServiceInfo implements android.os.Parcelable {
+    ctor public NsdServiceInfo();
+    method public int describeContents();
+    method public java.net.InetAddress getHost();
+    method public int getPort();
+    method public java.lang.String getServiceName();
+    method public java.lang.String getServiceType();
+    method public void setHost(java.net.InetAddress);
+    method public void setPort(int);
+    method public void setServiceName(java.lang.String);
+    method public void setServiceType(java.lang.String);
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator CREATOR;
   }
 
 }
@@ -15380,6 +15349,18 @@
     field public static final android.os.Bundle EMPTY;
   }
 
+  public final class CancellationSignal {
+    ctor public CancellationSignal();
+    method public void cancel();
+    method public boolean isCanceled();
+    method public void setOnCancelListener(android.os.CancellationSignal.OnCancelListener);
+    method public void throwIfCanceled();
+  }
+
+  public static abstract interface CancellationSignal.OnCancelListener {
+    method public abstract void onCancel();
+  }
+
   public class ConditionVariable {
     ctor public ConditionVariable();
     ctor public ConditionVariable(boolean);
@@ -15744,6 +15725,11 @@
     ctor public NetworkOnMainThreadException();
   }
 
+  public class OperationCanceledException extends java.lang.RuntimeException {
+    ctor public OperationCanceledException();
+    ctor public OperationCanceledException(java.lang.String);
+  }
+
   public final class Parcel {
     method public final void appendFrom(android.os.Parcel, int, int);
     method public final android.os.IBinder[] createBinderArray();
@@ -18601,95 +18587,104 @@
 
 package android.renderscript {
 
-  public deprecated class Allocation extends android.renderscript.BaseObj {
-    method public deprecated void copy1DRangeFrom(int, int, int[]);
-    method public deprecated void copy1DRangeFrom(int, int, short[]);
-    method public deprecated void copy1DRangeFrom(int, int, byte[]);
-    method public deprecated void copy1DRangeFrom(int, int, float[]);
-    method public deprecated void copy1DRangeFrom(int, int, android.renderscript.Allocation, int);
-    method public deprecated void copy1DRangeFromUnchecked(int, int, int[]);
-    method public deprecated void copy1DRangeFromUnchecked(int, int, short[]);
-    method public deprecated void copy1DRangeFromUnchecked(int, int, byte[]);
-    method public deprecated void copy1DRangeFromUnchecked(int, int, float[]);
-    method public deprecated void copy2DRangeFrom(int, int, int, int, byte[]);
-    method public deprecated void copy2DRangeFrom(int, int, int, int, short[]);
-    method public deprecated void copy2DRangeFrom(int, int, int, int, int[]);
-    method public deprecated void copy2DRangeFrom(int, int, int, int, float[]);
-    method public deprecated void copy2DRangeFrom(int, int, int, int, android.renderscript.Allocation, int, int);
-    method public deprecated void copy2DRangeFrom(int, int, android.graphics.Bitmap);
-    method public deprecated void copyFrom(android.renderscript.BaseObj[]);
-    method public deprecated void copyFrom(int[]);
-    method public deprecated void copyFrom(short[]);
-    method public deprecated void copyFrom(byte[]);
-    method public deprecated void copyFrom(float[]);
-    method public deprecated void copyFrom(android.graphics.Bitmap);
-    method public deprecated void copyFromUnchecked(int[]);
-    method public deprecated void copyFromUnchecked(short[]);
-    method public deprecated void copyFromUnchecked(byte[]);
-    method public deprecated void copyFromUnchecked(float[]);
-    method public deprecated void copyTo(android.graphics.Bitmap);
-    method public deprecated void copyTo(byte[]);
-    method public deprecated void copyTo(short[]);
-    method public deprecated void copyTo(int[]);
-    method public deprecated void copyTo(float[]);
-    method public static deprecated android.renderscript.Allocation createCubemapFromBitmap(android.renderscript.RenderScript, android.graphics.Bitmap, android.renderscript.Allocation.MipmapControl, int);
-    method public static deprecated android.renderscript.Allocation createCubemapFromBitmap(android.renderscript.RenderScript, android.graphics.Bitmap);
-    method public static deprecated android.renderscript.Allocation createCubemapFromCubeFaces(android.renderscript.RenderScript, android.graphics.Bitmap, android.graphics.Bitmap, android.graphics.Bitmap, android.graphics.Bitmap, android.graphics.Bitmap, android.graphics.Bitmap, android.renderscript.Allocation.MipmapControl, int);
-    method public static deprecated android.renderscript.Allocation createCubemapFromCubeFaces(android.renderscript.RenderScript, android.graphics.Bitmap, android.graphics.Bitmap, android.graphics.Bitmap, android.graphics.Bitmap, android.graphics.Bitmap, android.graphics.Bitmap);
-    method public static deprecated android.renderscript.Allocation createFromBitmap(android.renderscript.RenderScript, android.graphics.Bitmap, android.renderscript.Allocation.MipmapControl, int);
-    method public static deprecated android.renderscript.Allocation createFromBitmap(android.renderscript.RenderScript, android.graphics.Bitmap);
-    method public static deprecated android.renderscript.Allocation createFromBitmapResource(android.renderscript.RenderScript, android.content.res.Resources, int, android.renderscript.Allocation.MipmapControl, int);
-    method public static deprecated android.renderscript.Allocation createFromBitmapResource(android.renderscript.RenderScript, android.content.res.Resources, int);
-    method public static deprecated android.renderscript.Allocation createFromString(android.renderscript.RenderScript, java.lang.String, int);
-    method public static deprecated android.renderscript.Allocation createSized(android.renderscript.RenderScript, android.renderscript.Element, int, int);
-    method public static deprecated android.renderscript.Allocation createSized(android.renderscript.RenderScript, android.renderscript.Element, int);
-    method public static deprecated android.renderscript.Allocation createTyped(android.renderscript.RenderScript, android.renderscript.Type, android.renderscript.Allocation.MipmapControl, int);
-    method public static deprecated android.renderscript.Allocation createTyped(android.renderscript.RenderScript, android.renderscript.Type, int);
-    method public static deprecated android.renderscript.Allocation createTyped(android.renderscript.RenderScript, android.renderscript.Type);
-    method public deprecated void generateMipmaps();
-    method public deprecated android.renderscript.Type getType();
-    method public deprecated synchronized void resize(int);
-    method public deprecated void setFromFieldPacker(int, android.renderscript.FieldPacker);
-    method public deprecated void setFromFieldPacker(int, int, android.renderscript.FieldPacker);
-    method public deprecated void syncAll(int);
-    field public static final deprecated int USAGE_GRAPHICS_CONSTANTS = 8; // 0x8
-    field public static final deprecated int USAGE_GRAPHICS_RENDER_TARGET = 16; // 0x10
-    field public static final deprecated int USAGE_GRAPHICS_TEXTURE = 2; // 0x2
-    field public static final deprecated int USAGE_GRAPHICS_VERTEX = 4; // 0x4
-    field public static final deprecated int USAGE_SCRIPT = 1; // 0x1
+  public class Allocation extends android.renderscript.BaseObj {
+    method public void copy1DRangeFrom(int, int, int[]);
+    method public void copy1DRangeFrom(int, int, short[]);
+    method public void copy1DRangeFrom(int, int, byte[]);
+    method public void copy1DRangeFrom(int, int, float[]);
+    method public void copy1DRangeFrom(int, int, android.renderscript.Allocation, int);
+    method public void copy1DRangeFromUnchecked(int, int, int[]);
+    method public void copy1DRangeFromUnchecked(int, int, short[]);
+    method public void copy1DRangeFromUnchecked(int, int, byte[]);
+    method public void copy1DRangeFromUnchecked(int, int, float[]);
+    method public void copy2DRangeFrom(int, int, int, int, byte[]);
+    method public void copy2DRangeFrom(int, int, int, int, short[]);
+    method public void copy2DRangeFrom(int, int, int, int, int[]);
+    method public void copy2DRangeFrom(int, int, int, int, float[]);
+    method public void copy2DRangeFrom(int, int, int, int, android.renderscript.Allocation, int, int);
+    method public void copy2DRangeFrom(int, int, android.graphics.Bitmap);
+    method public void copyFrom(android.renderscript.BaseObj[]);
+    method public void copyFrom(int[]);
+    method public void copyFrom(short[]);
+    method public void copyFrom(byte[]);
+    method public void copyFrom(float[]);
+    method public void copyFrom(android.graphics.Bitmap);
+    method public void copyFromUnchecked(int[]);
+    method public void copyFromUnchecked(short[]);
+    method public void copyFromUnchecked(byte[]);
+    method public void copyFromUnchecked(float[]);
+    method public void copyTo(android.graphics.Bitmap);
+    method public void copyTo(byte[]);
+    method public void copyTo(short[]);
+    method public void copyTo(int[]);
+    method public void copyTo(float[]);
+    method public static android.renderscript.Allocation createCubemapFromBitmap(android.renderscript.RenderScript, android.graphics.Bitmap, android.renderscript.Allocation.MipmapControl, int);
+    method public static android.renderscript.Allocation createCubemapFromBitmap(android.renderscript.RenderScript, android.graphics.Bitmap);
+    method public static android.renderscript.Allocation createCubemapFromCubeFaces(android.renderscript.RenderScript, android.graphics.Bitmap, android.graphics.Bitmap, android.graphics.Bitmap, android.graphics.Bitmap, android.graphics.Bitmap, android.graphics.Bitmap, android.renderscript.Allocation.MipmapControl, int);
+    method public static android.renderscript.Allocation createCubemapFromCubeFaces(android.renderscript.RenderScript, android.graphics.Bitmap, android.graphics.Bitmap, android.graphics.Bitmap, android.graphics.Bitmap, android.graphics.Bitmap, android.graphics.Bitmap);
+    method public static android.renderscript.Allocation createFromBitmap(android.renderscript.RenderScript, android.graphics.Bitmap, android.renderscript.Allocation.MipmapControl, int);
+    method public static android.renderscript.Allocation createFromBitmap(android.renderscript.RenderScript, android.graphics.Bitmap);
+    method public static android.renderscript.Allocation createFromBitmapResource(android.renderscript.RenderScript, android.content.res.Resources, int, android.renderscript.Allocation.MipmapControl, int);
+    method public static android.renderscript.Allocation createFromBitmapResource(android.renderscript.RenderScript, android.content.res.Resources, int);
+    method public static android.renderscript.Allocation createFromString(android.renderscript.RenderScript, java.lang.String, int);
+    method public static android.renderscript.Allocation createSized(android.renderscript.RenderScript, android.renderscript.Element, int, int);
+    method public static android.renderscript.Allocation createSized(android.renderscript.RenderScript, android.renderscript.Element, int);
+    method public static android.renderscript.Allocation createTyped(android.renderscript.RenderScript, android.renderscript.Type, android.renderscript.Allocation.MipmapControl, int);
+    method public static android.renderscript.Allocation createTyped(android.renderscript.RenderScript, android.renderscript.Type, int);
+    method public static android.renderscript.Allocation createTyped(android.renderscript.RenderScript, android.renderscript.Type);
+    method public void generateMipmaps();
+    method public int getBytesSize();
+    method public android.renderscript.Element getElement();
+    method public android.view.Surface getSurface();
+    method public android.renderscript.Type getType();
+    method public int getUsage();
+    method public void ioReceive();
+    method public void ioSend();
+    method public synchronized void resize(int);
+    method public void setFromFieldPacker(int, android.renderscript.FieldPacker);
+    method public void setFromFieldPacker(int, int, android.renderscript.FieldPacker);
+    method public void setSurface(android.view.Surface);
+    method public void syncAll(int);
+    field public static final int USAGE_GRAPHICS_CONSTANTS = 8; // 0x8
+    field public static final int USAGE_GRAPHICS_RENDER_TARGET = 16; // 0x10
+    field public static final int USAGE_GRAPHICS_TEXTURE = 2; // 0x2
+    field public static final int USAGE_GRAPHICS_VERTEX = 4; // 0x4
+    field public static final int USAGE_IO_INPUT = 32; // 0x20
+    field public static final int USAGE_IO_OUTPUT = 64; // 0x40
+    field public static final int USAGE_SCRIPT = 1; // 0x1
   }
 
-  public static final deprecated class Allocation.MipmapControl extends java.lang.Enum {
+  public static final class Allocation.MipmapControl extends java.lang.Enum {
     method public static android.renderscript.Allocation.MipmapControl valueOf(java.lang.String);
     method public static final android.renderscript.Allocation.MipmapControl[] values();
-    enum_constant public static final deprecated android.renderscript.Allocation.MipmapControl MIPMAP_FULL;
-    enum_constant public static final deprecated android.renderscript.Allocation.MipmapControl MIPMAP_NONE;
-    enum_constant public static final deprecated android.renderscript.Allocation.MipmapControl MIPMAP_ON_SYNC_TO_TEXTURE;
+    enum_constant public static final android.renderscript.Allocation.MipmapControl MIPMAP_FULL;
+    enum_constant public static final android.renderscript.Allocation.MipmapControl MIPMAP_NONE;
+    enum_constant public static final android.renderscript.Allocation.MipmapControl MIPMAP_ON_SYNC_TO_TEXTURE;
   }
 
-  public deprecated class AllocationAdapter extends android.renderscript.Allocation {
-    method public static deprecated android.renderscript.AllocationAdapter create1D(android.renderscript.RenderScript, android.renderscript.Allocation);
-    method public static deprecated android.renderscript.AllocationAdapter create2D(android.renderscript.RenderScript, android.renderscript.Allocation);
-    method public deprecated void setFace(android.renderscript.Type.CubemapFace);
-    method public deprecated void setLOD(int);
-    method public deprecated void setY(int);
-    method public deprecated void setZ(int);
+  public class AllocationAdapter extends android.renderscript.Allocation {
+    method public static android.renderscript.AllocationAdapter create1D(android.renderscript.RenderScript, android.renderscript.Allocation);
+    method public static android.renderscript.AllocationAdapter create2D(android.renderscript.RenderScript, android.renderscript.Allocation);
+    method public void setFace(android.renderscript.Type.CubemapFace);
+    method public void setLOD(int);
+    method public void setY(int);
+    method public void setZ(int);
   }
 
-  public deprecated class BaseObj {
-    method public deprecated synchronized void destroy();
-    method public deprecated java.lang.String getName();
-    method public deprecated void setName(java.lang.String);
+  public class BaseObj {
+    method public synchronized void destroy();
+    method public java.lang.String getName();
+    method public void setName(java.lang.String);
   }
 
-  public deprecated class Byte2 {
+  public class Byte2 {
     ctor public Byte2();
     ctor public Byte2(byte, byte);
     field public byte x;
     field public byte y;
   }
 
-  public deprecated class Byte3 {
+  public class Byte3 {
     ctor public Byte3();
     ctor public Byte3(byte, byte, byte);
     field public byte x;
@@ -18697,7 +18692,7 @@
     field public byte z;
   }
 
-  public deprecated class Byte4 {
+  public class Byte4 {
     ctor public Byte4();
     ctor public Byte4(byte, byte, byte, byte);
     field public byte w;
@@ -18706,14 +18701,14 @@
     field public byte z;
   }
 
-  public deprecated class Double2 {
+  public class Double2 {
     ctor public Double2();
     ctor public Double2(double, double);
     field public double x;
     field public double y;
   }
 
-  public deprecated class Double3 {
+  public class Double3 {
     ctor public Double3();
     ctor public Double3(double, double, double);
     field public double x;
@@ -18721,7 +18716,7 @@
     field public double z;
   }
 
-  public deprecated class Double4 {
+  public class Double4 {
     ctor public Double4();
     ctor public Double4(double, double, double, double);
     field public double w;
@@ -18730,83 +18725,92 @@
     field public double z;
   }
 
-  public deprecated class Element extends android.renderscript.BaseObj {
-    method public static deprecated android.renderscript.Element ALLOCATION(android.renderscript.RenderScript);
-    method public static deprecated android.renderscript.Element A_8(android.renderscript.RenderScript);
-    method public static deprecated android.renderscript.Element BOOLEAN(android.renderscript.RenderScript);
-    method public static deprecated android.renderscript.Element ELEMENT(android.renderscript.RenderScript);
-    method public static deprecated android.renderscript.Element F32(android.renderscript.RenderScript);
-    method public static deprecated android.renderscript.Element F32_2(android.renderscript.RenderScript);
-    method public static deprecated android.renderscript.Element F32_3(android.renderscript.RenderScript);
-    method public static deprecated android.renderscript.Element F32_4(android.renderscript.RenderScript);
-    method public static deprecated android.renderscript.Element F64(android.renderscript.RenderScript);
-    method public static deprecated android.renderscript.Element F64_2(android.renderscript.RenderScript);
-    method public static deprecated android.renderscript.Element F64_3(android.renderscript.RenderScript);
-    method public static deprecated android.renderscript.Element F64_4(android.renderscript.RenderScript);
-    method public static deprecated android.renderscript.Element FONT(android.renderscript.RenderScript);
-    method public static deprecated android.renderscript.Element I16(android.renderscript.RenderScript);
-    method public static deprecated android.renderscript.Element I16_2(android.renderscript.RenderScript);
-    method public static deprecated android.renderscript.Element I16_3(android.renderscript.RenderScript);
-    method public static deprecated android.renderscript.Element I16_4(android.renderscript.RenderScript);
-    method public static deprecated android.renderscript.Element I32(android.renderscript.RenderScript);
-    method public static deprecated android.renderscript.Element I32_2(android.renderscript.RenderScript);
-    method public static deprecated android.renderscript.Element I32_3(android.renderscript.RenderScript);
-    method public static deprecated android.renderscript.Element I32_4(android.renderscript.RenderScript);
-    method public static deprecated android.renderscript.Element I64(android.renderscript.RenderScript);
-    method public static deprecated android.renderscript.Element I64_2(android.renderscript.RenderScript);
-    method public static deprecated android.renderscript.Element I64_3(android.renderscript.RenderScript);
-    method public static deprecated android.renderscript.Element I64_4(android.renderscript.RenderScript);
-    method public static deprecated android.renderscript.Element I8(android.renderscript.RenderScript);
-    method public static deprecated android.renderscript.Element I8_2(android.renderscript.RenderScript);
-    method public static deprecated android.renderscript.Element I8_3(android.renderscript.RenderScript);
-    method public static deprecated android.renderscript.Element I8_4(android.renderscript.RenderScript);
+  public class Element extends android.renderscript.BaseObj {
+    method public static android.renderscript.Element ALLOCATION(android.renderscript.RenderScript);
+    method public static android.renderscript.Element A_8(android.renderscript.RenderScript);
+    method public static android.renderscript.Element BOOLEAN(android.renderscript.RenderScript);
+    method public static android.renderscript.Element ELEMENT(android.renderscript.RenderScript);
+    method public static android.renderscript.Element F32(android.renderscript.RenderScript);
+    method public static android.renderscript.Element F32_2(android.renderscript.RenderScript);
+    method public static android.renderscript.Element F32_3(android.renderscript.RenderScript);
+    method public static android.renderscript.Element F32_4(android.renderscript.RenderScript);
+    method public static android.renderscript.Element F64(android.renderscript.RenderScript);
+    method public static android.renderscript.Element F64_2(android.renderscript.RenderScript);
+    method public static android.renderscript.Element F64_3(android.renderscript.RenderScript);
+    method public static android.renderscript.Element F64_4(android.renderscript.RenderScript);
+    method public static android.renderscript.Element FONT(android.renderscript.RenderScript);
+    method public static android.renderscript.Element I16(android.renderscript.RenderScript);
+    method public static android.renderscript.Element I16_2(android.renderscript.RenderScript);
+    method public static android.renderscript.Element I16_3(android.renderscript.RenderScript);
+    method public static android.renderscript.Element I16_4(android.renderscript.RenderScript);
+    method public static android.renderscript.Element I32(android.renderscript.RenderScript);
+    method public static android.renderscript.Element I32_2(android.renderscript.RenderScript);
+    method public static android.renderscript.Element I32_3(android.renderscript.RenderScript);
+    method public static android.renderscript.Element I32_4(android.renderscript.RenderScript);
+    method public static android.renderscript.Element I64(android.renderscript.RenderScript);
+    method public static android.renderscript.Element I64_2(android.renderscript.RenderScript);
+    method public static android.renderscript.Element I64_3(android.renderscript.RenderScript);
+    method public static android.renderscript.Element I64_4(android.renderscript.RenderScript);
+    method public static android.renderscript.Element I8(android.renderscript.RenderScript);
+    method public static android.renderscript.Element I8_2(android.renderscript.RenderScript);
+    method public static android.renderscript.Element I8_3(android.renderscript.RenderScript);
+    method public static android.renderscript.Element I8_4(android.renderscript.RenderScript);
     method public static deprecated android.renderscript.Element MATRIX4X4(android.renderscript.RenderScript);
-    method public static deprecated android.renderscript.Element MATRIX_2X2(android.renderscript.RenderScript);
-    method public static deprecated android.renderscript.Element MATRIX_3X3(android.renderscript.RenderScript);
-    method public static deprecated android.renderscript.Element MATRIX_4X4(android.renderscript.RenderScript);
-    method public static deprecated android.renderscript.Element MESH(android.renderscript.RenderScript);
-    method public static deprecated android.renderscript.Element PROGRAM_FRAGMENT(android.renderscript.RenderScript);
-    method public static deprecated android.renderscript.Element PROGRAM_RASTER(android.renderscript.RenderScript);
-    method public static deprecated android.renderscript.Element PROGRAM_STORE(android.renderscript.RenderScript);
-    method public static deprecated android.renderscript.Element PROGRAM_VERTEX(android.renderscript.RenderScript);
-    method public static deprecated android.renderscript.Element RGBA_4444(android.renderscript.RenderScript);
-    method public static deprecated android.renderscript.Element RGBA_5551(android.renderscript.RenderScript);
-    method public static deprecated android.renderscript.Element RGBA_8888(android.renderscript.RenderScript);
-    method public static deprecated android.renderscript.Element RGB_565(android.renderscript.RenderScript);
-    method public static deprecated android.renderscript.Element RGB_888(android.renderscript.RenderScript);
-    method public static deprecated android.renderscript.Element SAMPLER(android.renderscript.RenderScript);
-    method public static deprecated android.renderscript.Element SCRIPT(android.renderscript.RenderScript);
-    method public static deprecated android.renderscript.Element TYPE(android.renderscript.RenderScript);
-    method public static deprecated android.renderscript.Element U16(android.renderscript.RenderScript);
-    method public static deprecated android.renderscript.Element U16_2(android.renderscript.RenderScript);
-    method public static deprecated android.renderscript.Element U16_3(android.renderscript.RenderScript);
-    method public static deprecated android.renderscript.Element U16_4(android.renderscript.RenderScript);
-    method public static deprecated android.renderscript.Element U32(android.renderscript.RenderScript);
-    method public static deprecated android.renderscript.Element U32_2(android.renderscript.RenderScript);
-    method public static deprecated android.renderscript.Element U32_3(android.renderscript.RenderScript);
-    method public static deprecated android.renderscript.Element U32_4(android.renderscript.RenderScript);
-    method public static deprecated android.renderscript.Element U64(android.renderscript.RenderScript);
-    method public static deprecated android.renderscript.Element U64_2(android.renderscript.RenderScript);
-    method public static deprecated android.renderscript.Element U64_3(android.renderscript.RenderScript);
-    method public static deprecated android.renderscript.Element U64_4(android.renderscript.RenderScript);
-    method public static deprecated android.renderscript.Element U8(android.renderscript.RenderScript);
-    method public static deprecated android.renderscript.Element U8_2(android.renderscript.RenderScript);
-    method public static deprecated android.renderscript.Element U8_3(android.renderscript.RenderScript);
-    method public static deprecated android.renderscript.Element U8_4(android.renderscript.RenderScript);
-    method public static deprecated android.renderscript.Element createPixel(android.renderscript.RenderScript, android.renderscript.Element.DataType, android.renderscript.Element.DataKind);
-    method public static deprecated android.renderscript.Element createVector(android.renderscript.RenderScript, android.renderscript.Element.DataType, int);
-    method public deprecated boolean isCompatible(android.renderscript.Element);
-    method public deprecated boolean isComplex();
+    method public static android.renderscript.Element MATRIX_2X2(android.renderscript.RenderScript);
+    method public static android.renderscript.Element MATRIX_3X3(android.renderscript.RenderScript);
+    method public static android.renderscript.Element MATRIX_4X4(android.renderscript.RenderScript);
+    method public static android.renderscript.Element MESH(android.renderscript.RenderScript);
+    method public static android.renderscript.Element PROGRAM_FRAGMENT(android.renderscript.RenderScript);
+    method public static android.renderscript.Element PROGRAM_RASTER(android.renderscript.RenderScript);
+    method public static android.renderscript.Element PROGRAM_STORE(android.renderscript.RenderScript);
+    method public static android.renderscript.Element PROGRAM_VERTEX(android.renderscript.RenderScript);
+    method public static android.renderscript.Element RGBA_4444(android.renderscript.RenderScript);
+    method public static android.renderscript.Element RGBA_5551(android.renderscript.RenderScript);
+    method public static android.renderscript.Element RGBA_8888(android.renderscript.RenderScript);
+    method public static android.renderscript.Element RGB_565(android.renderscript.RenderScript);
+    method public static android.renderscript.Element RGB_888(android.renderscript.RenderScript);
+    method public static android.renderscript.Element SAMPLER(android.renderscript.RenderScript);
+    method public static android.renderscript.Element SCRIPT(android.renderscript.RenderScript);
+    method public static android.renderscript.Element TYPE(android.renderscript.RenderScript);
+    method public static android.renderscript.Element U16(android.renderscript.RenderScript);
+    method public static android.renderscript.Element U16_2(android.renderscript.RenderScript);
+    method public static android.renderscript.Element U16_3(android.renderscript.RenderScript);
+    method public static android.renderscript.Element U16_4(android.renderscript.RenderScript);
+    method public static android.renderscript.Element U32(android.renderscript.RenderScript);
+    method public static android.renderscript.Element U32_2(android.renderscript.RenderScript);
+    method public static android.renderscript.Element U32_3(android.renderscript.RenderScript);
+    method public static android.renderscript.Element U32_4(android.renderscript.RenderScript);
+    method public static android.renderscript.Element U64(android.renderscript.RenderScript);
+    method public static android.renderscript.Element U64_2(android.renderscript.RenderScript);
+    method public static android.renderscript.Element U64_3(android.renderscript.RenderScript);
+    method public static android.renderscript.Element U64_4(android.renderscript.RenderScript);
+    method public static android.renderscript.Element U8(android.renderscript.RenderScript);
+    method public static android.renderscript.Element U8_2(android.renderscript.RenderScript);
+    method public static android.renderscript.Element U8_3(android.renderscript.RenderScript);
+    method public static android.renderscript.Element U8_4(android.renderscript.RenderScript);
+    method public static android.renderscript.Element createPixel(android.renderscript.RenderScript, android.renderscript.Element.DataType, android.renderscript.Element.DataKind);
+    method public static android.renderscript.Element createVector(android.renderscript.RenderScript, android.renderscript.Element.DataType, int);
+    method public int getBytesSize();
+    method public android.renderscript.Element.DataKind getDataKind();
+    method public android.renderscript.Element.DataType getDataType();
+    method public android.renderscript.Element getSubElement(int);
+    method public int getSubElementArraySize(int);
+    method public int getSubElementCount();
+    method public java.lang.String getSubElementName(int);
+    method public int getSubElementOffsetBytes(int);
+    method public int getVectorSize();
+    method public boolean isCompatible(android.renderscript.Element);
+    method public boolean isComplex();
   }
 
-  public static deprecated class Element.Builder {
-    ctor public deprecated Element.Builder(android.renderscript.RenderScript);
-    method public deprecated android.renderscript.Element.Builder add(android.renderscript.Element, java.lang.String, int);
-    method public deprecated android.renderscript.Element.Builder add(android.renderscript.Element, java.lang.String);
-    method public deprecated android.renderscript.Element create();
+  public static class Element.Builder {
+    ctor public Element.Builder(android.renderscript.RenderScript);
+    method public android.renderscript.Element.Builder add(android.renderscript.Element, java.lang.String, int);
+    method public android.renderscript.Element.Builder add(android.renderscript.Element, java.lang.String);
+    method public android.renderscript.Element create();
   }
 
-  public static final deprecated class Element.DataKind extends java.lang.Enum {
+  public static final class Element.DataKind extends java.lang.Enum {
     method public static android.renderscript.Element.DataKind valueOf(java.lang.String);
     method public static final android.renderscript.Element.DataKind[] values();
     enum_constant public static final android.renderscript.Element.DataKind PIXEL_A;
@@ -18818,7 +18822,7 @@
     enum_constant public static final android.renderscript.Element.DataKind USER;
   }
 
-  public static final deprecated class Element.DataType extends java.lang.Enum {
+  public static final class Element.DataType extends java.lang.Enum {
     method public static android.renderscript.Element.DataType valueOf(java.lang.String);
     method public static final android.renderscript.Element.DataType[] values();
     enum_constant public static final android.renderscript.Element.DataType BOOLEAN;
@@ -18827,6 +18831,7 @@
     enum_constant public static final android.renderscript.Element.DataType MATRIX_2X2;
     enum_constant public static final android.renderscript.Element.DataType MATRIX_3X3;
     enum_constant public static final android.renderscript.Element.DataType MATRIX_4X4;
+    enum_constant public static final android.renderscript.Element.DataType NONE;
     enum_constant public static final android.renderscript.Element.DataType RS_ALLOCATION;
     enum_constant public static final android.renderscript.Element.DataType RS_ELEMENT;
     enum_constant public static final android.renderscript.Element.DataType RS_FONT;
@@ -18851,7 +18856,7 @@
     enum_constant public static final android.renderscript.Element.DataType UNSIGNED_8;
   }
 
-  public deprecated class FieldPacker {
+  public class FieldPacker {
     ctor public FieldPacker(int);
     method public void addBoolean(boolean);
     method public void addF32(float);
@@ -18928,14 +18933,14 @@
     method public deprecated android.renderscript.BaseObj getObject();
   }
 
-  public deprecated class Float2 {
+  public class Float2 {
     ctor public Float2();
     ctor public Float2(float, float);
     field public float x;
     field public float y;
   }
 
-  public deprecated class Float3 {
+  public class Float3 {
     ctor public Float3();
     ctor public Float3(float, float, float);
     field public float x;
@@ -18943,7 +18948,7 @@
     field public float z;
   }
 
-  public deprecated class Float4 {
+  public class Float4 {
     ctor public Float4();
     ctor public Float4(float, float, float, float);
     field public float w;
@@ -18969,14 +18974,14 @@
     enum_constant public static final deprecated android.renderscript.Font.Style NORMAL;
   }
 
-  public deprecated class Int2 {
+  public class Int2 {
     ctor public Int2();
     ctor public Int2(int, int);
     field public int x;
     field public int y;
   }
 
-  public deprecated class Int3 {
+  public class Int3 {
     ctor public Int3();
     ctor public Int3(int, int, int);
     field public int x;
@@ -18984,7 +18989,7 @@
     field public int z;
   }
 
-  public deprecated class Int4 {
+  public class Int4 {
     ctor public Int4();
     ctor public Int4(int, int, int, int);
     field public int w;
@@ -18993,14 +18998,14 @@
     field public int z;
   }
 
-  public deprecated class Long2 {
+  public class Long2 {
     ctor public Long2();
     ctor public Long2(long, long);
     field public long x;
     field public long y;
   }
 
-  public deprecated class Long3 {
+  public class Long3 {
     ctor public Long3();
     ctor public Long3(long, long, long);
     field public long x;
@@ -19008,7 +19013,7 @@
     field public long z;
   }
 
-  public deprecated class Long4 {
+  public class Long4 {
     ctor public Long4();
     ctor public Long4(long, long, long, long);
     field public long w;
@@ -19017,78 +19022,78 @@
     field public long z;
   }
 
-  public deprecated class Matrix2f {
-    ctor public deprecated Matrix2f();
-    ctor public deprecated Matrix2f(float[]);
-    method public deprecated float get(int, int);
-    method public deprecated float[] getArray();
-    method public deprecated void load(android.renderscript.Matrix2f);
-    method public deprecated void loadIdentity();
-    method public deprecated void loadMultiply(android.renderscript.Matrix2f, android.renderscript.Matrix2f);
-    method public deprecated void loadRotate(float);
-    method public deprecated void loadScale(float, float);
-    method public deprecated void multiply(android.renderscript.Matrix2f);
-    method public deprecated void rotate(float);
-    method public deprecated void scale(float, float);
-    method public deprecated void set(int, int, float);
-    method public deprecated void transpose();
+  public class Matrix2f {
+    ctor public Matrix2f();
+    ctor public Matrix2f(float[]);
+    method public float get(int, int);
+    method public float[] getArray();
+    method public void load(android.renderscript.Matrix2f);
+    method public void loadIdentity();
+    method public void loadMultiply(android.renderscript.Matrix2f, android.renderscript.Matrix2f);
+    method public void loadRotate(float);
+    method public void loadScale(float, float);
+    method public void multiply(android.renderscript.Matrix2f);
+    method public void rotate(float);
+    method public void scale(float, float);
+    method public void set(int, int, float);
+    method public void transpose();
   }
 
-  public deprecated class Matrix3f {
-    ctor public deprecated Matrix3f();
-    ctor public deprecated Matrix3f(float[]);
-    method public deprecated float get(int, int);
-    method public deprecated float[] getArray();
-    method public deprecated void load(android.renderscript.Matrix3f);
-    method public deprecated void loadIdentity();
-    method public deprecated void loadMultiply(android.renderscript.Matrix3f, android.renderscript.Matrix3f);
-    method public deprecated void loadRotate(float, float, float, float);
-    method public deprecated void loadRotate(float);
-    method public deprecated void loadScale(float, float);
-    method public deprecated void loadScale(float, float, float);
-    method public deprecated void loadTranslate(float, float);
-    method public deprecated void multiply(android.renderscript.Matrix3f);
-    method public deprecated void rotate(float, float, float, float);
-    method public deprecated void rotate(float);
-    method public deprecated void scale(float, float);
-    method public deprecated void scale(float, float, float);
-    method public deprecated void set(int, int, float);
-    method public deprecated void translate(float, float);
-    method public deprecated void transpose();
+  public class Matrix3f {
+    ctor public Matrix3f();
+    ctor public Matrix3f(float[]);
+    method public float get(int, int);
+    method public float[] getArray();
+    method public void load(android.renderscript.Matrix3f);
+    method public void loadIdentity();
+    method public void loadMultiply(android.renderscript.Matrix3f, android.renderscript.Matrix3f);
+    method public void loadRotate(float, float, float, float);
+    method public void loadRotate(float);
+    method public void loadScale(float, float);
+    method public void loadScale(float, float, float);
+    method public void loadTranslate(float, float);
+    method public void multiply(android.renderscript.Matrix3f);
+    method public void rotate(float, float, float, float);
+    method public void rotate(float);
+    method public void scale(float, float);
+    method public void scale(float, float, float);
+    method public void set(int, int, float);
+    method public void translate(float, float);
+    method public void transpose();
   }
 
-  public deprecated class Matrix4f {
-    ctor public deprecated Matrix4f();
-    ctor public deprecated Matrix4f(float[]);
-    method public deprecated float get(int, int);
-    method public deprecated float[] getArray();
-    method public deprecated boolean inverse();
-    method public deprecated boolean inverseTranspose();
-    method public deprecated void load(android.renderscript.Matrix4f);
-    method public deprecated void loadFrustum(float, float, float, float, float, float);
-    method public deprecated void loadIdentity();
-    method public deprecated void loadMultiply(android.renderscript.Matrix4f, android.renderscript.Matrix4f);
-    method public deprecated void loadOrtho(float, float, float, float, float, float);
-    method public deprecated void loadOrthoWindow(int, int);
-    method public deprecated void loadPerspective(float, float, float, float);
-    method public deprecated void loadProjectionNormalized(int, int);
-    method public deprecated void loadRotate(float, float, float, float);
-    method public deprecated void loadScale(float, float, float);
-    method public deprecated void loadTranslate(float, float, float);
-    method public deprecated void multiply(android.renderscript.Matrix4f);
-    method public deprecated void rotate(float, float, float, float);
-    method public deprecated void scale(float, float, float);
-    method public deprecated void set(int, int, float);
-    method public deprecated void translate(float, float, float);
-    method public deprecated void transpose();
+  public class Matrix4f {
+    ctor public Matrix4f();
+    ctor public Matrix4f(float[]);
+    method public float get(int, int);
+    method public float[] getArray();
+    method public boolean inverse();
+    method public boolean inverseTranspose();
+    method public void load(android.renderscript.Matrix4f);
+    method public void loadFrustum(float, float, float, float, float, float);
+    method public void loadIdentity();
+    method public void loadMultiply(android.renderscript.Matrix4f, android.renderscript.Matrix4f);
+    method public void loadOrtho(float, float, float, float, float, float);
+    method public void loadOrthoWindow(int, int);
+    method public void loadPerspective(float, float, float, float);
+    method public void loadProjectionNormalized(int, int);
+    method public void loadRotate(float, float, float, float);
+    method public void loadScale(float, float, float);
+    method public void loadTranslate(float, float, float);
+    method public void multiply(android.renderscript.Matrix4f);
+    method public void rotate(float, float, float, float);
+    method public void scale(float, float, float);
+    method public void set(int, int, float);
+    method public void translate(float, float, float);
+    method public void transpose();
   }
 
-  public deprecated class Mesh extends android.renderscript.BaseObj {
-    method public deprecated android.renderscript.Allocation getIndexSetAllocation(int);
-    method public deprecated android.renderscript.Mesh.Primitive getPrimitive(int);
-    method public deprecated int getPrimitiveCount();
-    method public deprecated android.renderscript.Allocation getVertexAllocation(int);
-    method public deprecated int getVertexAllocationCount();
+  public class Mesh extends android.renderscript.BaseObj {
+    method public android.renderscript.Allocation getIndexSetAllocation(int);
+    method public android.renderscript.Mesh.Primitive getPrimitive(int);
+    method public int getPrimitiveCount();
+    method public android.renderscript.Allocation getVertexAllocation(int);
+    method public int getVertexAllocationCount();
   }
 
   public static deprecated class Mesh.AllocationBuilder {
@@ -19101,27 +19106,27 @@
     method public deprecated int getCurrentVertexTypeIndex();
   }
 
-  public static deprecated class Mesh.Builder {
-    ctor public deprecated Mesh.Builder(android.renderscript.RenderScript, int);
-    method public deprecated android.renderscript.Mesh.Builder addIndexSetType(android.renderscript.Type, android.renderscript.Mesh.Primitive);
-    method public deprecated android.renderscript.Mesh.Builder addIndexSetType(android.renderscript.Mesh.Primitive);
-    method public deprecated android.renderscript.Mesh.Builder addIndexSetType(android.renderscript.Element, int, android.renderscript.Mesh.Primitive);
-    method public deprecated android.renderscript.Mesh.Builder addVertexType(android.renderscript.Type) throws java.lang.IllegalStateException;
-    method public deprecated android.renderscript.Mesh.Builder addVertexType(android.renderscript.Element, int) throws java.lang.IllegalStateException;
-    method public deprecated android.renderscript.Mesh create();
-    method public deprecated int getCurrentIndexSetIndex();
-    method public deprecated int getCurrentVertexTypeIndex();
+  public static class Mesh.Builder {
+    ctor public Mesh.Builder(android.renderscript.RenderScript, int);
+    method public android.renderscript.Mesh.Builder addIndexSetType(android.renderscript.Type, android.renderscript.Mesh.Primitive);
+    method public android.renderscript.Mesh.Builder addIndexSetType(android.renderscript.Mesh.Primitive);
+    method public android.renderscript.Mesh.Builder addIndexSetType(android.renderscript.Element, int, android.renderscript.Mesh.Primitive);
+    method public android.renderscript.Mesh.Builder addVertexType(android.renderscript.Type) throws java.lang.IllegalStateException;
+    method public android.renderscript.Mesh.Builder addVertexType(android.renderscript.Element, int) throws java.lang.IllegalStateException;
+    method public android.renderscript.Mesh create();
+    method public int getCurrentIndexSetIndex();
+    method public int getCurrentVertexTypeIndex();
   }
 
-  public static final deprecated class Mesh.Primitive extends java.lang.Enum {
+  public static final class Mesh.Primitive extends java.lang.Enum {
     method public static android.renderscript.Mesh.Primitive valueOf(java.lang.String);
     method public static final android.renderscript.Mesh.Primitive[] values();
-    enum_constant public static final deprecated android.renderscript.Mesh.Primitive LINE;
-    enum_constant public static final deprecated android.renderscript.Mesh.Primitive LINE_STRIP;
-    enum_constant public static final deprecated android.renderscript.Mesh.Primitive POINT;
-    enum_constant public static final deprecated android.renderscript.Mesh.Primitive TRIANGLE;
-    enum_constant public static final deprecated android.renderscript.Mesh.Primitive TRIANGLE_FAN;
-    enum_constant public static final deprecated android.renderscript.Mesh.Primitive TRIANGLE_STRIP;
+    enum_constant public static final android.renderscript.Mesh.Primitive LINE;
+    enum_constant public static final android.renderscript.Mesh.Primitive LINE_STRIP;
+    enum_constant public static final android.renderscript.Mesh.Primitive POINT;
+    enum_constant public static final android.renderscript.Mesh.Primitive TRIANGLE;
+    enum_constant public static final android.renderscript.Mesh.Primitive TRIANGLE_FAN;
+    enum_constant public static final android.renderscript.Mesh.Primitive TRIANGLE_STRIP;
   }
 
   public static deprecated class Mesh.TriangleMeshBuilder {
@@ -19138,42 +19143,48 @@
     field public static final deprecated int TEXTURE_0 = 256; // 0x100
   }
 
-  public deprecated class Program extends android.renderscript.BaseObj {
-    method public deprecated void bindConstants(android.renderscript.Allocation, int);
-    method public deprecated void bindSampler(android.renderscript.Sampler, int) throws java.lang.IllegalArgumentException;
-    method public deprecated void bindTexture(android.renderscript.Allocation, int) throws java.lang.IllegalArgumentException;
+  public class Program extends android.renderscript.BaseObj {
+    method public void bindConstants(android.renderscript.Allocation, int);
+    method public void bindSampler(android.renderscript.Sampler, int) throws java.lang.IllegalArgumentException;
+    method public void bindTexture(android.renderscript.Allocation, int) throws java.lang.IllegalArgumentException;
+    method public android.renderscript.Type getConstant(int);
+    method public int getConstantCount();
+    method public int getTextureCount();
+    method public java.lang.String getTextureName(int);
+    method public android.renderscript.Program.TextureType getTextureType(int);
   }
 
   public static class Program.BaseProgramBuilder {
-    ctor protected deprecated Program.BaseProgramBuilder(android.renderscript.RenderScript);
-    method public deprecated android.renderscript.Program.BaseProgramBuilder addConstant(android.renderscript.Type) throws java.lang.IllegalStateException;
-    method public deprecated android.renderscript.Program.BaseProgramBuilder addTexture(android.renderscript.Program.TextureType) throws java.lang.IllegalArgumentException;
-    method public deprecated int getCurrentConstantIndex();
-    method public deprecated int getCurrentTextureIndex();
-    method protected deprecated void initProgram(android.renderscript.Program);
-    method public deprecated android.renderscript.Program.BaseProgramBuilder setShader(java.lang.String);
-    method public deprecated android.renderscript.Program.BaseProgramBuilder setShader(android.content.res.Resources, int);
+    ctor protected Program.BaseProgramBuilder(android.renderscript.RenderScript);
+    method public android.renderscript.Program.BaseProgramBuilder addConstant(android.renderscript.Type) throws java.lang.IllegalStateException;
+    method public android.renderscript.Program.BaseProgramBuilder addTexture(android.renderscript.Program.TextureType) throws java.lang.IllegalArgumentException;
+    method public android.renderscript.Program.BaseProgramBuilder addTexture(android.renderscript.Program.TextureType, java.lang.String) throws java.lang.IllegalArgumentException;
+    method public int getCurrentConstantIndex();
+    method public int getCurrentTextureIndex();
+    method protected void initProgram(android.renderscript.Program);
+    method public android.renderscript.Program.BaseProgramBuilder setShader(java.lang.String);
+    method public android.renderscript.Program.BaseProgramBuilder setShader(android.content.res.Resources, int);
   }
 
-  public static final deprecated class Program.TextureType extends java.lang.Enum {
+  public static final class Program.TextureType extends java.lang.Enum {
     method public static android.renderscript.Program.TextureType valueOf(java.lang.String);
     method public static final android.renderscript.Program.TextureType[] values();
-    enum_constant public static final deprecated android.renderscript.Program.TextureType TEXTURE_2D;
-    enum_constant public static final deprecated android.renderscript.Program.TextureType TEXTURE_CUBE;
+    enum_constant public static final android.renderscript.Program.TextureType TEXTURE_2D;
+    enum_constant public static final android.renderscript.Program.TextureType TEXTURE_CUBE;
   }
 
-  public deprecated class ProgramFragment extends android.renderscript.Program {
+  public class ProgramFragment extends android.renderscript.Program {
   }
 
   public static class ProgramFragment.Builder extends android.renderscript.Program.BaseProgramBuilder {
-    ctor public deprecated ProgramFragment.Builder(android.renderscript.RenderScript);
-    method public deprecated android.renderscript.ProgramFragment create();
+    ctor public ProgramFragment.Builder(android.renderscript.RenderScript);
+    method public android.renderscript.ProgramFragment create();
   }
 
   public deprecated class ProgramFragmentFixedFunction extends android.renderscript.ProgramFragment {
   }
 
-  public static class ProgramFragmentFixedFunction.Builder {
+  public static deprecated class ProgramFragmentFixedFunction.Builder {
     ctor public deprecated ProgramFragmentFixedFunction.Builder(android.renderscript.RenderScript);
     method public deprecated android.renderscript.ProgramFragmentFixedFunction create();
     method public deprecated android.renderscript.ProgramFragmentFixedFunction.Builder setPointSpriteTexCoordinateReplacement(boolean);
@@ -19199,97 +19210,110 @@
     enum_constant public static final deprecated android.renderscript.ProgramFragmentFixedFunction.Builder.Format RGBA;
   }
 
-  public deprecated class ProgramRaster extends android.renderscript.BaseObj {
-    method public static deprecated android.renderscript.ProgramRaster CULL_BACK(android.renderscript.RenderScript);
-    method public static deprecated android.renderscript.ProgramRaster CULL_FRONT(android.renderscript.RenderScript);
-    method public static deprecated android.renderscript.ProgramRaster CULL_NONE(android.renderscript.RenderScript);
+  public class ProgramRaster extends android.renderscript.BaseObj {
+    method public static android.renderscript.ProgramRaster CULL_BACK(android.renderscript.RenderScript);
+    method public static android.renderscript.ProgramRaster CULL_FRONT(android.renderscript.RenderScript);
+    method public static android.renderscript.ProgramRaster CULL_NONE(android.renderscript.RenderScript);
+    method public android.renderscript.ProgramRaster.CullMode getCullMode();
+    method public boolean isPointSpriteEnabled();
   }
 
-  public static deprecated class ProgramRaster.Builder {
-    ctor public deprecated ProgramRaster.Builder(android.renderscript.RenderScript);
-    method public deprecated android.renderscript.ProgramRaster create();
-    method public deprecated android.renderscript.ProgramRaster.Builder setCullMode(android.renderscript.ProgramRaster.CullMode);
-    method public deprecated android.renderscript.ProgramRaster.Builder setPointSpriteEnabled(boolean);
+  public static class ProgramRaster.Builder {
+    ctor public ProgramRaster.Builder(android.renderscript.RenderScript);
+    method public android.renderscript.ProgramRaster create();
+    method public android.renderscript.ProgramRaster.Builder setCullMode(android.renderscript.ProgramRaster.CullMode);
+    method public android.renderscript.ProgramRaster.Builder setPointSpriteEnabled(boolean);
   }
 
-  public static final deprecated class ProgramRaster.CullMode extends java.lang.Enum {
+  public static final class ProgramRaster.CullMode extends java.lang.Enum {
     method public static android.renderscript.ProgramRaster.CullMode valueOf(java.lang.String);
     method public static final android.renderscript.ProgramRaster.CullMode[] values();
-    enum_constant public static final deprecated android.renderscript.ProgramRaster.CullMode BACK;
-    enum_constant public static final deprecated android.renderscript.ProgramRaster.CullMode FRONT;
-    enum_constant public static final deprecated android.renderscript.ProgramRaster.CullMode NONE;
+    enum_constant public static final android.renderscript.ProgramRaster.CullMode BACK;
+    enum_constant public static final android.renderscript.ProgramRaster.CullMode FRONT;
+    enum_constant public static final android.renderscript.ProgramRaster.CullMode NONE;
   }
 
-  public deprecated class ProgramStore extends android.renderscript.BaseObj {
-    method public static deprecated android.renderscript.ProgramStore BLEND_ALPHA_DEPTH_NONE(android.renderscript.RenderScript);
-    method public static deprecated android.renderscript.ProgramStore BLEND_ALPHA_DEPTH_TEST(android.renderscript.RenderScript);
-    method public static deprecated android.renderscript.ProgramStore BLEND_NONE_DEPTH_NONE(android.renderscript.RenderScript);
-    method public static deprecated android.renderscript.ProgramStore BLEND_NONE_DEPTH_TEST(android.renderscript.RenderScript);
+  public class ProgramStore extends android.renderscript.BaseObj {
+    method public static android.renderscript.ProgramStore BLEND_ALPHA_DEPTH_NONE(android.renderscript.RenderScript);
+    method public static android.renderscript.ProgramStore BLEND_ALPHA_DEPTH_TEST(android.renderscript.RenderScript);
+    method public static android.renderscript.ProgramStore BLEND_NONE_DEPTH_NONE(android.renderscript.RenderScript);
+    method public static android.renderscript.ProgramStore BLEND_NONE_DEPTH_TEST(android.renderscript.RenderScript);
+    method public android.renderscript.ProgramStore.BlendDstFunc getBlendDstFunc();
+    method public android.renderscript.ProgramStore.BlendSrcFunc getBlendSrcFunc();
+    method public android.renderscript.ProgramStore.DepthFunc getDepthFunc();
+    method public boolean isColorMaskAlphaEnabled();
+    method public boolean isColorMaskBlueEnabled();
+    method public boolean isColorMaskGreenEnabled();
+    method public boolean isColorMaskRedEnabled();
+    method public boolean isDepthMaskEnabled();
+    method public boolean isDitherEnabled();
   }
 
-  public static final deprecated class ProgramStore.BlendDstFunc extends java.lang.Enum {
+  public static final class ProgramStore.BlendDstFunc extends java.lang.Enum {
     method public static android.renderscript.ProgramStore.BlendDstFunc valueOf(java.lang.String);
     method public static final android.renderscript.ProgramStore.BlendDstFunc[] values();
-    enum_constant public static final deprecated android.renderscript.ProgramStore.BlendDstFunc DST_ALPHA;
-    enum_constant public static final deprecated android.renderscript.ProgramStore.BlendDstFunc ONE;
-    enum_constant public static final deprecated android.renderscript.ProgramStore.BlendDstFunc ONE_MINUS_DST_ALPHA;
-    enum_constant public static final deprecated android.renderscript.ProgramStore.BlendDstFunc ONE_MINUS_SRC_ALPHA;
-    enum_constant public static final deprecated android.renderscript.ProgramStore.BlendDstFunc ONE_MINUS_SRC_COLOR;
-    enum_constant public static final deprecated android.renderscript.ProgramStore.BlendDstFunc SRC_ALPHA;
-    enum_constant public static final deprecated android.renderscript.ProgramStore.BlendDstFunc SRC_COLOR;
-    enum_constant public static final deprecated android.renderscript.ProgramStore.BlendDstFunc ZERO;
+    enum_constant public static final android.renderscript.ProgramStore.BlendDstFunc DST_ALPHA;
+    enum_constant public static final android.renderscript.ProgramStore.BlendDstFunc ONE;
+    enum_constant public static final android.renderscript.ProgramStore.BlendDstFunc ONE_MINUS_DST_ALPHA;
+    enum_constant public static final android.renderscript.ProgramStore.BlendDstFunc ONE_MINUS_SRC_ALPHA;
+    enum_constant public static final android.renderscript.ProgramStore.BlendDstFunc ONE_MINUS_SRC_COLOR;
+    enum_constant public static final android.renderscript.ProgramStore.BlendDstFunc SRC_ALPHA;
+    enum_constant public static final android.renderscript.ProgramStore.BlendDstFunc SRC_COLOR;
+    enum_constant public static final android.renderscript.ProgramStore.BlendDstFunc ZERO;
   }
 
-  public static final deprecated class ProgramStore.BlendSrcFunc extends java.lang.Enum {
+  public static final class ProgramStore.BlendSrcFunc extends java.lang.Enum {
     method public static android.renderscript.ProgramStore.BlendSrcFunc valueOf(java.lang.String);
     method public static final android.renderscript.ProgramStore.BlendSrcFunc[] values();
-    enum_constant public static final deprecated android.renderscript.ProgramStore.BlendSrcFunc DST_ALPHA;
-    enum_constant public static final deprecated android.renderscript.ProgramStore.BlendSrcFunc DST_COLOR;
-    enum_constant public static final deprecated android.renderscript.ProgramStore.BlendSrcFunc ONE;
-    enum_constant public static final deprecated android.renderscript.ProgramStore.BlendSrcFunc ONE_MINUS_DST_ALPHA;
-    enum_constant public static final deprecated android.renderscript.ProgramStore.BlendSrcFunc ONE_MINUS_DST_COLOR;
-    enum_constant public static final deprecated android.renderscript.ProgramStore.BlendSrcFunc ONE_MINUS_SRC_ALPHA;
-    enum_constant public static final deprecated android.renderscript.ProgramStore.BlendSrcFunc SRC_ALPHA;
-    enum_constant public static final deprecated android.renderscript.ProgramStore.BlendSrcFunc SRC_ALPHA_SATURATE;
-    enum_constant public static final deprecated android.renderscript.ProgramStore.BlendSrcFunc ZERO;
+    enum_constant public static final android.renderscript.ProgramStore.BlendSrcFunc DST_ALPHA;
+    enum_constant public static final android.renderscript.ProgramStore.BlendSrcFunc DST_COLOR;
+    enum_constant public static final android.renderscript.ProgramStore.BlendSrcFunc ONE;
+    enum_constant public static final android.renderscript.ProgramStore.BlendSrcFunc ONE_MINUS_DST_ALPHA;
+    enum_constant public static final android.renderscript.ProgramStore.BlendSrcFunc ONE_MINUS_DST_COLOR;
+    enum_constant public static final android.renderscript.ProgramStore.BlendSrcFunc ONE_MINUS_SRC_ALPHA;
+    enum_constant public static final android.renderscript.ProgramStore.BlendSrcFunc SRC_ALPHA;
+    enum_constant public static final android.renderscript.ProgramStore.BlendSrcFunc SRC_ALPHA_SATURATE;
+    enum_constant public static final android.renderscript.ProgramStore.BlendSrcFunc ZERO;
   }
 
-  public static deprecated class ProgramStore.Builder {
+  public static class ProgramStore.Builder {
     ctor public ProgramStore.Builder(android.renderscript.RenderScript);
-    method public deprecated android.renderscript.ProgramStore create();
-    method public deprecated android.renderscript.ProgramStore.Builder setBlendFunc(android.renderscript.ProgramStore.BlendSrcFunc, android.renderscript.ProgramStore.BlendDstFunc);
-    method public deprecated android.renderscript.ProgramStore.Builder setColorMaskEnabled(boolean, boolean, boolean, boolean);
-    method public deprecated android.renderscript.ProgramStore.Builder setDepthFunc(android.renderscript.ProgramStore.DepthFunc);
-    method public deprecated android.renderscript.ProgramStore.Builder setDepthMaskEnabled(boolean);
-    method public deprecated android.renderscript.ProgramStore.Builder setDitherEnabled(boolean);
+    method public android.renderscript.ProgramStore create();
+    method public android.renderscript.ProgramStore.Builder setBlendFunc(android.renderscript.ProgramStore.BlendSrcFunc, android.renderscript.ProgramStore.BlendDstFunc);
+    method public android.renderscript.ProgramStore.Builder setColorMaskEnabled(boolean, boolean, boolean, boolean);
+    method public android.renderscript.ProgramStore.Builder setDepthFunc(android.renderscript.ProgramStore.DepthFunc);
+    method public android.renderscript.ProgramStore.Builder setDepthMaskEnabled(boolean);
+    method public android.renderscript.ProgramStore.Builder setDitherEnabled(boolean);
   }
 
-  public static final deprecated class ProgramStore.DepthFunc extends java.lang.Enum {
+  public static final class ProgramStore.DepthFunc extends java.lang.Enum {
     method public static android.renderscript.ProgramStore.DepthFunc valueOf(java.lang.String);
     method public static final android.renderscript.ProgramStore.DepthFunc[] values();
-    enum_constant public static final deprecated android.renderscript.ProgramStore.DepthFunc ALWAYS;
-    enum_constant public static final deprecated android.renderscript.ProgramStore.DepthFunc EQUAL;
-    enum_constant public static final deprecated android.renderscript.ProgramStore.DepthFunc GREATER;
-    enum_constant public static final deprecated android.renderscript.ProgramStore.DepthFunc GREATER_OR_EQUAL;
-    enum_constant public static final deprecated android.renderscript.ProgramStore.DepthFunc LESS;
-    enum_constant public static final deprecated android.renderscript.ProgramStore.DepthFunc LESS_OR_EQUAL;
-    enum_constant public static final deprecated android.renderscript.ProgramStore.DepthFunc NOT_EQUAL;
+    enum_constant public static final android.renderscript.ProgramStore.DepthFunc ALWAYS;
+    enum_constant public static final android.renderscript.ProgramStore.DepthFunc EQUAL;
+    enum_constant public static final android.renderscript.ProgramStore.DepthFunc GREATER;
+    enum_constant public static final android.renderscript.ProgramStore.DepthFunc GREATER_OR_EQUAL;
+    enum_constant public static final android.renderscript.ProgramStore.DepthFunc LESS;
+    enum_constant public static final android.renderscript.ProgramStore.DepthFunc LESS_OR_EQUAL;
+    enum_constant public static final android.renderscript.ProgramStore.DepthFunc NOT_EQUAL;
   }
 
-  public deprecated class ProgramVertex extends android.renderscript.Program {
+  public class ProgramVertex extends android.renderscript.Program {
+    method public android.renderscript.Element getInput(int);
+    method public int getInputCount();
   }
 
-  public static deprecated class ProgramVertex.Builder extends android.renderscript.Program.BaseProgramBuilder {
-    ctor public deprecated ProgramVertex.Builder(android.renderscript.RenderScript);
-    method public deprecated android.renderscript.ProgramVertex.Builder addInput(android.renderscript.Element) throws java.lang.IllegalStateException;
-    method public deprecated android.renderscript.ProgramVertex create();
+  public static class ProgramVertex.Builder extends android.renderscript.Program.BaseProgramBuilder {
+    ctor public ProgramVertex.Builder(android.renderscript.RenderScript);
+    method public android.renderscript.ProgramVertex.Builder addInput(android.renderscript.Element) throws java.lang.IllegalStateException;
+    method public android.renderscript.ProgramVertex create();
   }
 
   public deprecated class ProgramVertexFixedFunction extends android.renderscript.ProgramVertex {
     method public deprecated void bindConstants(android.renderscript.ProgramVertexFixedFunction.Constants);
   }
 
-  public static class ProgramVertexFixedFunction.Builder {
+  public static deprecated class ProgramVertexFixedFunction.Builder {
     ctor public deprecated ProgramVertexFixedFunction.Builder(android.renderscript.RenderScript);
     method public deprecated android.renderscript.ProgramVertexFixedFunction create();
     method public deprecated android.renderscript.ProgramVertexFixedFunction.Builder setTextureMatrixEnable(boolean);
@@ -19303,79 +19327,79 @@
     method public deprecated void setTexture(android.renderscript.Matrix4f);
   }
 
-  public deprecated class RSDriverException extends android.renderscript.RSRuntimeException {
+  public class RSDriverException extends android.renderscript.RSRuntimeException {
     ctor public RSDriverException(java.lang.String);
   }
 
-  public deprecated class RSIllegalArgumentException extends android.renderscript.RSRuntimeException {
-    ctor public deprecated RSIllegalArgumentException(java.lang.String);
+  public class RSIllegalArgumentException extends android.renderscript.RSRuntimeException {
+    ctor public RSIllegalArgumentException(java.lang.String);
   }
 
-  public deprecated class RSInvalidStateException extends android.renderscript.RSRuntimeException {
-    ctor public deprecated RSInvalidStateException(java.lang.String);
+  public class RSInvalidStateException extends android.renderscript.RSRuntimeException {
+    ctor public RSInvalidStateException(java.lang.String);
   }
 
-  public deprecated class RSRuntimeException extends java.lang.RuntimeException {
-    ctor public deprecated RSRuntimeException(java.lang.String);
+  public class RSRuntimeException extends java.lang.RuntimeException {
+    ctor public RSRuntimeException(java.lang.String);
   }
 
   public deprecated class RSSurfaceView extends android.view.SurfaceView implements android.view.SurfaceHolder.Callback {
     ctor public deprecated RSSurfaceView(android.content.Context);
     ctor public deprecated RSSurfaceView(android.content.Context, android.util.AttributeSet);
-    method public android.renderscript.RenderScriptGL createRenderScriptGL(android.renderscript.RenderScriptGL.SurfaceConfig);
-    method public void destroyRenderScriptGL();
-    method public android.renderscript.RenderScriptGL getRenderScriptGL();
+    method public deprecated android.renderscript.RenderScriptGL createRenderScriptGL(android.renderscript.RenderScriptGL.SurfaceConfig);
+    method public deprecated void destroyRenderScriptGL();
+    method public deprecated android.renderscript.RenderScriptGL getRenderScriptGL();
     method public deprecated void pause();
     method public deprecated void resume();
-    method public void setRenderScriptGL(android.renderscript.RenderScriptGL);
+    method public deprecated void setRenderScriptGL(android.renderscript.RenderScriptGL);
     method public deprecated void surfaceChanged(android.view.SurfaceHolder, int, int, int);
     method public deprecated void surfaceCreated(android.view.SurfaceHolder);
     method public deprecated void surfaceDestroyed(android.view.SurfaceHolder);
   }
 
-  public deprecated class RSTextureView extends android.view.TextureView implements android.view.TextureView.SurfaceTextureListener {
-    ctor public deprecated RSTextureView(android.content.Context);
-    ctor public deprecated RSTextureView(android.content.Context, android.util.AttributeSet);
-    method public deprecated android.renderscript.RenderScriptGL createRenderScriptGL(android.renderscript.RenderScriptGL.SurfaceConfig);
-    method public deprecated void destroyRenderScriptGL();
-    method public deprecated android.renderscript.RenderScriptGL getRenderScriptGL();
+  public class RSTextureView extends android.view.TextureView implements android.view.TextureView.SurfaceTextureListener {
+    ctor public RSTextureView(android.content.Context);
+    ctor public RSTextureView(android.content.Context, android.util.AttributeSet);
+    method public android.renderscript.RenderScriptGL createRenderScriptGL(android.renderscript.RenderScriptGL.SurfaceConfig);
+    method public void destroyRenderScriptGL();
+    method public android.renderscript.RenderScriptGL getRenderScriptGL();
     method public void onSurfaceTextureAvailable(android.graphics.SurfaceTexture, int, int);
     method public boolean onSurfaceTextureDestroyed(android.graphics.SurfaceTexture);
     method public void onSurfaceTextureSizeChanged(android.graphics.SurfaceTexture, int, int);
     method public void onSurfaceTextureUpdated(android.graphics.SurfaceTexture);
-    method public deprecated void pause();
-    method public deprecated void resume();
-    method public deprecated void setRenderScriptGL(android.renderscript.RenderScriptGL);
+    method public void pause();
+    method public void resume();
+    method public void setRenderScriptGL(android.renderscript.RenderScriptGL);
   }
 
-  public deprecated class RenderScript {
-    method public deprecated void contextDump();
-    method public static deprecated android.renderscript.RenderScript create(android.content.Context);
-    method public deprecated void destroy();
-    method public deprecated void finish();
-    method public final deprecated android.content.Context getApplicationContext();
+  public class RenderScript {
+    method public void contextDump();
+    method public static android.renderscript.RenderScript create(android.content.Context);
+    method public void destroy();
+    method public void finish();
+    method public final android.content.Context getApplicationContext();
     method public android.renderscript.RenderScript.RSErrorHandler getErrorHandler();
     method public android.renderscript.RenderScript.RSMessageHandler getMessageHandler();
     method public void setErrorHandler(android.renderscript.RenderScript.RSErrorHandler);
     method public void setMessageHandler(android.renderscript.RenderScript.RSMessageHandler);
-    method public deprecated void setPriority(android.renderscript.RenderScript.Priority);
+    method public void setPriority(android.renderscript.RenderScript.Priority);
   }
 
-  public static final deprecated class RenderScript.Priority extends java.lang.Enum {
+  public static final class RenderScript.Priority extends java.lang.Enum {
     method public static android.renderscript.RenderScript.Priority valueOf(java.lang.String);
     method public static final android.renderscript.RenderScript.Priority[] values();
     enum_constant public static final android.renderscript.RenderScript.Priority LOW;
     enum_constant public static final android.renderscript.RenderScript.Priority NORMAL;
   }
 
-  public static deprecated class RenderScript.RSErrorHandler implements java.lang.Runnable {
+  public static class RenderScript.RSErrorHandler implements java.lang.Runnable {
     ctor public RenderScript.RSErrorHandler();
     method public void run();
     field protected java.lang.String mErrorMessage;
     field protected int mErrorNum;
   }
 
-  public static deprecated class RenderScript.RSMessageHandler implements java.lang.Runnable {
+  public static class RenderScript.RSMessageHandler implements java.lang.Runnable {
     ctor public RenderScript.RSMessageHandler();
     method public void run();
     field protected int[] mData;
@@ -19383,40 +19407,45 @@
     field protected int mLength;
   }
 
-  public deprecated class RenderScriptGL extends android.renderscript.RenderScript {
-    ctor public deprecated RenderScriptGL(android.content.Context, android.renderscript.RenderScriptGL.SurfaceConfig);
-    method public deprecated void bindProgramFragment(android.renderscript.ProgramFragment);
-    method public deprecated void bindProgramRaster(android.renderscript.ProgramRaster);
-    method public deprecated void bindProgramStore(android.renderscript.ProgramStore);
-    method public deprecated void bindProgramVertex(android.renderscript.ProgramVertex);
-    method public deprecated void bindRootScript(android.renderscript.Script);
-    method public deprecated int getHeight();
-    method public deprecated int getWidth();
-    method public deprecated void pause();
-    method public deprecated void resume();
-    method public deprecated void setSurface(android.view.SurfaceHolder, int, int);
+  public class RenderScriptGL extends android.renderscript.RenderScript {
+    ctor public RenderScriptGL(android.content.Context, android.renderscript.RenderScriptGL.SurfaceConfig);
+    method public void bindProgramFragment(android.renderscript.ProgramFragment);
+    method public void bindProgramRaster(android.renderscript.ProgramRaster);
+    method public void bindProgramStore(android.renderscript.ProgramStore);
+    method public void bindProgramVertex(android.renderscript.ProgramVertex);
+    method public void bindRootScript(android.renderscript.Script);
+    method public int getHeight();
+    method public int getWidth();
+    method public void pause();
+    method public void resume();
+    method public void setSurface(android.view.SurfaceHolder, int, int);
     method public deprecated void setSurfaceTexture(android.graphics.SurfaceTexture, int, int);
   }
 
-  public static deprecated class RenderScriptGL.SurfaceConfig {
+  public static class RenderScriptGL.SurfaceConfig {
     ctor public RenderScriptGL.SurfaceConfig();
     ctor public RenderScriptGL.SurfaceConfig(android.renderscript.RenderScriptGL.SurfaceConfig);
-    method public deprecated void setAlpha(int, int);
-    method public deprecated void setColor(int, int);
-    method public deprecated void setDepth(int, int);
-    method public deprecated void setSamples(int, int, float);
+    method public void setAlpha(int, int);
+    method public void setColor(int, int);
+    method public void setDepth(int, int);
+    method public void setSamples(int, int, float);
   }
 
-  public deprecated class Sampler extends android.renderscript.BaseObj {
-    method public static deprecated android.renderscript.Sampler CLAMP_LINEAR(android.renderscript.RenderScript);
-    method public static deprecated android.renderscript.Sampler CLAMP_LINEAR_MIP_LINEAR(android.renderscript.RenderScript);
-    method public static deprecated android.renderscript.Sampler CLAMP_NEAREST(android.renderscript.RenderScript);
-    method public static deprecated android.renderscript.Sampler WRAP_LINEAR(android.renderscript.RenderScript);
-    method public static deprecated android.renderscript.Sampler WRAP_LINEAR_MIP_LINEAR(android.renderscript.RenderScript);
-    method public static deprecated android.renderscript.Sampler WRAP_NEAREST(android.renderscript.RenderScript);
+  public class Sampler extends android.renderscript.BaseObj {
+    method public static android.renderscript.Sampler CLAMP_LINEAR(android.renderscript.RenderScript);
+    method public static android.renderscript.Sampler CLAMP_LINEAR_MIP_LINEAR(android.renderscript.RenderScript);
+    method public static android.renderscript.Sampler CLAMP_NEAREST(android.renderscript.RenderScript);
+    method public static android.renderscript.Sampler WRAP_LINEAR(android.renderscript.RenderScript);
+    method public static android.renderscript.Sampler WRAP_LINEAR_MIP_LINEAR(android.renderscript.RenderScript);
+    method public static android.renderscript.Sampler WRAP_NEAREST(android.renderscript.RenderScript);
+    method public float getAnisotropy();
+    method public android.renderscript.Sampler.Value getMagnification();
+    method public android.renderscript.Sampler.Value getMinification();
+    method public android.renderscript.Sampler.Value getWrapS();
+    method public android.renderscript.Sampler.Value getWrapT();
   }
 
-  public static deprecated class Sampler.Builder {
+  public static class Sampler.Builder {
     ctor public Sampler.Builder(android.renderscript.RenderScript);
     method public android.renderscript.Sampler create();
     method public void setAnisotropy(float);
@@ -19426,31 +19455,31 @@
     method public void setWrapT(android.renderscript.Sampler.Value);
   }
 
-  public static final deprecated class Sampler.Value extends java.lang.Enum {
+  public static final class Sampler.Value extends java.lang.Enum {
     method public static android.renderscript.Sampler.Value valueOf(java.lang.String);
     method public static final android.renderscript.Sampler.Value[] values();
-    enum_constant public static final deprecated android.renderscript.Sampler.Value CLAMP;
-    enum_constant public static final deprecated android.renderscript.Sampler.Value LINEAR;
-    enum_constant public static final deprecated android.renderscript.Sampler.Value LINEAR_MIP_LINEAR;
-    enum_constant public static final deprecated android.renderscript.Sampler.Value LINEAR_MIP_NEAREST;
-    enum_constant public static final deprecated android.renderscript.Sampler.Value NEAREST;
-    enum_constant public static final deprecated android.renderscript.Sampler.Value WRAP;
+    enum_constant public static final android.renderscript.Sampler.Value CLAMP;
+    enum_constant public static final android.renderscript.Sampler.Value LINEAR;
+    enum_constant public static final android.renderscript.Sampler.Value LINEAR_MIP_LINEAR;
+    enum_constant public static final android.renderscript.Sampler.Value LINEAR_MIP_NEAREST;
+    enum_constant public static final android.renderscript.Sampler.Value NEAREST;
+    enum_constant public static final android.renderscript.Sampler.Value WRAP;
   }
 
-  public deprecated class Script extends android.renderscript.BaseObj {
-    method public deprecated void bindAllocation(android.renderscript.Allocation, int);
-    method protected deprecated void forEach(int, android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.FieldPacker);
-    method protected deprecated void invoke(int);
-    method protected deprecated void invoke(int, android.renderscript.FieldPacker);
-    method public deprecated void setTimeZone(java.lang.String);
-    method public deprecated void setVar(int, float);
-    method public deprecated void setVar(int, double);
-    method public deprecated void setVar(int, int);
-    method public deprecated void setVar(int, long);
-    method public deprecated void setVar(int, boolean);
-    method public deprecated void setVar(int, android.renderscript.BaseObj);
-    method public deprecated void setVar(int, android.renderscript.FieldPacker);
-    method public deprecated void setVar(int, android.renderscript.FieldPacker, android.renderscript.Element, int[]);
+  public class Script extends android.renderscript.BaseObj {
+    method public void bindAllocation(android.renderscript.Allocation, int);
+    method protected void forEach(int, android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.FieldPacker);
+    method protected void invoke(int);
+    method protected void invoke(int, android.renderscript.FieldPacker);
+    method public void setTimeZone(java.lang.String);
+    method public void setVar(int, float);
+    method public void setVar(int, double);
+    method public void setVar(int, int);
+    method public void setVar(int, long);
+    method public void setVar(int, boolean);
+    method public void setVar(int, android.renderscript.BaseObj);
+    method public void setVar(int, android.renderscript.FieldPacker);
+    method public void setVar(int, android.renderscript.FieldPacker, android.renderscript.Element, int[]);
   }
 
   public static class Script.Builder {
@@ -19468,19 +19497,19 @@
     field protected android.renderscript.Element mElement;
   }
 
-  public deprecated class ScriptC extends android.renderscript.Script {
-    ctor protected deprecated ScriptC(int, android.renderscript.RenderScript);
-    ctor protected deprecated ScriptC(android.renderscript.RenderScript, android.content.res.Resources, int);
+  public class ScriptC extends android.renderscript.Script {
+    ctor protected ScriptC(int, android.renderscript.RenderScript);
+    ctor protected ScriptC(android.renderscript.RenderScript, android.content.res.Resources, int);
   }
 
-  public deprecated class Short2 {
+  public class Short2 {
     ctor public Short2();
     ctor public Short2(short, short);
     field public short x;
     field public short y;
   }
 
-  public deprecated class Short3 {
+  public class Short3 {
     ctor public Short3();
     ctor public Short3(short, short, short);
     field public short x;
@@ -19488,7 +19517,7 @@
     field public short z;
   }
 
-  public deprecated class Short4 {
+  public class Short4 {
     ctor public Short4();
     ctor public Short4(short, short, short, short);
     field public short w;
@@ -19497,22 +19526,22 @@
     field public short z;
   }
 
-  public deprecated class Type extends android.renderscript.BaseObj {
-    method public deprecated int getCount();
-    method public deprecated android.renderscript.Element getElement();
-    method public deprecated int getX();
-    method public deprecated int getY();
-    method public deprecated int getZ();
-    method public deprecated boolean hasFaces();
-    method public deprecated boolean hasMipmaps();
+  public class Type extends android.renderscript.BaseObj {
+    method public int getCount();
+    method public android.renderscript.Element getElement();
+    method public int getX();
+    method public int getY();
+    method public int getZ();
+    method public boolean hasFaces();
+    method public boolean hasMipmaps();
   }
 
-  public static deprecated class Type.Builder {
-    ctor public deprecated Type.Builder(android.renderscript.RenderScript, android.renderscript.Element);
-    method public deprecated android.renderscript.Type create();
+  public static class Type.Builder {
+    ctor public Type.Builder(android.renderscript.RenderScript, android.renderscript.Element);
+    method public android.renderscript.Type create();
     method public android.renderscript.Type.Builder setFaces(boolean);
     method public android.renderscript.Type.Builder setMipmaps(boolean);
-    method public deprecated android.renderscript.Type.Builder setX(int);
+    method public android.renderscript.Type.Builder setX(int);
     method public android.renderscript.Type.Builder setY(int);
   }
 
@@ -24455,6 +24484,7 @@
     method public void onInitializeAccessibilityNodeInfo(android.view.View, android.view.accessibility.AccessibilityNodeInfo);
     method public void onPopulateAccessibilityEvent(android.view.View, android.view.accessibility.AccessibilityEvent);
     method public boolean onRequestSendAccessibilityEvent(android.view.ViewGroup, android.view.View, android.view.accessibility.AccessibilityEvent);
+    method public boolean performAccessibilityAction(android.view.View, int, android.os.Bundle);
     method public void sendAccessibilityEvent(android.view.View, int);
     method public void sendAccessibilityEventUnchecked(android.view.View, android.view.accessibility.AccessibilityEvent);
   }
@@ -25168,6 +25198,7 @@
     method public void appendRecord(android.view.accessibility.AccessibilityRecord);
     method public int describeContents();
     method public static java.lang.String eventTypeToString(int);
+    method public int getAction();
     method public long getEventTime();
     method public int getEventType();
     method public int getMovementGranularity();
@@ -25178,6 +25209,7 @@
     method public static android.view.accessibility.AccessibilityEvent obtain(int);
     method public static android.view.accessibility.AccessibilityEvent obtain(android.view.accessibility.AccessibilityEvent);
     method public static android.view.accessibility.AccessibilityEvent obtain();
+    method public void setAction(int);
     method public void setEventTime(long);
     method public void setEventType(int);
     method public void setMovementGranularity(int);
@@ -25259,6 +25291,7 @@
     method public boolean isPassword();
     method public boolean isScrollable();
     method public boolean isSelected();
+    method public boolean isVisibleToUser();
     method public static android.view.accessibility.AccessibilityNodeInfo obtain(android.view.View);
     method public static android.view.accessibility.AccessibilityNodeInfo obtain(android.view.View, int);
     method public static android.view.accessibility.AccessibilityNodeInfo obtain();
@@ -25288,6 +25321,7 @@
     method public void setSource(android.view.View);
     method public void setSource(android.view.View, int);
     method public void setText(java.lang.CharSequence);
+    method public void setVisibleToUser(boolean);
     method public void writeToParcel(android.os.Parcel, int);
     field public static final int ACTION_ACCESSIBILITY_FOCUS = 64; // 0x40
     field public static final java.lang.String ACTION_ARGUMENT_HTML_ELEMENT_STRING = "ACTION_ARGUMENT_HTML_ELEMENT_STRING";
diff --git a/cmds/pm/src/com/android/commands/pm/Pm.java b/cmds/pm/src/com/android/commands/pm/Pm.java
index e19ad66..f9ff861 100644
--- a/cmds/pm/src/com/android/commands/pm/Pm.java
+++ b/cmds/pm/src/com/android/commands/pm/Pm.java
@@ -16,9 +16,12 @@
 
 package com.android.commands.pm;
 
+import com.android.internal.content.PackageHelper;
+
 import android.app.ActivityManagerNative;
 import android.content.ComponentName;
 import android.content.pm.ApplicationInfo;
+import android.content.pm.ContainerEncryptionParams;
 import android.content.pm.FeatureInfo;
 import android.content.pm.IPackageDataObserver;
 import android.content.pm.IPackageDeleteObserver;
@@ -40,17 +43,20 @@
 import android.os.RemoteException;
 import android.os.ServiceManager;
 
-import com.android.internal.content.PackageHelper;
-
 import java.io.File;
 import java.lang.reflect.Field;
 import java.lang.reflect.Modifier;
+import java.security.InvalidAlgorithmParameterException;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.List;
 import java.util.WeakHashMap;
 
+import javax.crypto.SecretKey;
+import javax.crypto.spec.IvParameterSpec;
+import javax.crypto.spec.SecretKeySpec;
+
 public final class Pm {
     IPackageManager mPm;
 
@@ -763,6 +769,15 @@
         String installerPackageName = null;
 
         String opt;
+
+        String algo = null;
+        byte[] iv = null;
+        byte[] key = null;
+
+        String macAlgo = null;
+        byte[] macKey = null;
+        byte[] tag = null;
+
         while ((opt=nextOption()) != null) {
             if (opt.equals("-l")) {
                 installFlags |= PackageManager.INSTALL_FORWARD_LOCK;
@@ -783,6 +798,48 @@
             } else if (opt.equals("-f")) {
                 // Override if -s option is specified.
                 installFlags |= PackageManager.INSTALL_INTERNAL;
+            } else if (opt.equals("--algo")) {
+                algo = nextOptionData();
+                if (algo == null) {
+                    System.err.println("Error: must supply argument for --algo");
+                    showUsage();
+                    return;
+                }
+            } else if (opt.equals("--iv")) {
+                iv = hexToBytes(nextOptionData());
+                if (iv == null) {
+                    System.err.println("Error: must supply argument for --iv");
+                    showUsage();
+                    return;
+                }
+            } else if (opt.equals("--key")) {
+                key = hexToBytes(nextOptionData());
+                if (key == null) {
+                    System.err.println("Error: must supply argument for --key");
+                    showUsage();
+                    return;
+                }
+            } else if (opt.equals("--macalgo")) {
+                macAlgo = nextOptionData();
+                if (macAlgo == null) {
+                    System.err.println("Error: must supply argument for --macalgo");
+                    showUsage();
+                    return;
+                }
+            } else if (opt.equals("--mackey")) {
+                macKey = hexToBytes(nextOptionData());
+                if (macKey == null) {
+                    System.err.println("Error: must supply argument for --mackey");
+                    showUsage();
+                    return;
+                }
+            } else if (opt.equals("--tag")) {
+                tag = hexToBytes(nextOptionData());
+                if (tag == null) {
+                    System.err.println("Error: must supply argument for --tag");
+                    showUsage();
+                    return;
+                }
             } else {
                 System.err.println("Error: Unknown option: " + opt);
                 showUsage();
@@ -790,6 +847,44 @@
             }
         }
 
+        final ContainerEncryptionParams encryptionParams;
+        if (algo != null || iv != null || key != null || macAlgo != null || macKey != null
+                || tag != null) {
+            if (algo == null || iv == null || key == null) {
+                System.err.println("Error: all of --algo, --iv, and --key must be specified");
+                showUsage();
+                return;
+            }
+
+            if (macAlgo != null || macKey != null || tag != null) {
+                if (macAlgo == null || macKey == null || tag == null) {
+                    System.err.println("Error: all of --macalgo, --mackey, and --tag must "
+                            + "be specified");
+                    showUsage();
+                    return;
+                }
+            }
+
+            try {
+                final SecretKey encKey = new SecretKeySpec(key, "RAW");
+
+                final SecretKey macSecretKey;
+                if (macKey == null || macKey.length == 0) {
+                    macSecretKey = null;
+                } else {
+                    macSecretKey = new SecretKeySpec(macKey, "RAW");
+                }
+
+                encryptionParams = new ContainerEncryptionParams(algo, new IvParameterSpec(iv),
+                        encKey, macAlgo, null, macSecretKey, tag, -1, -1, -1);
+            } catch (InvalidAlgorithmParameterException e) {
+                e.printStackTrace();
+                return;
+            }
+        } else {
+            encryptionParams = null;
+        }
+
         final Uri apkURI;
         final Uri verificationURI;
 
@@ -816,7 +911,7 @@
         PackageInstallObserver obs = new PackageInstallObserver();
         try {
             mPm.installPackageWithVerification(apkURI, obs, installFlags, installerPackageName,
-                    verificationURI, null);
+                    verificationURI, null, encryptionParams);
 
             synchronized (obs) {
                 while (!obs.finished) {
@@ -839,6 +934,37 @@
         }
     }
 
+    /**
+     * Convert a string containing hex-encoded bytes to a byte array.
+     *
+     * @param input String containing hex-encoded bytes
+     * @return input as an array of bytes
+     */
+    private byte[] hexToBytes(String input) {
+        if (input == null) {
+            return null;
+        }
+
+        final int inputLength = input.length();
+        if ((inputLength % 2) != 0) {
+            System.err.print("Invalid length; must be multiple of 2");
+            return null;
+        }
+
+        final int byteLength = inputLength / 2;
+        final byte[] output = new byte[byteLength];
+
+        int inputIndex = 0;
+        int byteIndex = 0;
+        while (inputIndex < inputLength) {
+            output[byteIndex++] = (byte) Integer.parseInt(
+                    input.substring(inputIndex, inputIndex + 2), 16);
+            inputIndex += 2;
+        }
+
+        return output;
+    }
+
     public void runCreateUser() {
         // Need to be run as root
         if (Process.myUid() != ROOT_UID) {
@@ -1236,7 +1362,8 @@
         System.err.println("       pm list libraries");
         System.err.println("       pm list users");
         System.err.println("       pm path PACKAGE");
-        System.err.println("       pm install [-l] [-r] [-t] [-i INSTALLER_PACKAGE_NAME] [-s] [-f] PATH");
+        System.err.println("       pm install [-l] [-r] [-t] [-i INSTALLER_PACKAGE_NAME] [-s] [-f]");
+        System.err.println("                  [--algo <algorithm name> --key <key-in-hex> --iv <IV-in-hex>] PATH");
         System.err.println("       pm uninstall [-k] PACKAGE");
         System.err.println("       pm clear PACKAGE");
         System.err.println("       pm enable [--user USER_ID] PACKAGE_OR_COMPONENT");
diff --git a/core/java/android/accessibilityservice/AccessibilityService.java b/core/java/android/accessibilityservice/AccessibilityService.java
index b644dd1..c559e54 100644
--- a/core/java/android/accessibilityservice/AccessibilityService.java
+++ b/core/java/android/accessibilityservice/AccessibilityService.java
@@ -284,14 +284,14 @@
     public static final int GESTURE_SWIPE_DOWN_AND_RIGHT = 16;
 
     /**
-     * The user has performed a two finger tap gesture on the touch screen.
+     * The user has performed a double tap gesture on the touch screen.
      */
-    public static final int GESTURE_TWO_FINGER_TAP = 17;
+    public static final int GESTURE_DOUBLE_TAP = 17;
 
     /**
-     * The user has performed a two finger long press gesture on the touch screen.
+     * The user has performed a tap and hold gesture on the touch screen.
      */
-    public static final int GESTURE_TWO_FINGER_LONG_PRESS = 18;
+    public static final int GESTURE_TAP_AND_HOLD = 18;
 
     /**
      * The {@link Intent} that must be declared as handled by the service.
@@ -408,8 +408,8 @@
      * @see #GESTURE_SWIPE_RIGHT_AND_DOWN
      * @see #GESTURE_CLOCKWISE_CIRCLE
      * @see #GESTURE_COUNTER_CLOCKWISE_CIRCLE
-     * @see #GESTURE_TWO_FINGER_TAP
-     * @see #GESTURE_TWO_FINGER_LONG_PRESS
+     * @see #GESTURE_DOUBLE_TAP
+     * @see #GESTURE_TAP_AND_HOLD
      */
     protected boolean onGesture(int gestureId) {
         // TODO: Describe the default gesture processing in the javaDoc once it is finalized.
diff --git a/core/java/android/accessibilityservice/UiTestAutomationBridge.java b/core/java/android/accessibilityservice/UiTestAutomationBridge.java
index 4d4bfeb..69195c1 100644
--- a/core/java/android/accessibilityservice/UiTestAutomationBridge.java
+++ b/core/java/android/accessibilityservice/UiTestAutomationBridge.java
@@ -189,6 +189,7 @@
         final AccessibilityServiceInfo info = new AccessibilityServiceInfo();
         info.eventTypes = AccessibilityEvent.TYPES_ALL_MASK;
         info.feedbackType = AccessibilityServiceInfo.FEEDBACK_GENERIC;
+        info.flags |= AccessibilityNodeInfo.INCLUDE_NOT_IMPORTANT_VIEWS;
 
         try {
             manager.registerUiTestAutomationService(mListener, info);
diff --git a/core/java/android/animation/ValueAnimator.java b/core/java/android/animation/ValueAnimator.java
index 326f27c..f3a442a 100755
--- a/core/java/android/animation/ValueAnimator.java
+++ b/core/java/android/animation/ValueAnimator.java
@@ -910,7 +910,7 @@
         animationHandler.mPendingAnimations.add(this);
         if (mStartDelay == 0) {
             // This sets the initial value of the animation, prior to actually starting it running
-            setCurrentPlayTime(getCurrentPlayTime());
+            setCurrentPlayTime(0);
             mPlayingState = STOPPED;
             mRunning = true;
             notifyStartListeners();
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 29d96fe..ac55abe 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -2493,7 +2493,7 @@
         if (featureId == Window.FEATURE_OPTIONS_PANEL && menu != null) {
             boolean goforit = onPrepareOptionsMenu(menu);
             goforit |= mFragments.dispatchPrepareOptionsMenu(menu);
-            return goforit && menu.hasVisibleItems();
+            return goforit;
         }
         return true;
     }
@@ -2540,11 +2540,10 @@
                 if (item.getItemId() == android.R.id.home && mActionBar != null &&
                         (mActionBar.getDisplayOptions() & ActionBar.DISPLAY_HOME_AS_UP) != 0) {
                     if (mParent == null) {
-                        onNavigateUp();
+                        return onNavigateUp();
                     } else {
-                        mParent.onNavigateUpFromChild(this);
+                        return mParent.onNavigateUpFromChild(this);
                     }
-                    return true;
                 }
                 return false;
                 
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 314f5c2..8799194 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -2639,6 +2639,7 @@
                     if (DEBUG_CONFIGURATION) Slog.v(TAG, "Resuming activity "
                             + r.activityInfo.name + " with newConfig " + r.newConfig);
                     performConfigurationChanged(r.activity, r.newConfig);
+                    freeTextLayoutCachesIfNeeded(r.activity.mCurrentConfig.diff(r.newConfig));
                     r.newConfig = null;
                 }
                 if (localLOGV) Slog.v(TAG, "Resuming " + r + " with isForward="
@@ -2955,6 +2956,7 @@
                     if (DEBUG_CONFIGURATION) Slog.v(TAG, "Updating activity vis "
                             + r.activityInfo.name + " with new config " + r.newConfig);
                     performConfigurationChanged(r.activity, r.newConfig);
+                    freeTextLayoutCachesIfNeeded(r.activity.mCurrentConfig.diff(r.newConfig));
                     r.newConfig = null;
                 }
             } else {
@@ -3669,6 +3671,7 @@
     final void handleConfigurationChanged(Configuration config, CompatibilityInfo compat) {
 
         ArrayList<ComponentCallbacks2> callbacks = null;
+        int configDiff = 0;
 
         synchronized (mPackages) {
             if (mPendingConfiguration != null) {
@@ -3693,6 +3696,7 @@
             if (!mConfiguration.isOtherSeqNewer(config) && compat == null) {
                 return;
             }
+            configDiff = mConfiguration.diff(config);
             mConfiguration.updateFrom(config);
             config = applyCompatConfiguration();
             callbacks = collectComponentCallbacksLocked(false, config);
@@ -3701,6 +3705,8 @@
         // Cleanup hardware accelerated stuff
         WindowManagerImpl.getDefault().trimLocalMemory();
 
+        freeTextLayoutCachesIfNeeded(configDiff);
+
         if (callbacks != null) {
             final int N = callbacks.size();
             for (int i=0; i<N; i++) {
@@ -3709,6 +3715,17 @@
         }
     }
 
+    final void freeTextLayoutCachesIfNeeded(int configDiff) {
+        if (configDiff != 0) {
+            // Ask text layout engine to free its caches if there is a locale change
+            boolean hasLocaleConfigChange = ((configDiff & ActivityInfo.CONFIG_LOCALE) != 0);
+            if (hasLocaleConfigChange) {
+                Canvas.freeTextLayoutCaches();
+                if (DEBUG_CONFIGURATION) Slog.v(TAG, "Cleared TextLayout Caches");
+            }
+        }
+    }
+
     final void handleActivityConfigurationChanged(IBinder token) {
         ActivityClientRecord r = mActivities.get(token);
         if (r == null || r.activity == null) {
@@ -3719,6 +3736,8 @@
                 + r.activityInfo.name);
         
         performConfigurationChanged(r.activity, mCompatConfiguration);
+
+        freeTextLayoutCachesIfNeeded(r.activity.mCurrentConfig.diff(mCompatConfiguration));
     }
 
     final void handleProfilerControl(boolean start, ProfilerControlData pcd, int profileType) {
@@ -3821,6 +3840,9 @@
         // Ask graphics to free up as much as possible (font/image caches)
         Canvas.freeCaches();
 
+        // Ask text layout engine to free also as much as possible
+        Canvas.freeTextLayoutCaches();
+
         BinderInternal.forceGc("mem");
     }
 
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index 0510de1..191a696 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -24,6 +24,7 @@
 import android.content.pm.ActivityInfo;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.ComponentInfo;
+import android.content.pm.ContainerEncryptionParams;
 import android.content.pm.FeatureInfo;
 import android.content.pm.IPackageDataObserver;
 import android.content.pm.IPackageDeleteObserver;
@@ -973,10 +974,10 @@
     @Override
     public void installPackageWithVerification(Uri packageURI, IPackageInstallObserver observer,
             int flags, String installerPackageName, Uri verificationURI,
-            ManifestDigest manifestDigest) {
+            ManifestDigest manifestDigest, ContainerEncryptionParams encryptionParams) {
         try {
             mPM.installPackageWithVerification(packageURI, observer, flags, installerPackageName,
-                    verificationURI, manifestDigest);
+                    verificationURI, manifestDigest, encryptionParams);
         } catch (RemoteException e) {
             // Should never happen!
         }
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 64a05a8..4943c9a 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -387,7 +387,7 @@
                 public Object createService(ContextImpl ctx) {
                     IBinder b = ServiceManager.getService(NSD_SERVICE);
                     INsdManager service = INsdManager.Stub.asInterface(b);
-                    return new NsdManager(service);
+                    return new NsdManager(ctx.getOuterContext(), service);
                 }});
 
         // Note: this was previously cached in a static variable, but
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 0d76877..f962259 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -1436,6 +1436,7 @@
                 // Log.d("Notification", "has actions: " + mContentText);
                 big.setViewVisibility(R.id.actions, View.VISIBLE);
                 if (N>3) N=3;
+                big.removeAllViews(R.id.actions);
                 for (int i=0; i<N; i++) {
                     final RemoteViews button = generateActionButton(mActions.get(i));
                     //Log.d("Notification", "adding action " + i + ": " + mActions.get(i).title);
diff --git a/core/java/android/app/TaskStackBuilder.java b/core/java/android/app/TaskStackBuilder.java
index e546f6c..14c5736 100644
--- a/core/java/android/app/TaskStackBuilder.java
+++ b/core/java/android/app/TaskStackBuilder.java
@@ -196,18 +196,12 @@
         try {
             ActivityInfo info = pm.getActivityInfo(sourceActivityName, 0);
             String parentActivity = info.parentActivityName;
-            Intent parent = new Intent().setComponent(
-                    new ComponentName(info.packageName, parentActivity));
-            while (parent != null) {
+            while (parentActivity != null) {
+                Intent parent = new Intent().setComponent(
+                        new ComponentName(info.packageName, parentActivity));
                 mIntents.add(insertAt, parent);
                 info = pm.getActivityInfo(parent.getComponent(), 0);
                 parentActivity = info.parentActivityName;
-                if (parentActivity != null) {
-                    parent = new Intent().setComponent(
-                            new ComponentName(info.packageName, parentActivity));
-                } else {
-                    parent = null;
-                }
             }
         } catch (NameNotFoundException e) {
             Log.e(TAG, "Bad ComponentName while traversing activity parent metadata");
diff --git a/core/java/android/appwidget/AppWidgetHostView.java b/core/java/android/appwidget/AppWidgetHostView.java
index c9bacba..01b68d4 100644
--- a/core/java/android/appwidget/AppWidgetHostView.java
+++ b/core/java/android/appwidget/AppWidgetHostView.java
@@ -208,8 +208,10 @@
     }
 
     /**
-     * Provide guidance about the size of this widget to the AppWidgetManager. This information
-     * gets embedded into the AppWidgetExtras and causes a callback to the AppWidgetProvider.
+     * Provide guidance about the size of this widget to the AppWidgetManager. The widths and
+     * heights should correspond to the full area the AppWidgetHostView is given. Padding added by
+     * the framework will be accounted for automatically. This information gets embedded into the
+     * AppWidget options and causes a callback to the AppWidgetProvider.
      * @see AppWidgetProvider#onAppWidgetOptionsChanged(Context, AppWidgetManager, int, Bundle)
      *
      * @param options The bundle of options, in addition to the size information,
@@ -225,10 +227,20 @@
         if (options == null) {
             options = new Bundle();
         }
-        options.putInt(AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH, minWidth);
-        options.putInt(AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT, minHeight);
-        options.putInt(AppWidgetManager.OPTION_APPWIDGET_MAX_WIDTH, maxWidth);
-        options.putInt(AppWidgetManager.OPTION_APPWIDGET_MAX_HEIGHT, maxHeight);
+
+        Rect padding = new Rect();
+        if (mInfo != null) {
+            padding = getDefaultPaddingForWidget(mContext, mInfo.provider, padding);
+        }
+        float density = getResources().getDisplayMetrics().density;
+
+        int xPaddingDips = (int) ((padding.left + padding.right) / density);
+        int yPaddingDips = (int) ((padding.top + padding.bottom) / density);
+
+        options.putInt(AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH, minWidth - xPaddingDips);
+        options.putInt(AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT, minHeight - yPaddingDips);
+        options.putInt(AppWidgetManager.OPTION_APPWIDGET_MAX_WIDTH, maxWidth - xPaddingDips);
+        options.putInt(AppWidgetManager.OPTION_APPWIDGET_MAX_HEIGHT, maxHeight - yPaddingDips);
         updateAppWidgetOptions(options);
     }
 
diff --git a/core/java/android/content/AsyncTaskLoader.java b/core/java/android/content/AsyncTaskLoader.java
index da51952..f9025d9 100644
--- a/core/java/android/content/AsyncTaskLoader.java
+++ b/core/java/android/content/AsyncTaskLoader.java
@@ -18,6 +18,7 @@
 
 import android.os.AsyncTask;
 import android.os.Handler;
+import android.os.OperationCanceledException;
 import android.os.SystemClock;
 import android.util.Slog;
 import android.util.TimeUtils;
diff --git a/core/java/android/content/ContentProvider.java b/core/java/android/content/ContentProvider.java
index 1206056..b22179e 100644
--- a/core/java/android/content/ContentProvider.java
+++ b/core/java/android/content/ContentProvider.java
@@ -29,6 +29,9 @@
 import android.os.AsyncTask;
 import android.os.Binder;
 import android.os.Bundle;
+import android.os.CancellationSignal;
+import android.os.ICancellationSignal;
+import android.os.OperationCanceledException;
 import android.os.ParcelFileDescriptor;
 import android.os.Process;
 import android.os.RemoteException;
diff --git a/core/java/android/content/ContentProviderClient.java b/core/java/android/content/ContentProviderClient.java
index 3ac5e07..da2ab94 100644
--- a/core/java/android/content/ContentProviderClient.java
+++ b/core/java/android/content/ContentProviderClient.java
@@ -19,6 +19,8 @@
 import android.database.Cursor;
 import android.net.Uri;
 import android.os.Bundle;
+import android.os.CancellationSignal;
+import android.os.ICancellationSignal;
 import android.os.RemoteException;
 import android.os.ParcelFileDescriptor;
 import android.content.res.AssetFileDescriptor;
diff --git a/core/java/android/content/ContentProviderNative.java b/core/java/android/content/ContentProviderNative.java
index 4b31552..550a1c9 100644
--- a/core/java/android/content/ContentProviderNative.java
+++ b/core/java/android/content/ContentProviderNative.java
@@ -30,6 +30,7 @@
 import android.os.Bundle;
 import android.os.RemoteException;
 import android.os.IBinder;
+import android.os.ICancellationSignal;
 import android.os.Parcel;
 import android.os.ParcelFileDescriptor;
 import android.os.Parcelable;
diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java
index 722fdc6..d4bca0a 100644
--- a/core/java/android/content/ContentResolver.java
+++ b/core/java/android/content/ContentResolver.java
@@ -33,7 +33,10 @@
 import android.database.IContentObserver;
 import android.net.Uri;
 import android.os.Bundle;
+import android.os.CancellationSignal;
 import android.os.IBinder;
+import android.os.ICancellationSignal;
+import android.os.OperationCanceledException;
 import android.os.ParcelFileDescriptor;
 import android.os.RemoteException;
 import android.os.ServiceManager;
diff --git a/core/java/android/content/CursorLoader.java b/core/java/android/content/CursorLoader.java
index aed3728..9f7a104 100644
--- a/core/java/android/content/CursorLoader.java
+++ b/core/java/android/content/CursorLoader.java
@@ -19,6 +19,8 @@
 import android.database.ContentObserver;
 import android.database.Cursor;
 import android.net.Uri;
+import android.os.CancellationSignal;
+import android.os.OperationCanceledException;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
diff --git a/core/java/android/content/IContentProvider.java b/core/java/android/content/IContentProvider.java
index 16478b7..eeba1e0 100644
--- a/core/java/android/content/IContentProvider.java
+++ b/core/java/android/content/IContentProvider.java
@@ -21,6 +21,7 @@
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.IBinder;
+import android.os.ICancellationSignal;
 import android.os.IInterface;
 import android.os.ParcelFileDescriptor;
 import android.os.RemoteException;
diff --git a/core/java/android/content/SyncStorageEngine.java b/core/java/android/content/SyncStorageEngine.java
index 6c7e940..226e107 100644
--- a/core/java/android/content/SyncStorageEngine.java
+++ b/core/java/android/content/SyncStorageEngine.java
@@ -197,6 +197,29 @@
         long delayUntil;
         final ArrayList<Pair<Bundle, Long>> periodicSyncs;
 
+        /**
+         * Copy constructor for making deep-ish copies. Only the bundles stored
+         * in periodic syncs can make unexpected changes.
+         *
+         * @param toCopy AuthorityInfo to be copied.
+         */
+        AuthorityInfo(AuthorityInfo toCopy) {
+            account = toCopy.account;
+            userId = toCopy.userId;
+            authority = toCopy.authority;
+            ident = toCopy.ident;
+            enabled = toCopy.enabled;
+            syncable = toCopy.syncable;
+            backoffTime = toCopy.backoffTime;
+            backoffDelay = toCopy.backoffDelay;
+            delayUntil = toCopy.delayUntil;
+            periodicSyncs = new ArrayList<Pair<Bundle, Long>>();
+            for (Pair<Bundle, Long> sync : toCopy.periodicSyncs) {
+                // Still not a perfect copy, because we are just copying the mappings.
+                periodicSyncs.add(Pair.create(new Bundle(sync.first), sync.second));
+            }
+        }
+
         AuthorityInfo(Account account, int userId, String authority, int ident) {
             this.account = account;
             this.userId = userId;
@@ -1212,7 +1235,8 @@
             final int N = mAuthorities.size();
             ArrayList<AuthorityInfo> infos = new ArrayList<AuthorityInfo>(N);
             for (int i=0; i<N; i++) {
-                infos.add(mAuthorities.valueAt(i));
+                // Make deep copy because AuthorityInfo syncs are liable to change.
+                infos.add(new AuthorityInfo(mAuthorities.valueAt(i)));
             }
             return infos;
         }
diff --git a/core/java/android/content/ICancellationSignal.aidl b/core/java/android/content/pm/ContainerEncryptionParams.aidl
similarity index 70%
copy from core/java/android/content/ICancellationSignal.aidl
copy to core/java/android/content/pm/ContainerEncryptionParams.aidl
index cf1c5d3..c13d946 100644
--- a/core/java/android/content/ICancellationSignal.aidl
+++ b/core/java/android/content/pm/ContainerEncryptionParams.aidl
@@ -1,11 +1,11 @@
 /*
- * Copyright (C) 2012 The Android Open Source Project
+ * Copyright 2012, The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
  *
- *      http://www.apache.org/licenses/LICENSE-2.0
+ *     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,
@@ -14,11 +14,6 @@
  * limitations under the License.
  */
 
-package android.content;
+package android.content.pm;
 
-/**
- * @hide
- */
-interface ICancellationSignal {
-    oneway void cancel();
-}
+parcelable ContainerEncryptionParams;
diff --git a/core/java/android/content/pm/ContainerEncryptionParams.java b/core/java/android/content/pm/ContainerEncryptionParams.java
new file mode 100644
index 0000000..5b1440d
--- /dev/null
+++ b/core/java/android/content/pm/ContainerEncryptionParams.java
@@ -0,0 +1,378 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.content.pm;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.text.TextUtils;
+import android.util.Slog;
+
+import java.security.InvalidAlgorithmParameterException;
+import java.security.spec.AlgorithmParameterSpec;
+import java.util.Arrays;
+
+import javax.crypto.SecretKey;
+import javax.crypto.spec.IvParameterSpec;
+
+/**
+ * Represents encryption parameters used to read a container.
+ *
+ * @hide
+ */
+public class ContainerEncryptionParams implements Parcelable {
+    protected static final String TAG = "ContainerEncryptionParams";
+
+    /** What we print out first when toString() is called. */
+    private static final String TO_STRING_PREFIX = "ContainerEncryptionParams{";
+
+    /**
+     * Parameter type for parceling that indicates the next parameters are
+     * IvParameters.
+     */
+    private static final int ENC_PARAMS_IV_PARAMETERS = 1;
+
+    /** Parameter type for paceling that indicates there are no MAC parameters. */
+    private static final int MAC_PARAMS_NONE = 1;
+
+    /** The encryption algorithm used. */
+    private final String mEncryptionAlgorithm;
+
+    /** The parameter spec to be used for encryption. */
+    private final IvParameterSpec mEncryptionSpec;
+
+    /** Secret key to be used for decryption. */
+    private final SecretKey mEncryptionKey;
+
+    /** Algorithm name for the MAC to be used. */
+    private final String mMacAlgorithm;
+
+    /** The parameter spec to be used for the MAC tag authentication. */
+    private final AlgorithmParameterSpec mMacSpec;
+
+    /** Secret key to be used for MAC tag authentication. */
+    private final SecretKey mMacKey;
+
+    /** MAC tag authenticating the data in the container. */
+    private final byte[] mMacTag;
+
+    /** Offset into file where authenticated (e.g., MAC protected) data begins. */
+    private final int mAuthenticatedDataStart;
+
+    /** Offset into file where encrypted data begins. */
+    private final int mEncryptedDataStart;
+
+    /**
+     * Offset into file for the end of encrypted data (and, by extension,
+     * authenticated data) in file.
+     */
+    private final int mDataEnd;
+
+    public ContainerEncryptionParams(String encryptionAlgorithm,
+            AlgorithmParameterSpec encryptionSpec, SecretKey encryptionKey)
+            throws InvalidAlgorithmParameterException {
+        this(encryptionAlgorithm, encryptionSpec, encryptionKey, null, null, null, null, -1, -1,
+                -1);
+    }
+
+    /**
+     * Creates container encryption specifications for installing from encrypted
+     * containers.
+     *
+     * @param encryptionAlgorithm encryption algorithm to use; format matches
+     *            JCE
+     * @param encryptionSpec algorithm parameter specification
+     * @param encryptionKey key used for decryption
+     * @param macAlgorithm MAC algorithm to use; format matches JCE
+     * @param macSpec algorithm parameters specification, may be {@code null}
+     * @param macKey key used for authentication (i.e., for the MAC tag)
+     * @param authenticatedDataStart offset of start of authenticated data in
+     *            stream
+     * @param encryptedDataStart offset of start of encrypted data in stream
+     * @param dataEnd offset of the end of both the authenticated and encrypted
+     *            data
+     * @throws InvalidAlgorithmParameterException
+     */
+    public ContainerEncryptionParams(String encryptionAlgorithm,
+            AlgorithmParameterSpec encryptionSpec, SecretKey encryptionKey, String macAlgorithm,
+            AlgorithmParameterSpec macSpec, SecretKey macKey, byte[] macTag,
+            int authenticatedDataStart, int encryptedDataStart, int dataEnd)
+            throws InvalidAlgorithmParameterException {
+        if (TextUtils.isEmpty(encryptionAlgorithm)) {
+            throw new NullPointerException("algorithm == null");
+        } else if (encryptionSpec == null) {
+            throw new NullPointerException("encryptionSpec == null");
+        } else if (encryptionKey == null) {
+            throw new NullPointerException("encryptionKey == null");
+        }
+
+        if (!TextUtils.isEmpty(macAlgorithm)) {
+            if (macKey == null) {
+                throw new NullPointerException("macKey == null");
+            }
+        }
+
+        if (!(encryptionSpec instanceof IvParameterSpec)) {
+            throw new InvalidAlgorithmParameterException(
+                    "Unknown parameter spec class; must be IvParameters");
+        }
+
+        mEncryptionAlgorithm = encryptionAlgorithm;
+        mEncryptionSpec = (IvParameterSpec) encryptionSpec;
+        mEncryptionKey = encryptionKey;
+
+        mMacAlgorithm = macAlgorithm;
+        mMacSpec = macSpec;
+        mMacKey = macKey;
+        mMacTag = macTag;
+
+        mAuthenticatedDataStart = authenticatedDataStart;
+        mEncryptedDataStart = encryptedDataStart;
+        mDataEnd = dataEnd;
+    }
+
+    public String getEncryptionAlgorithm() {
+        return mEncryptionAlgorithm;
+    }
+
+    public AlgorithmParameterSpec getEncryptionSpec() {
+        return mEncryptionSpec;
+    }
+
+    public SecretKey getEncryptionKey() {
+        return mEncryptionKey;
+    }
+
+    public String getMacAlgorithm() {
+        return mMacAlgorithm;
+    }
+
+    public AlgorithmParameterSpec getMacSpec() {
+        return mMacSpec;
+    }
+
+    public SecretKey getMacKey() {
+        return mMacKey;
+    }
+
+    public byte[] getMacTag() {
+        return mMacTag;
+    }
+
+    public int getAuthenticatedDataStart() {
+        return mAuthenticatedDataStart;
+    }
+
+    public int getEncryptedDataStart() {
+        return mEncryptedDataStart;
+    }
+
+    public int getDataEnd() {
+        return mDataEnd;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+
+        if (!(o instanceof ContainerEncryptionParams)) {
+            return false;
+        }
+
+        final ContainerEncryptionParams other = (ContainerEncryptionParams) o;
+
+        // Primitive comparison
+        if ((mAuthenticatedDataStart != other.mAuthenticatedDataStart)
+                || (mEncryptedDataStart != other.mEncryptedDataStart)
+                || (mDataEnd != other.mDataEnd)) {
+            return false;
+        }
+
+        // String comparison
+        if (!mEncryptionAlgorithm.equals(other.mEncryptionAlgorithm)
+                || !mMacAlgorithm.equals(other.mMacAlgorithm)) {
+            return false;
+        }
+
+        // Object comparison
+        if (!isSecretKeyEqual(mEncryptionKey, other.mEncryptionKey)
+                || !isSecretKeyEqual(mMacKey, other.mMacKey)) {
+            return false;
+        }
+
+        if (!Arrays.equals(mEncryptionSpec.getIV(), other.mEncryptionSpec.getIV())
+                || !Arrays.equals(mMacTag, other.mMacTag) || (mMacSpec != other.mMacSpec)) {
+            return false;
+        }
+
+        return true;
+    }
+
+    private static final boolean isSecretKeyEqual(SecretKey key1, SecretKey key2) {
+        final String keyFormat = key1.getFormat();
+        final String otherKeyFormat = key2.getFormat();
+
+        if (keyFormat == null) {
+            if (keyFormat != otherKeyFormat) {
+                return false;
+            }
+
+            if (key1.getEncoded() != key2.getEncoded()) {
+                return false;
+            }
+        } else {
+            if (!keyFormat.equals(key2.getFormat())) {
+                return false;
+            }
+
+            if (!Arrays.equals(key1.getEncoded(), key2.getEncoded())) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int hash = 3;
+
+        hash += 5 * mEncryptionAlgorithm.hashCode();
+        hash += 7 * Arrays.hashCode(mEncryptionSpec.getIV());
+        hash += 11 * mEncryptionKey.hashCode();
+        hash += 13 * mMacAlgorithm.hashCode();
+        hash += 17 * mMacKey.hashCode();
+        hash += 19 * Arrays.hashCode(mMacTag);
+        hash += 23 * mAuthenticatedDataStart;
+        hash += 29 * mEncryptedDataStart;
+        hash += 31 * mDataEnd;
+
+        return hash;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder(TO_STRING_PREFIX);
+
+        sb.append("mEncryptionAlgorithm=\"");
+        sb.append(mEncryptionAlgorithm);
+        sb.append("\",");
+        sb.append("mEncryptionSpec=");
+        sb.append(mEncryptionSpec.toString());
+        sb.append("mEncryptionKey=");
+        sb.append(mEncryptionKey.toString());
+
+        sb.append("mMacAlgorithm=\"");
+        sb.append(mMacAlgorithm);
+        sb.append("\",");
+        sb.append("mMacSpec=");
+        sb.append(mMacSpec.toString());
+        sb.append("mMacKey=");
+        sb.append(mMacKey.toString());
+
+        sb.append(",mAuthenticatedDataStart=");
+        sb.append(mAuthenticatedDataStart);
+        sb.append(",mEncryptedDataStart=");
+        sb.append(mEncryptedDataStart);
+        sb.append(",mDataEnd=");
+        sb.append(mDataEnd);
+        sb.append('}');
+
+        return sb.toString();
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeString(mEncryptionAlgorithm);
+        dest.writeInt(ENC_PARAMS_IV_PARAMETERS);
+        dest.writeByteArray(mEncryptionSpec.getIV());
+        dest.writeSerializable(mEncryptionKey);
+
+        dest.writeString(mMacAlgorithm);
+        dest.writeInt(MAC_PARAMS_NONE);
+        dest.writeByteArray(new byte[0]);
+        dest.writeSerializable(mMacKey);
+
+        dest.writeByteArray(mMacTag);
+
+        dest.writeInt(mAuthenticatedDataStart);
+        dest.writeInt(mEncryptedDataStart);
+        dest.writeInt(mDataEnd);
+    }
+
+    private ContainerEncryptionParams(Parcel source) throws InvalidAlgorithmParameterException {
+        mEncryptionAlgorithm = source.readString();
+        final int encParamType = source.readInt();
+        final byte[] encParamsEncoded = source.createByteArray();
+        mEncryptionKey = (SecretKey) source.readSerializable();
+
+        mMacAlgorithm = source.readString();
+        final int macParamType = source.readInt();
+        source.createByteArray(); // byte[] macParamsEncoded
+        mMacKey = (SecretKey) source.readSerializable();
+
+        mMacTag = source.createByteArray();
+
+        mAuthenticatedDataStart = source.readInt();
+        mEncryptedDataStart = source.readInt();
+        mDataEnd = source.readInt();
+
+        switch (encParamType) {
+            case ENC_PARAMS_IV_PARAMETERS:
+                mEncryptionSpec = new IvParameterSpec(encParamsEncoded);
+                break;
+            default:
+                throw new InvalidAlgorithmParameterException("Unknown parameter type "
+                        + encParamType);
+        }
+
+        switch (macParamType) {
+            case MAC_PARAMS_NONE:
+                mMacSpec = null;
+                break;
+            default:
+                throw new InvalidAlgorithmParameterException("Unknown parameter type "
+                        + macParamType);
+        }
+
+        if (mEncryptionKey == null) {
+            throw new NullPointerException("encryptionKey == null");
+        }
+    }
+
+    public static final Parcelable.Creator<ContainerEncryptionParams> CREATOR =
+            new Parcelable.Creator<ContainerEncryptionParams>() {
+        public ContainerEncryptionParams createFromParcel(Parcel source) {
+            try {
+                return new ContainerEncryptionParams(source);
+            } catch (InvalidAlgorithmParameterException e) {
+                Slog.e(TAG, "Invalid algorithm parameters specified", e);
+                return null;
+            }
+        }
+
+        public ContainerEncryptionParams[] newArray(int size) {
+            return new ContainerEncryptionParams[size];
+        }
+    };
+}
\ No newline at end of file
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index 9b8454a..70c0c48 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -22,6 +22,7 @@
 import android.content.IntentFilter;
 import android.content.pm.ActivityInfo;
 import android.content.pm.ApplicationInfo;
+import android.content.pm.ContainerEncryptionParams;
 import android.content.pm.FeatureInfo;
 import android.content.pm.IPackageInstallObserver;
 import android.content.pm.IPackageDeleteObserver;
@@ -362,7 +363,7 @@
 
     void installPackageWithVerification(in Uri packageURI, in IPackageInstallObserver observer,
             int flags, in String installerPackageName, in Uri verificationURI,
-            in ManifestDigest manifestDigest);
+            in ManifestDigest manifestDigest, in ContainerEncryptionParams encryptionParams);
 
     void verifyPendingInstall(int id, int verificationCode);
 
diff --git a/core/java/android/content/pm/LimitedLengthInputStream.java b/core/java/android/content/pm/LimitedLengthInputStream.java
new file mode 100644
index 0000000..25a490f
--- /dev/null
+++ b/core/java/android/content/pm/LimitedLengthInputStream.java
@@ -0,0 +1,82 @@
+package android.content.pm;
+
+import java.io.FilterInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * A class that limits the amount of data that is read from an InputStream. When
+ * the specified length is reached, the stream returns an EOF even if the
+ * underlying stream still has more data.
+ *
+ * @hide
+ */
+public class LimitedLengthInputStream extends FilterInputStream {
+    /**
+     * The end of the stream where we don't want to allow more data to be read.
+     */
+    private final int mEnd;
+
+    /**
+     * Current offset in the stream.
+     */
+    private int mOffset;
+
+    /**
+     * @param in underlying stream to wrap
+     * @param offset offset into stream where data starts
+     * @param length length of data at offset
+     * @throws IOException if an error occured with the underlying stream
+     */
+    public LimitedLengthInputStream(InputStream in, int offset, int length) throws IOException {
+        super(in);
+
+        if (in == null) {
+            throw new IOException("in == null");
+        }
+
+        if (offset < 0) {
+            throw new IOException("offset == " + offset);
+        }
+
+        if (length < 0) {
+            throw new IOException("length must be non-negative; is " + length);
+        }
+
+        mEnd = offset + length;
+
+        skip(offset);
+        mOffset = offset;
+    }
+
+    @Override
+    public synchronized int read() throws IOException {
+        if (mOffset >= mEnd) {
+            return -1;
+        }
+
+        mOffset++;
+        return super.read();
+    }
+
+    @Override
+    public int read(byte[] buffer, int offset, int byteCount) throws IOException {
+        if (mOffset >= mEnd) {
+            return -1;
+        }
+
+        if (mOffset + byteCount > mEnd) {
+            byteCount = mEnd - mOffset;
+        }
+
+        final int numRead = super.read(buffer, offset, byteCount);
+        mOffset += numRead;
+
+        return numRead;
+    }
+
+    @Override
+    public int read(byte[] buffer) throws IOException {
+        return read(buffer, 0, buffer.length);
+    }
+}
diff --git a/core/java/android/content/pm/MacAuthenticatedInputStream.java b/core/java/android/content/pm/MacAuthenticatedInputStream.java
new file mode 100644
index 0000000..11f4b94
--- /dev/null
+++ b/core/java/android/content/pm/MacAuthenticatedInputStream.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.content.pm;
+
+import java.io.FilterInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.crypto.Mac;
+
+/**
+ * An input stream filter that applies a MAC to the data passing through it. At
+ * the end of the data that should be authenticated, the tag can be calculated.
+ * After that, the stream should not be used.
+ *
+ * @hide
+ */
+public class MacAuthenticatedInputStream extends FilterInputStream {
+    private final Mac mMac;
+
+    public MacAuthenticatedInputStream(InputStream in, Mac mac) {
+        super(in);
+
+        mMac = mac;
+    }
+
+    public boolean isTagEqual(byte[] tag) {
+        final byte[] actualTag = mMac.doFinal();
+
+        if (tag == null || actualTag == null || tag.length != actualTag.length) {
+            return false;
+        }
+
+        /*
+         * Attempt to prevent timing attacks by doing the same amount of work
+         * whether the first byte matches or not. Do not change this to a loop
+         * that exits early when a byte does not match.
+         */
+        int value = 0;
+        for (int i = 0; i < tag.length; i++) {
+            value |= tag[i] ^ actualTag[i];
+        }
+
+        return value == 0;
+    }
+
+    @Override
+    public int read() throws IOException {
+        final int b = super.read();
+        if (b >= 0) {
+            mMac.update((byte) b);
+        }
+        return b;
+    }
+
+    @Override
+    public int read(byte[] buffer, int offset, int count) throws IOException {
+        int numRead = super.read(buffer, offset, count);
+        if (numRead > 0) {
+            mMac.update(buffer, offset, numRead);
+        }
+        return numRead;
+    }
+}
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index c3ce1cf..a48924e 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -28,7 +28,6 @@
 import android.content.res.XmlResourceParser;
 import android.graphics.drawable.Drawable;
 import android.net.Uri;
-import android.os.Build;
 import android.os.Environment;
 import android.util.AndroidException;
 import android.util.DisplayMetrics;
@@ -2199,12 +2198,19 @@
      *            is performing the installation. This identifies which market
      *            the package came from.
      * @param verificationURI The location of the supplementary verification
-     *            file. This can be a 'file:' or a 'content:' URI.
+     *            file. This can be a 'file:' or a 'content:' URI. May be
+     *            {@code null}.
+     * @param manifestDigest an object that holds the digest of the package
+     *            which can be used to verify ownership. May be {@code null}.
+     * @param encryptionParams if the package to be installed is encrypted,
+     *            these parameters describing the encryption and authentication
+     *            used. May be {@code null}.
      * @hide
      */
     public abstract void installPackageWithVerification(Uri packageURI,
             IPackageInstallObserver observer, int flags, String installerPackageName,
-            Uri verificationURI, ManifestDigest manifestDigest);
+            Uri verificationURI, ManifestDigest manifestDigest,
+            ContainerEncryptionParams encryptionParams);
 
     /**
      * Allows a package listening to the
diff --git a/core/java/android/content/res/AssetFileDescriptor.java b/core/java/android/content/res/AssetFileDescriptor.java
index 9893133..7d46710 100644
--- a/core/java/android/content/res/AssetFileDescriptor.java
+++ b/core/java/android/content/res/AssetFileDescriptor.java
@@ -52,6 +52,9 @@
      */
     public AssetFileDescriptor(ParcelFileDescriptor fd, long startOffset,
             long length) {
+        if (fd == null) {
+            throw new IllegalArgumentException("fd must not be null");
+        }
         if (length < 0 && startOffset != 0) {
             throw new IllegalArgumentException(
                     "startOffset must be 0 when using UNKNOWN_LENGTH");
diff --git a/core/java/android/database/DatabaseUtils.java b/core/java/android/database/DatabaseUtils.java
index 40a54cf..a6af5c2 100644
--- a/core/java/android/database/DatabaseUtils.java
+++ b/core/java/android/database/DatabaseUtils.java
@@ -21,7 +21,6 @@
 import android.content.ContentValues;
 import android.content.Context;
 import android.content.OperationApplicationException;
-import android.content.OperationCanceledException;
 import android.database.sqlite.SQLiteAbortException;
 import android.database.sqlite.SQLiteConstraintException;
 import android.database.sqlite.SQLiteDatabase;
@@ -31,6 +30,7 @@
 import android.database.sqlite.SQLiteFullException;
 import android.database.sqlite.SQLiteProgram;
 import android.database.sqlite.SQLiteStatement;
+import android.os.OperationCanceledException;
 import android.os.Parcel;
 import android.os.ParcelFileDescriptor;
 import android.text.TextUtils;
diff --git a/core/java/android/database/sqlite/SQLiteConnection.java b/core/java/android/database/sqlite/SQLiteConnection.java
index acdc488..6f7c1f3 100644
--- a/core/java/android/database/sqlite/SQLiteConnection.java
+++ b/core/java/android/database/sqlite/SQLiteConnection.java
@@ -19,12 +19,12 @@
 import dalvik.system.BlockGuard;
 import dalvik.system.CloseGuard;
 
-import android.content.CancellationSignal;
-import android.content.OperationCanceledException;
 import android.database.Cursor;
 import android.database.CursorWindow;
 import android.database.DatabaseUtils;
 import android.database.sqlite.SQLiteDebug.DbStats;
+import android.os.CancellationSignal;
+import android.os.OperationCanceledException;
 import android.os.ParcelFileDescriptor;
 import android.util.Log;
 import android.util.LruCache;
diff --git a/core/java/android/database/sqlite/SQLiteConnectionPool.java b/core/java/android/database/sqlite/SQLiteConnectionPool.java
index a175662..3a1714c 100644
--- a/core/java/android/database/sqlite/SQLiteConnectionPool.java
+++ b/core/java/android/database/sqlite/SQLiteConnectionPool.java
@@ -18,9 +18,9 @@
 
 import dalvik.system.CloseGuard;
 
-import android.content.CancellationSignal;
-import android.content.OperationCanceledException;
 import android.database.sqlite.SQLiteDebug.DbStats;
+import android.os.CancellationSignal;
+import android.os.OperationCanceledException;
 import android.os.SystemClock;
 import android.util.Log;
 import android.util.PrefixPrinter;
diff --git a/core/java/android/database/sqlite/SQLiteDatabase.java b/core/java/android/database/sqlite/SQLiteDatabase.java
index 7bd0c8d..e2d44f2 100644
--- a/core/java/android/database/sqlite/SQLiteDatabase.java
+++ b/core/java/android/database/sqlite/SQLiteDatabase.java
@@ -16,16 +16,16 @@
 
 package android.database.sqlite;
 
-import android.content.CancellationSignal;
 import android.content.ContentValues;
-import android.content.OperationCanceledException;
 import android.database.Cursor;
 import android.database.DatabaseErrorHandler;
 import android.database.DatabaseUtils;
 import android.database.DefaultDatabaseErrorHandler;
 import android.database.SQLException;
 import android.database.sqlite.SQLiteDebug.DbStats;
+import android.os.CancellationSignal;
 import android.os.Looper;
+import android.os.OperationCanceledException;
 import android.text.TextUtils;
 import android.util.EventLog;
 import android.util.Log;
diff --git a/core/java/android/database/sqlite/SQLiteDirectCursorDriver.java b/core/java/android/database/sqlite/SQLiteDirectCursorDriver.java
index 294edc4..797430a 100644
--- a/core/java/android/database/sqlite/SQLiteDirectCursorDriver.java
+++ b/core/java/android/database/sqlite/SQLiteDirectCursorDriver.java
@@ -16,9 +16,9 @@
 
 package android.database.sqlite;
 
-import android.content.CancellationSignal;
 import android.database.Cursor;
 import android.database.sqlite.SQLiteDatabase.CursorFactory;
+import android.os.CancellationSignal;
 
 /**
  * A cursor driver that uses the given query directly.
diff --git a/core/java/android/database/sqlite/SQLiteProgram.java b/core/java/android/database/sqlite/SQLiteProgram.java
index e9b06c6..26e8c31 100644
--- a/core/java/android/database/sqlite/SQLiteProgram.java
+++ b/core/java/android/database/sqlite/SQLiteProgram.java
@@ -16,8 +16,8 @@
 
 package android.database.sqlite;
 
-import android.content.CancellationSignal;
 import android.database.DatabaseUtils;
+import android.os.CancellationSignal;
 
 import java.util.Arrays;
 
diff --git a/core/java/android/database/sqlite/SQLiteQuery.java b/core/java/android/database/sqlite/SQLiteQuery.java
index 30e77b5..62bcc20 100644
--- a/core/java/android/database/sqlite/SQLiteQuery.java
+++ b/core/java/android/database/sqlite/SQLiteQuery.java
@@ -16,9 +16,9 @@
 
 package android.database.sqlite;
 
-import android.content.CancellationSignal;
-import android.content.OperationCanceledException;
 import android.database.CursorWindow;
+import android.os.CancellationSignal;
+import android.os.OperationCanceledException;
 import android.util.Log;
 
 /**
diff --git a/core/java/android/database/sqlite/SQLiteQueryBuilder.java b/core/java/android/database/sqlite/SQLiteQueryBuilder.java
index 6f84b5e..91884ab 100644
--- a/core/java/android/database/sqlite/SQLiteQueryBuilder.java
+++ b/core/java/android/database/sqlite/SQLiteQueryBuilder.java
@@ -16,10 +16,10 @@
 
 package android.database.sqlite;
 
-import android.content.CancellationSignal;
-import android.content.OperationCanceledException;
 import android.database.Cursor;
 import android.database.DatabaseUtils;
+import android.os.CancellationSignal;
+import android.os.OperationCanceledException;
 import android.provider.BaseColumns;
 import android.text.TextUtils;
 import android.util.Log;
diff --git a/core/java/android/database/sqlite/SQLiteSession.java b/core/java/android/database/sqlite/SQLiteSession.java
index 9410243..beb5b3a 100644
--- a/core/java/android/database/sqlite/SQLiteSession.java
+++ b/core/java/android/database/sqlite/SQLiteSession.java
@@ -16,10 +16,10 @@
 
 package android.database.sqlite;
 
-import android.content.CancellationSignal;
-import android.content.OperationCanceledException;
 import android.database.CursorWindow;
 import android.database.DatabaseUtils;
+import android.os.CancellationSignal;
+import android.os.OperationCanceledException;
 import android.os.ParcelFileDescriptor;
 
 /**
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index 332f40a..33dea6c 100644
--- a/core/java/android/inputmethodservice/InputMethodService.java
+++ b/core/java/android/inputmethodservice/InputMethodService.java
@@ -402,7 +402,7 @@
             mShowInputFlags = 0;
             mShowInputRequested = false;
             mShowInputForced = false;
-            hideWindow();
+            doHideWindow();
             if (resultReceiver != null) {
                 resultReceiver.send(wasVis != isInputViewShown()
                         ? InputMethodManager.RESULT_HIDDEN
@@ -737,7 +737,7 @@
                         onDisplayCompletions(completions);
                     }
                 } else {
-                    hideWindow();
+                    doHideWindow();
                 }
             } else if (mCandidatesVisibility == View.VISIBLE) {
                 // If the candidates are currently visible, make sure the
@@ -745,7 +745,7 @@
                 showWindow(false);
             } else {
                 // Otherwise hide the window.
-                hideWindow();
+                doHideWindow();
             }
             // If user uses hard keyboard, IME button should always be shown.
             boolean showing = onEvaluateInputViewShown();
@@ -1096,7 +1096,7 @@
             if (shown) {
                 showWindow(false);
             } else {
-                hideWindow();
+                doHideWindow();
             }
         }
     }
@@ -1449,9 +1449,13 @@
         mCandidatesViewStarted = false;
     }
 
+    private void doHideWindow() {
+        mImm.setImeWindowStatus(mToken, 0, mBackDisposition);
+        hideWindow();
+    }
+
     public void hideWindow() {
         finishViews();
-        mImm.setImeWindowStatus(mToken, 0, mBackDisposition);
         if (mWindowVisible) {
             mWindow.hide();
             mWindowVisible = false;
@@ -1703,7 +1707,7 @@
                 // If we have the window visible for some other reason --
                 // most likely to show candidates -- then just get rid
                 // of it.  This really shouldn't happen, but just in case...
-                if (doIt) hideWindow();
+                if (doIt) doHideWindow();
             }
             return true;
         }
diff --git a/core/java/android/net/nsd/NetworkServiceInfo.java b/core/java/android/net/nsd/NetworkServiceInfo.java
deleted file mode 100644
index 34d83d1..0000000
--- a/core/java/android/net/nsd/NetworkServiceInfo.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.nsd;
-
-/**
- * Interface for a network service.
- *
- * {@hide}
- */
-public interface NetworkServiceInfo {
-
-    String getServiceName();
-    void setServiceName(String s);
-
-    String getServiceType();
-    void setServiceType(String s);
-
-}
diff --git a/core/java/android/net/nsd/NsdManager.java b/core/java/android/net/nsd/NsdManager.java
index 77e97e1..08ba728 100644
--- a/core/java/android/net/nsd/NsdManager.java
+++ b/core/java/android/net/nsd/NsdManager.java
@@ -22,12 +22,16 @@
 import android.os.Binder;
 import android.os.IBinder;
 import android.os.Handler;
+import android.os.HandlerThread;
 import android.os.Looper;
 import android.os.Message;
 import android.os.RemoteException;
 import android.os.Messenger;
 import android.text.TextUtils;
 import android.util.Log;
+import android.util.SparseArray;
+
+import java.util.concurrent.CountDownLatch;
 
 import com.android.internal.util.AsyncChannel;
 import com.android.internal.util.Protocol;
@@ -39,88 +43,73 @@
  * B. Another example use case is an application discovering printers on the network.
  *
  * <p> The API currently supports DNS based service discovery and discovery is currently
- * limited to a local network over Multicast DNS. In future, it will be extended to
- * support wide area discovery and other service discovery mechanisms.
- * DNS service discovery is described at http://files.dns-sd.org/draft-cheshire-dnsext-dns-sd.txt
+ * limited to a local network over Multicast DNS. DNS service discovery is described at
+ * http://files.dns-sd.org/draft-cheshire-dnsext-dns-sd.txt
  *
  * <p> The API is asynchronous and responses to requests from an application are on listener
- * callbacks provided by the application. The application must invoke {@link #initialize} before
- * doing any other operation.
+ * callbacks on a seperate thread.
  *
  * <p> There are three main operations the API supports - registration, discovery and resolution.
  * <pre>
  *                          Application start
  *                                 |
- *                                 |         <----------------------------------------------
- *                             initialize()                                                 |
- *                                 |                                                        |
- *                                 | Wait until channel connects                            |
- *                                 | before doing any operation                             |
- *                                 |                                                        |
- *                           onChannelConnected()                    __________             |
- *                                 |                                           |            |
- *                                 |                                           |            |
- *                                 |                  onServiceRegistered()    |            |
- *                     Register any local services  /                          |            |
- *                      to be advertised with       \                          |            | If application needs to
- *                       registerService()            onFailure()              |            | do any further operations
- *                                 |                                           |            | again, it needs to
- *                                 |                                           |            | initialize() connection
- *                          discoverServices()                                 |            | to framework again
- *                                 |                                           |            |
- *                      Maintain a list to track                               |            |
- *                        discovered services                                  |            |
- *                                 |                                           |            |
- *                                 |--------->                                 |-> onChannelDisconnected()
- *                                 |          |                                |
- *                                 |      onServiceFound()                     |
- *                                 |          |                                |
- *                                 |     add service to list                   |
- *                                 |          |                                |
- *                                 |<----------                                |
- *                                 |                                           |
- *                                 |--------->                                 |
- *                                 |          |                                |
- *                                 |      onServiceLost()                      |
- *                                 |          |                                |
- *                                 |   remove service from list                |
- *                                 |          |                                |
- *                                 |<----------                                |
- *                                 |                                           |
- *                                 |                                           |
- *                                 | Connect to a service                      |
- *                                 | from list ?                               |
- *                                 |                                           |
- *                          resolveService()                                   |
- *                                 |                                           |
- *                         onServiceResolved()                                 |
- *                                 |                                           |
- *                     Establish connection to service                         |
- *                     with the host and port information                      |
- *                                 |                                           |
- *                                 |                                ___________|
- *                           deinitialize()
- *                    when done with all operations
- *                          or before quit
+ *                                 |
+ *                                 |                  onServiceRegistered()
+ *                     Register any local services  /
+ *                      to be advertised with       \
+ *                       registerService()            onRegistrationFailed()
+ *                                 |
+ *                                 |
+ *                          discoverServices()
+ *                                 |
+ *                      Maintain a list to track
+ *                        discovered services
+ *                                 |
+ *                                 |--------->
+ *                                 |          |
+ *                                 |      onServiceFound()
+ *                                 |          |
+ *                                 |     add service to list
+ *                                 |          |
+ *                                 |<----------
+ *                                 |
+ *                                 |--------->
+ *                                 |          |
+ *                                 |      onServiceLost()
+ *                                 |          |
+ *                                 |   remove service from list
+ *                                 |          |
+ *                                 |<----------
+ *                                 |
+ *                                 |
+ *                                 | Connect to a service
+ *                                 | from list ?
+ *                                 |
+ *                          resolveService()
+ *                                 |
+ *                         onServiceResolved()
+ *                                 |
+ *                     Establish connection to service
+ *                     with the host and port information
  *
  * </pre>
  * An application that needs to advertise itself over a network for other applications to
  * discover it can do so with a call to {@link #registerService}. If Example is a http based
  * application that can provide HTML data to peer services, it can register a name "Example"
  * with service type "_http._tcp". A successful registration is notified with a callback to
- * {@link DnsSdRegisterListener#onServiceRegistered} and a failure to register is notified
- * over {@link DnsSdRegisterListener#onFailure}
+ * {@link RegistrationListener#onServiceRegistered} and a failure to register is notified
+ * over {@link RegistrationListener#onRegistrationFailed}
  *
  * <p> A peer application looking for http services can initiate a discovery for "_http._tcp"
  * with a call to {@link #discoverServices}. A service found is notified with a callback
- * to {@link DnsSdDiscoveryListener#onServiceFound} and a service lost is notified on
- * {@link DnsSdDiscoveryListener#onServiceLost}.
+ * to {@link DiscoveryListener#onServiceFound} and a service lost is notified on
+ * {@link DiscoveryListener#onServiceLost}.
  *
  * <p> Once the peer application discovers the "Example" http srevice, and needs to receive data
  * from the "Example" application, it can initiate a resolve with {@link #resolveService} to
  * resolve the host and port details for the purpose of establishing a connection. A successful
- * resolve is notified on {@link DnsSdResolveListener#onServiceResolved} and a failure is notified
- * on {@link DnsSdResolveListener#onFailure}.
+ * resolve is notified on {@link ResolveListener#onServiceResolved} and a failure is notified
+ * on {@link ResolveListener#onResolveFailed}.
  *
  * Applications can reserve for a service type at
  * http://www.iana.org/form/ports-service. Existing services can be found at
@@ -129,9 +118,9 @@
  * Get an instance of this class by calling {@link android.content.Context#getSystemService(String)
  * Context.getSystemService(Context.NSD_SERVICE)}.
  *
- * {@see DnsSdServiceInfo}
+ * {@see NsdServiceInfo}
  */
-public class NsdManager {
+public final class NsdManager {
     private static final String TAG = "NsdManager";
     INsdManager mService;
 
@@ -204,13 +193,6 @@
     public static final int UNREGISTER_SERVICE_SUCCEEDED            = BASE + 14;
 
     /** @hide */
-    public static final int UPDATE_SERVICE                          = BASE + 15;
-    /** @hide */
-    public static final int UPDATE_SERVICE_FAILED                   = BASE + 16;
-    /** @hide */
-    public static final int UPDATE_SERVICE_SUCCEEDED                = BASE + 17;
-
-    /** @hide */
     public static final int RESOLVE_SERVICE                         = BASE + 18;
     /** @hide */
     public static final int RESOLVE_SERVICE_FAILED                  = BASE + 19;
@@ -218,17 +200,27 @@
     public static final int RESOLVE_SERVICE_SUCCEEDED               = BASE + 20;
 
     /** @hide */
-    public static final int STOP_RESOLVE                            = BASE + 21;
-    /** @hide */
-    public static final int STOP_RESOLVE_FAILED                     = BASE + 22;
-    /** @hide */
-    public static final int STOP_RESOLVE_SUCCEEDED                  = BASE + 23;
-
-    /** @hide */
     public static final int ENABLE                                  = BASE + 24;
     /** @hide */
     public static final int DISABLE                                 = BASE + 25;
 
+    /** @hide */
+    public static final int NATIVE_DAEMON_EVENT                     = BASE + 26;
+
+    /** Dns based service discovery protocol */
+    public static final int PROTOCOL_DNS_SD = 0x0001;
+
+    private Context mContext;
+
+    private static final int INVALID_LISTENER_KEY = 0;
+    private int mListenerKey = 1;
+    private final SparseArray mListenerMap = new SparseArray();
+    private final SparseArray<NsdServiceInfo> mServiceMap = new SparseArray<NsdServiceInfo>();
+    private final Object mMapLock = new Object();
+
+    private final AsyncChannel mAsyncChannel = new AsyncChannel();
+    private ServiceHandler mHandler;
+    private final CountDownLatch mConnected = new CountDownLatch(1);
 
     /**
      * Create a new Nsd instance. Applications use
@@ -238,271 +230,213 @@
      * @hide - hide this because it takes in a parameter of type INsdManager, which
      * is a system private class.
      */
-    public NsdManager(INsdManager service) {
+    public NsdManager(Context context, INsdManager service) {
         mService = service;
+        mContext = context;
+        init();
     }
 
     /**
-     * Passed with onFailure() calls.
+     * Failures are passed with {@link RegistrationListener#onRegistrationFailed},
+     * {@link RegistrationListener#onUnregistrationFailed},
+     * {@link DiscoveryListener#onStartDiscoveryFailed},
+     * {@link DiscoveryListener#onStopDiscoveryFailed} or {@link ResolveListener#onResolveFailed}.
+     *
      * Indicates that the operation failed due to an internal error.
      */
-    public static final int ERROR               = 0;
+    public static final int FAILURE_INTERNAL_ERROR               = 0;
 
     /**
-     * Passed with onFailure() calls.
-     * Indicates that the operation failed because service discovery
-     * is unsupported on the device.
-     */
-    public static final int UNSUPPORTED         = 1;
-
-    /**
-     * Passed with onFailure() calls.
-     * Indicates that the operation failed because the framework is
-     * busy and unable to service the request.
-     */
-    public static final int BUSY                = 2;
-
-    /**
-     * Passed with onFailure() calls.
      * Indicates that the operation failed because it is already active.
      */
-    public static final int ALREADY_ACTIVE      = 3;
+    public static final int FAILURE_ALREADY_ACTIVE              = 3;
 
     /**
-     * Passed with onFailure() calls.
-     * Indicates that the operation failed because maximum limit on
-     * service registrations has reached.
+     * Indicates that the operation failed because the maximum outstanding
+     * requests from the applications have reached.
      */
-    public static final int MAX_REGS_REACHED    = 4;
-
-    /** Interface for callback invocation when framework channel is connected or lost */
-    public interface ChannelListener {
-       /**
-         * The channel to the framework is connected.
-         * Application can initiate calls into the framework using the channel instance passed.
-         */
-        public void onChannelConnected(Channel c);
-        /**
-         * The channel to the framework has been disconnected.
-         * Application could try re-initializing using {@link #initialize}
-         */
-        public void onChannelDisconnected();
-    }
-
-    /** Generic interface for callback invocation for a success or failure */
-    public interface ActionListener {
-
-        public void onFailure(int errorCode);
-
-        public void onSuccess();
-    }
+    public static final int FAILURE_MAX_LIMIT                   = 4;
 
     /** Interface for callback invocation for service discovery */
-    public interface DnsSdDiscoveryListener {
+    public interface DiscoveryListener {
 
-        public void onFailure(int errorCode);
+        public void onStartDiscoveryFailed(String serviceType, int errorCode);
 
-        public void onStarted(String serviceType);
+        public void onStopDiscoveryFailed(String serviceType, int errorCode);
 
-        public void onServiceFound(DnsSdServiceInfo serviceInfo);
+        public void onDiscoveryStarted(String serviceType);
 
-        public void onServiceLost(DnsSdServiceInfo serviceInfo);
+        public void onDiscoveryStopped(String serviceType);
+
+        public void onServiceFound(NsdServiceInfo serviceInfo);
+
+        public void onServiceLost(NsdServiceInfo serviceInfo);
 
     }
 
     /** Interface for callback invocation for service registration */
-    public interface DnsSdRegisterListener {
+    public interface RegistrationListener {
 
-        public void onFailure(int errorCode);
+        public void onRegistrationFailed(NsdServiceInfo serviceInfo, int errorCode);
 
-        public void onServiceRegistered(int registeredId, DnsSdServiceInfo serviceInfo);
-    }
+        public void onUnregistrationFailed(NsdServiceInfo serviceInfo, int errorCode);
 
-    /** @hide */
-    public interface DnsSdUpdateRegistrationListener {
+        public void onServiceRegistered(NsdServiceInfo serviceInfo);
 
-        public void onFailure(int errorCode);
-
-        public void onServiceUpdated(int registeredId, DnsSdTxtRecord txtRecord);
+        public void onServiceUnregistered(NsdServiceInfo serviceInfo);
     }
 
     /** Interface for callback invocation for service resolution */
-    public interface DnsSdResolveListener {
+    public interface ResolveListener {
 
-        public void onFailure(int errorCode);
+        public void onResolveFailed(NsdServiceInfo serviceInfo, int errorCode);
 
-        public void onServiceResolved(DnsSdServiceInfo serviceInfo);
+        public void onServiceResolved(NsdServiceInfo serviceInfo);
     }
 
-    /**
-     * A channel that connects the application to the NetworkService framework.
-     * Most service operations require a Channel as an argument. An instance of Channel is obtained
-     * by doing a call on {@link #initialize}
-     */
-    public static class Channel {
-        Channel(Looper looper, ChannelListener l) {
-            mAsyncChannel = new AsyncChannel();
-            mHandler = new ServiceHandler(looper);
-            mChannelListener = l;
+    private class ServiceHandler extends Handler {
+        ServiceHandler(Looper looper) {
+            super(looper);
         }
-        private ChannelListener mChannelListener;
-        private DnsSdDiscoveryListener mDnsSdDiscoveryListener;
-        private ActionListener mDnsSdStopDiscoveryListener;
-        private DnsSdRegisterListener mDnsSdRegisterListener;
-        private ActionListener mDnsSdUnregisterListener;
-        private DnsSdUpdateRegistrationListener mDnsSdUpdateListener;
-        private DnsSdResolveListener mDnsSdResolveListener;
-        private ActionListener mDnsSdStopResolveListener;
 
-        private AsyncChannel mAsyncChannel;
-        private ServiceHandler mHandler;
-        class ServiceHandler extends Handler {
-            ServiceHandler(Looper looper) {
-                super(looper);
+        @Override
+        public void handleMessage(Message message) {
+            Object listener = getListener(message.arg2);
+            boolean listenerRemove = true;
+            switch (message.what) {
+                case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED:
+                    mAsyncChannel.sendMessage(AsyncChannel.CMD_CHANNEL_FULL_CONNECTION);
+                    mConnected.countDown();
+                    break;
+                case AsyncChannel.CMD_CHANNEL_FULLY_CONNECTED:
+                    // Ignore
+                    break;
+                case AsyncChannel.CMD_CHANNEL_DISCONNECTED:
+                    Log.e(TAG, "Channel lost");
+                    break;
+                case DISCOVER_SERVICES_STARTED:
+                    String s = ((NsdServiceInfo) message.obj).getServiceType();
+                    ((DiscoveryListener) listener).onDiscoveryStarted(s);
+                    // Keep listener until stop discovery
+                    listenerRemove = false;
+                    break;
+                case DISCOVER_SERVICES_FAILED:
+                    ((DiscoveryListener) listener).onStartDiscoveryFailed(
+                            getNsdService(message.arg2).getServiceType(), message.arg1);
+                    break;
+                case SERVICE_FOUND:
+                    ((DiscoveryListener) listener).onServiceFound((NsdServiceInfo) message.obj);
+                    // Keep listener until stop discovery
+                    listenerRemove = false;
+                    break;
+                case SERVICE_LOST:
+                    ((DiscoveryListener) listener).onServiceLost((NsdServiceInfo) message.obj);
+                    // Keep listener until stop discovery
+                    listenerRemove = false;
+                    break;
+                case STOP_DISCOVERY_FAILED:
+                    ((DiscoveryListener) listener).onStopDiscoveryFailed(
+                            getNsdService(message.arg2).getServiceType(), message.arg1);
+                    break;
+                case STOP_DISCOVERY_SUCCEEDED:
+                    ((DiscoveryListener) listener).onDiscoveryStopped(
+                            getNsdService(message.arg2).getServiceType());
+                    break;
+                case REGISTER_SERVICE_FAILED:
+                    ((RegistrationListener) listener).onRegistrationFailed(
+                            getNsdService(message.arg2), message.arg1);
+                    break;
+                case REGISTER_SERVICE_SUCCEEDED:
+                    ((RegistrationListener) listener).onServiceRegistered(
+                            (NsdServiceInfo) message.obj);
+                    // Keep listener until unregister
+                    listenerRemove = false;
+                    break;
+                case UNREGISTER_SERVICE_FAILED:
+                    ((RegistrationListener) listener).onUnregistrationFailed(
+                            getNsdService(message.arg2), message.arg1);
+                    break;
+                case UNREGISTER_SERVICE_SUCCEEDED:
+                    ((RegistrationListener) listener).onServiceUnregistered(
+                            getNsdService(message.arg2));
+                    break;
+                case RESOLVE_SERVICE_FAILED:
+                    ((ResolveListener) listener).onResolveFailed(
+                            getNsdService(message.arg2), message.arg1);
+                    break;
+                case RESOLVE_SERVICE_SUCCEEDED:
+                    ((ResolveListener) listener).onServiceResolved((NsdServiceInfo) message.obj);
+                    break;
+                default:
+                    Log.d(TAG, "Ignored " + message);
+                    break;
             }
-
-            @Override
-            public void handleMessage(Message message) {
-                switch (message.what) {
-                    case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED:
-                        mAsyncChannel.sendMessage(AsyncChannel.CMD_CHANNEL_FULL_CONNECTION);
-                        break;
-                    case AsyncChannel.CMD_CHANNEL_FULLY_CONNECTED:
-                        if (mChannelListener != null) {
-                            mChannelListener.onChannelConnected(Channel.this);
-                        }
-                        break;
-                    case AsyncChannel.CMD_CHANNEL_DISCONNECTED:
-                        if (mChannelListener != null) {
-                            mChannelListener.onChannelDisconnected();
-                            mChannelListener = null;
-                        }
-                        break;
-                    case DISCOVER_SERVICES_STARTED:
-                        if (mDnsSdDiscoveryListener != null) {
-                            mDnsSdDiscoveryListener.onStarted((String) message.obj);
-                        }
-                        break;
-                    case DISCOVER_SERVICES_FAILED:
-                        if (mDnsSdDiscoveryListener != null) {
-                            mDnsSdDiscoveryListener.onFailure(message.arg1);
-                        }
-                        break;
-                    case SERVICE_FOUND:
-                        if (mDnsSdDiscoveryListener != null) {
-                            mDnsSdDiscoveryListener.onServiceFound(
-                                    (DnsSdServiceInfo) message.obj);
-                        }
-                        break;
-                    case SERVICE_LOST:
-                        if (mDnsSdDiscoveryListener != null) {
-                            mDnsSdDiscoveryListener.onServiceLost(
-                                    (DnsSdServiceInfo) message.obj);
-                        }
-                        break;
-                    case STOP_DISCOVERY_FAILED:
-                        if (mDnsSdStopDiscoveryListener != null) {
-                            mDnsSdStopDiscoveryListener.onFailure(message.arg1);
-                        }
-                        break;
-                    case STOP_DISCOVERY_SUCCEEDED:
-                        if (mDnsSdStopDiscoveryListener != null) {
-                            mDnsSdStopDiscoveryListener.onSuccess();
-                        }
-                        break;
-                    case REGISTER_SERVICE_FAILED:
-                        if (mDnsSdRegisterListener != null) {
-                            mDnsSdRegisterListener.onFailure(message.arg1);
-                        }
-                        break;
-                    case REGISTER_SERVICE_SUCCEEDED:
-                        if (mDnsSdRegisterListener != null) {
-                            mDnsSdRegisterListener.onServiceRegistered(message.arg1,
-                                    (DnsSdServiceInfo) message.obj);
-                        }
-                        break;
-                    case UNREGISTER_SERVICE_FAILED:
-                        if (mDnsSdUnregisterListener != null) {
-                            mDnsSdUnregisterListener.onFailure(message.arg1);
-                        }
-                        break;
-                    case UNREGISTER_SERVICE_SUCCEEDED:
-                        if (mDnsSdUnregisterListener != null) {
-                            mDnsSdUnregisterListener.onSuccess();
-                        }
-                        break;
-                   case UPDATE_SERVICE_FAILED:
-                        if (mDnsSdUpdateListener != null) {
-                            mDnsSdUpdateListener.onFailure(message.arg1);
-                        }
-                        break;
-                    case UPDATE_SERVICE_SUCCEEDED:
-                        if (mDnsSdUpdateListener != null) {
-                            mDnsSdUpdateListener.onServiceUpdated(message.arg1,
-                                    (DnsSdTxtRecord) message.obj);
-                        }
-                        break;
-                    case RESOLVE_SERVICE_FAILED:
-                        if (mDnsSdResolveListener != null) {
-                            mDnsSdResolveListener.onFailure(message.arg1);
-                        }
-                        break;
-                    case RESOLVE_SERVICE_SUCCEEDED:
-                        if (mDnsSdResolveListener != null) {
-                            mDnsSdResolveListener.onServiceResolved(
-                                    (DnsSdServiceInfo) message.obj);
-                        }
-                        break;
-                    case STOP_RESOLVE_FAILED:
-                        if (mDnsSdStopResolveListener!= null) {
-                            mDnsSdStopResolveListener.onFailure(message.arg1);
-                        }
-                        break;
-                    case STOP_RESOLVE_SUCCEEDED:
-                        if (mDnsSdStopResolveListener != null) {
-                            mDnsSdStopResolveListener.onSuccess();
-                        }
-                        break;
-                    default:
-                        Log.d(TAG, "Ignored " + message);
-                        break;
-                }
+            if (listenerRemove) {
+                removeListener(message.arg2);
             }
         }
-   }
-
-    private static void checkChannel(Channel c) {
-        if (c == null) throw new IllegalArgumentException("Channel needs to be initialized");
     }
 
+    private int putListener(Object listener, NsdServiceInfo s) {
+        if (listener == null) return INVALID_LISTENER_KEY;
+        int key;
+        synchronized (mMapLock) {
+            do {
+                key = mListenerKey++;
+            } while (key == INVALID_LISTENER_KEY);
+            mListenerMap.put(key, listener);
+            mServiceMap.put(key, s);
+        }
+        return key;
+    }
+
+    private Object getListener(int key) {
+        if (key == INVALID_LISTENER_KEY) return null;
+        synchronized (mMapLock) {
+            return mListenerMap.get(key);
+        }
+    }
+
+    private NsdServiceInfo getNsdService(int key) {
+        synchronized (mMapLock) {
+            return mServiceMap.get(key);
+        }
+    }
+
+    private void removeListener(int key) {
+        if (key == INVALID_LISTENER_KEY) return;
+        synchronized (mMapLock) {
+            mListenerMap.remove(key);
+            mServiceMap.remove(key);
+        }
+    }
+
+    private int getListenerKey(Object listener) {
+        synchronized (mMapLock) {
+            int valueIndex = mListenerMap.indexOfValue(listener);
+            if (valueIndex != -1) {
+                return mListenerMap.keyAt(valueIndex);
+            }
+        }
+        return INVALID_LISTENER_KEY;
+    }
+
+
     /**
-     * Registers the application with the service discovery framework. This function
-     * must be the first to be called before any other operations are performed. No service
-     * discovery operations must be performed until the ChannelListener callback notifies
-     * that the channel is connected
-     *
-     * @param srcContext is the context of the source
-     * @param srcLooper is the Looper on which the callbacks are receivied
-     * @param listener for callback at loss of framework communication. Cannot be null.
+     * Initialize AsyncChannel
      */
-    public void initialize(Context srcContext, Looper srcLooper, ChannelListener listener) {
-        Messenger messenger = getMessenger();
+    private void init() {
+        final Messenger messenger = getMessenger();
         if (messenger == null) throw new RuntimeException("Failed to initialize");
-        if (listener == null) throw new IllegalArgumentException("ChannelListener cannot be null");
-
-        Channel c = new Channel(srcLooper, listener);
-        c.mAsyncChannel.connect(srcContext, c.mHandler, messenger);
-    }
-
-    /**
-     * Disconnects application from service discovery framework. No further operations
-     * will succeed until a {@link #initialize} is called again.
-     *
-     * @param c channel initialized with {@link #initialize}
-     */
-    public void deinitialize(Channel c) {
-        checkChannel(c);
-        c.mAsyncChannel.disconnect();
+        HandlerThread t = new HandlerThread("NsdManager");
+        t.start();
+        mHandler = new ServiceHandler(t.getLooper());
+        mAsyncChannel.connect(mContext, mHandler, messenger);
+        try {
+            mConnected.await();
+        } catch (InterruptedException e) {
+            Log.e(TAG, "interrupted wait at init");
+        }
     }
 
     /**
@@ -510,45 +444,51 @@
      *
      * <p> The function call immediately returns after sending a request to register service
      * to the framework. The application is notified of a success to initiate
-     * discovery through the callback {@link DnsSdRegisterListener#onServiceRegistered} or a failure
-     * through {@link DnsSdRegisterListener#onFailure}.
+     * discovery through the callback {@link RegistrationListener#onServiceRegistered} or a failure
+     * through {@link RegistrationListener#onRegistrationFailed}.
      *
-     * @param c is the channel created at {@link #initialize}
-     * @param serviceType The service type being advertised.
-     * @param port on which the service is listenering for incoming connections
-     * @param listener for success or failure callback. Can be null.
+     * @param serviceInfo The service being registered
+     * @param protocolType The service discovery protocol
+     * @param listener The listener notifies of a successful registration and is used to
+     * unregister this service through a call on {@link #unregisterService}. Cannot be null.
      */
-    public void registerService(Channel c, String serviceName, String serviceType, int port,
-            DnsSdRegisterListener listener) {
-        checkChannel(c);
-        if (TextUtils.isEmpty(serviceName) || TextUtils.isEmpty(serviceType)) {
+    public void registerService(NsdServiceInfo serviceInfo, int protocolType,
+            RegistrationListener listener) {
+        if (TextUtils.isEmpty(serviceInfo.getServiceName()) ||
+                TextUtils.isEmpty(serviceInfo.getServiceType())) {
             throw new IllegalArgumentException("Service name or type cannot be empty");
         }
-        if (port <= 0) {
+        if (serviceInfo.getPort() <= 0) {
             throw new IllegalArgumentException("Invalid port number");
         }
-        DnsSdServiceInfo serviceInfo = new DnsSdServiceInfo(serviceName, serviceType, null);
-        serviceInfo.setPort(port);
-        c.mDnsSdRegisterListener = listener;
-        c.mAsyncChannel.sendMessage(REGISTER_SERVICE, serviceInfo);
+        if (listener == null) {
+            throw new IllegalArgumentException("listener cannot be null");
+        }
+        if (protocolType != PROTOCOL_DNS_SD) {
+            throw new IllegalArgumentException("Unsupported protocol");
+        }
+        mAsyncChannel.sendMessage(REGISTER_SERVICE, 0, putListener(listener, serviceInfo),
+                serviceInfo);
     }
 
     /**
-     * Unregister a service registered through {@link #registerService}
-     * @param c is the channel created at {@link #initialize}
-     * @param registeredId is obtained at {@link DnsSdRegisterListener#onServiceRegistered}
-     * @param listener provides callbacks for success or failure. Can be null.
+     * Unregister a service registered through {@link #registerService}. A successful
+     * unregister is notified to the application with a call to
+     * {@link RegistrationListener#onServiceUnregistered}.
+     *
+     * @param listener This should be the listener object that was passed to
+     * {@link #registerService}. It identifies the service that should be unregistered
+     * and notifies of a successful unregistration.
      */
-    public void unregisterService(Channel c, int registeredId, ActionListener listener) {
-        checkChannel(c);
-        c.mDnsSdUnregisterListener = listener;
-        c.mAsyncChannel.sendMessage(UNREGISTER_SERVICE, registeredId);
-    }
-
-    /** @hide */
-    public void updateService(Channel c, int registeredId, DnsSdTxtRecord txtRecord) {
-        checkChannel(c);
-        c.mAsyncChannel.sendMessage(UPDATE_SERVICE, registeredId, 0, txtRecord);
+    public void unregisterService(RegistrationListener listener) {
+        int id = getListenerKey(listener);
+        if (id == INVALID_LISTENER_KEY) {
+            throw new IllegalArgumentException("listener not registered");
+        }
+        if (listener == null) {
+            throw new IllegalArgumentException("listener cannot be null");
+        }
+        mAsyncChannel.sendMessage(UNREGISTER_SERVICE, 0, id);
     }
 
     /**
@@ -558,51 +498,61 @@
      *
      * <p> The function call immediately returns after sending a request to start service
      * discovery to the framework. The application is notified of a success to initiate
-     * discovery through the callback {@link DnsSdDiscoveryListener#onStarted} or a failure
-     * through {@link DnsSdDiscoveryListener#onFailure}.
+     * discovery through the callback {@link DiscoveryListener#onDiscoveryStarted} or a failure
+     * through {@link DiscoveryListener#onStartDiscoveryFailed}.
      *
      * <p> Upon successful start, application is notified when a service is found with
-     * {@link DnsSdDiscoveryListener#onServiceFound} or when a service is lost with
-     * {@link DnsSdDiscoveryListener#onServiceLost}.
+     * {@link DiscoveryListener#onServiceFound} or when a service is lost with
+     * {@link DiscoveryListener#onServiceLost}.
      *
      * <p> Upon failure to start, service discovery is not active and application does
      * not need to invoke {@link #stopServiceDiscovery}
      *
-     * @param c is the channel created at {@link #initialize}
      * @param serviceType The service type being discovered. Examples include "_http._tcp" for
      * http services or "_ipp._tcp" for printers
-     * @param listener provides callbacks when service is found or lost. Cannot be null.
+     * @param protocolType The service discovery protocol
+     * @param listener  The listener notifies of a successful discovery and is used
+     * to stop discovery on this serviceType through a call on {@link #stopServiceDiscovery}.
+     * Cannot be null.
      */
-    public void discoverServices(Channel c, String serviceType, DnsSdDiscoveryListener listener) {
-        checkChannel(c);
+    public void discoverServices(String serviceType, int protocolType, DiscoveryListener listener) {
         if (listener == null) {
-            throw new IllegalStateException("Discovery listener needs to be set first");
+            throw new IllegalArgumentException("listener cannot be null");
         }
         if (TextUtils.isEmpty(serviceType)) {
-            throw new IllegalStateException("Service type cannot be empty");
+            throw new IllegalArgumentException("Service type cannot be empty");
         }
-        DnsSdServiceInfo s = new DnsSdServiceInfo();
+
+        if (protocolType != PROTOCOL_DNS_SD) {
+            throw new IllegalArgumentException("Unsupported protocol");
+        }
+
+        NsdServiceInfo s = new NsdServiceInfo();
         s.setServiceType(serviceType);
-        c.mDnsSdDiscoveryListener = listener;
-        c.mAsyncChannel.sendMessage(DISCOVER_SERVICES, s);
+        mAsyncChannel.sendMessage(DISCOVER_SERVICES, 0, putListener(listener, s), s);
     }
 
     /**
      * Stop service discovery initiated with {@link #discoverServices}. An active service
-     * discovery is notified to the application with {@link DnsSdDiscoveryListener#onStarted}
-     * and it stays active until the application invokes a stop service discovery.
+     * discovery is notified to the application with {@link DiscoveryListener#onDiscoveryStarted}
+     * and it stays active until the application invokes a stop service discovery. A successful
+     * stop is notified to with a call to {@link DiscoveryListener#onDiscoveryStopped}.
      *
-     * <p> Upon failure to start service discovery notified through
-     * {@link DnsSdDiscoveryListener#onFailure} service discovery is not active and
-     * application does not need to stop it.
+     * <p> Upon failure to stop service discovery, application is notified through
+     * {@link DiscoveryListener#onStopDiscoveryFailed}.
      *
-     * @param c is the channel created at {@link #initialize}
-     * @param listener notifies success or failure. Can be null.
+     * @param listener This should be the listener object that was passed to {@link #discoverServices}.
+     * It identifies the discovery that should be stopped and notifies of a successful stop.
      */
-    public void stopServiceDiscovery(Channel c, ActionListener listener) {
-        checkChannel(c);
-        c.mDnsSdStopDiscoveryListener = listener;
-        c.mAsyncChannel.sendMessage(STOP_DISCOVERY);
+    public void stopServiceDiscovery(DiscoveryListener listener) {
+        int id = getListenerKey(listener);
+        if (id == INVALID_LISTENER_KEY) {
+            throw new IllegalArgumentException("service discovery not active on listener");
+        }
+        if (listener == null) {
+            throw new IllegalArgumentException("listener cannot be null");
+        }
+        mAsyncChannel.sendMessage(STOP_DISCOVERY, 0, id);
     }
 
     /**
@@ -610,30 +560,19 @@
      * establishing a connection to fetch the IP and port details on which to setup
      * the connection.
      *
-     * @param c is the channel created at {@link #initialize}
-     * @param serviceName of the the service
-     * @param serviceType of the service
+     * @param serviceInfo service to be resolved
      * @param listener to receive callback upon success or failure. Cannot be null.
      */
-    public void resolveService(Channel c, String serviceName, String serviceType,
-            DnsSdResolveListener listener) {
-        checkChannel(c);
-        if (TextUtils.isEmpty(serviceName) || TextUtils.isEmpty(serviceType)) {
+    public void resolveService(NsdServiceInfo serviceInfo, ResolveListener listener) {
+        if (TextUtils.isEmpty(serviceInfo.getServiceName()) ||
+                TextUtils.isEmpty(serviceInfo.getServiceType())) {
             throw new IllegalArgumentException("Service name or type cannot be empty");
         }
-        if (listener == null) throw new
-                IllegalStateException("Resolve listener cannot be null");
-        c.mDnsSdResolveListener = listener;
-        DnsSdServiceInfo serviceInfo = new DnsSdServiceInfo(serviceName, serviceType, null);
-        c.mAsyncChannel.sendMessage(RESOLVE_SERVICE, serviceInfo);
-    }
-
-    /** @hide */
-    public void stopServiceResolve(Channel c) {
-        checkChannel(c);
-        if (c.mDnsSdResolveListener == null) throw new
-                IllegalStateException("Resolve listener needs to be set first");
-        c.mAsyncChannel.sendMessage(STOP_RESOLVE);
+        if (listener == null) {
+            throw new IllegalArgumentException("listener cannot be null");
+        }
+        mAsyncChannel.sendMessage(RESOLVE_SERVICE, 0, putListener(listener, serviceInfo),
+                serviceInfo);
     }
 
     /** Internal use only @hide */
diff --git a/core/java/android/net/nsd/DnsSdServiceInfo.java b/core/java/android/net/nsd/NsdServiceInfo.java
similarity index 86%
rename from core/java/android/net/nsd/DnsSdServiceInfo.java
rename to core/java/android/net/nsd/NsdServiceInfo.java
index 66abd3a..205a21d 100644
--- a/core/java/android/net/nsd/DnsSdServiceInfo.java
+++ b/core/java/android/net/nsd/NsdServiceInfo.java
@@ -25,7 +25,7 @@
  * A class representing service information for network service discovery
  * {@see NsdManager}
  */
-public class DnsSdServiceInfo implements NetworkServiceInfo, Parcelable {
+public final class NsdServiceInfo implements Parcelable {
 
     private String mServiceName;
 
@@ -37,36 +37,32 @@
 
     private int mPort;
 
-    public DnsSdServiceInfo() {
+    public NsdServiceInfo() {
     }
 
     /** @hide */
-    public DnsSdServiceInfo(String sn, String rt, DnsSdTxtRecord tr) {
+    public NsdServiceInfo(String sn, String rt, DnsSdTxtRecord tr) {
         mServiceName = sn;
         mServiceType = rt;
         mTxtRecord = tr;
     }
 
     /** Get the service name */
-    @Override
     public String getServiceName() {
         return mServiceName;
     }
 
     /** Set the service name */
-    @Override
     public void setServiceName(String s) {
         mServiceName = s;
     }
 
     /** Get the service type */
-    @Override
     public String getServiceType() {
         return mServiceType;
     }
 
     /** Set the service type */
-    @Override
     public void setServiceType(String s) {
         mServiceType = s;
     }
@@ -132,10 +128,10 @@
     }
 
     /** Implement the Parcelable interface */
-    public static final Creator<DnsSdServiceInfo> CREATOR =
-        new Creator<DnsSdServiceInfo>() {
-            public DnsSdServiceInfo createFromParcel(Parcel in) {
-                DnsSdServiceInfo info = new DnsSdServiceInfo();
+    public static final Creator<NsdServiceInfo> CREATOR =
+        new Creator<NsdServiceInfo>() {
+            public NsdServiceInfo createFromParcel(Parcel in) {
+                NsdServiceInfo info = new NsdServiceInfo();
                 info.mServiceName = in.readString();
                 info.mServiceType = in.readString();
                 info.mTxtRecord = in.readParcelable(null);
@@ -150,8 +146,8 @@
                 return info;
             }
 
-            public DnsSdServiceInfo[] newArray(int size) {
-                return new DnsSdServiceInfo[size];
+            public NsdServiceInfo[] newArray(int size) {
+                return new NsdServiceInfo[size];
             }
         };
 }
diff --git a/core/java/android/content/CancellationSignal.java b/core/java/android/os/CancellationSignal.java
similarity index 98%
rename from core/java/android/content/CancellationSignal.java
rename to core/java/android/os/CancellationSignal.java
index dcaeeb7..dcba9b7 100644
--- a/core/java/android/content/CancellationSignal.java
+++ b/core/java/android/os/CancellationSignal.java
@@ -14,9 +14,10 @@
  * limitations under the License.
  */
 
-package android.content;
+package android.os;
 
-import android.os.RemoteException;
+import android.os.ICancellationSignal;
+import android.os.ICancellationSignal.Stub;
 
 /**
  * Provides the ability to cancel an operation in progress.
diff --git a/core/java/android/content/ICancellationSignal.aidl b/core/java/android/os/ICancellationSignal.aidl
similarity index 96%
rename from core/java/android/content/ICancellationSignal.aidl
rename to core/java/android/os/ICancellationSignal.aidl
index cf1c5d3..d92464c 100644
--- a/core/java/android/content/ICancellationSignal.aidl
+++ b/core/java/android/os/ICancellationSignal.aidl
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package android.content;
+package android.os;
 
 /**
  * @hide
diff --git a/core/java/android/content/OperationCanceledException.java b/core/java/android/os/OperationCanceledException.java
similarity index 97%
rename from core/java/android/content/OperationCanceledException.java
rename to core/java/android/os/OperationCanceledException.java
index d783a07..b0cd663 100644
--- a/core/java/android/content/OperationCanceledException.java
+++ b/core/java/android/os/OperationCanceledException.java
@@ -14,7 +14,8 @@
  * limitations under the License.
  */
 
-package android.content;
+package android.os;
+
 
 /**
  * An exception type that is thrown when an operation in progress is canceled.
diff --git a/core/java/android/os/Trace.java b/core/java/android/os/Trace.java
index ac9ee26..7b6fd64 100644
--- a/core/java/android/os/Trace.java
+++ b/core/java/android/os/Trace.java
@@ -39,6 +39,14 @@
     public static final long TRACE_TAG_SYNC_MANAGER = 1L << 7;
     public static final long TRACE_TAG_AUDIO = 1L << 8;
 
+    public static final int TRACE_FLAGS_START_BIT = 1;
+    public static final String[] TRACE_TAGS = {
+        "Graphics", "Input", "View", "WebView", "Window Manager",
+        "Activity Manager", "Sync Manager", "Audio"
+    };
+
+    public static final String PROPERTY_TRACE_TAG_ENABLEFLAGS = "debug.atrace.tags.enableflags";
+
     private static final long sEnabledTags = nativeGetEnabledTags();
 
     private static native long nativeGetEnabledTags();
diff --git a/core/java/android/preference/MultiCheckPreference.java b/core/java/android/preference/MultiCheckPreference.java
new file mode 100644
index 0000000..6953075
--- /dev/null
+++ b/core/java/android/preference/MultiCheckPreference.java
@@ -0,0 +1,327 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.preference;
+
+import java.util.Arrays;
+
+import android.app.AlertDialog.Builder;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.res.TypedArray;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.AttributeSet;
+
+/**
+ * @hide
+ * A {@link Preference} that displays a list of entries as
+ * a dialog which allow the user to toggle each individually on and off.
+ * 
+ * @attr ref android.R.styleable#ListPreference_entries
+ * @attr ref android.R.styleable#ListPreference_entryValues
+ */
+public class MultiCheckPreference extends DialogPreference {
+    private CharSequence[] mEntries;
+    private String[] mEntryValues;
+    private boolean[] mSetValues;
+    private boolean[] mOrigValues;
+    private String mSummary;
+    
+    public MultiCheckPreference(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        
+        TypedArray a = context.obtainStyledAttributes(attrs,
+                com.android.internal.R.styleable.ListPreference, 0, 0);
+        mEntries = a.getTextArray(com.android.internal.R.styleable.ListPreference_entries);
+        if (mEntries != null) {
+            setEntries(mEntries);
+        }
+        setEntryValuesCS(a.getTextArray(
+                com.android.internal.R.styleable.ListPreference_entryValues));
+        a.recycle();
+
+        /* Retrieve the Preference summary attribute since it's private
+         * in the Preference class.
+         */
+        a = context.obtainStyledAttributes(attrs,
+                com.android.internal.R.styleable.Preference, 0, 0);
+        mSummary = a.getString(com.android.internal.R.styleable.Preference_summary);
+        a.recycle();
+    }
+
+    public MultiCheckPreference(Context context) {
+        this(context, null);
+    }
+
+    /**
+     * Sets the human-readable entries to be shown in the list. This will be
+     * shown in subsequent dialogs.
+     * <p>
+     * Each entry must have a corresponding index in
+     * {@link #setEntryValues(CharSequence[])}.
+     * 
+     * @param entries The entries.
+     * @see #setEntryValues(CharSequence[])
+     */
+    public void setEntries(CharSequence[] entries) {
+        mEntries = entries;
+        mSetValues = new boolean[entries.length];
+        mOrigValues = new boolean[entries.length];
+    }
+    
+    /**
+     * @see #setEntries(CharSequence[])
+     * @param entriesResId The entries array as a resource.
+     */
+    public void setEntries(int entriesResId) {
+        setEntries(getContext().getResources().getTextArray(entriesResId));
+    }
+    
+    /**
+     * The list of entries to be shown in the list in subsequent dialogs.
+     * 
+     * @return The list as an array.
+     */
+    public CharSequence[] getEntries() {
+        return mEntries;
+    }
+    
+    /**
+     * The array to find the value to save for a preference when an entry from
+     * entries is selected. If a user clicks on the second item in entries, the
+     * second item in this array will be saved to the preference.
+     * 
+     * @param entryValues The array to be used as values to save for the preference.
+     */
+    public void setEntryValues(String[] entryValues) {
+        mEntryValues = entryValues;
+        Arrays.fill(mSetValues, false);
+        Arrays.fill(mOrigValues, false);
+    }
+
+    /**
+     * @see #setEntryValues(CharSequence[])
+     * @param entryValuesResId The entry values array as a resource.
+     */
+    public void setEntryValues(int entryValuesResId) {
+        setEntryValuesCS(getContext().getResources().getTextArray(entryValuesResId));
+    }
+
+    private void setEntryValuesCS(CharSequence[] values) {
+        setValues(null);
+        if (values != null) {
+            mEntryValues = new String[values.length];
+            for (int i=0; i<values.length; i++) {
+                mEntryValues[i] = values[i].toString();
+            }
+        }
+    }
+
+    /**
+     * Returns the array of values to be saved for the preference.
+     * 
+     * @return The array of values.
+     */
+    public String[] getEntryValues() {
+        return mEntryValues;
+    }
+
+    /**
+     * Get the boolean state of a given value.
+     */
+    public boolean getValue(int index) {
+        return mSetValues[index];
+    }
+
+    /**
+     * Set the boolean state of a given value.
+     */
+    public void setValue(int index, boolean state) {
+        mSetValues[index] = state;
+    }
+
+    /**
+     * Sets the current values.
+     */
+    public void setValues(boolean[] values) {
+        if (mSetValues != null) {
+            Arrays.fill(mSetValues, false);
+            Arrays.fill(mOrigValues, false);
+            if (values != null) {
+                System.arraycopy(values, 0, mSetValues, 0,
+                        values.length < mSetValues.length ? values.length : mSetValues.length);
+            }
+        }
+    }
+
+    /**
+     * Returns the summary of this ListPreference. If the summary
+     * has a {@linkplain java.lang.String#format String formatting}
+     * marker in it (i.e. "%s" or "%1$s"), then the current entry
+     * value will be substituted in its place.
+     *
+     * @return the summary with appropriate string substitution
+     */
+    @Override
+    public CharSequence getSummary() {
+        if (mSummary == null) {
+            return super.getSummary();
+        } else {
+            return mSummary;
+        }
+    }
+
+    /**
+     * Sets the summary for this Preference with a CharSequence.
+     * If the summary has a
+     * {@linkplain java.lang.String#format String formatting}
+     * marker in it (i.e. "%s" or "%1$s"), then the current entry
+     * value will be substituted in its place when it's retrieved.
+     *
+     * @param summary The summary for the preference.
+     */
+    @Override
+    public void setSummary(CharSequence summary) {
+        super.setSummary(summary);
+        if (summary == null && mSummary != null) {
+            mSummary = null;
+        } else if (summary != null && !summary.equals(mSummary)) {
+            mSummary = summary.toString();
+        }
+    }
+    
+    /**
+     * Returns the currently selected values.
+     */
+    public boolean[] getValues() {
+        return mSetValues;
+    }
+    
+    /**
+     * Returns the index of the given value (in the entry values array).
+     * 
+     * @param value The value whose index should be returned.
+     * @return The index of the value, or -1 if not found.
+     */
+    public int findIndexOfValue(String value) {
+        if (value != null && mEntryValues != null) {
+            for (int i = mEntryValues.length - 1; i >= 0; i--) {
+                if (mEntryValues[i].equals(value)) {
+                    return i;
+                }
+            }
+        }
+        return -1;
+    }
+    
+    @Override
+    protected void onPrepareDialogBuilder(Builder builder) {
+        super.onPrepareDialogBuilder(builder);
+        
+        if (mEntries == null || mEntryValues == null) {
+            throw new IllegalStateException(
+                    "ListPreference requires an entries array and an entryValues array.");
+        }
+
+        mOrigValues = Arrays.copyOf(mSetValues, mSetValues.length);
+        builder.setMultiChoiceItems(mEntries, mSetValues,
+                new DialogInterface.OnMultiChoiceClickListener() {
+                    @Override
+                    public void onClick(DialogInterface dialog, int which, boolean isChecked) {
+                        mSetValues[which] = isChecked;
+                    }
+        });
+    }
+
+    @Override
+    protected void onDialogClosed(boolean positiveResult) {
+        super.onDialogClosed(positiveResult);
+
+        if (positiveResult) {
+            if (callChangeListener(getValues())) {
+                return;
+            }
+        }
+        System.arraycopy(mOrigValues, 0, mSetValues, 0, mSetValues.length);
+    }
+
+    @Override
+    protected Object onGetDefaultValue(TypedArray a, int index) {
+        return a.getString(index);
+    }
+
+    @Override
+    protected void onSetInitialValue(boolean restoreValue, Object defaultValue) {
+    }
+
+    @Override
+    protected Parcelable onSaveInstanceState() {
+        final Parcelable superState = super.onSaveInstanceState();
+        if (isPersistent()) {
+            // No need to save instance state since it's persistent
+            return superState;
+        }
+        
+        final SavedState myState = new SavedState(superState);
+        myState.values = getValues();
+        return myState;
+    }
+
+    @Override
+    protected void onRestoreInstanceState(Parcelable state) {
+        if (state == null || !state.getClass().equals(SavedState.class)) {
+            // Didn't save state for us in onSaveInstanceState
+            super.onRestoreInstanceState(state);
+            return;
+        }
+         
+        SavedState myState = (SavedState) state;
+        super.onRestoreInstanceState(myState.getSuperState());
+        setValues(myState.values);
+    }
+    
+    private static class SavedState extends BaseSavedState {
+        boolean[] values;
+        
+        public SavedState(Parcel source) {
+            super(source);
+            values = source.createBooleanArray();
+        }
+
+        @Override
+        public void writeToParcel(Parcel dest, int flags) {
+            super.writeToParcel(dest, flags);
+            dest.writeBooleanArray(values);
+        }
+
+        public SavedState(Parcelable superState) {
+            super(superState);
+        }
+
+        public static final Parcelable.Creator<SavedState> CREATOR =
+                new Parcelable.Creator<SavedState>() {
+            public SavedState createFromParcel(Parcel in) {
+                return new SavedState(in);
+            }
+
+            public SavedState[] newArray(int size) {
+                return new SavedState[size];
+            }
+        };
+    }
+    
+}
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 2c49bd2..ba8c4c9 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -1557,6 +1557,9 @@
          * will likely be removed in a future release with support for
          * audio/vibe feedback profiles.
          *
+         * Not used anymore. On devices with vibrator, the user explicitly selects
+         * silent or vibrate mode.
+         * Kept for use by legacy database upgrade code in DatabaseHelper.
          * @hide
          */
         public static final String VIBRATE_IN_SILENT = "vibrate_in_silent";
@@ -1746,6 +1749,20 @@
         public static final String USER_ROTATION = "user_rotation";
 
         /**
+         * Whether the phone vibrates when it is ringing due to an incoming call. This will
+         * be used by Phone and Setting apps; it shouldn't affect other apps.
+         * The value is boolean (1 or 0).
+         *
+         * Note: this is not same as "vibrate on ring", which had been available until ICS.
+         * It was about AudioManager's setting and thus affected all the applications which
+         * relied on the setting, while this is purely about the vibration setting for incoming
+         * calls.
+         *
+         * @hide
+         */
+        public static final String VIBRATE_WHEN_RINGING = "vibrate_when_ringing";
+
+        /**
          * Whether the audible DTMF tones are played by the dialer when dialing. The value is
          * boolean (1 or 0).
          */
@@ -1983,7 +2000,6 @@
             SCREEN_BRIGHTNESS,
             SCREEN_BRIGHTNESS_MODE,
             SCREEN_AUTO_BRIGHTNESS_ADJ,
-            VIBRATE_ON,
             VIBRATE_INPUT_DEVICES,
             MODE_RINGER,
             MODE_RINGER_STREAMS_AFFECTED,
@@ -2002,7 +2018,6 @@
             VOLUME_ALARM + APPEND_FOR_LAST_AUDIBLE,
             VOLUME_NOTIFICATION + APPEND_FOR_LAST_AUDIBLE,
             VOLUME_BLUETOOTH_SCO + APPEND_FOR_LAST_AUDIBLE,
-            VIBRATE_IN_SILENT,
             TEXT_AUTO_REPLACE,
             TEXT_AUTO_CAPS,
             TEXT_AUTO_PUNCTUATE,
@@ -2029,6 +2044,7 @@
             SIP_CALL_OPTIONS,
             SIP_RECEIVE_CALLS,
             POINTER_SPEED,
+            VIBRATE_WHEN_RINGING
         };
 
         // Settings moved to Settings.Secure
diff --git a/core/java/android/view/AccessibilityInteractionController.java b/core/java/android/view/AccessibilityInteractionController.java
index 6387148..881594d 100644
--- a/core/java/android/view/AccessibilityInteractionController.java
+++ b/core/java/android/view/AccessibilityInteractionController.java
@@ -126,6 +126,16 @@
         }
     }
 
+    private boolean isShown(View view) {
+        // The first two checks are made also made by isShown() which
+        // however traverses the tree up to the parent to catch that.
+        // Therefore, we do some fail fast check to minimize the up
+        // tree traversal.
+        return (view.mAttachInfo != null
+                && view.mAttachInfo.mWindowVisibility == View.VISIBLE
+                && view.isShown());
+    }
+
     public void findAccessibilityNodeInfoByAccessibilityIdClientThread(
             long accessibilityNodeId, int interactionId,
             IAccessibilityInteractionConnectionCallback callback, int flags, int interrogatingPid,
@@ -174,7 +184,7 @@
             } else {
                 root = findViewByAccessibilityId(accessibilityViewId);
             }
-            if (root != null && root.isDisplayedOnScreen()) {
+            if (root != null && isShown(root)) {
                 mPrefetcher.prefetchAccessibilityNodeInfos(root, virtualDescendantId, flags, infos);
             }
         } finally {
@@ -236,7 +246,7 @@
             }
             if (root != null) {
                 View target = root.findViewById(viewId);
-                if (target != null && target.isDisplayedOnScreen()) {
+                if (target != null && isShown(target)) {
                     info = target.createAccessibilityNodeInfo();
                 }
             }
@@ -298,7 +308,7 @@
             } else {
                 root = mViewRootImpl.mView;
             }
-            if (root != null && root.isDisplayedOnScreen()) {
+            if (root != null && isShown(root)) {
                 AccessibilityNodeProvider provider = root.getAccessibilityNodeProvider();
                 if (provider != null) {
                     infos = provider.findAccessibilityNodeInfosByText(text,
@@ -315,7 +325,7 @@
                         final int viewCount = foundViews.size();
                         for (int i = 0; i < viewCount; i++) {
                             View foundView = foundViews.get(i);
-                            if (foundView.isDisplayedOnScreen()) {
+                            if (isShown(foundView)) {
                                 provider = foundView.getAccessibilityNodeProvider();
                                 if (provider != null) {
                                     List<AccessibilityNodeInfo> infosFromProvider =
@@ -390,7 +400,7 @@
             } else {
                 root = mViewRootImpl.mView;
             }
-            if (root != null && root.isDisplayedOnScreen()) {
+            if (root != null && isShown(root)) {
                 switch (focusType) {
                     case AccessibilityNodeInfo.FOCUS_ACCESSIBILITY: {
                         View host = mViewRootImpl.mAccessibilityFocusedHost;
@@ -411,7 +421,7 @@
                     case AccessibilityNodeInfo.FOCUS_INPUT: {
                         // Input focus cannot go to virtual views.
                         View target = root.findFocus();
-                        if (target != null && target.isDisplayedOnScreen()) {
+                        if (target != null && isShown(target)) {
                             focused = target.createAccessibilityNodeInfo();
                         }
                     } break;
@@ -477,7 +487,7 @@
             } else {
                 root = mViewRootImpl.mView;
             }
-            if (root != null && root.isDisplayedOnScreen()) {
+            if (root != null && isShown(root)) {
                 if ((direction & View.FOCUS_ACCESSIBILITY) ==  View.FOCUS_ACCESSIBILITY) {
                     AccessibilityNodeProvider provider = root.getAccessibilityNodeProvider();
                     if (provider != null) {
@@ -565,7 +575,7 @@
             } else {
                 target = mViewRootImpl.mView;
             }
-            if (target != null && target.isDisplayedOnScreen()) {
+            if (target != null && isShown(target)) {
                 AccessibilityNodeProvider provider = target.getAccessibilityNodeProvider();
                 if (provider != null) {
                     succeeded = provider.performAction(virtualDescendantId, action,
@@ -590,7 +600,7 @@
             return null;
         }
         View foundView = root.findViewByAccessibilityId(accessibilityId);
-        if (foundView != null && !foundView.isDisplayedOnScreen()) {
+        if (foundView != null && !isShown(foundView)) {
             return null;
         }
         return foundView;
@@ -670,7 +680,7 @@
                         }
                         View child = children.getChildAt(i);
                         if (child.getAccessibilityViewId() != current.getAccessibilityViewId()
-                                &&  child.isDisplayedOnScreen()) {
+                                &&  isShown(child)) {
                             AccessibilityNodeInfo info = null;
                             AccessibilityNodeProvider provider = child.getAccessibilityNodeProvider();
                             if (provider == null) {
@@ -706,7 +716,7 @@
                         return;
                     }
                     View child = children.getChildAt(i);
-                    if (child.isDisplayedOnScreen()) {
+                    if (isShown(child)) {
                         AccessibilityNodeProvider provider = child.getAccessibilityNodeProvider();
                         if (provider == null) {
                             AccessibilityNodeInfo info = child.createAccessibilityNodeInfo();
diff --git a/core/java/android/view/AccessibilityIterators.java b/core/java/android/view/AccessibilityIterators.java
new file mode 100644
index 0000000..386c866d
--- /dev/null
+++ b/core/java/android/view/AccessibilityIterators.java
@@ -0,0 +1,352 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view;
+
+import android.content.ComponentCallbacks;
+import android.content.Context;
+import android.content.pm.ActivityInfo;
+import android.content.res.Configuration;
+
+import java.text.BreakIterator;
+import java.util.Locale;
+
+/**
+ * This class contains the implementation of text segment iterators
+ * for accessibility support.
+ *
+ * Note: Such iterators are needed in the view package since we want
+ * to be able to iterator over content description of any view.
+ *
+ * @hide
+ */
+public final class AccessibilityIterators {
+
+    /**
+     * @hide
+     */
+    public static interface TextSegmentIterator {
+        public int[] following(int current);
+        public int[] preceding(int current);
+    }
+
+    /**
+     * @hide
+     */
+    public static abstract class AbstractTextSegmentIterator implements TextSegmentIterator {
+        protected static final int DONE = -1;
+
+        protected String mText;
+
+        private final int[] mSegment = new int[2];
+
+        public void initialize(String text) {
+            mText = text;
+        }
+
+        protected int[] getRange(int start, int end) {
+            if (start < 0 || end < 0 || start ==  end) {
+                return null;
+            }
+            mSegment[0] = start;
+            mSegment[1] = end;
+            return mSegment;
+        }
+    }
+
+    static class CharacterTextSegmentIterator extends AbstractTextSegmentIterator
+            implements ComponentCallbacks {
+        private static CharacterTextSegmentIterator sInstance;
+
+        private final Context mAppContext;
+
+        protected BreakIterator mImpl;
+
+        public static CharacterTextSegmentIterator getInstance(Context context) {
+            if (sInstance == null) {
+                sInstance = new CharacterTextSegmentIterator(context);
+            }
+            return sInstance;
+        }
+
+        private CharacterTextSegmentIterator(Context context) {
+            mAppContext = context.getApplicationContext();
+            Locale locale = mAppContext.getResources().getConfiguration().locale;
+            onLocaleChanged(locale);
+            ViewRootImpl.addConfigCallback(this);
+        }
+
+        @Override
+        public void initialize(String text) {
+            super.initialize(text);
+            mImpl.setText(text);
+        }
+
+        @Override
+        public int[] following(int offset) {
+            final int textLegth = mText.length();
+            if (textLegth <= 0) {
+                return null;
+            }
+            if (offset >= textLegth) {
+                return null;
+            }
+            int start = -1;
+            if (offset < 0) {
+                offset = 0;
+                if (mImpl.isBoundary(offset)) {
+                    start = offset;
+                }
+            }
+            if (start < 0) {
+                start = mImpl.following(offset);
+            }
+            if (start < 0) {
+                return null;
+            }
+            final int end = mImpl.following(start);
+            return getRange(start, end);
+        }
+
+        @Override
+        public int[] preceding(int offset) {
+            final int textLegth = mText.length();
+            if (textLegth <= 0) {
+                return null;
+            }
+            if (offset <= 0) {
+                return null;
+            }
+            int end = -1;
+            if (offset > mText.length()) {
+                offset = mText.length();
+                if (mImpl.isBoundary(offset)) {
+                    end = offset;
+                }
+            }
+            if (end < 0) {
+                end = mImpl.preceding(offset);
+            }
+            if (end < 0) {
+                return null;
+            }
+            final int start = mImpl.preceding(end);
+            return getRange(start, end);
+        }
+
+        @Override
+        public void onConfigurationChanged(Configuration newConfig) {
+            Configuration oldConfig = mAppContext.getResources().getConfiguration();
+            final int changed = oldConfig.diff(newConfig);
+            if ((changed & ActivityInfo.CONFIG_LOCALE) != 0) {
+                Locale locale = newConfig.locale;
+                onLocaleChanged(locale);
+            }
+        }
+
+        @Override
+        public void onLowMemory() {
+            /* ignore */
+        }
+
+        protected void onLocaleChanged(Locale locale) {
+            mImpl = BreakIterator.getCharacterInstance(locale);
+        }
+    }
+
+    static class WordTextSegmentIterator extends CharacterTextSegmentIterator {
+        private static WordTextSegmentIterator sInstance;
+
+        public static WordTextSegmentIterator getInstance(Context context) {
+            if (sInstance == null) {
+                sInstance = new WordTextSegmentIterator(context);
+            }
+            return sInstance;
+        }
+
+        private WordTextSegmentIterator(Context context) {
+           super(context);
+        }
+
+        @Override
+        protected void onLocaleChanged(Locale locale) {
+            mImpl = BreakIterator.getWordInstance(locale);
+        }
+
+        @Override
+        public int[] following(int offset) {
+            final int textLegth = mText.length();
+            if (textLegth <= 0) {
+                return null;
+            }
+            if (offset >= mText.length()) {
+                return null;
+            }
+            int start = -1;
+            if (offset < 0) {
+                offset = 0;
+                if (mImpl.isBoundary(offset) && isLetterOrDigit(offset)) {
+                    start = offset;
+                }
+            }
+            if (start < 0) {
+                while ((offset = mImpl.following(offset)) != DONE) {
+                    if (isLetterOrDigit(offset)) {
+                        start = offset;
+                        break;
+                    }
+                }
+            }
+            if (start < 0) {
+                return null;
+            }
+            final int end = mImpl.following(start);
+            return getRange(start, end);
+        }
+
+        @Override
+        public int[] preceding(int offset) {
+            final int textLegth = mText.length();
+            if (textLegth <= 0) {
+                return null;
+            }
+            if (offset <= 0) {
+                return null;
+            }
+            int end = -1;
+            if (offset > mText.length()) {
+                offset = mText.length();
+                if (mImpl.isBoundary(offset) && offset > 0 && isLetterOrDigit(offset - 1)) {
+                    end = offset;
+                }
+            }
+            if (end < 0) {
+                while ((offset = mImpl.preceding(offset)) != DONE) {
+                    if (offset > 0 && isLetterOrDigit(offset - 1)) {
+                        end = offset;
+                        break;
+                    }
+                }
+            }
+            if (end < 0) {
+                return null;
+            }
+            final int start = mImpl.preceding(end);
+            return getRange(start, end);
+        }
+
+        private boolean isLetterOrDigit(int index) {
+            if (index >= 0 && index < mText.length()) {
+                final int codePoint = mText.codePointAt(index);
+                return Character.isLetterOrDigit(codePoint);
+            }
+            return false;
+        }
+    }
+
+    static class ParagraphTextSegmentIterator extends AbstractTextSegmentIterator {
+        private static ParagraphTextSegmentIterator sInstance;
+
+        public static ParagraphTextSegmentIterator getInstance() {
+            if (sInstance == null) {
+                sInstance = new ParagraphTextSegmentIterator();
+            }
+            return sInstance;
+        }
+
+        @Override
+        public int[] following(int offset) {
+            final int textLength = mText.length();
+            if (textLength <= 0) {
+                return null;
+            }
+            if (offset >= textLength) {
+                return null;
+            }
+            int start = -1;
+            if (offset < 0) {
+                start = 0;
+            } else {
+                for (int i = offset + 1; i < textLength; i++) {
+                    if (mText.charAt(i) == '\n') {
+                        start = i;
+                        break;
+                    }
+                }
+            }
+            while (start < textLength && mText.charAt(start) == '\n') {
+                start++;
+            }
+            if (start < 0) {
+                return null;
+            }
+            int end = start;
+            for (int i = end + 1; i < textLength; i++) {
+                end = i;
+                if (mText.charAt(i) == '\n') {
+                    break;
+                }
+            }
+            while (end < textLength && mText.charAt(end) == '\n') {
+                end++;
+            }
+            return getRange(start, end);
+        }
+
+        @Override
+        public int[] preceding(int offset) {
+            final int textLength = mText.length();
+            if (textLength <= 0) {
+                return null;
+            }
+            if (offset <= 0) {
+                return null;
+            }
+            int end = -1;
+            if (offset > mText.length()) {
+                end = mText.length();
+            } else {
+                if (offset > 0 && mText.charAt(offset - 1) == '\n') {
+                    offset--;
+                }
+                for (int i = offset - 1; i >= 0; i--) {
+                    if (i > 0 && mText.charAt(i - 1) == '\n') {
+                        end = i;
+                        break;
+                    }
+                }
+            }
+            if (end <= 0) {
+                return null;
+            }
+            int start = end;
+            while (start > 0 && mText.charAt(start - 1) == '\n') {
+                start--;
+            }
+            if (start == 0 && mText.charAt(start) == '\n') {
+                return null;
+            }
+            for (int i = start - 1; i >= 0; i--) {
+                start = i;
+                if (start > 0 && mText.charAt(i - 1) == '\n') {
+                    break;
+                }
+            }
+            start = Math.max(0, start);
+            return getRange(start, end);
+        }
+    }
+}
diff --git a/core/java/android/view/Choreographer.java b/core/java/android/view/Choreographer.java
index b319cd5..825f351 100644
--- a/core/java/android/view/Choreographer.java
+++ b/core/java/android/view/Choreographer.java
@@ -92,6 +92,7 @@
     private boolean mFrameScheduled;
     private boolean mCallbacksRunning;
     private long mLastFrameTimeNanos;
+    private long mFrameIntervalNanos;
 
     /**
      * Callback type: Input callback.  Runs first.
@@ -116,6 +117,8 @@
         mHandler = new FrameHandler(looper);
         mDisplayEventReceiver = USE_VSYNC ? new FrameDisplayEventReceiver(looper) : null;
         mLastFrameTimeNanos = Long.MIN_VALUE;
+        mFrameIntervalNanos = (long)(1000000000 /
+                new Display(Display.DEFAULT_DISPLAY, null).getRefreshRate());
 
         mCallbackQueues = new CallbackQueue[CALLBACK_LAST + 1];
         for (int i = 0; i <= CALLBACK_LAST; i++) {
@@ -343,19 +346,39 @@
     }
 
     void doFrame(long timestampNanos, int frame) {
+        final long startNanos;
         synchronized (mLock) {
             if (!mFrameScheduled) {
                 return; // no work to do
             }
+
+            startNanos = System.nanoTime();
+            final long jitterNanos = startNanos - timestampNanos;
+            if (jitterNanos >= mFrameIntervalNanos) {
+                final long lastFrameOffset = jitterNanos % mFrameIntervalNanos;
+                if (DEBUG) {
+                    Log.d(TAG, "Missed vsync by " + (jitterNanos * 0.000001f) + " ms "
+                            + "which is more than the frame interval of "
+                            + (mFrameIntervalNanos * 0.000001f) + " ms!  "
+                            + "Setting frame time to " + (lastFrameOffset * 0.000001f)
+                            + " ms in the past.");
+                }
+                timestampNanos = startNanos - lastFrameOffset;
+            }
+
+            if (timestampNanos < mLastFrameTimeNanos) {
+                if (DEBUG) {
+                    Log.d(TAG, "Frame time appears to be going backwards.  May be due to a "
+                            + "previously skipped frame.  Waiting for next vsync");
+                }
+                scheduleVsyncLocked();
+                return;
+            }
+
             mFrameScheduled = false;
             mLastFrameTimeNanos = timestampNanos;
         }
 
-        final long startNanos;
-        if (DEBUG) {
-            startNanos = System.nanoTime();
-        }
-
         doCallbacks(Choreographer.CALLBACK_INPUT);
         doCallbacks(Choreographer.CALLBACK_ANIMATION);
         doCallbacks(Choreographer.CALLBACK_TRAVERSAL);
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index c054d38..058e163 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -47,7 +47,6 @@
 import android.os.RemoteException;
 import android.os.SystemClock;
 import android.os.SystemProperties;
-import android.text.TextUtils;
 import android.util.AttributeSet;
 import android.util.FloatProperty;
 import android.util.LocaleUtil;
@@ -60,6 +59,10 @@
 import android.util.SparseArray;
 import android.util.TypedValue;
 import android.view.ContextMenu.ContextMenuInfo;
+import android.view.AccessibilityIterators.TextSegmentIterator;
+import android.view.AccessibilityIterators.CharacterTextSegmentIterator;
+import android.view.AccessibilityIterators.WordTextSegmentIterator;
+import android.view.AccessibilityIterators.ParagraphTextSegmentIterator;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityEventSource;
 import android.view.accessibility.AccessibilityManager;
@@ -1528,7 +1531,8 @@
             | AccessibilityEvent.TYPE_VIEW_HOVER_EXIT
             | AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED
             | AccessibilityEvent.TYPE_VIEW_TEXT_SELECTION_CHANGED
-            | AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED;
+            | AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED
+            | AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY;
 
     /**
      * Temporary Rect currently for use in setBackground().  This will probably
@@ -1594,6 +1598,11 @@
     int mAccessibilityViewId = NO_ID;
 
     /**
+     * @hide
+     */
+    private int mAccessibilityCursorPosition = -1;
+
+    /**
      * The view's tag.
      * {@hide}
      *
@@ -4642,6 +4651,51 @@
     }
 
     /**
+     * Gets the location of this view in screen coordintates.
+     *
+     * @param outRect The output location
+     */
+    private void getBoundsOnScreen(Rect outRect) {
+        if (mAttachInfo == null) {
+            return;
+        }
+
+        RectF position = mAttachInfo.mTmpTransformRect;
+        position.set(0, 0, mRight - mLeft, mBottom - mTop);
+
+        if (!hasIdentityMatrix()) {
+            getMatrix().mapRect(position);
+        }
+
+        position.offset(mLeft, mTop);
+
+        ViewParent parent = mParent;
+        while (parent instanceof View) {
+            View parentView = (View) parent;
+
+            position.offset(-parentView.mScrollX, -parentView.mScrollY);
+
+            if (!parentView.hasIdentityMatrix()) {
+                parentView.getMatrix().mapRect(position);
+            }
+
+            position.offset(parentView.mLeft, parentView.mTop);
+
+            parent = parentView.mParent;
+        }
+
+        if (parent instanceof ViewRootImpl) {
+            ViewRootImpl viewRootImpl = (ViewRootImpl) parent;
+            position.offset(0, -viewRootImpl.mCurScrollY);
+        }
+
+        position.offset(mAttachInfo.mWindowLeft, mAttachInfo.mWindowTop);
+
+        outRect.set((int) (position.left + 0.5f), (int) (position.top + 0.5f),
+                (int) (position.right + 0.5f), (int) (position.bottom + 0.5f));
+    }
+
+    /**
      * @see #onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo)
      *
      * Note: Called from the default {@link AccessibilityDelegate}.
@@ -4651,8 +4705,7 @@
         getDrawingRect(bounds);
         info.setBoundsInParent(bounds);
 
-        getGlobalVisibleRect(bounds);
-        bounds.offset(mAttachInfo.mWindowLeft, mAttachInfo.mWindowTop);
+        getBoundsOnScreen(bounds);
         info.setBoundsInScreen(bounds);
 
         if ((mPrivateFlags & IS_ROOT_NAMESPACE) == 0) {
@@ -4662,6 +4715,8 @@
             }
         }
 
+        info.setVisibleToUser(isVisibleToUser());
+
         info.setPackageName(mContext.getPackageName());
         info.setClassName(View.class.getName());
         info.setContentDescription(getContentDescription());
@@ -4688,8 +4743,11 @@
             }
         }
 
-        info.addAction(AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS);
-        info.addAction(AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS);
+        if (!isAccessibilityFocused()) {
+            info.addAction(AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS);
+        } else {
+            info.addAction(AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS);
+        }
 
         if (isClickable()) {
             info.addAction(AccessibilityNodeInfo.ACTION_CLICK);
@@ -4699,20 +4757,23 @@
             info.addAction(AccessibilityNodeInfo.ACTION_LONG_CLICK);
         }
 
-        if (getContentDescription() != null) {
+        if (mContentDescription != null && mContentDescription.length() > 0) {
             info.addAction(AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY);
             info.addAction(AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY);
             info.setMovementGranularities(AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER
-                    | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD);
+                    | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD
+                    | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PARAGRAPH);
         }
     }
 
     /**
-     * Computes whether this view is visible on the screen.
+     * Computes whether this view is visible to the user. Such a view is
+     * attached, visible, all its predecessors are visible, it is not clipped
+     * entirely by its predecessors, and has an alpha greater than zero.
      *
      * @return Whether the view is visible on the screen.
      */
-    boolean isDisplayedOnScreen() {
+    private boolean isVisibleToUser() {
         // The first two checks are made also made by isShown() which
         // however traverses the tree up to the parent to catch that.
         // Therefore, we do some fail fast check to minimize the up
@@ -5929,7 +5990,8 @@
                 outViews.add(this);
             }
         } else if ((flags & FIND_VIEWS_WITH_CONTENT_DESCRIPTION) != 0
-                && !TextUtils.isEmpty(searched) && !TextUtils.isEmpty(mContentDescription)) {
+                && (searched != null && searched.length() > 0)
+                && (mContentDescription != null && mContentDescription.length() > 0)) {
             String searchedLowerCase = searched.toString().toLowerCase();
             String contentDescriptionLowerCase = mContentDescription.toString().toLowerCase();
             if (contentDescriptionLowerCase.contains(searchedLowerCase)) {
@@ -6030,6 +6092,10 @@
             invalidate();
             sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED);
             notifyAccessibilityStateChanged();
+
+            // Clear the text navigation state.
+            setAccessibilityCursorPosition(-1);
+
             // Try to move accessibility focus to the input focus.
             View rootView = getRootView();
             if (rootView != null) {
@@ -6357,9 +6423,9 @@
     boolean includeForAccessibility() {
         if (mAttachInfo != null) {
             if (!mAttachInfo.mIncludeNotImportantViews) {
-                return isImportantForAccessibility() && isDisplayedOnScreen();
+                return isImportantForAccessibility();
             } else {
-                return isDisplayedOnScreen();
+                return true;
             }
         }
         return false;
@@ -6425,11 +6491,31 @@
     /**
      * Performs the specified accessibility action on the view. For
      * possible accessibility actions look at {@link AccessibilityNodeInfo}.
+    * <p>
+    * If an {@link AccessibilityDelegate} has been specified via calling
+    * {@link #setAccessibilityDelegate(AccessibilityDelegate)} its
+    * {@link AccessibilityDelegate#performAccessibilityAction(View, int, Bundle)}
+    * is responsible for handling this call.
+    * </p>
      *
      * @param action The action to perform.
+     * @param arguments Optional action arguments.
      * @return Whether the action was performed.
      */
-    public boolean performAccessibilityAction(int action, Bundle args) {
+    public boolean performAccessibilityAction(int action, Bundle arguments) {
+      if (mAccessibilityDelegate != null) {
+          return mAccessibilityDelegate.performAccessibilityAction(this, action, arguments);
+      } else {
+          return performAccessibilityActionInternal(action, arguments);
+      }
+    }
+
+   /**
+    * @see #performAccessibilityAction(int, Bundle)
+    *
+    * Note: Called from the default {@link AccessibilityDelegate}.
+    */
+    boolean performAccessibilityActionInternal(int action, Bundle arguments) {
         switch (action) {
             case AccessibilityNodeInfo.ACTION_CLICK: {
                 if (isClickable()) {
@@ -6478,14 +6564,155 @@
                     return true;
                 }
             } break;
+            case AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY: {
+                if (arguments != null) {
+                    final int granularity = arguments.getInt(
+                            AccessibilityNodeInfo.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT);
+                    return nextAtGranularity(granularity);
+                }
+            } break;
+            case AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY: {
+                if (arguments != null) {
+                    final int granularity = arguments.getInt(
+                            AccessibilityNodeInfo.ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT);
+                    return previousAtGranularity(granularity);
+                }
+            } break;
         }
         return false;
     }
 
+    private boolean nextAtGranularity(int granularity) {
+        CharSequence text = getIterableTextForAccessibility();
+        if (text != null && text.length() > 0) {
+            return false;
+        }
+        TextSegmentIterator iterator = getIteratorForGranularity(granularity);
+        if (iterator == null) {
+            return false;
+        }
+        final int current = getAccessibilityCursorPosition();
+        final int[] range = iterator.following(current);
+        if (range == null) {
+            setAccessibilityCursorPosition(-1);
+            return false;
+        }
+        final int start = range[0];
+        final int end = range[1];
+        setAccessibilityCursorPosition(start);
+        sendViewTextTraversedAtGranularityEvent(
+                AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY,
+                granularity, start, end);
+        return true;
+    }
+
+    private boolean previousAtGranularity(int granularity) {
+        CharSequence text = getIterableTextForAccessibility();
+        if (text != null && text.length() > 0) {
+            return false;
+        }
+        TextSegmentIterator iterator = getIteratorForGranularity(granularity);
+        if (iterator == null) {
+            return false;
+        }
+        final int selectionStart = getAccessibilityCursorPosition();
+        final int current = selectionStart >= 0 ? selectionStart : text.length() + 1;
+        final int[] range = iterator.preceding(current);
+        if (range == null) {
+            setAccessibilityCursorPosition(-1);
+            return false;
+        }
+        final int start = range[0];
+        final int end = range[1];
+        setAccessibilityCursorPosition(end);
+        sendViewTextTraversedAtGranularityEvent(
+                AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY,
+                granularity, start, end);
+        return true;
+    }
+
+    /**
+     * Gets the text reported for accessibility purposes.
+     *
+     * @return The accessibility text.
+     *
+     * @hide
+     */
+    public CharSequence getIterableTextForAccessibility() {
+        return mContentDescription;
+    }
+
+    /**
+     * @hide
+     */
+    public int getAccessibilityCursorPosition() {
+        return mAccessibilityCursorPosition;
+    }
+
+    /**
+     * @hide
+     */
+    public void setAccessibilityCursorPosition(int position) {
+        mAccessibilityCursorPosition = position;
+    }
+
+    private void sendViewTextTraversedAtGranularityEvent(int action, int granularity,
+            int fromIndex, int toIndex) {
+        if (mParent == null) {
+            return;
+        }
+        AccessibilityEvent event = AccessibilityEvent.obtain(
+                AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY);
+        onInitializeAccessibilityEvent(event);
+        onPopulateAccessibilityEvent(event);
+        event.setFromIndex(fromIndex);
+        event.setToIndex(toIndex);
+        event.setAction(action);
+        event.setMovementGranularity(granularity);
+        mParent.requestSendAccessibilityEvent(this, event);
+    }
+
+    /**
+     * @hide
+     */
+    public TextSegmentIterator getIteratorForGranularity(int granularity) {
+        switch (granularity) {
+            case AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER: {
+                CharSequence text = getIterableTextForAccessibility();
+                if (text != null && text.length() > 0) {
+                    CharacterTextSegmentIterator iterator =
+                        CharacterTextSegmentIterator.getInstance(mContext);
+                    iterator.initialize(text.toString());
+                    return iterator;
+                }
+            } break;
+            case AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD: {
+                CharSequence text = getIterableTextForAccessibility();
+                if (text != null && text.length() > 0) {
+                    WordTextSegmentIterator iterator =
+                        WordTextSegmentIterator.getInstance(mContext);
+                    iterator.initialize(text.toString());
+                    return iterator;
+                }
+            } break;
+            case AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PARAGRAPH: {
+                CharSequence text = getIterableTextForAccessibility();
+                if (text != null && text.length() > 0) {
+                    ParagraphTextSegmentIterator iterator =
+                        ParagraphTextSegmentIterator.getInstance();
+                    iterator.initialize(text.toString());
+                    return iterator;
+                }
+            } break;
+        }
+        return null;
+    }
+
     /**
      * @hide
      */
     public void dispatchStartTemporaryDetach() {
+        clearAccessibilityFocus();
         onStartTemporaryDetach();
     }
 
@@ -10849,22 +11076,30 @@
         if ((mPrivateFlags & REQUEST_TRANSPARENT_REGIONS) != 0) {
             mParent.requestTransparentRegion(this);
         }
+
         if ((mPrivateFlags & AWAKEN_SCROLL_BARS_ON_ATTACH) != 0) {
             initialAwakenScrollBars();
             mPrivateFlags &= ~AWAKEN_SCROLL_BARS_ON_ATTACH;
         }
+
         jumpDrawablesToCurrentState();
+
         // Order is important here: LayoutDirection MUST be resolved before Padding
         // and TextDirection
         resolveLayoutDirection();
         resolvePadding();
         resolveTextDirection();
         resolveTextAlignment();
+
         clearAccessibilityFocus();
         if (isFocused()) {
             InputMethodManager imm = InputMethodManager.peekInstance();
             imm.focusIn(this);
         }
+
+        if (mAttachInfo != null && mDisplayList != null) {
+            mAttachInfo.mViewRootImpl.dequeueDisplayList(mDisplayList);
+        }
     }
 
     /**
@@ -11077,7 +11312,7 @@
 
         if (mAttachInfo != null) {
             if (mDisplayList != null) {
-                mAttachInfo.mViewRootImpl.invalidateDisplayList(mDisplayList);
+                mAttachInfo.mViewRootImpl.enqueueDisplayList(mDisplayList);
             }
             mAttachInfo.mViewRootImpl.cancelInvalidate(this);
         } else {
@@ -11092,7 +11327,6 @@
         resetResolvedLayoutDirection();
         resetResolvedTextAlignment();
         resetAccessibilityStateChanged();
-        clearAccessibilityFocus();
     }
 
     /**
@@ -11772,7 +12006,6 @@
 
             boolean caching = false;
             final HardwareCanvas canvas = displayList.start();
-            int restoreCount = 0;
             int width = mRight - mLeft;
             int height = mBottom - mTop;
 
@@ -12405,10 +12638,6 @@
         return more;
     }
 
-    void setDisplayListProperties() {
-        setDisplayListProperties(mDisplayList);
-    }
-
     /**
      * This method is called by getDisplayList() when a display list is created or re-rendered.
      * It sets or resets the current value of all properties on that display list (resetting is
@@ -17213,6 +17442,26 @@
         }
 
         /**
+         * Performs the specified accessibility action on the view. For
+         * possible accessibility actions look at {@link AccessibilityNodeInfo}.
+         * <p>
+         * The default implementation behaves as
+         * {@link View#performAccessibilityAction(int, Bundle)
+         *  View#performAccessibilityAction(int, Bundle)} for the case of
+         *  no accessibility delegate been set.
+         * </p>
+         *
+         * @param action The action to perform.
+         * @return Whether the action was performed.
+         *
+         * @see View#performAccessibilityAction(int, Bundle)
+         *      View#performAccessibilityAction(int, Bundle)
+         */
+        public boolean performAccessibilityAction(View host, int action, Bundle args) {
+            return host.performAccessibilityActionInternal(action, args);
+        }
+
+        /**
          * Sends an accessibility event. This method behaves exactly as
          * {@link #sendAccessibilityEvent(View, int)} but takes as an argument an
          * empty {@link AccessibilityEvent} and does not perform a check whether
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 1b624dc..56b7734 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -3586,6 +3586,8 @@
             clearChildFocus = true;
         }
 
+        view.clearAccessibilityFocus();
+
         cancelTouchTarget(view);
         cancelHoverTarget(view);
 
@@ -3669,6 +3671,8 @@
                 clearChildFocus = view;
             }
 
+            view.clearAccessibilityFocus();
+
             cancelTouchTarget(view);
             cancelHoverTarget(view);
 
@@ -3742,6 +3746,8 @@
                 clearChildFocus = view;
             }
 
+            view.clearAccessibilityFocus();
+
             cancelTouchTarget(view);
             cancelHoverTarget(view);
 
@@ -3790,6 +3796,8 @@
             child.clearFocus();
         }
 
+        child.clearAccessibilityFocus();
+
         cancelTouchTarget(child);
         cancelHoverTarget(child);
 
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index ec6bd81..5f295cb 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -4412,14 +4412,23 @@
         mInvalidateOnAnimationRunnable.addViewRect(info);
     }
 
-    public void invalidateDisplayList(DisplayList displayList) {
+    public void enqueueDisplayList(DisplayList displayList) {
         mDisplayLists.add(displayList);
 
         mHandler.removeMessages(MSG_INVALIDATE_DISPLAY_LIST);
         Message msg = mHandler.obtainMessage(MSG_INVALIDATE_DISPLAY_LIST);
         mHandler.sendMessage(msg);
     }
-    
+
+    public void dequeueDisplayList(DisplayList displayList) {
+        if (mDisplayLists.remove(displayList)) {
+            displayList.invalidate();
+            if (mDisplayLists.size() == 0) {
+                mHandler.removeMessages(MSG_INVALIDATE_DISPLAY_LIST);
+            }
+        }
+    }
+
     public void cancelInvalidate(View view) {
         mHandler.removeMessages(MSG_INVALIDATE, view);
         // fixme: might leak the AttachInfo.InvalidateInfo objects instead of returning
diff --git a/core/java/android/view/ViewTreeObserver.java b/core/java/android/view/ViewTreeObserver.java
index 1c5d436..6a8a60a 100644
--- a/core/java/android/view/ViewTreeObserver.java
+++ b/core/java/android/view/ViewTreeObserver.java
@@ -20,7 +20,6 @@
 import android.graphics.Region;
 
 import java.util.ArrayList;
-import java.util.concurrent.CopyOnWriteArrayList;
 
 /**
  * A view tree observer is used to register listeners that can be notified of global
@@ -32,12 +31,12 @@
  * for more information.
  */
 public final class ViewTreeObserver {
-    private CopyOnWriteArrayList<OnGlobalFocusChangeListener> mOnGlobalFocusListeners;
-    private CopyOnWriteArrayList<OnGlobalLayoutListener> mOnGlobalLayoutListeners;
-    private CopyOnWriteArrayList<OnTouchModeChangeListener> mOnTouchModeChangeListeners;
-    private CopyOnWriteArrayList<OnComputeInternalInsetsListener> mOnComputeInternalInsetsListeners;
-    private CopyOnWriteArrayList<OnScrollChangedListener> mOnScrollChangedListeners;
-    private ArrayList<OnPreDrawListener> mOnPreDrawListeners;
+    private CopyOnWriteArray<OnGlobalFocusChangeListener> mOnGlobalFocusListeners;
+    private CopyOnWriteArray<OnGlobalLayoutListener> mOnGlobalLayoutListeners;
+    private CopyOnWriteArray<OnTouchModeChangeListener> mOnTouchModeChangeListeners;
+    private CopyOnWriteArray<OnComputeInternalInsetsListener> mOnComputeInternalInsetsListeners;
+    private CopyOnWriteArray<OnScrollChangedListener> mOnScrollChangedListeners;
+    private CopyOnWriteArray<OnPreDrawListener> mOnPreDrawListeners;
     private ArrayList<OnDrawListener> mOnDrawListeners;
 
     private boolean mAlive = true;
@@ -147,7 +146,7 @@
          * windows behind it should be placed.
          */
         public final Rect contentInsets = new Rect();
-        
+
         /**
          * Offsets from the frame of the window at which windows behind it
          * are visible.
@@ -166,13 +165,13 @@
          * can be touched.
          */
         public static final int TOUCHABLE_INSETS_FRAME = 0;
-        
+
         /**
          * Option for {@link #setTouchableInsets(int)}: the area inside of
          * the content insets can be touched.
          */
         public static final int TOUCHABLE_INSETS_CONTENT = 1;
-        
+
         /**
          * Option for {@link #setTouchableInsets(int)}: the area inside of
          * the visible insets can be touched.
@@ -195,7 +194,7 @@
         }
 
         int mTouchableInsets;
-        
+
         void reset() {
             contentInsets.setEmpty();
             visibleInsets.setEmpty();
@@ -231,7 +230,7 @@
             mTouchableInsets = other.mTouchableInsets;
         }
     }
-    
+
     /**
      * Interface definition for a callback to be invoked when layout has
      * completed and the client can compute its interior insets.
@@ -328,7 +327,7 @@
         checkIsAlive();
 
         if (mOnGlobalFocusListeners == null) {
-            mOnGlobalFocusListeners = new CopyOnWriteArrayList<OnGlobalFocusChangeListener>();
+            mOnGlobalFocusListeners = new CopyOnWriteArray<OnGlobalFocusChangeListener>();
         }
 
         mOnGlobalFocusListeners.add(listener);
@@ -363,7 +362,7 @@
         checkIsAlive();
 
         if (mOnGlobalLayoutListeners == null) {
-            mOnGlobalLayoutListeners = new CopyOnWriteArrayList<OnGlobalLayoutListener>();
+            mOnGlobalLayoutListeners = new CopyOnWriteArray<OnGlobalLayoutListener>();
         }
 
         mOnGlobalLayoutListeners.add(listener);
@@ -413,7 +412,7 @@
         checkIsAlive();
 
         if (mOnPreDrawListeners == null) {
-            mOnPreDrawListeners = new ArrayList<OnPreDrawListener>();
+            mOnPreDrawListeners = new CopyOnWriteArray<OnPreDrawListener>();
         }
 
         mOnPreDrawListeners.add(listener);
@@ -485,7 +484,7 @@
         checkIsAlive();
 
         if (mOnScrollChangedListeners == null) {
-            mOnScrollChangedListeners = new CopyOnWriteArrayList<OnScrollChangedListener>();
+            mOnScrollChangedListeners = new CopyOnWriteArray<OnScrollChangedListener>();
         }
 
         mOnScrollChangedListeners.add(listener);
@@ -519,7 +518,7 @@
         checkIsAlive();
 
         if (mOnTouchModeChangeListeners == null) {
-            mOnTouchModeChangeListeners = new CopyOnWriteArrayList<OnTouchModeChangeListener>();
+            mOnTouchModeChangeListeners = new CopyOnWriteArray<OnTouchModeChangeListener>();
         }
 
         mOnTouchModeChangeListeners.add(listener);
@@ -558,7 +557,7 @@
 
         if (mOnComputeInternalInsetsListeners == null) {
             mOnComputeInternalInsetsListeners =
-                    new CopyOnWriteArrayList<OnComputeInternalInsetsListener>();
+                    new CopyOnWriteArray<OnComputeInternalInsetsListener>();
         }
 
         mOnComputeInternalInsetsListeners.add(listener);
@@ -622,10 +621,16 @@
         // perform the dispatching. The iterator is a safe guard against listeners that
         // could mutate the list by calling the various add/remove methods. This prevents
         // the array from being modified while we iterate it.
-        final CopyOnWriteArrayList<OnGlobalFocusChangeListener> listeners = mOnGlobalFocusListeners;
+        final CopyOnWriteArray<OnGlobalFocusChangeListener> listeners = mOnGlobalFocusListeners;
         if (listeners != null && listeners.size() > 0) {
-            for (OnGlobalFocusChangeListener listener : listeners) {
-                listener.onGlobalFocusChanged(oldFocus, newFocus);
+            CopyOnWriteArray.Access<OnGlobalFocusChangeListener> access = listeners.start();
+            try {
+                int count = access.size();
+                for (int i = 0; i < count; i++) {
+                    access.get(i).onGlobalFocusChanged(oldFocus, newFocus);
+                }
+            } finally {
+                listeners.end();
             }
         }
     }
@@ -640,10 +645,16 @@
         // perform the dispatching. The iterator is a safe guard against listeners that
         // could mutate the list by calling the various add/remove methods. This prevents
         // the array from being modified while we iterate it.
-        final CopyOnWriteArrayList<OnGlobalLayoutListener> listeners = mOnGlobalLayoutListeners;
+        final CopyOnWriteArray<OnGlobalLayoutListener> listeners = mOnGlobalLayoutListeners;
         if (listeners != null && listeners.size() > 0) {
-            for (OnGlobalLayoutListener listener : listeners) {
-                listener.onGlobalLayout();
+            CopyOnWriteArray.Access<OnGlobalLayoutListener> access = listeners.start();
+            try {
+                int count = access.size();
+                for (int i = 0; i < count; i++) {
+                    access.get(i).onGlobalLayout();
+                }
+            } finally {
+                listeners.end();
             }
         }
     }
@@ -658,17 +669,17 @@
      */
     @SuppressWarnings("unchecked")
     public final boolean dispatchOnPreDraw() {
-        // NOTE: we *must* clone the listener list to perform the dispatching.
-        // The clone is a safe guard against listeners that
-        // could mutate the list by calling the various add/remove methods. This prevents
-        // the array from being modified while we process it.
         boolean cancelDraw = false;
-        if (mOnPreDrawListeners != null && mOnPreDrawListeners.size() > 0) {
-            final ArrayList<OnPreDrawListener> listeners =
-                    (ArrayList<OnPreDrawListener>) mOnPreDrawListeners.clone();
-            int numListeners = listeners.size();
-            for (int i = 0; i < numListeners; ++i) {
-                cancelDraw |= !(listeners.get(i).onPreDraw());
+        final CopyOnWriteArray<OnPreDrawListener> listeners = mOnPreDrawListeners;
+        if (listeners != null && listeners.size() > 0) {
+            CopyOnWriteArray.Access<OnPreDrawListener> access = listeners.start();
+            try {
+                int count = access.size();
+                for (int i = 0; i < count; i++) {
+                    cancelDraw |= !(access.get(i).onPreDraw());
+                }
+            } finally {
+                listeners.end();
             }
         }
         return cancelDraw;
@@ -693,11 +704,17 @@
      * @param inTouchMode True if the touch mode is now enabled, false otherwise.
      */
     final void dispatchOnTouchModeChanged(boolean inTouchMode) {
-        final CopyOnWriteArrayList<OnTouchModeChangeListener> listeners =
+        final CopyOnWriteArray<OnTouchModeChangeListener> listeners =
                 mOnTouchModeChangeListeners;
         if (listeners != null && listeners.size() > 0) {
-            for (OnTouchModeChangeListener listener : listeners) {
-                listener.onTouchModeChanged(inTouchMode);
+            CopyOnWriteArray.Access<OnTouchModeChangeListener> access = listeners.start();
+            try {
+                int count = access.size();
+                for (int i = 0; i < count; i++) {
+                    access.get(i).onTouchModeChanged(inTouchMode);
+                }
+            } finally {
+                listeners.end();
             }
         }
     }
@@ -710,10 +727,16 @@
         // perform the dispatching. The iterator is a safe guard against listeners that
         // could mutate the list by calling the various add/remove methods. This prevents
         // the array from being modified while we iterate it.
-        final CopyOnWriteArrayList<OnScrollChangedListener> listeners = mOnScrollChangedListeners;
+        final CopyOnWriteArray<OnScrollChangedListener> listeners = mOnScrollChangedListeners;
         if (listeners != null && listeners.size() > 0) {
-            for (OnScrollChangedListener listener : listeners) {
-                listener.onScrollChanged();
+            CopyOnWriteArray.Access<OnScrollChangedListener> access = listeners.start();
+            try {
+                int count = access.size();
+                for (int i = 0; i < count; i++) {
+                    access.get(i).onScrollChanged();
+                }
+            } finally {
+                listeners.end();
             }
         }
     }
@@ -722,11 +745,11 @@
      * Returns whether there are listeners for computing internal insets.
      */
     final boolean hasComputeInternalInsetsListeners() {
-        final CopyOnWriteArrayList<OnComputeInternalInsetsListener> listeners =
+        final CopyOnWriteArray<OnComputeInternalInsetsListener> listeners =
                 mOnComputeInternalInsetsListeners;
         return (listeners != null && listeners.size() > 0);
     }
-    
+
     /**
      * Calls all listeners to compute the current insets.
      */
@@ -735,12 +758,105 @@
         // perform the dispatching. The iterator is a safe guard against listeners that
         // could mutate the list by calling the various add/remove methods. This prevents
         // the array from being modified while we iterate it.
-        final CopyOnWriteArrayList<OnComputeInternalInsetsListener> listeners =
+        final CopyOnWriteArray<OnComputeInternalInsetsListener> listeners =
                 mOnComputeInternalInsetsListeners;
         if (listeners != null && listeners.size() > 0) {
-            for (OnComputeInternalInsetsListener listener : listeners) {
-                listener.onComputeInternalInsets(inoutInfo);
+            CopyOnWriteArray.Access<OnComputeInternalInsetsListener> access = listeners.start();
+            try {
+                int count = access.size();
+                for (int i = 0; i < count; i++) {
+                    access.get(i).onComputeInternalInsets(inoutInfo);
+                }
+            } finally {
+                listeners.end();
             }
         }
     }
+
+    /**
+     * Copy on write array. This array is not thread safe, and only one loop can
+     * iterate over this array at any given time. This class avoids allocations
+     * until a concurrent modification happens.
+     * 
+     * Usage:
+     * 
+     * CopyOnWriteArray.Access<MyData> access = array.start();
+     * try {
+     *     for (int i = 0; i < access.size(); i++) {
+     *         MyData d = access.get(i);
+     *     }
+     * } finally {
+     *     access.end();
+     * }
+     */
+    static class CopyOnWriteArray<T> {
+        private ArrayList<T> mData = new ArrayList<T>();
+        private ArrayList<T> mDataCopy;
+
+        private final Access<T> mAccess = new Access<T>();
+
+        private boolean mStart;
+
+        static class Access<T> {
+            private ArrayList<T> mData;
+            private int mSize;
+
+            T get(int index) {
+                return mData.get(index);
+            }
+
+            int size() {
+                return mSize;
+            }
+        }
+
+        CopyOnWriteArray() {
+        }
+
+        private ArrayList<T> getArray() {
+            if (mStart) {
+                if (mDataCopy == null) mDataCopy = new ArrayList<T>(mData);
+                return mDataCopy;
+            }
+            return mData;
+        }
+
+        Access<T> start() {
+            if (mStart) throw new IllegalStateException("Iteration already started");
+            mStart = true;
+            mDataCopy = null;
+            mAccess.mData = mData;
+            mAccess.mSize = mData.size();
+            return mAccess;
+        }
+
+        void end() {
+            if (!mStart) throw new IllegalStateException("Iteration not started");
+            mStart = false;
+            if (mDataCopy != null) {
+                mData = mDataCopy;
+            }
+            mDataCopy = null;
+        }
+
+        int size() {
+            return getArray().size();
+        }
+
+        void add(T item) {
+            getArray().add(item);
+        }
+
+        void addAll(CopyOnWriteArray<T> array) {
+            getArray().addAll(array.mData);
+        }
+
+        void remove(T item) {
+            getArray().remove(item);
+        }
+
+        void clear() {
+            getArray().clear();
+        }
+    }
 }
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
index e725e75..388cfb3 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -1017,7 +1017,7 @@
 
     /**
      * Called when we have finished booting and can now display the home
-     * screen to the user.  This wilWl happen after systemReady(), and at
+     * screen to the user.  This will happen after systemReady(), and at
      * this point the display is active.
      */
     public void enableScreenAfterBoot();
diff --git a/core/java/android/view/WindowOrientationListener.java b/core/java/android/view/WindowOrientationListener.java
index c28b220..4c34dd4 100755
--- a/core/java/android/view/WindowOrientationListener.java
+++ b/core/java/android/view/WindowOrientationListener.java
@@ -21,6 +21,7 @@
 import android.hardware.SensorEvent;
 import android.hardware.SensorEventListener;
 import android.hardware.SensorManager;
+import android.os.SystemProperties;
 import android.util.FloatMath;
 import android.util.Log;
 import android.util.Slog;
@@ -34,20 +35,15 @@
  * "App/Activity/Screen Orientation" to ensure that all orientation
  * modes still work correctly.
  *
- * You can also visualize the behavior of the WindowOrientationListener by
- * enabling the window orientation listener log using the Development Settings
- * in the Dev Tools application (Development.apk)
- * and running frameworks/base/tools/orientationplot/orientationplot.py.
- *
- * More information about how to tune this algorithm in
- * frameworks/base/tools/orientationplot/README.txt.
+ * You can also visualize the behavior of the WindowOrientationListener.
+ * Refer to frameworks/base/tools/orientationplot/README.txt for details.
  *
  * @hide
  */
 public abstract class WindowOrientationListener {
     private static final String TAG = "WindowOrientationListener";
-    private static final boolean DEBUG = false;
-    private static final boolean localLOGV = DEBUG || false;
+    private static final boolean LOG = SystemProperties.getBoolean(
+            "debug.orientation.log", false);
 
     private static final boolean USE_GRAVITY_SENSOR = false;
 
@@ -56,7 +52,6 @@
     private int mRate;
     private Sensor mSensor;
     private SensorEventListenerImpl mSensorEventListener;
-    boolean mLogEnabled;
     int mCurrentRotation = -1;
 
     /**
@@ -100,7 +95,9 @@
             return;
         }
         if (mEnabled == false) {
-            if (localLOGV) Log.d(TAG, "WindowOrientationListener enabled");
+            if (LOG) {
+                Log.d(TAG, "WindowOrientationListener enabled");
+            }
             mSensorManager.registerListener(mSensorEventListener, mSensor, mRate);
             mEnabled = true;
         }
@@ -115,7 +112,9 @@
             return;
         }
         if (mEnabled == true) {
-            if (localLOGV) Log.d(TAG, "WindowOrientationListener disabled");
+            if (LOG) {
+                Log.d(TAG, "WindowOrientationListener disabled");
+            }
             mSensorManager.unregisterListener(mSensorEventListener);
             mEnabled = false;
         }
@@ -165,16 +164,6 @@
     public abstract void onProposedRotationChanged(int rotation);
 
     /**
-     * Enables or disables the window orientation listener logging for use with
-     * the orientationplot.py tool.
-     * Logging is usually enabled via Development Settings.  (See class comments.)
-     * @param enable True to enable logging.
-     */
-    public void setLogEnabled(boolean enable) {
-        mLogEnabled = enable;
-    }
-
-    /**
      * This class filters the raw accelerometer data and tries to detect actual changes in
      * orientation. This is a very ill-defined problem so there are a lot of tweakable parameters,
      * but here's the outline:
@@ -238,11 +227,16 @@
         // can change.
         private static final long PROPOSAL_MIN_TIME_SINCE_FLAT_ENDED_NANOS = 500 * NANOS_PER_MS;
 
-        // The mininum amount of time that must have elapsed since the device stopped
+        // The minimum amount of time that must have elapsed since the device stopped
         // swinging (time since device appeared to be in the process of being put down
         // or put away into a pocket) before the proposed rotation can change.
         private static final long PROPOSAL_MIN_TIME_SINCE_SWING_ENDED_NANOS = 300 * NANOS_PER_MS;
 
+        // The minimum amount of time that must have elapsed since the device stopped
+        // undergoing external acceleration before the proposed rotation can change.
+        private static final long PROPOSAL_MIN_TIME_SINCE_ACCELERATION_ENDED_NANOS =
+                500 * NANOS_PER_MS;
+
         // If the tilt angle remains greater than the specified angle for a minimum of
         // the specified time, then the device is deemed to be lying flat
         // (just chillin' on a table).
@@ -300,10 +294,15 @@
         // singularities in the tilt and orientation calculations.
         //
         // In both cases, we postpone choosing an orientation.
+        //
+        // However, we need to tolerate some acceleration because the angular momentum
+        // of turning the device can skew the observed acceleration for a short period of time.
+        private static final float NEAR_ZERO_MAGNITUDE = 1; // m/s^2
+        private static final float ACCELERATION_TOLERANCE = 4; // m/s^2
         private static final float MIN_ACCELERATION_MAGNITUDE =
-                SensorManager.STANDARD_GRAVITY * 0.3f;
+                SensorManager.STANDARD_GRAVITY - ACCELERATION_TOLERANCE;
         private static final float MAX_ACCELERATION_MAGNITUDE =
-            SensorManager.STANDARD_GRAVITY * 1.25f;
+            SensorManager.STANDARD_GRAVITY + ACCELERATION_TOLERANCE;
 
         // Maximum absolute tilt angle at which to consider orientation data.  Beyond this (i.e.
         // when screen is facing the sky or ground), we completely ignore orientation data.
@@ -353,6 +352,9 @@
         // Timestamp when the device last appeared to be swinging.
         private long mSwingTimestampNanos;
 
+        // Timestamp when the device last appeared to be undergoing external acceleration.
+        private long mAccelerationTimestampNanos;
+
         // History of observed tilt angles.
         private static final int TILT_HISTORY_SIZE = 40;
         private float[] mTiltHistory = new float[TILT_HISTORY_SIZE];
@@ -374,15 +376,13 @@
 
         @Override
         public void onSensorChanged(SensorEvent event) {
-            final boolean log = mOrientationListener.mLogEnabled;
-
             // The vector given in the SensorEvent points straight up (towards the sky) under ideal
             // conditions (the phone is not accelerating).  I'll call this up vector elsewhere.
             float x = event.values[ACCELEROMETER_DATA_X];
             float y = event.values[ACCELEROMETER_DATA_Y];
             float z = event.values[ACCELEROMETER_DATA_Z];
 
-            if (log) {
+            if (LOG) {
                 Slog.v(TAG, "Raw acceleration vector: "
                         + "x=" + x + ", y=" + y + ", z=" + z
                         + ", magnitude=" + FloatMath.sqrt(x * x + y * y + z * z));
@@ -399,7 +399,7 @@
             if (now < then
                     || now > then + MAX_FILTER_DELTA_TIME_NANOS
                     || (x == 0 && y == 0 && z == 0)) {
-                if (log) {
+                if (LOG) {
                     Slog.v(TAG, "Resetting orientation listener.");
                 }
                 reset();
@@ -409,7 +409,7 @@
                 x = alpha * (x - mLastFilteredX) + mLastFilteredX;
                 y = alpha * (y - mLastFilteredY) + mLastFilteredY;
                 z = alpha * (z - mLastFilteredZ) + mLastFilteredZ;
-                if (log) {
+                if (LOG) {
                     Slog.v(TAG, "Filtered acceleration vector: "
                             + "x=" + x + ", y=" + y + ", z=" + z
                             + ", magnitude=" + FloatMath.sqrt(x * x + y * y + z * z));
@@ -421,18 +421,24 @@
             mLastFilteredY = y;
             mLastFilteredZ = z;
 
+            boolean isAccelerating = false;
             boolean isFlat = false;
             boolean isSwinging = false;
             if (!skipSample) {
                 // Calculate the magnitude of the acceleration vector.
                 final float magnitude = FloatMath.sqrt(x * x + y * y + z * z);
-                if (magnitude < MIN_ACCELERATION_MAGNITUDE
-                        || magnitude > MAX_ACCELERATION_MAGNITUDE) {
-                    if (log) {
-                        Slog.v(TAG, "Ignoring sensor data, magnitude out of range.");
+                if (magnitude < NEAR_ZERO_MAGNITUDE) {
+                    if (LOG) {
+                        Slog.v(TAG, "Ignoring sensor data, magnitude too close to zero.");
                     }
                     clearPredictedRotation();
                 } else {
+                    // Determine whether the device appears to be undergoing external acceleration.
+                    if (isAccelerating(magnitude)) {
+                        isAccelerating = true;
+                        mAccelerationTimestampNanos = now;
+                    }
+
                     // Calculate the tilt angle.
                     // This is the angle between the up vector and the x-y plane (the plane of
                     // the screen) in a range of [-90, 90] degrees.
@@ -441,6 +447,7 @@
                     //    90 degrees: screen horizontal and facing the sky (on table)
                     final int tiltAngle = (int) Math.round(
                             Math.asin(z / magnitude) * RADIANS_TO_DEGREES);
+                    addTiltHistoryEntry(now, tiltAngle);
 
                     // Determine whether the device appears to be flat or swinging.
                     if (isFlat(now)) {
@@ -451,12 +458,11 @@
                         isSwinging = true;
                         mSwingTimestampNanos = now;
                     }
-                    addTiltHistoryEntry(now, tiltAngle);
 
                     // If the tilt angle is too close to horizontal then we cannot determine
                     // the orientation angle of the screen.
                     if (Math.abs(tiltAngle) > MAX_TILT) {
-                        if (log) {
+                        if (LOG) {
                             Slog.v(TAG, "Ignoring sensor data, tilt angle too high: "
                                     + "tiltAngle=" + tiltAngle);
                         }
@@ -483,7 +489,7 @@
                                 && isOrientationAngleAcceptable(nearestRotation,
                                         orientationAngle)) {
                             updatePredictedRotation(now, nearestRotation);
-                            if (log) {
+                            if (LOG) {
                                 Slog.v(TAG, "Predicted: "
                                         + "tiltAngle=" + tiltAngle
                                         + ", orientationAngle=" + orientationAngle
@@ -493,7 +499,7 @@
                                                         * 0.000001f));
                             }
                         } else {
-                            if (log) {
+                            if (LOG) {
                                 Slog.v(TAG, "Ignoring sensor data, no predicted rotation: "
                                         + "tiltAngle=" + tiltAngle
                                         + ", orientationAngle=" + orientationAngle);
@@ -511,15 +517,18 @@
             }
 
             // Write final statistics about where we are in the orientation detection process.
-            if (log) {
+            if (LOG) {
                 Slog.v(TAG, "Result: currentRotation=" + mOrientationListener.mCurrentRotation
                         + ", proposedRotation=" + mProposedRotation
                         + ", predictedRotation=" + mPredictedRotation
                         + ", timeDeltaMS=" + timeDeltaMS
+                        + ", isAccelerating=" + isAccelerating
                         + ", isFlat=" + isFlat
                         + ", isSwinging=" + isSwinging
                         + ", timeUntilSettledMS=" + remainingMS(now,
                                 mPredictedRotationTimestampNanos + PROPOSAL_SETTLE_TIME_NANOS)
+                        + ", timeUntilAccelerationDelayExpiredMS=" + remainingMS(now,
+                                mAccelerationTimestampNanos + PROPOSAL_MIN_TIME_SINCE_ACCELERATION_ENDED_NANOS)
                         + ", timeUntilFlatDelayExpiredMS=" + remainingMS(now,
                                 mFlatTimestampNanos + PROPOSAL_MIN_TIME_SINCE_FLAT_ENDED_NANOS)
                         + ", timeUntilSwingDelayExpiredMS=" + remainingMS(now,
@@ -528,7 +537,7 @@
 
             // Tell the listener.
             if (mProposedRotation != oldProposedRotation && mProposedRotation >= 0) {
-                if (log) {
+                if (LOG) {
                     Slog.v(TAG, "Proposed rotation changed!  proposedRotation=" + mProposedRotation
                             + ", oldProposedRotation=" + oldProposedRotation);
                 }
@@ -618,6 +627,12 @@
                 return false;
             }
 
+            // The last acceleration state must have been sufficiently long ago.
+            if (now < mAccelerationTimestampNanos
+                    + PROPOSAL_MIN_TIME_SINCE_ACCELERATION_ENDED_NANOS) {
+                return false;
+            }
+
             // Looks good!
             return true;
         }
@@ -627,6 +642,7 @@
             mProposedRotation = -1;
             mFlatTimestampNanos = Long.MIN_VALUE;
             mSwingTimestampNanos = Long.MIN_VALUE;
+            mAccelerationTimestampNanos = Long.MIN_VALUE;
             clearPredictedRotation();
             clearTiltHistory();
         }
@@ -643,6 +659,11 @@
             }
         }
 
+        private boolean isAccelerating(float magnitude) {
+            return magnitude < MIN_ACCELERATION_MAGNITUDE
+                    || magnitude > MAX_ACCELERATION_MAGNITUDE;
+        }
+
         private void clearTiltHistory() {
             mTiltHistoryTimestampNanos[0] = Long.MIN_VALUE;
             mTiltHistoryIndex = 1;
diff --git a/core/java/android/view/accessibility/AccessibilityEvent.java b/core/java/android/view/accessibility/AccessibilityEvent.java
index f70ffa9..1a2a194 100644
--- a/core/java/android/view/accessibility/AccessibilityEvent.java
+++ b/core/java/android/view/accessibility/AccessibilityEvent.java
@@ -236,12 +236,19 @@
  *   <li>{@link #getClassName()} - The class name of the source.</li>
  *   <li>{@link #getPackageName()} - The package name of the source.</li>
  *   <li>{@link #getEventTime()}  - The event time.</li>
- *   <li>{@link #getText()} - The text of the current text at the movement granularity.</li>
+ *   <li>{@link #getMovementGranularity()} - Sets the granularity at which a view's text
+ *       was traversed.</li>
+ *   <li>{@link #getText()} -  The text of the source's sub-tree.</li>
+ *   <li>{@link #getFromIndex()} - The start of the next/previous text at the specified granularity
+ *           - inclusive.</li>
+ *   <li>{@link #getToIndex()} - The end of the next/previous text at the specified granularity
+ *           - exclusive.</li>
  *   <li>{@link #isPassword()} - Whether the source is password.</li>
  *   <li>{@link #isEnabled()} - Whether the source is enabled.</li>
  *   <li>{@link #getContentDescription()} - The content description of the source.</li>
  *   <li>{@link #getMovementGranularity()} - Sets the granularity at which a view's text
  *       was traversed.</li>
+ *   <li>{@link #getAction()} - Gets traversal action which specifies the direction.</li>
  * </ul>
  * </p>
  * <p>
@@ -635,6 +642,7 @@
     private CharSequence mPackageName;
     private long mEventTime;
     int mMovementGranularity;
+    int mAction;
 
     private final ArrayList<AccessibilityRecord> mRecords = new ArrayList<AccessibilityRecord>();
 
@@ -653,6 +661,7 @@
         super.init(event);
         mEventType = event.mEventType;
         mMovementGranularity = event.mMovementGranularity;
+        mAction = event.mAction;
         mEventTime = event.mEventTime;
         mPackageName = event.mPackageName;
     }
@@ -791,6 +800,27 @@
     }
 
     /**
+     * Sets the performed action that triggered this event.
+     *
+     * @param action The action.
+     *
+     * @throws IllegalStateException If called from an AccessibilityService.
+     */
+    public void setAction(int action) {
+        enforceNotSealed();
+        mAction = action;
+    }
+
+    /**
+     * Gets the performed action that triggered this event.
+     *
+     * @return The action.
+     */
+    public int getAction() {
+        return mAction;
+    }
+
+    /**
      * Returns a cached instance if such is available or a new one is
      * instantiated with its type property set.
      *
@@ -879,6 +909,7 @@
         super.clear();
         mEventType = 0;
         mMovementGranularity = 0;
+        mAction = 0;
         mPackageName = null;
         mEventTime = 0;
         while (!mRecords.isEmpty()) {
@@ -896,6 +927,7 @@
         mSealed = (parcel.readInt() == 1);
         mEventType = parcel.readInt();
         mMovementGranularity = parcel.readInt();
+        mAction = parcel.readInt();
         mPackageName = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel);
         mEventTime = parcel.readLong();
         mConnectionId = parcel.readInt();
@@ -947,6 +979,7 @@
         parcel.writeInt(isSealed() ? 1 : 0);
         parcel.writeInt(mEventType);
         parcel.writeInt(mMovementGranularity);
+        parcel.writeInt(mAction);
         TextUtils.writeToParcel(mPackageName, parcel, 0);
         parcel.writeLong(mEventTime);
         parcel.writeInt(mConnectionId);
@@ -1004,6 +1037,7 @@
         builder.append("; EventTime: ").append(mEventTime);
         builder.append("; PackageName: ").append(mPackageName);
         builder.append("; MovementGranularity: ").append(mMovementGranularity);
+        builder.append("; Action: ").append(mAction);
         builder.append(super.toString());
         if (DEBUG) {
             builder.append("\n");
diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfo.java b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
index c0696a9..6b14ba5 100644
--- a/core/java/android/view/accessibility/AccessibilityNodeInfo.java
+++ b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
@@ -102,12 +102,12 @@
     public static final int ACTION_CLEAR_SELECTION = 0x00000008;
 
     /**
-     * Action that long clicks on the node info.
+     * Action that clicks on the node info.
      */
     public static final int ACTION_CLICK = 0x00000010;
 
     /**
-     * Action that clicks on the node.
+     * Action that long clicks on the node.
      */
     public static final int ACTION_LONG_CLICK = 0x00000020;
 
@@ -287,6 +287,8 @@
 
     private static final int PROPERTY_ACCESSIBILITY_FOCUSED = 0x00000400;
 
+    private static final int PROPERTY_VISIBLE_TO_USER = 0x00000800;
+
     /**
      * Bits that provide the id of a virtual descendant of a view.
      */
@@ -910,6 +912,31 @@
     }
 
     /**
+     * Sets whether this node is visible to the user.
+     *
+     * @return Whether the node is visible to the user.
+     */
+    public boolean isVisibleToUser() {
+        return getBooleanProperty(PROPERTY_VISIBLE_TO_USER);
+    }
+
+    /**
+     * Sets whether this node is visible to the user.
+     * <p>
+     *   <strong>Note:</strong> Cannot be called from an
+     *   {@link android.accessibilityservice.AccessibilityService}.
+     *   This class is made immutable before being delivered to an AccessibilityService.
+     * </p>
+     *
+     * @param visibleToUser Whether the node is visible to the user.
+     *
+     * @throws IllegalStateException If called from an AccessibilityService.
+     */
+    public void setVisibleToUser(boolean visibleToUser) {
+        setBooleanProperty(PROPERTY_VISIBLE_TO_USER, visibleToUser);
+    }
+
+    /**
      * Gets whether this node is accessibility focused.
      *
      * @return True if the node is accessibility focused.
diff --git a/core/java/android/view/inputmethod/InputMethodSubtype.java b/core/java/android/view/inputmethod/InputMethodSubtype.java
index c22750e..b7c94a3 100644
--- a/core/java/android/view/inputmethod/InputMethodSubtype.java
+++ b/core/java/android/view/inputmethod/InputMethodSubtype.java
@@ -58,7 +58,7 @@
     private final String mSubtypeLocale;
     private final String mSubtypeMode;
     private final String mSubtypeExtraValue;
-    private HashMap<String, String> mExtraValueHashMapCache;
+    private volatile HashMap<String, String> mExtraValueHashMapCache;
 
     /**
      * Constructor.
@@ -237,18 +237,22 @@
 
     private HashMap<String, String> getExtraValueHashMap() {
         if (mExtraValueHashMapCache == null) {
-            mExtraValueHashMapCache = new HashMap<String, String>();
-            final String[] pairs = mSubtypeExtraValue.split(EXTRA_VALUE_PAIR_SEPARATOR);
-            final int N = pairs.length;
-            for (int i = 0; i < N; ++i) {
-                final String[] pair = pairs[i].split(EXTRA_VALUE_KEY_VALUE_SEPARATOR);
-                if (pair.length == 1) {
-                    mExtraValueHashMapCache.put(pair[0], null);
-                } else if (pair.length > 1) {
-                    if (pair.length > 2) {
-                        Slog.w(TAG, "ExtraValue has two or more '='s");
+            synchronized(this) {
+                if (mExtraValueHashMapCache == null) {
+                    mExtraValueHashMapCache = new HashMap<String, String>();
+                    final String[] pairs = mSubtypeExtraValue.split(EXTRA_VALUE_PAIR_SEPARATOR);
+                    final int N = pairs.length;
+                    for (int i = 0; i < N; ++i) {
+                        final String[] pair = pairs[i].split(EXTRA_VALUE_KEY_VALUE_SEPARATOR);
+                        if (pair.length == 1) {
+                            mExtraValueHashMapCache.put(pair[0], null);
+                        } else if (pair.length > 1) {
+                            if (pair.length > 2) {
+                                Slog.w(TAG, "ExtraValue has two or more '='s");
+                            }
+                            mExtraValueHashMapCache.put(pair[0], pair[1]);
+                        }
                     }
-                    mExtraValueHashMapCache.put(pair[0], pair[1]);
                 }
             }
         }
diff --git a/core/java/android/webkit/WebHistoryItem.java b/core/java/android/webkit/WebHistoryItem.java
index ccf3d6b..788d05c 100644
--- a/core/java/android/webkit/WebHistoryItem.java
+++ b/core/java/android/webkit/WebHistoryItem.java
@@ -32,12 +32,8 @@
     private static int sNextId = 0;
     // Unique identifier.
     private final int mId;
-    // The title of this item's document.
-    private String mTitle;
-    // The base url of this item.
-    private String mUrl;
-    // The original requested url of this item.
-    private String mOriginalUrl;
+    // A point to a native WebHistoryItem instance which contains the actual data
+    private int mNativeBridge;
     // The favicon for this item.
     private Bitmap mFavicon;
     // The pre-flattened data used for saving the state.
@@ -55,10 +51,19 @@
      * Basic constructor that assigns a unique id to the item. Called by JNI
      * only.
      */
-    private WebHistoryItem() {
+    private WebHistoryItem(int nativeBridge) {
         synchronized (WebHistoryItem.class) {
             mId = sNextId++;
         }
+        mNativeBridge = nativeBridge;
+        nativeRef(mNativeBridge);
+    }
+
+    protected void finalize() throws Throwable {
+        if (mNativeBridge != 0) {
+            nativeUnref(mNativeBridge);
+            mNativeBridge = 0;
+        }
     }
 
     /**
@@ -66,7 +71,6 @@
      * @param data The pre-flattened data coming from restoreState.
      */
     /*package*/ WebHistoryItem(byte[] data) {
-        mUrl = null; // This will be updated natively
         mFlattenedData = data;
         synchronized (WebHistoryItem.class) {
             mId = sNextId++;
@@ -78,12 +82,14 @@
      * @param item The history item to clone.
      */
     private WebHistoryItem(WebHistoryItem item) {
-        mUrl = item.mUrl;
-        mTitle = item.mTitle;
         mFlattenedData = item.mFlattenedData;
-        mFavicon = item.mFavicon;
         mId = item.mId;
-}
+        mFavicon = item.mFavicon;
+        mNativeBridge = item.mNativeBridge;
+        if (mNativeBridge != 0) {
+            nativeRef(mNativeBridge);
+        }
+    }
 
     /**
      * Return an identifier for this history item. If an item is a copy of
@@ -106,7 +112,8 @@
      * to synchronize this method.
      */
     public String getUrl() {
-        return mUrl;
+        if (mNativeBridge == 0) return null;
+        return nativeGetUrl(mNativeBridge);
     }
 
     /**
@@ -116,7 +123,8 @@
      * @return The original url of this history item.
      */
     public String getOriginalUrl() {
-        return mOriginalUrl;
+        if (mNativeBridge == 0) return null;
+        return nativeGetOriginalUrl(mNativeBridge);
     }
     
     /**
@@ -126,7 +134,8 @@
      * to synchronize this method.
      */
     public String getTitle() {
-        return mTitle;
+        if (mNativeBridge == 0) return null;
+        return nativeGetTitle(mNativeBridge);
     }
 
     /**
@@ -136,6 +145,9 @@
      * to synchronize this method.
      */
     public Bitmap getFavicon() {
+        if (mFavicon == null && mNativeBridge != 0) {
+            mFavicon = nativeGetFavicon(mNativeBridge);
+        }
         return mFavicon;
     }
 
@@ -156,7 +168,7 @@
         }
 
         try {
-            URL url = new URL(mOriginalUrl);
+            URL url = new URL(getOriginalUrl());
             mTouchIconUrlServerDefault = new URL(url.getProtocol(), url.getHost(), url.getPort(),
                     "/apple-touch-icon.png").toString();
         } catch (MalformedURLException e) {
@@ -214,6 +226,9 @@
      * to synchronize this method.
      */
     /*package*/ byte[] getFlattenedData() {
+        if (mNativeBridge != 0) {
+            return nativeGetFlattenedData(mNativeBridge);
+        }
         return mFlattenedData;
     }
 
@@ -223,7 +238,8 @@
      * to synchronize this method.
      */
     /*package*/ void inflate(int nativeFrame) {
-        inflate(nativeFrame, mFlattenedData);
+        mNativeBridge = inflate(nativeFrame, mFlattenedData);
+        mFlattenedData = null;
     }
 
     /**
@@ -235,15 +251,13 @@
 
     /* Natively inflate this item, this method is called in the WebCore thread.
      */
-    private native void inflate(int nativeFrame, byte[] data);
+    private native int inflate(int nativeFrame, byte[] data);
+    private native void nativeRef(int nptr);
+    private native void nativeUnref(int nptr);
+    private native String nativeGetTitle(int nptr);
+    private native String nativeGetUrl(int nptr);
+    private native String nativeGetOriginalUrl(int nptr);
+    private native byte[] nativeGetFlattenedData(int nptr);
+    private native Bitmap nativeGetFavicon(int nptr);
 
-    /* Called by jni when the item is updated */
-    private void update(String url, String originalUrl, String title, 
-            Bitmap favicon, byte[] data) {
-        mUrl = url;
-        mOriginalUrl = originalUrl;
-        mTitle = title;
-        mFavicon = favicon;
-        mFlattenedData = data;
-    }
 }
diff --git a/core/java/android/webkit/WebViewClassic.java b/core/java/android/webkit/WebViewClassic.java
index eb5f835..057c3d1 100644
--- a/core/java/android/webkit/WebViewClassic.java
+++ b/core/java/android/webkit/WebViewClassic.java
@@ -149,24 +149,6 @@
 @SuppressWarnings("deprecation")
 public final class WebViewClassic implements WebViewProvider, WebViewProvider.ScrollDelegate,
         WebViewProvider.ViewDelegate {
-    private class InnerGlobalLayoutListener implements ViewTreeObserver.OnGlobalLayoutListener {
-        @Override
-        public void onGlobalLayout() {
-            if (mWebView.isShown()) {
-                setInvScreenRect();
-            }
-        }
-    }
-
-    private class InnerScrollChangedListener implements ViewTreeObserver.OnScrollChangedListener {
-        @Override
-        public void onScrollChanged() {
-            if (mWebView.isShown()) {
-                setInvScreenRect();
-            }
-        }
-    }
-
     /**
      * InputConnection used for ContentEditable. This captures changes
      * to the text and sends them either as key strokes or text changes.
@@ -617,12 +599,6 @@
         }
     }
 
-    // The listener to capture global layout change event.
-    private InnerGlobalLayoutListener mGlobalLayoutListener = null;
-
-    // The listener to capture scroll event.
-    private InnerScrollChangedListener mScrollChangedListener = null;
-
     // if AUTO_REDRAW_HACK is true, then the CALL key will toggle redrawing
     // the screen all-the-time. Good for profiling our drawing code
     static private final boolean AUTO_REDRAW_HACK = false;
@@ -633,6 +609,10 @@
     // The presumed scroll rate for the first scroll of edit text
     static private final long TEXT_SCROLL_FIRST_SCROLL_MS = 16;
 
+    // Buffer pixels of the caret rectangle when moving edit text into view
+    // after resize.
+    static private final int EDIT_RECT_BUFFER = 10;
+
     // true means redraw the screen all-the-time. Only with AUTO_REDRAW_HACK
     private boolean mAutoRedraw;
 
@@ -647,7 +627,7 @@
     private final Rect mInvScreenRect = new Rect();
     private final Rect mScreenRect = new Rect();
     private final RectF mVisibleContentRect = new RectF();
-    private boolean mGLViewportEmpty = false;
+    private boolean mIsWebViewVisible = true;
     WebViewInputConnection mInputConnection = null;
     private int mFieldPointer;
     private PastePopupWindow mPasteWindow;
@@ -2024,11 +2004,6 @@
     }
 
     private void destroyImpl() {
-        int drawGLFunction = nativeGetDrawGLFunction(mNativeClass);
-        ViewRootImpl viewRoot = mWebView.getViewRootImpl();
-        Log.d(LOGTAG, String.format("destroyImpl, drawGLFunction %x,  viewroot == null %b, isHWAccel %b",
-                                    drawGLFunction, (viewRoot == null), mWebView.isHardwareAccelerated()));
-
         mCallbackProxy.blockMessages();
         clearHelpers();
         if (mListBoxDialog != null) {
@@ -2979,7 +2954,10 @@
             // updated when we get out of that mode.
             if (!mDrawHistory) {
                 // repin our scroll, taking into account the new content size
-                updateScrollCoordinates(pinLocX(getScrollX()), pinLocY(getScrollY()));
+                if (updateScrollCoordinates(pinLocX(getScrollX()),
+                        pinLocY(getScrollY()))) {
+                    invalidate();
+                }
                 if (!mScroller.isFinished()) {
                     // We are in the middle of a scroll.  Repin the final scroll
                     // position.
@@ -3050,21 +3028,14 @@
         r.bottom = viewToContentY(r.bottom);
     }
 
-    private Rect mContentVisibleRect = new Rect();
+    private final Rect mTempContentVisibleRect = new Rect();
     // Sets r to be our visible rectangle in content coordinates. We use this
     // method on the native side to compute the position of the fixed layers.
     // Uses floating coordinates (necessary to correctly place elements when
     // the scale factor is not 1)
     private void calcOurContentVisibleRectF(RectF r) {
-        calcOurVisibleRect(mContentVisibleRect);
-        r.left = viewToContentXf(mContentVisibleRect.left) / mWebView.getScaleX();
-        // viewToContentY will remove the total height of the title bar.  Add
-        // the visible height back in to account for the fact that if the title
-        // bar is partially visible, the part of the visible rect which is
-        // displaying our content is displaced by that amount.
-        r.top = viewToContentYf(mContentVisibleRect.top + getVisibleTitleHeightImpl()) / mWebView.getScaleY();
-        r.right = viewToContentXf(mContentVisibleRect.right) / mWebView.getScaleX();
-        r.bottom = viewToContentYf(mContentVisibleRect.bottom) / mWebView.getScaleY();
+        calcOurVisibleRect(mTempContentVisibleRect);
+        viewToContentVisibleRect(r, mTempContentVisibleRect);
     }
 
     static class ViewSizeData {
@@ -3327,7 +3298,8 @@
     }
 
     public int getPageBackgroundColor() {
-        return nativeGetBackgroundColor();
+        if (mNativeClass == 0) return Color.WHITE;
+        return nativeGetBackgroundColor(mNativeClass);
     }
 
     /**
@@ -4224,8 +4196,8 @@
 
         calcOurContentVisibleRectF(mVisibleContentRect);
         if (canvas.isHardwareAccelerated()) {
-            Rect invScreenRect = mGLViewportEmpty ? null : mInvScreenRect;
-            Rect screenRect = mGLViewportEmpty ? null : mScreenRect;
+            Rect invScreenRect = mIsWebViewVisible ? mInvScreenRect : null;
+            Rect screenRect = mIsWebViewVisible ? mScreenRect : null;
 
             int functor = nativeCreateDrawGLFunction(mNativeClass, invScreenRect,
                     screenRect, mVisibleContentRect, getScale(), extras);
@@ -4484,7 +4456,7 @@
         if (mNativeClass == 0) {
             return 0;
         }
-        return nativeGetBaseLayer();
+        return nativeGetBaseLayer(mNativeClass);
     }
 
     private void onZoomAnimationStart() {
@@ -5405,15 +5377,6 @@
     @Override
     public void onAttachedToWindow() {
         if (mWebView.hasWindowFocus()) setActive(true);
-        final ViewTreeObserver treeObserver = mWebView.getViewTreeObserver();
-        if (mGlobalLayoutListener == null) {
-            mGlobalLayoutListener = new InnerGlobalLayoutListener();
-            treeObserver.addOnGlobalLayoutListener(mGlobalLayoutListener);
-        }
-        if (mScrollChangedListener == null) {
-            mScrollChangedListener = new InnerScrollChangedListener();
-            treeObserver.addOnScrollChangedListener(mScrollChangedListener);
-        }
 
         addAccessibilityApisToJavaScript();
 
@@ -5426,24 +5389,12 @@
         mZoomManager.dismissZoomPicker();
         if (mWebView.hasWindowFocus()) setActive(false);
 
-        final ViewTreeObserver treeObserver = mWebView.getViewTreeObserver();
-        if (mGlobalLayoutListener != null) {
-            treeObserver.removeGlobalOnLayoutListener(mGlobalLayoutListener);
-            mGlobalLayoutListener = null;
-        }
-        if (mScrollChangedListener != null) {
-            treeObserver.removeOnScrollChangedListener(mScrollChangedListener);
-            mScrollChangedListener = null;
-        }
-
         removeAccessibilityApisFromJavaScript();
         updateHwAccelerated();
 
-        int drawGLFunction = nativeGetDrawGLFunction(mNativeClass);
-        ViewRootImpl viewRoot = mWebView.getViewRootImpl();
-        Log.d(LOGTAG, String.format("onDetachedFromWindow, drawGLFunction %x,  viewroot == null %b, isHWAccel %b",
-                                    drawGLFunction, (viewRoot == null), mWebView.isHardwareAccelerated()));
         if (mWebView.isHardwareAccelerated()) {
+            int drawGLFunction = nativeGetDrawGLFunction(mNativeClass);
+            ViewRootImpl viewRoot = mWebView.getViewRootImpl();
             if (drawGLFunction != 0 && viewRoot != null) {
                 viewRoot.detachFunctor(drawGLFunction);
             }
@@ -5547,11 +5498,18 @@
         }
     }
 
-    void setInvScreenRect() {
+    // updateRectsForGL() happens almost every draw call, in order to avoid creating
+    // any object in this code path, we move the local variable out to be a private
+    // final member, and we marked them as mTemp*.
+    private final Point mTempVisibleRectOffset = new Point();
+    private final Rect mTempVisibleRect = new Rect();
+
+    void updateRectsForGL() {
         // Use the getGlobalVisibleRect() to get the intersection among the parents
         // visible == false means we're clipped - send a null rect down to indicate that
         // we should not draw
-        boolean visible = mWebView.getGlobalVisibleRect(mInvScreenRect);
+        boolean visible = mWebView.getGlobalVisibleRect(mTempVisibleRect, mTempVisibleRectOffset);
+        mInvScreenRect.set(mTempVisibleRect);
         if (visible) {
             // Then need to invert the Y axis, just for GL
             View rootView = mWebView.getRootView();
@@ -5560,16 +5518,33 @@
             int savedWebViewBottom = mInvScreenRect.bottom;
             mInvScreenRect.bottom = rootViewHeight - mInvScreenRect.top - getVisibleTitleHeightImpl();
             mInvScreenRect.top = rootViewHeight - savedWebViewBottom;
-            mGLViewportEmpty = false;
+            mIsWebViewVisible = true;
         } else {
-            mGLViewportEmpty = true;
+            mIsWebViewVisible = false;
         }
-        calcOurContentVisibleRectF(mVisibleContentRect);
-        nativeUpdateDrawGLFunction(mNativeClass, mGLViewportEmpty ? null : mInvScreenRect,
-                mGLViewportEmpty ? null : mScreenRect,
+
+        mTempVisibleRect.offset(-mTempVisibleRectOffset.x, -mTempVisibleRectOffset.y);
+        viewToContentVisibleRect(mVisibleContentRect, mTempVisibleRect);
+
+        nativeUpdateDrawGLFunction(mNativeClass, mIsWebViewVisible ? mInvScreenRect : null,
+                mIsWebViewVisible ? mScreenRect : null,
                 mVisibleContentRect, getScale());
     }
 
+    // Input : viewRect, rect in view/screen coordinate.
+    // Output: contentRect, rect in content/document coordinate.
+    private void viewToContentVisibleRect(RectF contentRect, Rect viewRect) {
+        contentRect.left = viewToContentXf(viewRect.left) / mWebView.getScaleX();
+        // viewToContentY will remove the total height of the title bar.  Add
+        // the visible height back in to account for the fact that if the title
+        // bar is partially visible, the part of the visible rect which is
+        // displaying our content is displaced by that amount.
+        contentRect.top = viewToContentYf(viewRect.top + getVisibleTitleHeightImpl())
+                / mWebView.getScaleY();
+        contentRect.right = viewToContentXf(viewRect.right) / mWebView.getScaleX();
+        contentRect.bottom = viewToContentYf(viewRect.bottom) / mWebView.getScaleY();
+    }
+
     @Override
     public boolean setFrame(int left, int top, int right, int bottom) {
         boolean changed = mWebViewPrivate.super_setFrame(left, top, right, bottom);
@@ -5582,7 +5557,7 @@
             // notify the WebKit about the new dimensions.
             sendViewSizeZoom(false);
         }
-        setInvScreenRect();
+        updateRectsForGL();
         return changed;
     }
 
@@ -5604,9 +5579,76 @@
             // However, do not update the base layer as that hasn't changed
             setNewPicture(mLoadedPicture, false);
         }
+        if (mIsEditingText) {
+            scrollEditIntoView();
+        }
         relocateAutoCompletePopup();
     }
 
+    /**
+     * Scrolls the edit field into view using the minimum scrolling necessary.
+     * If the edit field is too large to fit in the visible window, the caret
+     * dimensions are used so that at least the caret is visible.
+     * A buffer of EDIT_RECT_BUFFER in view pixels is used to offset the
+     * edit rectangle to ensure a margin with the edge of the screen.
+     */
+    private void scrollEditIntoView() {
+        Rect visibleRect = new Rect(viewToContentX(getScrollX()),
+                viewToContentY(getScrollY()),
+                viewToContentX(getScrollX() + getWidth()),
+                viewToContentY(getScrollY() + getViewHeightWithTitle()));
+        if (visibleRect.contains(mEditTextContentBounds)) {
+            return; // no need to scroll
+        }
+        syncSelectionCursors();
+        final int buffer = Math.max(1, viewToContentDimension(EDIT_RECT_BUFFER));
+        Rect showRect = new Rect(
+                Math.max(0, mEditTextContentBounds.left - buffer),
+                Math.max(0, mEditTextContentBounds.top - buffer),
+                mEditTextContentBounds.right + buffer,
+                mEditTextContentBounds.bottom + buffer);
+        Point caretTop = calculateCaretTop();
+        if (visibleRect.width() < mEditTextContentBounds.width()) {
+            // The whole edit won't fit in the width, so use the caret rect
+            if (mSelectCursorBase.x < caretTop.x) {
+                showRect.left = Math.max(0, mSelectCursorBase.x - buffer);
+                showRect.right = caretTop.x + buffer;
+            } else {
+                showRect.left = Math.max(0, caretTop.x - buffer);
+                showRect.right = mSelectCursorBase.x + buffer;
+            }
+        }
+        if (visibleRect.height() < mEditTextContentBounds.height()) {
+            // The whole edit won't fit in the height, so use the caret rect
+            if (mSelectCursorBase.y > caretTop.y) {
+                showRect.top = Math.max(0, caretTop.y - buffer);
+                showRect.bottom = mSelectCursorBase.y + buffer;
+            } else {
+                showRect.top = Math.max(0, mSelectCursorBase.y - buffer);
+                showRect.bottom = caretTop.y + buffer;
+            }
+        }
+
+        if (visibleRect.contains(showRect)) {
+            return; // no need to scroll
+        }
+
+        int scrollX = visibleRect.left;
+        if (visibleRect.left > showRect.left) {
+            scrollX = showRect.left;
+        } else if (visibleRect.right < showRect.right) {
+            scrollX = Math.max(0, showRect.right - visibleRect.width());
+        }
+        int scrollY = visibleRect.top;
+        if (visibleRect.top > showRect.top) {
+            scrollY = showRect.top;
+        } else if (visibleRect.bottom < showRect.bottom) {
+            scrollY = Math.max(0, showRect.bottom - visibleRect.height());
+        }
+
+        contentScrollTo(scrollX, scrollY, false);
+    }
+
     @Override
     public void onScrollChanged(int l, int t, int oldl, int oldt) {
         if (!mInOverScrollMode) {
@@ -8616,7 +8658,7 @@
     private native void     nativeSetHeightCanMeasure(boolean measure);
     private native boolean  nativeSetBaseLayer(int nativeInstance,
             int layer, boolean showVisualIndicator, boolean isPictureAfterFirstLayout);
-    private native int      nativeGetBaseLayer();
+    private native int      nativeGetBaseLayer(int nativeInstance);
     private native void     nativeCopyBaseContentToPicture(Picture pict);
     private native boolean  nativeHasContent();
     private native void     nativeStopGL();
@@ -8644,7 +8686,7 @@
      */
     private native boolean  nativeScrollLayer(int nativeInstance, int layer, int newX, int newY);
     private native void     nativeSetIsScrolling(boolean isScrolling);
-    private native int      nativeGetBackgroundColor();
+    private native int      nativeGetBackgroundColor(int nativeInstance);
     native boolean  nativeSetProperty(String key, String value);
     native String   nativeGetProperty(String key);
     /**
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 449870e..3aafba5 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -25,6 +25,7 @@
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
 import android.graphics.drawable.TransitionDrawable;
+import android.os.Bundle;
 import android.os.Debug;
 import android.os.Handler;
 import android.os.Parcel;
@@ -57,6 +58,7 @@
 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.animation.Interpolator;
 import android.view.animation.LinearInterpolator;
@@ -648,6 +650,11 @@
     private int mGlowPaddingLeft;
     private int mGlowPaddingRight;
 
+    /**
+     * Used for interacting with list items from an accessibility service.
+     */
+    private ListItemAccessibilityDelegate mAccessibilityDelegate;
+
     private int mLastAccessibilityScrollEventFromIndex;
     private int mLastAccessibilityScrollEventToIndex;
 
@@ -2121,9 +2128,77 @@
             child.setLayoutParams(lp);
         }
 
+        if (AccessibilityManager.getInstance(mContext).isEnabled()) {
+            if (mAccessibilityDelegate == null) {
+                mAccessibilityDelegate = new ListItemAccessibilityDelegate();
+            }
+            child.setAccessibilityDelegate(mAccessibilityDelegate);
+        }
+
         return child;
     }
 
+    class ListItemAccessibilityDelegate extends AccessibilityDelegate {
+        @Override
+        public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) {
+            super.onInitializeAccessibilityNodeInfo(host, info);
+
+            final int position = getPositionForView(host);
+
+            if (position == INVALID_POSITION) {
+                return;
+            }
+
+            if (isClickable()) {
+                info.addAction(AccessibilityNodeInfo.ACTION_CLICK);
+                info.setClickable(true);
+            }
+
+            if (isLongClickable()) {
+                info.addAction(AccessibilityNodeInfo.ACTION_LONG_CLICK);
+                info.setLongClickable(true);
+            }
+
+            info.addAction(AccessibilityNodeInfo.ACTION_SELECT);
+
+            if (position == getSelectedItemPosition()) {
+                info.setSelected(true);
+            }
+        }
+
+        @Override
+        public boolean performAccessibilityAction(View host, int action, Bundle arguments) {
+            final int position = getPositionForView(host);
+
+            if (position == INVALID_POSITION) {
+                return false;
+            }
+
+            final long id = getItemIdAtPosition(position);
+
+            switch (action) {
+                case AccessibilityNodeInfo.ACTION_SELECT:
+                    setSelection(position);
+                    return true;
+                case AccessibilityNodeInfo.ACTION_CLICK:
+                    if (!super.performAccessibilityAction(host, action, arguments)) {
+                        return performItemClick(host, position, id);
+                    }
+                    return true;
+                case AccessibilityNodeInfo.ACTION_LONG_CLICK:
+                    if (!super.performAccessibilityAction(host, action, arguments)) {
+                        return performLongPress(host, position, id);
+                    }
+                    return true;
+                case AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS:
+                    smoothScrollToPosition(position);
+                    break;
+            }
+
+            return super.performAccessibilityAction(host, action, arguments);
+        }
+    }
+
     void positionSelector(int position, View sel) {
         if (position != INVALID_POSITION) {
             mSelectorPosition = position;
@@ -3985,7 +4060,7 @@
     }
 
     class PositionScroller implements Runnable {
-        private static final int SCROLL_DURATION = 400;
+        private static final int SCROLL_DURATION = 200;
 
         private static final int MOVE_DOWN_POS = 1;
         private static final int MOVE_UP_POS = 2;
@@ -4006,21 +4081,37 @@
             mExtraScroll = ViewConfiguration.get(mContext).getScaledFadingEdgeLength();
         }
 
-        void start(int position) {
+        void start(final int position) {
             stop();
 
+            if (mDataChanged) {
+                // Wait until we're back in a stable state to try this.
+                post(new Runnable() {
+                    @Override public void run() {
+                        start(position);
+                    }
+                });
+                return;
+            }
+
+            final int childCount = getChildCount();
+            if (childCount == 0) {
+                // Can't scroll without children.
+                return;
+            }
+
             final int firstPos = mFirstPosition;
-            final int lastPos = firstPos + getChildCount() - 1;
+            final int lastPos = firstPos + childCount - 1;
 
             int viewTravelCount;
-            if (position <= firstPos) {
+            if (position < firstPos) {
                 viewTravelCount = firstPos - position + 1;
                 mMode = MOVE_UP_POS;
-            } else if (position >= lastPos) {
+            } else if (position > lastPos) {
                 viewTravelCount = position - lastPos + 1;
                 mMode = MOVE_DOWN_POS;
             } else {
-                // Already on screen, nothing to do
+                scrollToVisible(position, INVALID_POSITION, SCROLL_DURATION);
                 return;
             }
 
@@ -4036,7 +4127,7 @@
             postOnAnimation(this);
         }
 
-        void start(int position, int boundPosition) {
+        void start(final int position, final int boundPosition) {
             stop();
 
             if (boundPosition == INVALID_POSITION) {
@@ -4044,11 +4135,27 @@
                 return;
             }
 
+            if (mDataChanged) {
+                // Wait until we're back in a stable state to try this.
+                post(new Runnable() {
+                    @Override public void run() {
+                        start(position, boundPosition);
+                    }
+                });
+                return;
+            }
+
+            final int childCount = getChildCount();
+            if (childCount == 0) {
+                // Can't scroll without children.
+                return;
+            }
+
             final int firstPos = mFirstPosition;
-            final int lastPos = firstPos + getChildCount() - 1;
+            final int lastPos = firstPos + childCount - 1;
 
             int viewTravelCount;
-            if (position <= firstPos) {
+            if (position < firstPos) {
                 final int boundPosFromLast = lastPos - boundPosition;
                 if (boundPosFromLast < 1) {
                     // Moving would shift our bound position off the screen. Abort.
@@ -4064,7 +4171,7 @@
                     viewTravelCount = posTravel;
                     mMode = MOVE_UP_POS;
                 }
-            } else if (position >= lastPos) {
+            } else if (position > lastPos) {
                 final int boundPosFromFirst = boundPosition - firstPos;
                 if (boundPosFromFirst < 1) {
                     // Moving would shift our bound position off the screen. Abort.
@@ -4081,7 +4188,7 @@
                     mMode = MOVE_DOWN_POS;
                 }
             } else {
-                // Already on screen, nothing to do
+                scrollToVisible(position, boundPosition, SCROLL_DURATION);
                 return;
             }
 
@@ -4101,9 +4208,26 @@
             startWithOffset(position, offset, SCROLL_DURATION);
         }
 
-        void startWithOffset(int position, int offset, int duration) {
+        void startWithOffset(final int position, int offset, final int duration) {
             stop();
 
+            if (mDataChanged) {
+                // Wait until we're back in a stable state to try this.
+                final int postOffset = offset;
+                post(new Runnable() {
+                    @Override public void run() {
+                        startWithOffset(position, postOffset, duration);
+                    }
+                });
+                return;
+            }
+
+            final int childCount = getChildCount();
+            if (childCount == 0) {
+                // Can't scroll without children.
+                return;
+            }
+
             offset += getPaddingTop();
 
             mTargetPos = position;
@@ -4113,7 +4237,6 @@
             mMode = MOVE_OFFSET;
 
             final int firstPos = mFirstPosition;
-            final int childCount = getChildCount();
             final int lastPos = firstPos + childCount - 1;
 
             int viewTravelCount;
@@ -4137,6 +4260,60 @@
             postOnAnimation(this);
         }
 
+        /**
+         * Scroll such that targetPos is in the visible padded region without scrolling
+         * boundPos out of view. Assumes targetPos is onscreen.
+         */
+        void scrollToVisible(int targetPos, int boundPos, int duration) {
+            final int firstPos = mFirstPosition;
+            final int childCount = getChildCount();
+            final int lastPos = firstPos + childCount - 1;
+            final int paddedTop = mListPadding.top;
+            final int paddedBottom = getHeight() - mListPadding.bottom;
+
+            if (targetPos < firstPos || targetPos > lastPos) {
+                Log.w(TAG, "scrollToVisible called with targetPos " + targetPos +
+                        " not visible [" + firstPos + ", " + lastPos + "]");
+            }
+            if (boundPos < firstPos || boundPos > lastPos) {
+                // boundPos doesn't matter, it's already offscreen.
+                boundPos = INVALID_POSITION;
+            }
+
+            final View targetChild = getChildAt(targetPos - firstPos);
+            final int targetTop = targetChild.getTop();
+            final int targetBottom = targetChild.getBottom();
+            int scrollBy = 0;
+
+            if (targetBottom > paddedBottom) {
+                scrollBy = targetBottom - paddedBottom;
+            }
+            if (targetTop < paddedTop) {
+                scrollBy = targetTop - paddedTop;
+            }
+
+            if (scrollBy == 0) {
+                return;
+            }
+
+            if (boundPos >= 0) {
+                final View boundChild = getChildAt(boundPos - firstPos);
+                final int boundTop = boundChild.getTop();
+                final int boundBottom = boundChild.getBottom();
+                final int absScroll = Math.abs(scrollBy);
+
+                if (scrollBy < 0 && boundBottom + absScroll > paddedBottom) {
+                    // Don't scroll the bound view off the bottom of the screen.
+                    scrollBy = Math.max(0, boundBottom - paddedBottom);
+                } else if (scrollBy > 0 && boundTop - absScroll < paddedTop) {
+                    // Don't scroll the bound view off the top of the screen.
+                    scrollBy = Math.min(0, boundTop - paddedTop);
+                }
+            }
+
+            smoothScrollBy(scrollBy, duration);
+        }
+
         void stop() {
             removeCallbacks(this);
         }
@@ -4432,7 +4609,7 @@
 
         if (distance == 0 || mItemCount == 0 || childCount == 0 ||
                 (firstPos == 0 && getChildAt(0).getTop() == topLimit && distance < 0) ||
-                (lastPos == mItemCount - 1 &&
+                (lastPos == mItemCount &&
                         getChildAt(childCount - 1).getBottom() == bottomLimit && distance > 0)) {
             mFlingRunnable.endFling();
             if (mPositionScroller != null) {
@@ -5569,6 +5746,7 @@
             // Don't reclaim header or footer views, or views that should be ignored
             if (lp != null && mRecycler.shouldRecycleViewType(lp.viewType)) {
                 views.add(child);
+                child.setAccessibilityDelegate(null);
                 if (listener != null) {
                     // Pretend they went through the scrap heap
                     listener.onMovedToScrapHeap(child);
@@ -6124,6 +6302,7 @@
                 mScrapViews[viewType].add(scrap);
             }
 
+            scrap.setAccessibilityDelegate(null);
             if (mRecyclerListener != null) {
                 mRecyclerListener.onMovedToScrapHeap(scrap);
             }
@@ -6185,6 +6364,7 @@
                     lp.scrappedFromPosition = mFirstActivePosition + i;
                     scrapViews.add(victim);
 
+                    victim.setAccessibilityDelegate(null);
                     if (hasListener) {
                         mRecyclerListener.onMovedToScrapHeap(victim);
                     }
@@ -6217,6 +6397,16 @@
                     removeDetachedView(scrapPile.remove(size--), false);
                 }
             }
+
+            if (mTransientStateViews != null) {
+                for (int i = 0; i < mTransientStateViews.size(); i++) {
+                    final View v = mTransientStateViews.valueAt(i);
+                    if (!v.hasTransientState()) {
+                        mTransientStateViews.removeAt(i);
+                        i--;
+                    }
+                }
+            }
         }
 
         /**
diff --git a/core/java/android/widget/AccessibilityIterators.java b/core/java/android/widget/AccessibilityIterators.java
new file mode 100644
index 0000000..e800e8df
--- /dev/null
+++ b/core/java/android/widget/AccessibilityIterators.java
@@ -0,0 +1,219 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.widget;
+
+import android.graphics.Rect;
+import android.text.Layout;
+import android.text.Spannable;
+import android.view.AccessibilityIterators.AbstractTextSegmentIterator;
+
+/**
+ * This class contains the implementation of text segment iterators
+ * for accessibility support.
+ */
+final class AccessibilityIterators {
+
+    static class LineTextSegmentIterator extends AbstractTextSegmentIterator {
+        private static LineTextSegmentIterator sLineInstance;
+
+        protected static final int DIRECTION_START = -1;
+        protected static final int DIRECTION_END = 1;
+
+        protected Layout mLayout;
+
+        public static LineTextSegmentIterator getInstance() {
+            if (sLineInstance == null) {
+                sLineInstance = new LineTextSegmentIterator();
+            }
+            return sLineInstance;
+        }
+
+        public void initialize(Spannable text, Layout layout) {
+            mText = text.toString();
+            mLayout = layout;
+        }
+
+        @Override
+        public int[] following(int offset) {
+            final int textLegth = mText.length();
+            if (textLegth <= 0) {
+                return null;
+            }
+            if (offset >= mText.length()) {
+                return null;
+            }
+            int nextLine = -1;
+            if (offset < 0) {
+                nextLine = mLayout.getLineForOffset(0);
+            } else {
+                final int currentLine = mLayout.getLineForOffset(offset);
+                if (currentLine < mLayout.getLineCount() - 1) {
+                    nextLine = currentLine + 1;
+                }
+            }
+            if (nextLine < 0) {
+                return null;
+            }
+            final int start = getLineEdgeIndex(nextLine, DIRECTION_START);
+            final int end = getLineEdgeIndex(nextLine, DIRECTION_END) + 1;
+            return getRange(start, end);
+        }
+
+        @Override
+        public int[] preceding(int offset) {
+            final int textLegth = mText.length();
+            if (textLegth <= 0) {
+                return null;
+            }
+            if (offset <= 0) {
+                return null;
+            }
+            int previousLine = -1;
+            if (offset > mText.length()) {
+                previousLine = mLayout.getLineForOffset(mText.length());
+            } else {
+                final int currentLine = mLayout.getLineForOffset(offset - 1);
+                if (currentLine > 0) {
+                    previousLine = currentLine - 1;
+                }
+            }
+            if (previousLine < 0) {
+                return null;
+            }
+            final int start = getLineEdgeIndex(previousLine, DIRECTION_START);
+            final int end = getLineEdgeIndex(previousLine, DIRECTION_END) + 1;
+            return getRange(start, end);
+        }
+
+        protected int getLineEdgeIndex(int lineNumber, int direction) {
+            final int paragraphDirection = mLayout.getParagraphDirection(lineNumber);
+            if (direction * paragraphDirection < 0) {
+                return mLayout.getLineStart(lineNumber);
+            } else {
+                return mLayout.getLineEnd(lineNumber) - 1;
+            }
+        }
+    }
+
+    static class PageTextSegmentIterator extends LineTextSegmentIterator {
+        private static PageTextSegmentIterator sPageInstance;
+
+        private TextView mView;
+
+        private final Rect mTempRect = new Rect();
+
+        public static PageTextSegmentIterator getInstance() {
+            if (sPageInstance == null) {
+                sPageInstance = new PageTextSegmentIterator();
+            }
+            return sPageInstance;
+        }
+
+        public void initialize(TextView view) {
+            super.initialize((Spannable) view.getIterableTextForAccessibility(), view.getLayout());
+            mView = view;
+        }
+
+        @Override
+        public int[] following(int offset) {
+            final int textLegth = mText.length();
+            if (textLegth <= 0) {
+                return null;
+            }
+            if (offset >= mText.length()) {
+                return null;
+            }
+            if (!mView.getGlobalVisibleRect(mTempRect)) {
+                return null;
+            }
+
+            final int currentLine = mLayout.getLineForOffset(offset);
+            final int currentLineTop = mLayout.getLineTop(currentLine);
+            final int pageHeight = mTempRect.height() - mView.getTotalPaddingTop()
+                    - mView.getTotalPaddingBottom();
+
+            final int nextPageStartLine;
+            final int nextPageEndLine;
+            if (offset < 0) {
+                nextPageStartLine = currentLine;
+                final int nextPageEndY = currentLineTop + pageHeight;
+                nextPageEndLine = mLayout.getLineForVertical(nextPageEndY);
+            } else {
+                final int nextPageStartY = currentLineTop + pageHeight;
+                nextPageStartLine = mLayout.getLineForVertical(nextPageStartY) + 1;
+                if (mLayout.getLineTop(nextPageStartLine) <= nextPageStartY) {
+                    return null;
+                }
+                final int nextPageEndY = nextPageStartY + pageHeight;
+                nextPageEndLine = mLayout.getLineForVertical(nextPageEndY);
+            }
+
+            final int start = getLineEdgeIndex(nextPageStartLine, DIRECTION_START);
+            final int end = getLineEdgeIndex(nextPageEndLine, DIRECTION_END) + 1;
+
+            return getRange(start, end);
+        }
+
+        @Override
+        public int[] preceding(int offset) {
+            final int textLegth = mText.length();
+            if (textLegth <= 0) {
+                return null;
+            }
+            if (offset <= 0) {
+                return null;
+            }
+            if (!mView.getGlobalVisibleRect(mTempRect)) {
+                return null;
+            }
+
+            final int currentLine = mLayout.getLineForOffset(offset);
+            final int currentLineTop = mLayout.getLineTop(currentLine);
+            final int pageHeight = mTempRect.height() - mView.getTotalPaddingTop()
+                    - mView.getTotalPaddingBottom();
+
+            final int previousPageStartLine;
+            final int previousPageEndLine;
+            if (offset > mText.length()) {
+                final int prevousPageStartY = mLayout.getHeight() - pageHeight;
+                if (prevousPageStartY < 0) {
+                    return null;
+                }
+                previousPageStartLine = mLayout.getLineForVertical(prevousPageStartY);
+                previousPageEndLine = mLayout.getLineCount() - 1;
+            } else {
+                final int prevousPageStartY;
+                if (offset == mText.length()) {
+                    prevousPageStartY = mLayout.getHeight() - 2 * pageHeight;
+                } else {
+                    prevousPageStartY = currentLineTop - 2 * pageHeight;
+                }
+                if (prevousPageStartY < 0) {
+                    return null;
+                }
+                previousPageStartLine = mLayout.getLineForVertical(prevousPageStartY);
+                final int previousPageEndY = prevousPageStartY + pageHeight;
+                previousPageEndLine = mLayout.getLineForVertical(previousPageEndY) - 1;
+            }
+
+            final int start = getLineEdgeIndex(previousPageStartLine, DIRECTION_START);
+            final int end = getLineEdgeIndex(previousPageEndLine, DIRECTION_END) + 1;
+
+            return getRange(start, end);
+        }
+    }
+}
diff --git a/core/java/android/widget/ActivityChooserModel.java b/core/java/android/widget/ActivityChooserModel.java
index fba8d3a..c6104bc 100644
--- a/core/java/android/widget/ActivityChooserModel.java
+++ b/core/java/android/widget/ActivityChooserModel.java
@@ -23,7 +23,6 @@
 import android.database.DataSetObservable;
 import android.database.DataSetObserver;
 import android.os.AsyncTask;
-import android.os.Handler;
 import android.text.TextUtils;
 import android.util.Log;
 import android.util.Xml;
@@ -42,10 +41,8 @@
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
-import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Map;
-import java.util.Set;
 
 /**
  * <p>
@@ -239,7 +236,7 @@
     /**
      * List of activities that can handle the current intent.
      */
-    private final List<ActivityResolveInfo> mActivites = new ArrayList<ActivityResolveInfo>();
+    private final List<ActivityResolveInfo> mActivities = new ArrayList<ActivityResolveInfo>();
 
     /**
      * List with historical choice records.
@@ -278,18 +275,18 @@
 
     /**
      * Flag whether choice history can be read. In general many clients can
-     * share the same data model and {@link #readHistoricalData()} may be called
+     * share the same data model and {@link #readHistoricalDataIfNeeded()} may be called
      * by arbitrary of them any number of times. Therefore, this class guarantees
      * that the very first read succeeds and subsequent reads can be performed
-     * only after a call to {@link #persistHistoricalData()} followed by change
+     * only after a call to {@link #persistHistoricalDataIfNeeded()} followed by change
      * of the share records.
      */
     private boolean mCanReadHistoricalData = true;
 
     /**
      * Flag whether the choice history was read. This is used to enforce that
-     * before calling {@link #persistHistoricalData()} a call to
-     * {@link #persistHistoricalData()} has been made. This aims to avoid a
+     * before calling {@link #persistHistoricalDataIfNeeded()} a call to
+     * {@link #persistHistoricalDataIfNeeded()} has been made. This aims to avoid a
      * scenario in which a choice history file exits, it is not read yet and
      * it is overwritten. Note that always all historical records are read in
      * full and the file is rewritten. This is necessary since we need to
@@ -299,16 +296,16 @@
 
     /**
      * Flag whether the choice records have changed. In general many clients can
-     * share the same data model and {@link #persistHistoricalData()} may be called
+     * share the same data model and {@link #persistHistoricalDataIfNeeded()} may be called
      * by arbitrary of them any number of times. Therefore, this class guarantees
      * that choice history will be persisted only if it has changed.
      */
     private boolean mHistoricalRecordsChanged = true;
 
     /**
-     * Hander for scheduling work on client tread.
+     * Flag whether to reload the activities for the current intent.
      */
-    private final Handler mHandler = new Handler();
+    private boolean mReloadActivities = false;
 
     /**
      * Policy for controlling how the model handles chosen activities.
@@ -346,7 +343,6 @@
                 dataModel = new ActivityChooserModel(context, historyFileName);
                 sDataModelRegistry.put(historyFileName, dataModel);
             }
-            dataModel.readHistoricalData();
             return dataModel;
         }
     }
@@ -383,7 +379,8 @@
                 return;
             }
             mIntent = intent;
-            loadActivitiesLocked();
+            mReloadActivities = true;
+            ensureConsistentState();
         }
     }
 
@@ -407,7 +404,8 @@
      */
     public int getActivityCount() {
         synchronized (mInstanceLock) {
-            return mActivites.size();
+            ensureConsistentState();
+            return mActivities.size();
         }
     }
 
@@ -421,7 +419,8 @@
      */
     public ResolveInfo getActivity(int index) {
         synchronized (mInstanceLock) {
-            return mActivites.get(index).resolveInfo;
+            ensureConsistentState();
+            return mActivities.get(index).resolveInfo;
         }
     }
 
@@ -433,15 +432,18 @@
      * @return The index if found, -1 otherwise.
      */
     public int getActivityIndex(ResolveInfo activity) {
-        List<ActivityResolveInfo> activities = mActivites;
-        final int activityCount = activities.size();
-        for (int i = 0; i < activityCount; i++) {
-            ActivityResolveInfo currentActivity = activities.get(i);
-            if (currentActivity.resolveInfo == activity) {
-                return i;
+        synchronized (mInstanceLock) {
+            ensureConsistentState();
+            List<ActivityResolveInfo> activities = mActivities;
+            final int activityCount = activities.size();
+            for (int i = 0; i < activityCount; i++) {
+                ActivityResolveInfo currentActivity = activities.get(i);
+                if (currentActivity.resolveInfo == activity) {
+                    return i;
+                }
             }
+            return INVALID_INDEX;
         }
-        return INVALID_INDEX;
     }
 
     /**
@@ -462,30 +464,34 @@
      * @see OnChooseActivityListener
      */
     public Intent chooseActivity(int index) {
-        ActivityResolveInfo chosenActivity = mActivites.get(index);
+        synchronized (mInstanceLock) {
+            ensureConsistentState();
 
-        ComponentName chosenName = new ComponentName(
-                chosenActivity.resolveInfo.activityInfo.packageName,
-                chosenActivity.resolveInfo.activityInfo.name);
+            ActivityResolveInfo chosenActivity = mActivities.get(index);
 
-        Intent choiceIntent = new Intent(mIntent);
-        choiceIntent.setComponent(chosenName);
+            ComponentName chosenName = new ComponentName(
+                    chosenActivity.resolveInfo.activityInfo.packageName,
+                    chosenActivity.resolveInfo.activityInfo.name);
 
-        if (mActivityChoserModelPolicy != null) {
-            // Do not allow the policy to change the intent.
-            Intent choiceIntentCopy = new Intent(choiceIntent);
-            final boolean handled = mActivityChoserModelPolicy.onChooseActivity(this,
-                    choiceIntentCopy);
-            if (handled) {
-                return null;
+            Intent choiceIntent = new Intent(mIntent);
+            choiceIntent.setComponent(chosenName);
+
+            if (mActivityChoserModelPolicy != null) {
+                // Do not allow the policy to change the intent.
+                Intent choiceIntentCopy = new Intent(choiceIntent);
+                final boolean handled = mActivityChoserModelPolicy.onChooseActivity(this,
+                        choiceIntentCopy);
+                if (handled) {
+                    return null;
+                }
             }
+
+            HistoricalRecord historicalRecord = new HistoricalRecord(chosenName,
+                    System.currentTimeMillis(), DEFAULT_HISTORICAL_RECORD_WEIGHT);
+            addHisoricalRecord(historicalRecord);
+
+            return choiceIntent;
         }
-
-        HistoricalRecord historicalRecord = new HistoricalRecord(chosenName,
-                System.currentTimeMillis(), DEFAULT_HISTORICAL_RECORD_WEIGHT);
-        addHisoricalRecord(historicalRecord);
-
-        return choiceIntent;
     }
 
     /**
@@ -494,7 +500,9 @@
      * @param listener The listener.
      */
     public void setOnChooseActivityListener(OnChooseActivityListener listener) {
-        mActivityChoserModelPolicy = listener;
+        synchronized (mInstanceLock) {
+            mActivityChoserModelPolicy = listener;
+        }
     }
 
     /**
@@ -508,8 +516,9 @@
      */
     public ResolveInfo getDefaultActivity() {
         synchronized (mInstanceLock) {
-            if (!mActivites.isEmpty()) {
-                return mActivites.get(0).resolveInfo;
+            ensureConsistentState();
+            if (!mActivities.isEmpty()) {
+                return mActivities.get(0).resolveInfo;
             }
         }
         return null;
@@ -526,72 +535,50 @@
      * @param index The index of the activity to set as default.
      */
     public void setDefaultActivity(int index) {
-        ActivityResolveInfo newDefaultActivity = mActivites.get(index);
-        ActivityResolveInfo oldDefaultActivity = mActivites.get(0);
-
-        final float weight;
-        if (oldDefaultActivity != null) {
-            // Add a record with weight enough to boost the chosen at the top.
-            weight = oldDefaultActivity.weight - newDefaultActivity.weight
-                + DEFAULT_ACTIVITY_INFLATION;
-        } else {
-            weight = DEFAULT_HISTORICAL_RECORD_WEIGHT;
-        }
-
-        ComponentName defaultName = new ComponentName(
-                newDefaultActivity.resolveInfo.activityInfo.packageName,
-                newDefaultActivity.resolveInfo.activityInfo.name);
-        HistoricalRecord historicalRecord = new HistoricalRecord(defaultName,
-                System.currentTimeMillis(), weight);
-        addHisoricalRecord(historicalRecord);
-    }
-
-    /**
-     * Reads the history data from the backing file if the latter
-     * was provided. Calling this method more than once before a call
-     * to {@link #persistHistoricalData()} has been made has no effect.
-     * <p>
-     * <strong>Note:</strong> Historical data is read asynchronously and
-     *       as soon as the reading is completed any registered
-     *       {@link DataSetObserver}s will be notified. Also no historical
-     *       data is read until this method is invoked.
-     * <p>
-     */
-    private void readHistoricalData() {
         synchronized (mInstanceLock) {
-            if (!mCanReadHistoricalData || !mHistoricalRecordsChanged) {
-                return;
+            ensureConsistentState();
+
+            ActivityResolveInfo newDefaultActivity = mActivities.get(index);
+            ActivityResolveInfo oldDefaultActivity = mActivities.get(0);
+
+            final float weight;
+            if (oldDefaultActivity != null) {
+                // Add a record with weight enough to boost the chosen at the top.
+                weight = oldDefaultActivity.weight - newDefaultActivity.weight
+                    + DEFAULT_ACTIVITY_INFLATION;
+            } else {
+                weight = DEFAULT_HISTORICAL_RECORD_WEIGHT;
             }
-            mCanReadHistoricalData = false;
-            mReadShareHistoryCalled = true;
-            if (!TextUtils.isEmpty(mHistoryFileName)) {
-                AsyncTask.SERIAL_EXECUTOR.execute(new HistoryLoader());
-            }
+
+            ComponentName defaultName = new ComponentName(
+                    newDefaultActivity.resolveInfo.activityInfo.packageName,
+                    newDefaultActivity.resolveInfo.activityInfo.name);
+            HistoricalRecord historicalRecord = new HistoricalRecord(defaultName,
+                    System.currentTimeMillis(), weight);
+            addHisoricalRecord(historicalRecord);
         }
     }
 
     /**
      * Persists the history data to the backing file if the latter
-     * was provided. Calling this method before a call to {@link #readHistoricalData()}
+     * was provided. Calling this method before a call to {@link #readHistoricalDataIfNeeded()}
      * throws an exception. Calling this method more than one without choosing an
      * activity has not effect.
      *
      * @throws IllegalStateException If this method is called before a call to
-     *         {@link #readHistoricalData()}.
+     *         {@link #readHistoricalDataIfNeeded()}.
      */
-    private void persistHistoricalData() {
-        synchronized (mInstanceLock) {
-            if (!mReadShareHistoryCalled) {
-                throw new IllegalStateException("No preceding call to #readHistoricalData");
-            }
-            if (!mHistoricalRecordsChanged) {
-                return;
-            }
-            mHistoricalRecordsChanged = false;
-            mCanReadHistoricalData = true;
-            if (!TextUtils.isEmpty(mHistoryFileName)) {
-                AsyncTask.SERIAL_EXECUTOR.execute(new HistoryPersister());
-            }
+    private void persistHistoricalDataIfNeeded() {
+        if (!mReadShareHistoryCalled) {
+            throw new IllegalStateException("No preceding call to #readHistoricalData");
+        }
+        if (!mHistoricalRecordsChanged) {
+            return;
+        }
+        mHistoricalRecordsChanged = false;
+        if (!TextUtils.isEmpty(mHistoryFileName)) {
+            new PersistHistoryAsyncTask().executeOnExecutor(AsyncTask.SERIAL_EXECUTOR,
+                    new ArrayList<HistoricalRecord>(mHistoricalRecords), mHistoryFileName);
         }
     }
 
@@ -608,21 +595,7 @@
                 return;
             }
             mActivitySorter = activitySorter;
-            sortActivities();
-        }
-    }
-
-    /**
-     * Sorts the activities based on history and an intent. If
-     * a sorter is not specified this a default implementation is used.
-     *
-     * @see #setActivitySorter(ActivitySorter)
-     */
-    private void sortActivities() {
-        synchronized (mInstanceLock) {
-            if (mActivitySorter != null && !mActivites.isEmpty()) {
-                mActivitySorter.sort(mIntent, mActivites,
-                        Collections.unmodifiableList(mHistoricalRecords));
+            if (sortActivitiesIfNeeded()) {
                 notifyChanged();
             }
         }
@@ -647,8 +620,10 @@
                 return;
             }
             mHistoryMaxSize = historyMaxSize;
-            pruneExcessiveHistoricalRecordsLocked();
-            sortActivities();
+            pruneExcessiveHistoricalRecordsIfNeeded();
+            if (sortActivitiesIfNeeded()) {
+                notifyChanged();
+            }
         }
     }
 
@@ -670,6 +645,7 @@
      */
     public int getHistorySize() {
         synchronized (mInstanceLock) {
+            ensureConsistentState();
             return mHistoricalRecords.size();
         }
     }
@@ -681,36 +657,107 @@
     }
 
     /**
+     * Ensures the model is in a consistent state which is the
+     * activities for the current intent have been loaded, the
+     * most recent history has been read, and the activities
+     * are sorted.
+     */
+    private void ensureConsistentState() {
+        boolean stateChanged = loadActivitiesIfNeeded();
+        stateChanged |= readHistoricalDataIfNeeded();
+        pruneExcessiveHistoricalRecordsIfNeeded();
+        if (stateChanged) {
+            sortActivitiesIfNeeded();
+            notifyChanged();
+        }
+    }
+
+    /**
+     * Sorts the activities if necessary which is if there is a
+     * sorter, there are some activities to sort, and there is some
+     * historical data.
+     *
+     * @return Whether sorting was performed.
+     */
+    private boolean sortActivitiesIfNeeded() {
+        if (mActivitySorter != null && mIntent != null
+                && !mActivities.isEmpty() && !mHistoricalRecords.isEmpty()) {
+            mActivitySorter.sort(mIntent, mActivities,
+                    Collections.unmodifiableList(mHistoricalRecords));
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Loads the activities for the current intent if needed which is
+     * if they are not already loaded for the current intent.
+     *
+     * @return Whether loading was performed.
+     */
+    private boolean loadActivitiesIfNeeded() {
+        if (mReloadActivities && mIntent != null) {
+            mReloadActivities = false;
+            mActivities.clear();
+            List<ResolveInfo> resolveInfos = mContext.getPackageManager()
+                    .queryIntentActivities(mIntent, 0);
+            final int resolveInfoCount = resolveInfos.size();
+            for (int i = 0; i < resolveInfoCount; i++) {
+                ResolveInfo resolveInfo = resolveInfos.get(i);
+                mActivities.add(new ActivityResolveInfo(resolveInfo));
+            }
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Reads the historical data if necessary which is it has
+     * changed, there is a history file, and there is not persist
+     * in progress.
+     *
+     * @return Whether reading was performed.
+     */
+    private boolean readHistoricalDataIfNeeded() {
+        if (mCanReadHistoricalData && mHistoricalRecordsChanged &&
+                !TextUtils.isEmpty(mHistoryFileName)) {
+            mCanReadHistoricalData = false;
+            mReadShareHistoryCalled = true;
+            readHistoricalDataImpl();
+            return true;
+        }
+        return false;
+    }
+
+    /**
      * Adds a historical record.
      *
      * @param historicalRecord The record to add.
      * @return True if the record was added.
      */
     private boolean addHisoricalRecord(HistoricalRecord historicalRecord) {
-        synchronized (mInstanceLock) {
-            final boolean added = mHistoricalRecords.add(historicalRecord);
-            if (added) {
-                mHistoricalRecordsChanged = true;
-                pruneExcessiveHistoricalRecordsLocked();
-                persistHistoricalData();
-                sortActivities();
-            }
-            return added;
+        final boolean added = mHistoricalRecords.add(historicalRecord);
+        if (added) {
+            mHistoricalRecordsChanged = true;
+            pruneExcessiveHistoricalRecordsIfNeeded();
+            persistHistoricalDataIfNeeded();
+            sortActivitiesIfNeeded();
+            notifyChanged();
         }
+        return added;
     }
 
     /**
-     * Prunes older excessive records to guarantee {@link #mHistoryMaxSize}.
+     * Prunes older excessive records to guarantee maxHistorySize.
      */
-    private void pruneExcessiveHistoricalRecordsLocked() {
-        List<HistoricalRecord> choiceRecords = mHistoricalRecords;
-        final int pruneCount = choiceRecords.size() - mHistoryMaxSize;
+    private void pruneExcessiveHistoricalRecordsIfNeeded() {
+        final int pruneCount = mHistoricalRecords.size() - mHistoryMaxSize;
         if (pruneCount <= 0) {
             return;
         }
         mHistoricalRecordsChanged = true;
         for (int i = 0; i < pruneCount; i++) {
-            HistoricalRecord prunedRecord = choiceRecords.remove(0);
+            HistoricalRecord prunedRecord = mHistoricalRecords.remove(0);
             if (DEBUG) {
                 Log.i(LOG_TAG, "Pruned: " + prunedRecord);
             }
@@ -718,49 +765,6 @@
     }
 
     /**
-     * Loads the activities.
-     */
-    private void loadActivitiesLocked() {
-        mActivites.clear();
-        if (mIntent != null) {
-            List<ResolveInfo> resolveInfos =
-                mContext.getPackageManager().queryIntentActivities(mIntent, 0);
-            final int resolveInfoCount = resolveInfos.size();
-            for (int i = 0; i < resolveInfoCount; i++) {
-                ResolveInfo resolveInfo = resolveInfos.get(i);
-                mActivites.add(new ActivityResolveInfo(resolveInfo));
-            }
-            sortActivities();
-        } else {
-            notifyChanged();
-        }
-    }
-
-    /**
-     * Prunes historical records for a package that goes away.
-     *
-     * @param packageName The name of the package that goes away.
-     */
-    private void pruneHistoricalRecordsForPackageLocked(String packageName) {
-        boolean recordsRemoved = false;
-
-        List<HistoricalRecord> historicalRecords = mHistoricalRecords;
-        for (int i = 0; i < historicalRecords.size(); i++) {
-            HistoricalRecord historicalRecord = historicalRecords.get(i);
-            String recordPackageName = historicalRecord.activity.getPackageName();
-            if (recordPackageName.equals(packageName)) {
-                historicalRecords.remove(historicalRecord);
-                recordsRemoved = true;
-            }
-        }
-
-        if (recordsRemoved) {
-            mHistoricalRecordsChanged = true;
-            sortActivities();
-        }
-    }
-
-    /**
      * Gets whether the given observer is already registered.
      *
      * @param observer The observer.
@@ -974,112 +978,72 @@
     /**
      * Command for reading the historical records from a file off the UI thread.
      */
-    private final class HistoryLoader implements Runnable {
-
-       public void run() {
-            FileInputStream fis = null;
-            try {
-                fis = mContext.openFileInput(mHistoryFileName);
-            } catch (FileNotFoundException fnfe) {
-                if (DEBUG) {
-                    Log.i(LOG_TAG, "Could not open historical records file: " + mHistoryFileName);
-                }
-                return;
+    private void readHistoricalDataImpl() {
+        FileInputStream fis = null;
+        try {
+            fis = mContext.openFileInput(mHistoryFileName);
+        } catch (FileNotFoundException fnfe) {
+            if (DEBUG) {
+                Log.i(LOG_TAG, "Could not open historical records file: " + mHistoryFileName);
             }
-            try {
-                XmlPullParser parser = Xml.newPullParser();
-                parser.setInput(fis, null);
+            return;
+        }
+        try {
+            XmlPullParser parser = Xml.newPullParser();
+            parser.setInput(fis, null);
 
-                int type = XmlPullParser.START_DOCUMENT;
-                while (type != XmlPullParser.END_DOCUMENT && type != XmlPullParser.START_TAG) {
-                    type = parser.next();
+            int type = XmlPullParser.START_DOCUMENT;
+            while (type != XmlPullParser.END_DOCUMENT && type != XmlPullParser.START_TAG) {
+                type = parser.next();
+            }
+
+            if (!TAG_HISTORICAL_RECORDS.equals(parser.getName())) {
+                throw new XmlPullParserException("Share records file does not start with "
+                        + TAG_HISTORICAL_RECORDS + " tag.");
+            }
+
+            List<HistoricalRecord> historicalRecords = mHistoricalRecords;
+            historicalRecords.clear();
+
+            while (true) {
+                type = parser.next();
+                if (type == XmlPullParser.END_DOCUMENT) {
+                    break;
+                }
+                if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
+                    continue;
+                }
+                String nodeName = parser.getName();
+                if (!TAG_HISTORICAL_RECORD.equals(nodeName)) {
+                    throw new XmlPullParserException("Share records file not well-formed.");
                 }
 
-                if (!TAG_HISTORICAL_RECORDS.equals(parser.getName())) {
-                    throw new XmlPullParserException("Share records file does not start with "
-                            + TAG_HISTORICAL_RECORDS + " tag.");
-                }
-
-                List<HistoricalRecord> readRecords = new ArrayList<HistoricalRecord>();
-
-                while (true) {
-                    type = parser.next();
-                    if (type == XmlPullParser.END_DOCUMENT) {
-                        break;
-                    }
-                    if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
-                        continue;
-                    }
-                    String nodeName = parser.getName();
-                    if (!TAG_HISTORICAL_RECORD.equals(nodeName)) {
-                        throw new XmlPullParserException("Share records file not well-formed.");
-                    }
-
-                    String activity = parser.getAttributeValue(null, ATTRIBUTE_ACTIVITY);
-                    final long time =
-                        Long.parseLong(parser.getAttributeValue(null, ATTRIBUTE_TIME));
-                    final float weight =
-                        Float.parseFloat(parser.getAttributeValue(null, ATTRIBUTE_WEIGHT));
-
-                    HistoricalRecord readRecord = new HistoricalRecord(activity, time,
-                            weight);
-                    readRecords.add(readRecord);
-
-                    if (DEBUG) {
-                        Log.i(LOG_TAG, "Read " + readRecord.toString());
-                    }
-                }
+                String activity = parser.getAttributeValue(null, ATTRIBUTE_ACTIVITY);
+                final long time =
+                    Long.parseLong(parser.getAttributeValue(null, ATTRIBUTE_TIME));
+                final float weight =
+                    Float.parseFloat(parser.getAttributeValue(null, ATTRIBUTE_WEIGHT));
+                 HistoricalRecord readRecord = new HistoricalRecord(activity, time, weight);
+                historicalRecords.add(readRecord);
 
                 if (DEBUG) {
-                    Log.i(LOG_TAG, "Read " + readRecords.size() + " historical records.");
+                    Log.i(LOG_TAG, "Read " + readRecord.toString());
                 }
+            }
 
-                synchronized (mInstanceLock) {
-                    Set<HistoricalRecord> uniqueShareRecords =
-                        new LinkedHashSet<HistoricalRecord>(readRecords);
-
-                    // Make sure no duplicates. Example: Read a file with
-                    // one record, add one record, persist the two records,
-                    // add a record, read the persisted records - the
-                    // read two records should not be added again.
-                    List<HistoricalRecord> historicalRecords = mHistoricalRecords;
-                    final int historicalRecordsCount = historicalRecords.size();
-                    for (int i = historicalRecordsCount - 1; i >= 0; i--) {
-                        HistoricalRecord historicalRecord = historicalRecords.get(i);
-                        uniqueShareRecords.add(historicalRecord);
-                    }
-
-                    if (historicalRecords.size() == uniqueShareRecords.size()) {
-                        return;
-                    }
-
-                    // Make sure the oldest records go to the end.
-                    historicalRecords.clear();
-                    historicalRecords.addAll(uniqueShareRecords);
-
-                    mHistoricalRecordsChanged = true;
-
-                    // Do this on the client thread since the client may be on the UI
-                    // thread, wait for data changes which happen during sorting, and
-                    // perform UI modification based on the data change.
-                    mHandler.post(new Runnable() {
-                        public void run() {
-                            pruneExcessiveHistoricalRecordsLocked();
-                            sortActivities();
-                        }
-                    });
-                }
-            } catch (XmlPullParserException xppe) {
-                Log.e(LOG_TAG, "Error reading historical recrod file: " + mHistoryFileName, xppe);
-            } catch (IOException ioe) {
-                Log.e(LOG_TAG, "Error reading historical recrod file: " + mHistoryFileName, ioe);
-            } finally {
-                if (fis != null) {
-                    try {
-                        fis.close();
-                    } catch (IOException ioe) {
-                        /* ignore */
-                    }
+            if (DEBUG) {
+                Log.i(LOG_TAG, "Read " + historicalRecords.size() + " historical records.");
+            }
+        } catch (XmlPullParserException xppe) {
+            Log.e(LOG_TAG, "Error reading historical recrod file: " + mHistoryFileName, xppe);
+        } catch (IOException ioe) {
+            Log.e(LOG_TAG, "Error reading historical recrod file: " + mHistoryFileName, ioe);
+        } finally {
+            if (fis != null) {
+                try {
+                    fis.close();
+                } catch (IOException ioe) {
+                    /* ignore */
                 }
             }
         }
@@ -1088,21 +1052,21 @@
     /**
      * Command for persisting the historical records to a file off the UI thread.
      */
-    private final class HistoryPersister implements Runnable {
+    private final class PersistHistoryAsyncTask extends AsyncTask<Object, Void, Void> {
 
-        public void run() {
+        @Override
+        @SuppressWarnings("unchecked")
+        public Void doInBackground(Object... args) {
+            List<HistoricalRecord> historicalRecords = (List<HistoricalRecord>) args[0];
+            String hostoryFileName = (String) args[1];
+
             FileOutputStream fos = null;
-            List<HistoricalRecord> records = null;
-
-            synchronized (mInstanceLock) {
-                records = new ArrayList<HistoricalRecord>(mHistoricalRecords);
-            }
 
             try {
-                fos = mContext.openFileOutput(mHistoryFileName, Context.MODE_PRIVATE);
+                fos = mContext.openFileOutput(hostoryFileName, Context.MODE_PRIVATE);
             } catch (FileNotFoundException fnfe) {
-                Log.e(LOG_TAG, "Error writing historical recrod file: " + mHistoryFileName, fnfe);
-                return;
+                Log.e(LOG_TAG, "Error writing historical recrod file: " + hostoryFileName, fnfe);
+                return null;
             }
 
             XmlSerializer serializer = Xml.newSerializer();
@@ -1112,11 +1076,12 @@
                 serializer.startDocument("UTF-8", true);
                 serializer.startTag(null, TAG_HISTORICAL_RECORDS);
 
-                final int recordCount = records.size();
+                final int recordCount = historicalRecords.size();
                 for (int i = 0; i < recordCount; i++) {
-                    HistoricalRecord record = records.remove(0);
+                    HistoricalRecord record = historicalRecords.remove(0);
                     serializer.startTag(null, TAG_HISTORICAL_RECORD);
-                    serializer.attribute(null, ATTRIBUTE_ACTIVITY, record.activity.flattenToString());
+                    serializer.attribute(null, ATTRIBUTE_ACTIVITY,
+                            record.activity.flattenToString());
                     serializer.attribute(null, ATTRIBUTE_TIME, String.valueOf(record.time));
                     serializer.attribute(null, ATTRIBUTE_WEIGHT, String.valueOf(record.weight));
                     serializer.endTag(null, TAG_HISTORICAL_RECORD);
@@ -1138,6 +1103,7 @@
             } catch (IOException ioe) {
                 Log.e(LOG_TAG, "Error writing historical recrod file: " + mHistoryFileName, ioe);
             } finally {
+                mCanReadHistoricalData = true;
                 if (fos != null) {
                     try {
                         fos.close();
@@ -1146,6 +1112,7 @@
                     }
                 }
             }
+            return null;
         }
     }
 
@@ -1155,33 +1122,8 @@
     private final class DataModelPackageMonitor extends PackageMonitor {
 
         @Override
-        public void onPackageAdded(String packageName, int uid) {
-            synchronized (mInstanceLock) {
-                loadActivitiesLocked();
-            }
-        }
-
-        @Override
-        public void onPackageAppeared(String packageName, int reason) {
-            synchronized (mInstanceLock) {
-                loadActivitiesLocked();
-            }
-        }
-
-        @Override
-        public void onPackageRemoved(String packageName, int uid) {
-            synchronized (mInstanceLock) {
-                pruneHistoricalRecordsForPackageLocked(packageName);
-                loadActivitiesLocked();
-            }
-        }
-
-        @Override
-        public void onPackageDisappeared(String packageName, int reason) {
-            synchronized (mInstanceLock) {
-                pruneHistoricalRecordsForPackageLocked(packageName);
-                loadActivitiesLocked();
-            }
+        public void onSomePackagesChanged() {
+            mReloadActivities = true;
         }
     }
 }
diff --git a/core/java/android/widget/ShareActionProvider.java b/core/java/android/widget/ShareActionProvider.java
index 367561e..21840ca 100644
--- a/core/java/android/widget/ShareActionProvider.java
+++ b/core/java/android/widget/ShareActionProvider.java
@@ -240,12 +240,25 @@
      * <p>
      * <strong>Note:</strong> The history file name can be set any time, however
      * only the action views created by {@link #onCreateActionView()} after setting
-     * the file name will be backed by the provided file. Hence, if you are using
-     * a share action provider on a menu item and want to change the history file
-     * based on the type of the currently selected item, you need to call
-     * {@link android.app.Activity#invalidateOptionsMenu()} to force the system
-     * to recreate the menu UI.
+     * the file name will be backed by the provided file. Therefore, if you want to
+     * use different history files for sharing specific types of content, every time
+     * you change the history file {@link #setShareHistoryFileName(String)} you must
+     * call {@link android.app.Activity#invalidateOptionsMenu()} to recreate the
+     * action view. You should <strong>not</strong> call
+     * {@link android.app.Activity#invalidateOptionsMenu()} from
+     * {@link android.app.Activity#onCreateOptionsMenu(Menu)}.
      * <p>
+     * <code>
+     * private void doShare(Intent intent) {
+     *     if (IMAGE.equals(intent.getMimeType())) {
+     *         mShareActionProvider.setHistoryFileName(SHARE_IMAGE_HISTORY_FILE_NAME);
+     *     } else if (TEXT.equals(intent.getMimeType())) {
+     *         mShareActionProvider.setHistoryFileName(SHARE_TEXT_HISTORY_FILE_NAME);
+     *     }
+     *     mShareActionProvider.setIntent(intent);
+     *     invalidateOptionsMenu();
+     * }
+     * <code>
      *
      * @param shareHistoryFile The share history file name.
      */
diff --git a/core/java/android/widget/SpellChecker.java b/core/java/android/widget/SpellChecker.java
index e1103dd..ebf8a4a 100644
--- a/core/java/android/widget/SpellChecker.java
+++ b/core/java/android/widget/SpellChecker.java
@@ -427,12 +427,6 @@
         if (spellCheckSpanStart < 0 || spellCheckSpanEnd <= spellCheckSpanStart)
             return; // span was removed in the meantime
 
-        final int suggestionsCount = suggestionsInfo.getSuggestionsCount();
-        if (suggestionsCount <= 0) {
-            // A negative suggestion count is possible
-            return;
-        }
-
         final int start;
         final int end;
         if (offset != USE_SPAN_RANGE && length != USE_SPAN_RANGE) {
@@ -443,9 +437,15 @@
             end = spellCheckSpanEnd;
         }
 
-        String[] suggestions = new String[suggestionsCount];
-        for (int i = 0; i < suggestionsCount; i++) {
-            suggestions[i] = suggestionsInfo.getSuggestionAt(i);
+        final int suggestionsCount = suggestionsInfo.getSuggestionsCount();
+        String[] suggestions;
+        if (suggestionsCount > 0) {
+            suggestions = new String[suggestionsCount];
+            for (int i = 0; i < suggestionsCount; i++) {
+                suggestions[i] = suggestionsInfo.getSuggestionAt(i);
+            }
+        } else {
+            suggestions = ArrayUtils.emptyArray(String.class);
         }
 
         SuggestionSpan suggestionSpan = new SuggestionSpan(mTextView.getContext(), suggestions,
@@ -453,7 +453,7 @@
         // TODO: Remove mIsSentenceSpellCheckSupported by extracting an interface
         // to share the logic of word level spell checker and sentence level spell checker
         if (mIsSentenceSpellCheckSupported) {
-            final long key = TextUtils.packRangeInLong(start, end);
+            final Long key = Long.valueOf(TextUtils.packRangeInLong(start, end));
             final SuggestionSpan tempSuggestionSpan = mSuggestionSpanCache.get(key);
             if (tempSuggestionSpan != null) {
                 if (DBG) {
@@ -611,6 +611,9 @@
                     if (spellCheckEnd < start) {
                         break;
                     }
+                    if (spellCheckEnd <= spellCheckStart) {
+                        break;
+                    }
                     if (createSpellCheckSpan) {
                         addSpellCheckSpan(editable, spellCheckStart, spellCheckEnd);
                     }
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index ba814d3..dadae78 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -26,7 +26,6 @@
 import android.content.res.TypedArray;
 import android.content.res.XmlResourceParser;
 import android.graphics.Canvas;
-import android.graphics.Color;
 import android.graphics.Paint;
 import android.graphics.Path;
 import android.graphics.Rect;
@@ -91,6 +90,7 @@
 import android.util.FloatMath;
 import android.util.Log;
 import android.util.TypedValue;
+import android.view.AccessibilityIterators.TextSegmentIterator;
 import android.view.ActionMode;
 import android.view.DragEvent;
 import android.view.Gravity;
@@ -397,7 +397,7 @@
 
     /**
      * EditText specific data, created on demand when one of the Editor fields is used.
-     * See {@link #createEditorIfNeeded(String)}.
+     * See {@link #createEditorIfNeeded()}.
      */
     private Editor mEditor;
 
@@ -798,20 +798,20 @@
                 break;
 
             case com.android.internal.R.styleable.TextView_imeOptions:
-                createEditorIfNeeded("IME options specified in constructor");
+                createEditorIfNeeded();
                 mEditor.createInputContentTypeIfNeeded();
                 mEditor.mInputContentType.imeOptions = a.getInt(attr,
                         mEditor.mInputContentType.imeOptions);
                 break;
 
             case com.android.internal.R.styleable.TextView_imeActionLabel:
-                createEditorIfNeeded("IME action label specified in constructor");
+                createEditorIfNeeded();
                 mEditor.createInputContentTypeIfNeeded();
                 mEditor.mInputContentType.imeActionLabel = a.getText(attr);
                 break;
 
             case com.android.internal.R.styleable.TextView_imeActionId:
-                createEditorIfNeeded("IME action id specified in constructor");
+                createEditorIfNeeded();
                 mEditor.createInputContentTypeIfNeeded();
                 mEditor.mInputContentType.imeActionId = a.getInt(attr,
                         mEditor.mInputContentType.imeActionId);
@@ -883,7 +883,7 @@
             }
 
             try {
-                createEditorIfNeeded("inputMethod in ctor");
+                createEditorIfNeeded();
                 mEditor.mKeyListener = (KeyListener) c.newInstance();
             } catch (InstantiationException ex) {
                 throw new RuntimeException(ex);
@@ -898,7 +898,7 @@
                 mEditor.mInputType = EditorInfo.TYPE_CLASS_TEXT;
             }
         } else if (digits != null) {
-            createEditorIfNeeded("digits in ctor");
+            createEditorIfNeeded();
             mEditor.mKeyListener = DigitsKeyListener.getInstance(digits.toString());
             // If no input type was specified, we will default to generic
             // text, since we can't tell the IME about the set of digits
@@ -910,11 +910,11 @@
             // If set, the input type overrides what was set using the deprecated singleLine flag.
             singleLine = !isMultilineInputType(inputType);
         } else if (phone) {
-            createEditorIfNeeded("dialer in ctor");
+            createEditorIfNeeded();
             mEditor.mKeyListener = DialerKeyListener.getInstance();
             mEditor.mInputType = inputType = EditorInfo.TYPE_CLASS_PHONE;
         } else if (numeric != 0) {
-            createEditorIfNeeded("numeric in ctor");
+            createEditorIfNeeded();
             mEditor.mKeyListener = DigitsKeyListener.getInstance((numeric & SIGNED) != 0,
                                                    (numeric & DECIMAL) != 0);
             inputType = EditorInfo.TYPE_CLASS_NUMBER;
@@ -951,7 +951,7 @@
                 break;
             }
 
-            createEditorIfNeeded("text input in ctor");
+            createEditorIfNeeded();
             mEditor.mKeyListener = TextKeyListener.getInstance(autotext, cap);
             mEditor.mInputType = inputType;
         } else if (isTextSelectable()) {
@@ -964,7 +964,7 @@
             // So that selection can be changed using arrow keys and touch is handled.
             setMovementMethod(ArrowKeyMovementMethod.getInstance());
         } else if (editable) {
-            createEditorIfNeeded("editable input in ctor");
+            createEditorIfNeeded();
             mEditor.mKeyListener = TextKeyListener.getInstance();
             mEditor.mInputType = EditorInfo.TYPE_CLASS_TEXT;
         } else {
@@ -987,7 +987,7 @@
                 webPasswordInputType, numberPasswordInputType);
 
         if (selectallonfocus) {
-            createEditorIfNeeded("selectallonfocus in constructor");
+            createEditorIfNeeded();
             mEditor.mSelectAllOnFocus = true;
 
             if (bufferType == BufferType.NORMAL)
@@ -1335,7 +1335,7 @@
         fixFocusableAndClickableSettings();
 
         if (input != null) {
-            createEditorIfNeeded("input is not null");
+            createEditorIfNeeded();
             try {
                 mEditor.mInputType = mEditor.mKeyListener.getInputType();
             } catch (IncompatibleClassChangeError e) {
@@ -1355,7 +1355,7 @@
     private void setKeyListenerOnly(KeyListener input) {
         if (mEditor == null && input == null) return; // null is the default value
 
-        createEditorIfNeeded("setKeyListenerOnly");
+        createEditorIfNeeded();
         if (mEditor.mKeyListener != input) {
             mEditor.mKeyListener = input;
             if (input != null && !(mText instanceof Editable)) {
@@ -2375,7 +2375,7 @@
      */
     @android.view.RemotableViewMethod
     public final void setShowSoftInputOnFocus(boolean show) {
-        createEditorIfNeeded("setShowSoftInputOnFocus");
+        createEditorIfNeeded();
         mEditor.mShowSoftInputOnFocus = show;
     }
 
@@ -3255,7 +3255,7 @@
                     Selection.setSelection((Spannable) mText, ss.selStart, ss.selEnd);
 
                     if (ss.frozenWithFocus) {
-                        createEditorIfNeeded("restore instance with focus");
+                        createEditorIfNeeded();
                         mEditor.mFrozenWithFocus = true;
                     }
                 }
@@ -3416,7 +3416,7 @@
 
         if (type == BufferType.EDITABLE || getKeyListener() != null ||
                 needEditableForNotification) {
-            createEditorIfNeeded("setText with BufferType.EDITABLE or non null mInput");
+            createEditorIfNeeded();
             Editable t = mEditableFactory.newEditable(text);
             text = t;
             setFilters(t, mFilters);
@@ -3760,7 +3760,7 @@
      */
     public void setRawInputType(int type) {
         if (type == InputType.TYPE_NULL && mEditor == null) return; //TYPE_NULL is the default value
-        createEditorIfNeeded("non null input type");
+        createEditorIfNeeded();
         mEditor.mInputType = type;
     }
 
@@ -3803,7 +3803,7 @@
         }
         setRawInputType(type);
         if (direct) {
-            createEditorIfNeeded("setInputType");
+            createEditorIfNeeded();
             mEditor.mKeyListener = input;
         } else {
             setKeyListenerOnly(input);
@@ -3829,7 +3829,7 @@
      * @attr ref android.R.styleable#TextView_imeOptions
      */
     public void setImeOptions(int imeOptions) {
-        createEditorIfNeeded("IME options specified");
+        createEditorIfNeeded();
         mEditor.createInputContentTypeIfNeeded();
         mEditor.mInputContentType.imeOptions = imeOptions;
     }
@@ -3856,7 +3856,7 @@
      * @attr ref android.R.styleable#TextView_imeActionId
      */
     public void setImeActionLabel(CharSequence label, int actionId) {
-        createEditorIfNeeded("IME action label specified");
+        createEditorIfNeeded();
         mEditor.createInputContentTypeIfNeeded();
         mEditor.mInputContentType.imeActionLabel = label;
         mEditor.mInputContentType.imeActionId = actionId;
@@ -3893,7 +3893,7 @@
      * modifier will, however, allow the user to insert a newline character.
      */
     public void setOnEditorActionListener(OnEditorActionListener l) {
-        createEditorIfNeeded("Editor action listener set");
+        createEditorIfNeeded();
         mEditor.createInputContentTypeIfNeeded();
         mEditor.mInputContentType.onEditorActionListener = l;
     }
@@ -3990,7 +3990,7 @@
      * @attr ref android.R.styleable#TextView_privateImeOptions
      */
     public void setPrivateImeOptions(String type) {
-        createEditorIfNeeded("Private IME option set");
+        createEditorIfNeeded();
         mEditor.createInputContentTypeIfNeeded();
         mEditor.mInputContentType.privateImeOptions = type;
     }
@@ -4018,7 +4018,7 @@
      * @attr ref android.R.styleable#TextView_editorExtras
      */
     public void setInputExtras(int xmlResId) throws XmlPullParserException, IOException {
-        createEditorIfNeeded("Input extra set");
+        createEditorIfNeeded();
         XmlResourceParser parser = getResources().getXml(xmlResId);
         mEditor.createInputContentTypeIfNeeded();
         mEditor.mInputContentType.extras = new Bundle();
@@ -4037,7 +4037,7 @@
      */
     public Bundle getInputExtras(boolean create) {
         if (mEditor == null && !create) return null;
-        createEditorIfNeeded("get Input extra");
+        createEditorIfNeeded();
         if (mEditor.mInputContentType == null) {
             if (!create) return null;
             mEditor.createInputContentTypeIfNeeded();
@@ -4089,7 +4089,7 @@
      * be cleared (and you should provide a <code>null</code> icon as well).
      */
     public void setError(CharSequence error, Drawable icon) {
-        createEditorIfNeeded("setError");
+        createEditorIfNeeded();
         mEditor.setError(error, icon);
     }
 
@@ -4598,7 +4598,7 @@
     public void setTextIsSelectable(boolean selectable) {
         if (!selectable && mEditor == null) return; // false is default value with no edit data
 
-        createEditorIfNeeded("setTextIsSelectable");
+        createEditorIfNeeded();
         if (mEditor.mTextIsSelectable == selectable) return;
 
         mEditor.mTextIsSelectable = selectable;
@@ -5411,7 +5411,7 @@
      * @return Returns true if the text was successfully extracted, else false.
      */
     public boolean extractText(ExtractedTextRequest request, ExtractedText outText) {
-        createEditorIfNeeded("extractText");
+        createEditorIfNeeded();
         return mEditor.extractText(request, outText);
     }
 
@@ -6825,7 +6825,7 @@
      */
     @android.view.RemotableViewMethod
     public void setSelectAllOnFocus(boolean selectAllOnFocus) {
-        createEditorIfNeeded("setSelectAllOnFocus");
+        createEditorIfNeeded();
         mEditor.mSelectAllOnFocus = selectAllOnFocus;
 
         if (selectAllOnFocus && !(mText instanceof Spannable)) {
@@ -6844,7 +6844,7 @@
     @android.view.RemotableViewMethod
     public void setCursorVisible(boolean visible) {
         if (visible && mEditor == null) return; // visible is the default value with no edit data
-        createEditorIfNeeded("setCursorVisible");
+        createEditorIfNeeded();
         if (mEditor.mCursorVisible != visible) {
             mEditor.mCursorVisible = visible;
             invalidate();
@@ -7701,6 +7701,17 @@
         if (!isPassword) {
             info.setText(getTextForAccessibility());
         }
+
+        if (TextUtils.isEmpty(getContentDescription())
+                && !TextUtils.isEmpty(mText)) {
+            info.addAction(AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY);
+            info.addAction(AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY);
+            info.setMovementGranularities(AccessibilityNodeInfo.MOVEMENT_GRANULARITY_CHARACTER
+                    | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD
+                    | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_LINE
+                    | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PARAGRAPH
+                    | AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE);
+        }
     }
 
     @Override
@@ -7715,12 +7726,13 @@
     }
 
     /**
-     * Gets the text reported for accessibility purposes. It is the
-     * text if not empty or the hint.
+     * Gets the text reported for accessibility purposes.
      *
      * @return The accessibility text.
+     *
+     * @hide
      */
-    private CharSequence getTextForAccessibility() {
+    public CharSequence getTextForAccessibility() {
         CharSequence text = getText();
         if (TextUtils.isEmpty(text)) {
             text = getHint();
@@ -7891,7 +7903,7 @@
      * that case, to allow for quick replacement.
      */
     public void setCustomSelectionActionModeCallback(ActionMode.Callback actionModeCallback) {
-        createEditorIfNeeded("custom selection action mode set");
+        createEditorIfNeeded();
         mEditor.mCustomSelectionActionModeCallback = actionModeCallback;
     }
 
@@ -8262,16 +8274,82 @@
      * Also note that for performance reasons, the mEditor is created when needed, but not
      * reset when no more edit-specific fields are needed.
      */
-    private void createEditorIfNeeded(String reason) {
+    private void createEditorIfNeeded() {
         if (mEditor == null) {
-            if (!(this instanceof EditText)) {
-                Log.e(LOG_TAG + " EDITOR", "Creating an Editor on a regular TextView. " + reason);
-            }
             mEditor = new Editor(this);
-        } else {
-            if (!(this instanceof EditText)) {
-                Log.d(LOG_TAG + " EDITOR", "Redundant Editor creation. " + reason);
+        }
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    public CharSequence getIterableTextForAccessibility() {
+        if (getContentDescription() == null) {
+            if (!(mText instanceof Spannable)) {
+                setText(mText, BufferType.SPANNABLE);
             }
+            return mText;
+        }
+        return super.getIterableTextForAccessibility();
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    public TextSegmentIterator getIteratorForGranularity(int granularity) {
+        switch (granularity) {
+            case AccessibilityNodeInfo.MOVEMENT_GRANULARITY_LINE: {
+                Spannable text = (Spannable) getIterableTextForAccessibility();
+                if (!TextUtils.isEmpty(text) && getLayout() != null) {
+                    AccessibilityIterators.LineTextSegmentIterator iterator =
+                        AccessibilityIterators.LineTextSegmentIterator.getInstance();
+                    iterator.initialize(text, getLayout());
+                    return iterator;
+                }
+            } break;
+            case AccessibilityNodeInfo.MOVEMENT_GRANULARITY_PAGE: {
+                Spannable text = (Spannable) getIterableTextForAccessibility();
+                if (!TextUtils.isEmpty(text) && getLayout() != null) {
+                    AccessibilityIterators.PageTextSegmentIterator iterator =
+                        AccessibilityIterators.PageTextSegmentIterator.getInstance();
+                    iterator.initialize(this);
+                    return iterator;
+                }
+            } break;
+        }
+        return super.getIteratorForGranularity(granularity);
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    public int getAccessibilityCursorPosition() {
+        if (TextUtils.isEmpty(getContentDescription())) {
+            return getSelectionEnd();
+        } else {
+            return super.getAccessibilityCursorPosition();
+        }
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    public void setAccessibilityCursorPosition(int index) {
+        if (getAccessibilityCursorPosition() == index) {
+            return;
+        }
+        if (TextUtils.isEmpty(getContentDescription())) {
+            if (index >= 0) {
+                Selection.setSelection((Spannable) mText, index);
+            } else {
+                Selection.removeSelection((Spannable) mText);
+            }
+        } else {
+            super.setAccessibilityCursorPosition(index);
         }
     }
 
diff --git a/core/java/com/android/internal/app/IMediaContainerService.aidl b/core/java/com/android/internal/app/IMediaContainerService.aidl
index 727c094..c9f7a58 100755
--- a/core/java/com/android/internal/app/IMediaContainerService.aidl
+++ b/core/java/com/android/internal/app/IMediaContainerService.aidl
@@ -18,6 +18,7 @@
 
 import android.net.Uri;
 import android.os.ParcelFileDescriptor;
+import android.content.pm.ContainerEncryptionParams;
 import android.content.pm.PackageInfoLite;
 import android.content.res.ObbInfo;
 
@@ -25,9 +26,9 @@
     String copyResourceToContainer(in Uri packageURI, String containerId, String key,
             String resFileName, String publicResFileName, boolean isExternal,
             boolean isForwardLocked);
-    int copyResource(in Uri packageURI,
-                in ParcelFileDescriptor outStream);
-    PackageInfoLite getMinimalPackageInfo(in Uri fileUri, in int flags, in long threshold);
+    int copyResource(in Uri packageURI, in ContainerEncryptionParams encryptionParams,
+            in ParcelFileDescriptor outStream);
+    PackageInfoLite getMinimalPackageInfo(in String packagePath, in int flags, in long threshold);
     boolean checkInternalFreeStorage(in Uri fileUri, boolean isForwardLocked, in long threshold);
     boolean checkExternalFreeStorage(in Uri fileUri, boolean isForwardLocked);
     ObbInfo getObbInfo(in String filename);
diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java
index 4f2afa7..614f73f 100644
--- a/core/java/com/android/internal/app/ResolverActivity.java
+++ b/core/java/com/android/internal/app/ResolverActivity.java
@@ -210,12 +210,29 @@
     }
 
     @Override
+    protected void onRestoreInstanceState(Bundle savedInstanceState) {
+        super.onRestoreInstanceState(savedInstanceState);
+        if (mAlwaysUseOption) {
+            final int checkedPos = mGrid.getCheckedItemPosition();
+            final boolean enabled = checkedPos != GridView.INVALID_POSITION;
+            mAlwaysButton.setEnabled(enabled);
+            mOnceButton.setEnabled(enabled);
+            if (enabled) {
+                mGrid.setSelection(checkedPos);
+            }
+        }
+    }
+
+    @Override
     public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
         if (mAlwaysUseOption) {
             final int checkedPos = mGrid.getCheckedItemPosition();
             final boolean enabled = checkedPos != GridView.INVALID_POSITION;
             mAlwaysButton.setEnabled(enabled);
             mOnceButton.setEnabled(enabled);
+            if (enabled) {
+                mGrid.smoothScrollToPosition(checkedPos);
+            }
         } else {
             startSelected(position, false);
         }
diff --git a/core/java/com/android/internal/content/PackageHelper.java b/core/java/com/android/internal/content/PackageHelper.java
index 48ed561..246b0c9 100644
--- a/core/java/com/android/internal/content/PackageHelper.java
+++ b/core/java/com/android/internal/content/PackageHelper.java
@@ -57,25 +57,25 @@
     public static final int APP_INSTALL_INTERNAL = 1;
     public static final int APP_INSTALL_EXTERNAL = 2;
 
-    public static IMountService getMountService() {
+    public static IMountService getMountService() throws RemoteException {
         IBinder service = ServiceManager.getService("mount");
         if (service != null) {
             return IMountService.Stub.asInterface(service);
         } else {
             Log.e(TAG, "Can't get mount service");
+            throw new RemoteException("Could not contact mount service");
         }
-        return null;
     }
 
     public static String createSdDir(int sizeMb, String cid, String sdEncKey, int uid,
             boolean isExternal) {
         // Create mount point via MountService
-        IMountService mountService = getMountService();
-
-        if (localLOGV)
-            Log.i(TAG, "Size of container " + sizeMb + " MB");
-
         try {
+            IMountService mountService = getMountService();
+
+            if (localLOGV)
+                Log.i(TAG, "Size of container " + sizeMb + " MB");
+
             int rc = mountService.createSecureContainer(cid, sizeMb, "ext4", sdEncKey, uid,
                     isExternal);
             if (rc != StorageResultCode.OperationSucceeded) {
diff --git a/core/java/com/android/internal/view/menu/ListMenuPresenter.java b/core/java/com/android/internal/view/menu/ListMenuPresenter.java
index a331bec..b3e2d27 100644
--- a/core/java/com/android/internal/view/menu/ListMenuPresenter.java
+++ b/core/java/com/android/internal/view/menu/ListMenuPresenter.java
@@ -220,7 +220,6 @@
         private int mExpandedIndex = -1;
 
         public MenuAdapter() {
-            registerDataSetObserver(new ExpandedIndexObserver());
             findExpandedIndex();
         }
 
@@ -273,12 +272,11 @@
             }
             mExpandedIndex = -1;
         }
-    }
 
-    private class ExpandedIndexObserver extends DataSetObserver {
         @Override
-        public void onChanged() {
-            mAdapter.findExpandedIndex();
+        public void notifyDataSetChanged() {
+            findExpandedIndex();
+            super.notifyDataSetChanged();
         }
     }
 }
diff --git a/core/java/com/android/internal/view/menu/MenuPopupHelper.java b/core/java/com/android/internal/view/menu/MenuPopupHelper.java
index 329b457..cacc86b 100644
--- a/core/java/com/android/internal/view/menu/MenuPopupHelper.java
+++ b/core/java/com/android/internal/view/menu/MenuPopupHelper.java
@@ -307,7 +307,6 @@
 
         public MenuAdapter(MenuBuilder menu) {
             mAdapterMenu = menu;
-            registerDataSetObserver(new ExpandedIndexObserver());
             findExpandedIndex();
         }
 
@@ -363,12 +362,11 @@
             }
             mExpandedIndex = -1;
         }
-    }
 
-    private class ExpandedIndexObserver extends DataSetObserver {
         @Override
-        public void onChanged() {
-            mAdapter.findExpandedIndex();
+        public void notifyDataSetChanged() {
+            findExpandedIndex();
+            super.notifyDataSetChanged();
         }
     }
 }
diff --git a/core/jni/Android.mk b/core/jni/Android.mk
index 523b2d5..cd0959b 100644
--- a/core/jni/Android.mk
+++ b/core/jni/Android.mk
@@ -218,6 +218,7 @@
 	libusbhost \
 	libharfbuzz \
 	libz \
+	libsuspend \
 
 ifeq ($(USE_OPENGL_RENDERER),true)
 	LOCAL_SHARED_LIBRARIES += libhwui
diff --git a/core/jni/android/graphics/Canvas.cpp b/core/jni/android/graphics/Canvas.cpp
index ef6af74..6b74705 100644
--- a/core/jni/android/graphics/Canvas.cpp
+++ b/core/jni/android/graphics/Canvas.cpp
@@ -69,7 +69,11 @@
         SkImageRef_GlobalPool::SetRAMUsed(0);
         SkGraphics::PurgeFontCache();
     }
-    
+
+    static void freeTextLayoutCaches(JNIEnv* env, jobject) {
+        TextLayoutEngine::getInstance().purgeCaches();
+    }
+
     static jboolean isOpaque(JNIEnv* env, jobject jcanvas) {
         NPE_CHECK_RETURN_ZERO(env, jcanvas);
         SkCanvas* canvas = GraphicsJNI::getNativeCanvas(env, jcanvas);
@@ -986,7 +990,9 @@
         (void*) SkCanvasGlue::drawTextOnPath__StringPathFFPaint},
     {"native_drawPicture", "(II)V", (void*) SkCanvasGlue::drawPicture},
 
-    {"freeCaches", "()V", (void*) SkCanvasGlue::freeCaches}
+    {"freeCaches", "()V", (void*) SkCanvasGlue::freeCaches},
+
+    {"freeTextLayoutCaches", "()V", (void*) SkCanvasGlue::freeTextLayoutCaches}
 };
 
 ///////////////////////////////////////////////////////////////////////////////
diff --git a/core/jni/android/graphics/TextLayoutCache.cpp b/core/jni/android/graphics/TextLayoutCache.cpp
index 16f377d..673c38d 100644
--- a/core/jni/android/graphics/TextLayoutCache.cpp
+++ b/core/jni/android/graphics/TextLayoutCache.cpp
@@ -1015,4 +1015,11 @@
     return value;
 }
 
+void TextLayoutEngine::purgeCaches() {
+#if USE_TEXT_LAYOUT_CACHE
+    mTextLayoutCache->clear();
+#endif
+}
+
+
 } // namespace android
diff --git a/core/jni/android/graphics/TextLayoutCache.h b/core/jni/android/graphics/TextLayoutCache.h
index 0be61c65..027e888 100644
--- a/core/jni/android/graphics/TextLayoutCache.h
+++ b/core/jni/android/graphics/TextLayoutCache.h
@@ -310,6 +310,9 @@
 
     sp<TextLayoutValue> getValue(const SkPaint* paint, const jchar* text, jint start,
             jint count, jint contextCount, jint dirFlags);
+
+    void purgeCaches();
+
 private:
     TextLayoutCache* mTextLayoutCache;
     TextLayoutShaper* mShaper;
diff --git a/core/jni/android_hardware_SensorManager.cpp b/core/jni/android_hardware_SensorManager.cpp
index eddd838..3c1b9c8 100644
--- a/core/jni/android_hardware_SensorManager.cpp
+++ b/core/jni/android_hardware_SensorManager.cpp
@@ -130,10 +130,13 @@
         res = queue->waitForEvent();
         if (res != NO_ERROR)
             return -1;
+        // here we're guaranteed to have an event
         res = queue->read(&event, 1);
+        ALOGE_IF(res==0, "sensors_data_poll: nothing to read after waitForEvent()");
     }
-    if (res < 0)
+    if (res <= 0) {
         return -1;
+    }
 
     jint accuracy = event.vector.status;
     env->SetFloatArrayRegion(values, 0, 3, event.vector.v);
diff --git a/core/jni/android_os_Power.cpp b/core/jni/android_os_Power.cpp
index 48845f6..373abd4 100644
--- a/core/jni/android_os_Power.cpp
+++ b/core/jni/android_os_Power.cpp
@@ -24,6 +24,7 @@
 #include <hardware/power.h>
 #include <hardware_legacy/power.h>
 #include <cutils/android_reboot.h>
+#include <suspend/autosuspend.h>
 
 static struct power_module *sPowerModule;
 
@@ -70,8 +71,18 @@
 static int
 setScreenState(JNIEnv *env, jobject clazz, jboolean on)
 {
-    if (sPowerModule)
-        sPowerModule->setInteractive(sPowerModule, on);
+    if (on) {
+        autosuspend_disable();
+        if (sPowerModule) {
+            sPowerModule->setInteractive(sPowerModule, true);
+        }
+    } else {
+        if (sPowerModule) {
+            sPowerModule->setInteractive(sPowerModule, false);
+        }
+        autosuspend_enable();
+    }
+
     return 0;
 }
 
diff --git a/core/jni/android_os_SystemProperties.cpp b/core/jni/android_os_SystemProperties.cpp
index 66af965..add616e 100644
--- a/core/jni/android_os_SystemProperties.cpp
+++ b/core/jni/android_os_SystemProperties.cpp
@@ -65,6 +65,7 @@
     int len;
     const char* key;
     char buf[PROPERTY_VALUE_MAX];
+    char* end;
     jint result = defJ;
 
     if (keyJ == NULL) {
@@ -76,9 +77,10 @@
 
     len = property_get(key, buf, "");
     if (len > 0) {
-        jint temp;
-        if (sscanf(buf, "%d", &temp) == 1)
-            result = temp;
+        result = strtol(buf, &end, 0);
+        if (end == buf) {
+            result = defJ;
+        }
     }
 
     env->ReleaseStringUTFChars(keyJ, key);
@@ -93,6 +95,7 @@
     int len;
     const char* key;
     char buf[PROPERTY_VALUE_MAX];
+    char* end;
     jlong result = defJ;
 
     if (keyJ == NULL) {
@@ -104,9 +107,10 @@
 
     len = property_get(key, buf, "");
     if (len > 0) {
-        jlong temp;
-        if (sscanf(buf, "%lld", &temp) == 1)
-            result = temp;
+        result = strtoll(buf, &end, 0);
+        if (end == buf) {
+            result = defJ;
+        }
     }
 
     env->ReleaseStringUTFChars(keyJ, key);
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index e16e49a..dbc60f9 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1594,7 +1594,8 @@
         android:protectionLevel="signature" />
 
     <!-- Allows low-level access to setting the keyboard layout.
-         Not for use by normal applications. -->
+         Not for use by normal applications.
+         @hide -->
     <permission android:name="android.permission.SET_KEYBOARD_LAYOUT"
         android:label="@string/permlab_setKeyboardLayout"
         android:description="@string/permdesc_setKeyboardLayout"
diff --git a/core/res/res/layout-sw600dp/keyguard_screen_sim_pin_portrait.xml b/core/res/res/layout-sw600dp/keyguard_screen_sim_pin_portrait.xml
index d8bea56..1be4462 100644
--- a/core/res/res/layout-sw600dp/keyguard_screen_sim_pin_portrait.xml
+++ b/core/res/res/layout-sw600dp/keyguard_screen_sim_pin_portrait.xml
@@ -57,12 +57,13 @@
             android:background="@android:drawable/edit_text">
 
             <!-- displays dots as user enters pin -->
-            <TextView android:id="@+id/pinDisplay"
+            <EditText android:id="@+id/pinDisplay"
                 android:layout_width="0dip"
                 android:layout_height="wrap_content"
                 android:layout_weight="1"
                 android:maxLines="1"
                 android:textAppearance="?android:attr/textAppearanceLargeInverse"
+                android:textColor="@android:color/primary_text_holo_light"
                 android:textStyle="bold"
                 android:inputType="textPassword"
             />
diff --git a/core/res/res/layout/keyguard_screen_sim_pin_portrait.xml b/core/res/res/layout/keyguard_screen_sim_pin_portrait.xml
index 6e8a645..9ca351c 100644
--- a/core/res/res/layout/keyguard_screen_sim_pin_portrait.xml
+++ b/core/res/res/layout/keyguard_screen_sim_pin_portrait.xml
@@ -57,12 +57,13 @@
             android:background="@android:drawable/edit_text">
 
             <!-- displays dots as user enters pin -->
-            <TextView android:id="@+id/pinDisplay"
+            <EditText android:id="@+id/pinDisplay"
                 android:layout_width="0dip"
                 android:layout_height="wrap_content"
                 android:layout_weight="1"
                 android:maxLines="1"
                 android:textAppearance="?android:attr/textAppearanceLargeInverse"
+                android:textColor="@android:color/primary_text_holo_light"
                 android:textStyle="bold"
                 android:inputType="textPassword"
             />
diff --git a/core/res/res/layout/keyguard_screen_sim_puk_landscape.xml b/core/res/res/layout/keyguard_screen_sim_puk_landscape.xml
index 722dc26..56e6426 100644
--- a/core/res/res/layout/keyguard_screen_sim_puk_landscape.xml
+++ b/core/res/res/layout/keyguard_screen_sim_puk_landscape.xml
@@ -122,14 +122,16 @@
                       android:background="@android:drawable/edit_text">
 
                       <!-- displays dots as user enters new pin -->
-                      <TextView android:id="@+id/pinDisplay"
+                      <EditText android:id="@+id/pinDisplay"
                           android:layout_width="0dip"
                           android:layout_height="wrap_content"
                           android:layout_weight="1"
                           android:maxLines="1"
                           android:textAppearance="?android:attr/textAppearanceLargeInverse"
+                          android:textColor="@android:color/primary_text_holo_light"
                           android:textStyle="bold"
                           android:inputType="textPassword"
+                          android:hint="@android:string/keyguard_password_enter_pin_prompt"
                       />
 
                       <ImageButton android:id="@+id/pinDel"
diff --git a/core/res/res/layout/notification_template_big_base.xml b/core/res/res/layout/notification_template_big_base.xml
index 097d15d..f8b24e2 100644
--- a/core/res/res/layout/notification_template_big_base.xml
+++ b/core/res/res/layout/notification_template_big_base.xml
@@ -43,99 +43,106 @@
         android:gravity="center_vertical"
         >
         <LinearLayout
-            android:id="@+id/line1"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:orientation="horizontal"
+            android:minHeight="@dimen/notification_large_icon_height"
+            android:orientation="vertical"
             >
-            <TextView android:id="@+id/title"
-                android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Title"
+            <LinearLayout
+                android:id="@+id/line1"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
+                android:orientation="horizontal"
+                >
+                <TextView android:id="@+id/title"
+                    android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Title"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:singleLine="true"
+                    android:ellipsize="marquee"
+                    android:fadingEdge="horizontal"
+                    android:layout_weight="1"
+                    />
+                <ViewStub android:id="@+id/time"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_gravity="center"
+                    android:layout_weight="0"
+                    android:visibility="gone"
+                    android:layout="@layout/notification_template_part_time"
+                    />
+                <ViewStub android:id="@+id/chronometer"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_gravity="center"
+                    android:layout_weight="0"
+                    android:visibility="gone"
+                    android:layout="@layout/notification_template_part_chronometer"
+                    />
+            </LinearLayout>
+            <TextView android:id="@+id/text2"
+                android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Line2"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="-2dp"
+                android:layout_marginBottom="-2dp"
                 android:singleLine="true"
-                android:ellipsize="marquee"
                 android:fadingEdge="horizontal"
-                android:layout_weight="1"
-                />
-            <ViewStub android:id="@+id/time"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:layout_gravity="center"
-                android:layout_weight="0"
+                android:ellipsize="marquee"
                 android:visibility="gone"
-                android:layout="@layout/notification_template_part_time"
                 />
-            <ViewStub android:id="@+id/chronometer"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:layout_gravity="center"
-                android:layout_weight="0"
-                android:visibility="gone"
-                android:layout="@layout/notification_template_part_chronometer"
-                />
-        </LinearLayout>
-        <TextView android:id="@+id/text2"
-            android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Line2"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:layout_marginTop="-2dp"
-            android:layout_marginBottom="-2dp"
-            android:singleLine="true"
-            android:fadingEdge="horizontal"
-            android:ellipsize="marquee"
-            android:visibility="gone"
-            />
-        <TextView android:id="@+id/big_text"
-            android:textAppearance="@style/TextAppearance.StatusBar.EventContent"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:singleLine="false"
-            android:visibility="gone"
-            />
-        <LinearLayout
-            android:id="@+id/line3"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:orientation="horizontal"
-            >
-            <TextView android:id="@+id/text"
+            <TextView android:id="@+id/big_text"
                 android:textAppearance="@style/TextAppearance.StatusBar.EventContent"
-                android:layout_width="0dp"
+                android:layout_width="match_parent"
                 android:layout_height="wrap_content"
-                android:layout_weight="1"
-                android:layout_gravity="center"
-                android:singleLine="true"
-                android:ellipsize="marquee"
-                android:fadingEdge="horizontal"
-                />
-            <TextView android:id="@+id/info"
-                android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Info"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:layout_gravity="center"
-                android:layout_weight="0"
-                android:singleLine="true"
-                android:gravity="center"
-                android:paddingLeft="8dp"
-                />
-            <ImageView android:id="@+id/right_icon"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:layout_gravity="center"
-                android:layout_weight="0"
-                android:scaleType="center"
-                android:paddingLeft="8dp"
+                android:singleLine="false"
                 android:visibility="gone"
-                android:drawableAlpha="180"
+                />
+            <LinearLayout
+                android:id="@+id/line3"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:orientation="horizontal"
+                >
+                <TextView android:id="@+id/text"
+                    android:textAppearance="@style/TextAppearance.StatusBar.EventContent"
+                    android:layout_width="0dp"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="1"
+                    android:layout_gravity="center"
+                    android:singleLine="true"
+                    android:ellipsize="marquee"
+                    android:fadingEdge="horizontal"
+                    />
+                <TextView android:id="@+id/info"
+                    android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Info"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_gravity="center"
+                    android:layout_weight="0"
+                    android:singleLine="true"
+                    android:gravity="center"
+                    android:paddingLeft="8dp"
+                    />
+                <ImageView android:id="@+id/right_icon"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_gravity="center"
+                    android:layout_weight="0"
+                    android:scaleType="center"
+                    android:paddingLeft="8dp"
+                    android:visibility="gone"
+                    android:drawableAlpha="180"
+                    />
+            </LinearLayout>
+            <ProgressBar
+                android:id="@android:id/progress"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:visibility="gone"
+                style="?android:attr/progressBarStyleHorizontal"
                 />
         </LinearLayout>
-        <ProgressBar
-            android:id="@android:id/progress"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:visibility="gone"
-            style="?android:attr/progressBarStyleHorizontal"
-            />
         <LinearLayout
             android:id="@+id/actions"
             android:layout_width="match_parent"
diff --git a/core/res/res/layout/resolver_grid.xml b/core/res/res/layout/resolver_grid.xml
index f10a59f0..4a0e84a 100644
--- a/core/res/res/layout/resolver_grid.xml
+++ b/core/res/res/layout/resolver_grid.xml
@@ -23,15 +23,20 @@
               android:divider="?android:attr/dividerHorizontal"
               android:showDividers="middle"
               android:dividerPadding="0dip">
-    <GridView
-        android:layout_gravity="center"
-        android:layout_height="wrap_content"
-        android:layout_width="wrap_content"
-        android:id="@+id/resolver_grid"
-        android:numColumns="4"
-        android:columnWidth="128dp"
-        android:padding="16dp"
-        android:clipToPadding="false" />
+    <FrameLayout android:layout_width="match_parent"
+                 android:layout_height="wrap_content"
+                 android:layout_weight="1">
+        <GridView
+            android:layout_gravity="center"
+            android:layout_width="wrap_content"
+            android:layout_height="match_parent"
+            android:id="@+id/resolver_grid"
+            android:numColumns="4"
+            android:columnWidth="128dp"
+            android:padding="16dp"
+            android:clipToPadding="false"
+            android:scrollbarStyle="outsideOverlay" />
+    </FrameLayout>
     <LinearLayout
         android:id="@+id/button_bar"
         android:visibility="gone"
diff --git a/core/res/res/values-h720dp/dimens.xml b/core/res/res/values-h720dp/dimens.xml
index 5a9c777..f726a98 100644
--- a/core/res/res/values-h720dp/dimens.xml
+++ b/core/res/res/values-h720dp/dimens.xml
@@ -19,12 +19,4 @@
 <resources>
     <!-- Dialog button bar height -->
     <dimen name="alert_dialog_button_bar_height">54dip</dimen>
-    <!-- Preference fragment padding, bottom -->
-    <dimen name="preference_fragment_padding_bottom">16dp</dimen>
-
-    <dimen name="preference_screen_header_padding_side">0dip</dimen>
-
-    <integer name="preference_screen_header_scrollbarStyle">0x0</integer> <!-- insideOverlay -->
-    <integer name="preference_fragment_scrollbarStyle">0x02000000</integer> <!-- outsideOverlay -->
-
 </resources>
diff --git a/core/res/res/values-sw600dp-w1024dp/dimens.xml b/core/res/res/values-sw600dp-w1024dp/dimens.xml
deleted file mode 100644
index 4d6a4da..0000000
--- a/core/res/res/values-sw600dp-w1024dp/dimens.xml
+++ /dev/null
@@ -1,23 +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.
--->
-
-<resources>
-    <!-- Increase size (used to be 0 for dual pane -->
-    <!-- Preference activity side margins -->
-    <dimen name="preference_screen_side_margin">48dp</dimen>
-    <!-- Preference activity side margins negative-->
-    <dimen name="preference_screen_side_margin_negative">-52dp</dimen>
-</resources>
diff --git a/tools/localize/testdata/res/values-zz-rZZ/strings.xml b/core/res/res/values-sw600dp-w960dp/dimens.xml
similarity index 71%
rename from tools/localize/testdata/res/values-zz-rZZ/strings.xml
rename to core/res/res/values-sw600dp-w960dp/dimens.xml
index c2a783d..724904e 100644
--- a/tools/localize/testdata/res/values-zz-rZZ/strings.xml
+++ b/core/res/res/values-sw600dp-w960dp/dimens.xml
@@ -1,12 +1,12 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2007 The Android Open Source Project
+<!-- 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.
@@ -14,9 +14,8 @@
      limitations under the License.
 -->
 
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="changed_in_xx">AAAA</string>
-    <string name="previously_translated">CCC</string>
+<resources>
+    <dimen name="preference_screen_header_padding_side">48dp</dimen>
+    <!-- Preference fragment padding, sides -->
+    <dimen name="preference_fragment_padding_side">48dp</dimen>
 </resources>
-
-
diff --git a/core/res/res/values-sw600dp/bools.xml b/core/res/res/values-sw600dp/bools.xml
index 92b6171..b8db31f 100644
--- a/core/res/res/values-sw600dp/bools.xml
+++ b/core/res/res/values-sw600dp/bools.xml
@@ -15,6 +15,5 @@
 -->
 
 <resources>
-    <bool name="preferences_prefer_dual_pane">true</bool>
     <bool name="target_honeycomb_needs_options_menu">false</bool>
 </resources>
diff --git a/core/res/res/values-sw600dp/dimens.xml b/core/res/res/values-sw600dp/dimens.xml
index f8f865e..61136e3 100644
--- a/core/res/res/values-sw600dp/dimens.xml
+++ b/core/res/res/values-sw600dp/dimens.xml
@@ -47,12 +47,6 @@
     <!-- Size of status line font in LockScreen. -->
     <dimen name="keyguard_pattern_unlock_status_line_font_size">14sp</dimen>
 
-    <!-- Preference activity, vertical padding for the header list -->
-    <dimen name="preference_screen_header_vertical_padding">32dp</dimen>
-    <dimen name="preference_screen_side_margin">0dp</dimen>
-    <!-- Compensate for double margin : preference_screen_side_margin + 4 (frame background shadow) = -preference_screen_side_margin_negative -->
-    <dimen name="preference_screen_side_margin_negative">-4dp</dimen>
-
     <!-- Default padding to apply to AppWidgetHostViews containing widgets targeting API level 14 and up. -->
     <dimen name="default_app_widget_padding_left">12dp</dimen>
     <dimen name="default_app_widget_padding_top">4dp</dimen>
@@ -78,5 +72,9 @@
     <!-- Height of the bottom navigation bar in portrait; on sw600dp devices
          this is a bit taller -->
     <dimen name="navigation_bar_height_portrait">56dp</dimen>
+
+    <!-- Preference fragment padding, sides -->
+    <dimen name="preference_fragment_padding_side">24dp</dimen>
+    <dimen name="preference_screen_header_padding_side">24dip</dimen>
 </resources>
 
diff --git a/core/res/res/values-sw600dp/styles.xml b/core/res/res/values-sw600dp/styles.xml
index f9e95b7..7dea9b8 100644
--- a/core/res/res/values-sw600dp/styles.xml
+++ b/core/res/res/values-sw600dp/styles.xml
@@ -25,12 +25,4 @@
         <item name="android:measureWithLargestChild">true</item>
         <item name="android:tabLayout">@android:layout/tab_indicator_holo</item>
     </style>
-
-    <style name="PreferencePanel">
-        <item name="android:layout_marginLeft">@dimen/preference_screen_side_margin</item>
-        <item name="android:layout_marginRight">@dimen/preference_screen_side_margin</item>
-        <item name="android:layout_marginTop">@dimen/preference_screen_top_margin</item>
-        <item name="android:layout_marginBottom">@dimen/preference_screen_bottom_margin</item>
-        <item name="android:background">?attr/detailsElementBackground</item>
-    </style>
 </resources>
diff --git a/core/res/res/values-sw600dp-w1280dp/dimens.xml b/core/res/res/values-sw720dp-w1280dp/dimens.xml
similarity index 100%
rename from core/res/res/values-sw600dp-w1280dp/dimens.xml
rename to core/res/res/values-sw720dp-w1280dp/dimens.xml
diff --git a/tools/localize/testdata/merge_xx_old.xml b/core/res/res/values-sw720dp/bools.xml
similarity index 72%
rename from tools/localize/testdata/merge_xx_old.xml
rename to core/res/res/values-sw720dp/bools.xml
index 9d3a7d8..7d5813f 100644
--- a/tools/localize/testdata/merge_xx_old.xml
+++ b/core/res/res/values-sw720dp/bools.xml
@@ -1,12 +1,12 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2007 The Android Open Source Project
+<!-- Copyright (C) 2012 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -14,8 +14,6 @@
      limitations under the License.
 -->
 
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="changed_in_xx">aaa</string>
-    <string name="previously_translated">CCC</string>
+<resources>
+    <bool name="preferences_prefer_dual_pane">true</bool>
 </resources>
-
diff --git a/core/res/res/values-sw720dp/dimens.xml b/core/res/res/values-sw720dp/dimens.xml
index 7b1bc4c5..34c7ea3 100644
--- a/core/res/res/values-sw720dp/dimens.xml
+++ b/core/res/res/values-sw720dp/dimens.xml
@@ -38,6 +38,32 @@
     <dimen name="thumbnail_width">230dp</dimen>
     <!-- The height that is used when creating thumbnails of applications. -->
     <dimen name="thumbnail_height">135dp</dimen>
+
+    <!-- Preference activity, vertical padding for the header list -->
+    <dimen name="preference_screen_header_vertical_padding">32dp</dimen>
+    <dimen name="preference_screen_side_margin">0dp</dimen>
+    <!-- Compensate for double margin : preference_screen_side_margin + 4 (frame background shadow) = -preference_screen_side_margin_negative -->
+    <dimen name="preference_screen_side_margin_negative">-4dp</dimen>
+
+    <!-- Preference fragment padding, bottom -->
+    <dimen name="preference_fragment_padding_bottom">16dp</dimen>
+    <dimen name="preference_screen_header_padding_side">0dip</dimen>
+    <integer name="preference_screen_header_scrollbarStyle">0x0</integer> <!-- insideOverlay -->
+
+    <!-- Preference fragment padding, sides -->
+    <dimen name="preference_fragment_padding_side">32dp</dimen>
+    <!-- Padding to the left of the preference panel breadcrumb -->
+    <dimen name="preference_breadcrumb_paddingLeft">32dp</dimen>
+    <!-- Padding to the right of the preference panel breadcrumb -->
+    <dimen name="preference_breadcrumb_paddingRight">32dp</dimen>
+    <!-- Weight of the left pane in a multi-pane preference layout. -->
+    <integer name="preferences_left_pane_weight">1</integer>
+    <!-- Weight of the right pane in a multi-pane preference layout. So the split is 1:2 -->
+    <integer name="preferences_right_pane_weight">2</integer>
+    <!-- Minimum space to allocate to the left of a preference item for an icon.
+        This helps in aligning titles when some items have icons and some don't. When space is
+        at a premium, we don't pre-allocate any space. -->
+    <dimen name="preference_icon_minWidth">56dp</dimen>
 </resources>
 
 
diff --git a/core/res/res/values-sw720dp/styles.xml b/core/res/res/values-sw720dp/styles.xml
new file mode 100644
index 0000000..640e898
--- /dev/null
+++ b/core/res/res/values-sw720dp/styles.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<resources>
+    <style name="PreferencePanel">
+        <item name="android:layout_marginLeft">@dimen/preference_screen_side_margin</item>
+        <item name="android:layout_marginRight">@dimen/preference_screen_side_margin</item>
+        <item name="android:layout_marginTop">@dimen/preference_screen_top_margin</item>
+        <item name="android:layout_marginBottom">@dimen/preference_screen_bottom_margin</item>
+        <item name="android:background">?attr/detailsElementBackground</item>
+    </style>
+</resources>
diff --git a/core/res/res/values-w720dp/dimens.xml b/core/res/res/values-w720dp/dimens.xml
deleted file mode 100644
index a37f588..0000000
--- a/core/res/res/values-w720dp/dimens.xml
+++ /dev/null
@@ -1,37 +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.
--->
-
-<resources>
-    <!-- Preference fragment padding, sides -->
-    <dimen name="preference_fragment_padding_side">32dp</dimen>
-    <!-- Padding to the left of the preference panel breadcrumb -->
-    <dimen name="preference_breadcrumb_paddingLeft">32dp</dimen>
-    <!-- Padding to the right of the preference panel breadcrumb -->
-    <dimen name="preference_breadcrumb_paddingRight">32dp</dimen>
-    <!-- Weight of the left pane in a multi-pane preference layout. -->
-    <integer name="preferences_left_pane_weight">1</integer>
-    <!-- Weight of the right pane in a multi-pane preference layout. So the split is 1:2 -->
-    <integer name="preferences_right_pane_weight">2</integer>
-    <!-- Minimum space to allocate to the left of a preference item for an icon.
-        This helps in aligning titles when some items have icons and some don't. When space is
-        at a premium, we don't pre-allocate any space. -->
-    <dimen name="preference_icon_minWidth">56dp</dimen>
-
-    <dimen name="preference_screen_header_padding_side">0dip</dimen>
-
-    <integer name="preference_screen_header_scrollbarStyle">0x0</integer> <!-- insideOverlay -->
-    <integer name="preference_fragment_scrollbarStyle">0x02000000</integer> <!-- outsideOverlay -->
-</resources>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index e7ad4c2..687a00b 100755
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -3562,7 +3562,7 @@
 
     <!-- Title for a button to choose the currently selected activity
          as the default in the activity resolver. [CHAR LIMIT=25] -->
-    <string name="activity_resolver_use_always">Use Always</string>
+    <string name="activity_resolver_use_always">Always</string>
 
     <!-- Title for a button to choose the currently selected activity
          from the activity resolver to use just this once. [CHAR LIMIT=25] -->
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java
index 19aa77b..f7b0cd0 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java
@@ -246,9 +246,7 @@
 
         initializeNetworkStates();
 
-        mWifiManager.setWifiEnabled(true);
         log("Clear Wifi before we start the test.");
-        sleep(SHORT_TIMEOUT);
         removeConfiguredNetworksAndDisableWifi();
         mWifiRegexs = mCM.getTetherableWifiRegexs();
      }
@@ -645,6 +643,11 @@
      */
     public boolean disconnectAP() {
         // remove saved networks
+        if (!mWifiManager.isWifiEnabled()) {
+            log("Enabled wifi before remove configured networks");
+            mWifiManager.setWifiEnabled(true);
+            sleep(SHORT_TIMEOUT);
+        }
         List<WifiConfiguration> wifiConfigList = mWifiManager.getConfiguredNetworks();
         log("size of wifiConfigList: " + wifiConfigList.size());
         for (WifiConfiguration wifiConfig: wifiConfigList) {
diff --git a/core/tests/coretests/src/android/content/pm/ContainerEncryptionParamsTest.java b/core/tests/coretests/src/android/content/pm/ContainerEncryptionParamsTest.java
new file mode 100644
index 0000000..7deaa9a
--- /dev/null
+++ b/core/tests/coretests/src/android/content/pm/ContainerEncryptionParamsTest.java
@@ -0,0 +1,370 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.content.pm;
+
+import android.os.Parcel;
+import android.test.AndroidTestCase;
+
+import java.util.Arrays;
+
+import javax.crypto.SecretKey;
+import javax.crypto.spec.IvParameterSpec;
+import javax.crypto.spec.SecretKeySpec;
+
+public class ContainerEncryptionParamsTest extends AndroidTestCase {
+    private static final String ENC_ALGORITHM = "AES/CBC/PKCS7Padding";
+
+    private static final byte[] IV_BYTES = "FOOBAR".getBytes();
+
+    private static final IvParameterSpec ENC_PARAMS = new IvParameterSpec(IV_BYTES);
+
+    private static final byte[] ENC_KEY_BYTES = "abcd1234wxyz7890".getBytes();
+
+    private static final SecretKey ENC_KEY = new SecretKeySpec(ENC_KEY_BYTES, "RAW");
+
+    private static final String MAC_ALGORITHM = "HMAC-SHA1";
+
+    private static final byte[] MAC_KEY_BYTES = "4wxyzabcd1237890".getBytes();
+
+    private static final SecretKey MAC_KEY = new SecretKeySpec(MAC_KEY_BYTES, "RAW");
+
+    private static final byte[] MAC_TAG = "faketag".getBytes();
+
+    private static final int AUTHENTICATED_START = 5;
+
+    private static final int ENCRYPTED_START = 11;
+
+    private static final int DATA_END = 19;
+
+    public void testParcel() throws Exception {
+        ContainerEncryptionParams expected = new ContainerEncryptionParams(ENC_ALGORITHM,
+                ENC_PARAMS, ENC_KEY, MAC_ALGORITHM, null, MAC_KEY, MAC_TAG, AUTHENTICATED_START,
+                ENCRYPTED_START, DATA_END);
+
+        Parcel parcel = Parcel.obtain();
+        expected.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+
+        ContainerEncryptionParams actual = ContainerEncryptionParams.CREATOR
+                .createFromParcel(parcel);
+
+        assertEquals(ENC_ALGORITHM, actual.getEncryptionAlgorithm());
+
+        if (!(actual.getEncryptionSpec() instanceof IvParameterSpec)) {
+            fail("encryption parameters should be IvParameterSpec");
+        } else {
+            IvParameterSpec actualParams = (IvParameterSpec) actual.getEncryptionSpec();
+            assertTrue(Arrays.equals(IV_BYTES, actualParams.getIV()));
+        }
+
+        assertEquals(ENC_KEY, actual.getEncryptionKey());
+
+        assertEquals(MAC_ALGORITHM, actual.getMacAlgorithm());
+
+        assertNull(actual.getMacSpec());
+
+        assertEquals(MAC_KEY, actual.getMacKey());
+
+        assertTrue(Arrays.equals(MAC_TAG, actual.getMacTag()));
+
+        assertEquals(AUTHENTICATED_START, actual.getAuthenticatedDataStart());
+
+        assertEquals(ENCRYPTED_START, actual.getEncryptedDataStart());
+
+        assertEquals(DATA_END, actual.getDataEnd());
+    }
+
+    public void testEquals_Success() throws Exception {
+        ContainerEncryptionParams params1 = new ContainerEncryptionParams(ENC_ALGORITHM,
+                ENC_PARAMS, ENC_KEY, MAC_ALGORITHM, null, MAC_KEY, MAC_TAG, AUTHENTICATED_START,
+                ENCRYPTED_START, DATA_END);
+
+        ContainerEncryptionParams params2 = new ContainerEncryptionParams(
+                new String(ENC_ALGORITHM), new IvParameterSpec(IV_BYTES.clone()),
+                new SecretKeySpec(ENC_KEY_BYTES.clone(), "RAW"), new String(MAC_ALGORITHM), null,
+                new SecretKeySpec(MAC_KEY_BYTES.clone(), "RAW"), MAC_TAG, AUTHENTICATED_START,
+                ENCRYPTED_START, DATA_END);
+
+        assertEquals(params1, params2);
+    }
+
+    public void testEquals_EncAlgo_Failure() throws Exception {
+        ContainerEncryptionParams params1 = new ContainerEncryptionParams(ENC_ALGORITHM,
+                ENC_PARAMS, ENC_KEY, MAC_ALGORITHM, null, MAC_KEY, MAC_TAG, AUTHENTICATED_START,
+                ENCRYPTED_START, DATA_END);
+
+        ContainerEncryptionParams params2 = new ContainerEncryptionParams(new String(
+                "AES-256/CBC/PKCS7Padding"), new IvParameterSpec(IV_BYTES.clone()),
+                new SecretKeySpec(ENC_KEY_BYTES.clone(), "RAW"), new String(MAC_ALGORITHM), null,
+                new SecretKeySpec(MAC_KEY_BYTES.clone(), "RAW"), MAC_TAG, AUTHENTICATED_START,
+                ENCRYPTED_START, DATA_END);
+
+        assertFalse(params1.equals(params2));
+    }
+
+    public void testEquals_EncParams_Failure() throws Exception {
+        ContainerEncryptionParams params1 = new ContainerEncryptionParams(ENC_ALGORITHM,
+                ENC_PARAMS, ENC_KEY, MAC_ALGORITHM, null, MAC_KEY, MAC_TAG, AUTHENTICATED_START,
+                ENCRYPTED_START, DATA_END);
+
+        ContainerEncryptionParams params2 = new ContainerEncryptionParams(
+                new String(ENC_ALGORITHM), new IvParameterSpec("BLAHBLAH".getBytes()),
+                new SecretKeySpec(ENC_KEY_BYTES.clone(), "RAW"), new String(MAC_ALGORITHM), null,
+                new SecretKeySpec(MAC_KEY_BYTES.clone(), "RAW"), MAC_TAG, AUTHENTICATED_START,
+                ENCRYPTED_START, DATA_END);
+
+        assertFalse(params1.equals(params2));
+    }
+
+    public void testEquals_EncKey_Failure() throws Exception {
+        ContainerEncryptionParams params1 = new ContainerEncryptionParams(ENC_ALGORITHM,
+                ENC_PARAMS, ENC_KEY, MAC_ALGORITHM, null, MAC_KEY, MAC_TAG, AUTHENTICATED_START,
+                ENCRYPTED_START, DATA_END);
+
+        ContainerEncryptionParams params2 = new ContainerEncryptionParams(
+                new String(ENC_ALGORITHM), new IvParameterSpec(IV_BYTES.clone()),
+                new SecretKeySpec("BLAHBLAH".getBytes(), "RAW"), new String(MAC_ALGORITHM), null,
+                new SecretKeySpec(MAC_KEY_BYTES.clone(), "RAW"), MAC_TAG, AUTHENTICATED_START,
+                ENCRYPTED_START, DATA_END);
+
+        assertFalse(params1.equals(params2));
+    }
+
+    public void testEquals_MacAlgo_Failure() throws Exception {
+        ContainerEncryptionParams params1 = new ContainerEncryptionParams(ENC_ALGORITHM,
+                ENC_PARAMS, ENC_KEY, MAC_ALGORITHM, null, MAC_KEY, MAC_TAG, AUTHENTICATED_START,
+                ENCRYPTED_START, DATA_END);
+
+        ContainerEncryptionParams params2 = new ContainerEncryptionParams(
+                new String(ENC_ALGORITHM), new IvParameterSpec(IV_BYTES.clone()),
+                new SecretKeySpec(ENC_KEY_BYTES.clone(), "RAW"), "BLAHBLAH", null,
+                new SecretKeySpec(MAC_KEY_BYTES.clone(), "RAW"), MAC_TAG, AUTHENTICATED_START,
+                ENCRYPTED_START, DATA_END);
+
+        assertFalse(params1.equals(params2));
+    }
+
+    public void testEquals_MacKey_Failure() throws Exception {
+        ContainerEncryptionParams params1 = new ContainerEncryptionParams(ENC_ALGORITHM,
+                ENC_PARAMS, ENC_KEY, MAC_ALGORITHM, null, MAC_KEY, MAC_TAG, AUTHENTICATED_START,
+                ENCRYPTED_START, DATA_END);
+
+        ContainerEncryptionParams params2 = new ContainerEncryptionParams(
+                new String(ENC_ALGORITHM), new IvParameterSpec(IV_BYTES.clone()),
+                new SecretKeySpec(ENC_KEY_BYTES.clone(), "RAW"), new String(MAC_ALGORITHM), null,
+                new SecretKeySpec("FAKE_MAC_KEY".getBytes(), "RAW"), MAC_TAG, AUTHENTICATED_START,
+                ENCRYPTED_START, DATA_END);
+
+        assertFalse(params1.equals(params2));
+    }
+
+    public void testEquals_MacTag_Failure() throws Exception {
+        ContainerEncryptionParams params1 = new ContainerEncryptionParams(ENC_ALGORITHM,
+                ENC_PARAMS, ENC_KEY, MAC_ALGORITHM, null, MAC_KEY, MAC_TAG, AUTHENTICATED_START,
+                ENCRYPTED_START, DATA_END);
+
+        ContainerEncryptionParams params2 = new ContainerEncryptionParams(
+                new String(ENC_ALGORITHM), new IvParameterSpec(IV_BYTES.clone()),
+                new SecretKeySpec(ENC_KEY_BYTES.clone(), "RAW"), new String(MAC_ALGORITHM), null,
+                new SecretKeySpec(MAC_KEY_BYTES.clone(), "RAW"), "broken".getBytes(),
+                AUTHENTICATED_START, ENCRYPTED_START, DATA_END);
+
+        assertFalse(params1.equals(params2));
+    }
+
+    public void testEquals_AuthenticatedStart_Failure() throws Exception {
+        ContainerEncryptionParams params1 = new ContainerEncryptionParams(ENC_ALGORITHM,
+                ENC_PARAMS, ENC_KEY, MAC_ALGORITHM, null, MAC_KEY, MAC_TAG, AUTHENTICATED_START,
+                ENCRYPTED_START, DATA_END);
+
+        ContainerEncryptionParams params2 = new ContainerEncryptionParams(
+                new String(ENC_ALGORITHM), new IvParameterSpec(IV_BYTES.clone()),
+                new SecretKeySpec(ENC_KEY_BYTES.clone(), "RAW"), new String(MAC_ALGORITHM), null,
+                new SecretKeySpec(MAC_KEY_BYTES.clone(), "RAW"), MAC_TAG, AUTHENTICATED_START - 1,
+                ENCRYPTED_START, DATA_END);
+
+        assertFalse(params1.equals(params2));
+    }
+
+    public void testEquals_EncryptedStart_Failure() throws Exception {
+        ContainerEncryptionParams params1 = new ContainerEncryptionParams(ENC_ALGORITHM,
+                ENC_PARAMS, ENC_KEY, MAC_ALGORITHM, null, MAC_KEY, MAC_TAG, AUTHENTICATED_START,
+                ENCRYPTED_START, DATA_END);
+
+        ContainerEncryptionParams params2 = new ContainerEncryptionParams(
+                new String(ENC_ALGORITHM), new IvParameterSpec(IV_BYTES.clone()),
+                new SecretKeySpec(ENC_KEY_BYTES.clone(), "RAW"), new String(MAC_ALGORITHM), null,
+                new SecretKeySpec(MAC_KEY_BYTES.clone(), "RAW"), MAC_TAG, AUTHENTICATED_START,
+                ENCRYPTED_START - 1, DATA_END);
+
+        assertFalse(params1.equals(params2));
+    }
+
+    public void testEquals_DataEnd_Failure() throws Exception {
+        ContainerEncryptionParams params1 = new ContainerEncryptionParams(ENC_ALGORITHM,
+                ENC_PARAMS, ENC_KEY, MAC_ALGORITHM, null, MAC_KEY, MAC_TAG, AUTHENTICATED_START,
+                ENCRYPTED_START, DATA_END);
+
+        ContainerEncryptionParams params2 = new ContainerEncryptionParams(
+                new String(ENC_ALGORITHM), new IvParameterSpec(IV_BYTES.clone()),
+                new SecretKeySpec(ENC_KEY_BYTES.clone(), "RAW"), new String(MAC_ALGORITHM), null,
+                new SecretKeySpec(MAC_KEY_BYTES.clone(), "RAW"), MAC_TAG, AUTHENTICATED_START,
+                ENCRYPTED_START, DATA_END + 1);
+
+        assertFalse(params1.equals(params2));
+    }
+
+    public void testHashCode_Success() throws Exception {
+        ContainerEncryptionParams params1 = new ContainerEncryptionParams(ENC_ALGORITHM,
+                ENC_PARAMS, ENC_KEY, MAC_ALGORITHM, null, MAC_KEY, MAC_TAG, AUTHENTICATED_START,
+                ENCRYPTED_START, DATA_END);
+
+        ContainerEncryptionParams params2 = new ContainerEncryptionParams(
+                new String(ENC_ALGORITHM), new IvParameterSpec(IV_BYTES.clone()),
+                new SecretKeySpec(ENC_KEY_BYTES.clone(), "RAW"), new String(MAC_ALGORITHM), null,
+                new SecretKeySpec(MAC_KEY_BYTES.clone(), "RAW"), MAC_TAG, AUTHENTICATED_START,
+                ENCRYPTED_START, DATA_END);
+
+        assertEquals(params1.hashCode(), params2.hashCode());
+    }
+
+    public void testHashCode_EncAlgo_Failure() throws Exception {
+        ContainerEncryptionParams params1 = new ContainerEncryptionParams(ENC_ALGORITHM,
+                ENC_PARAMS, ENC_KEY, MAC_ALGORITHM, null, MAC_KEY, MAC_TAG, AUTHENTICATED_START,
+                ENCRYPTED_START, DATA_END);
+
+        ContainerEncryptionParams params2 = new ContainerEncryptionParams(new String(
+                "AES-256/CBC/PKCS7Padding"), new IvParameterSpec(IV_BYTES.clone()),
+                new SecretKeySpec(ENC_KEY_BYTES.clone(), "RAW"), new String(MAC_ALGORITHM), null,
+                new SecretKeySpec(MAC_KEY_BYTES.clone(), "RAW"), MAC_TAG, AUTHENTICATED_START,
+                ENCRYPTED_START, DATA_END);
+
+        assertFalse(params1.hashCode() == params2.hashCode());
+    }
+
+    public void testHashCode_EncParams_Failure() throws Exception {
+        ContainerEncryptionParams params1 = new ContainerEncryptionParams(ENC_ALGORITHM,
+                ENC_PARAMS, ENC_KEY, MAC_ALGORITHM, null, MAC_KEY, MAC_TAG, AUTHENTICATED_START,
+                ENCRYPTED_START, DATA_END);
+
+        ContainerEncryptionParams params2 = new ContainerEncryptionParams(
+                new String(ENC_ALGORITHM), new IvParameterSpec("BLAHBLAH".getBytes()),
+                new SecretKeySpec(ENC_KEY_BYTES.clone(), "RAW"), new String(MAC_ALGORITHM), null,
+                new SecretKeySpec(MAC_KEY_BYTES.clone(), "RAW"), MAC_TAG, AUTHENTICATED_START,
+                ENCRYPTED_START, DATA_END);
+
+        assertFalse(params1.hashCode() == params2.hashCode());
+    }
+
+    public void testHashCode_EncKey_Failure() throws Exception {
+        ContainerEncryptionParams params1 = new ContainerEncryptionParams(ENC_ALGORITHM,
+                ENC_PARAMS, ENC_KEY, MAC_ALGORITHM, null, MAC_KEY, MAC_TAG, AUTHENTICATED_START,
+                ENCRYPTED_START, DATA_END);
+
+        ContainerEncryptionParams params2 = new ContainerEncryptionParams(
+                new String(ENC_ALGORITHM), new IvParameterSpec(IV_BYTES.clone()),
+                new SecretKeySpec("BLAHBLAH".getBytes(), "RAW"), new String(MAC_ALGORITHM), null,
+                new SecretKeySpec(MAC_KEY_BYTES.clone(), "RAW"), MAC_TAG, AUTHENTICATED_START,
+                ENCRYPTED_START, DATA_END);
+
+        assertFalse(params1.hashCode() == params2.hashCode());
+    }
+
+    public void testHashCode_MacAlgo_Failure() throws Exception {
+        ContainerEncryptionParams params1 = new ContainerEncryptionParams(ENC_ALGORITHM,
+                ENC_PARAMS, ENC_KEY, MAC_ALGORITHM, null, MAC_KEY, MAC_TAG, AUTHENTICATED_START,
+                ENCRYPTED_START, DATA_END);
+
+        ContainerEncryptionParams params2 = new ContainerEncryptionParams(
+                new String(ENC_ALGORITHM), new IvParameterSpec(IV_BYTES.clone()),
+                new SecretKeySpec(ENC_KEY_BYTES.clone(), "RAW"), "BLAHBLAH", null,
+                new SecretKeySpec(MAC_KEY_BYTES.clone(), "RAW"), MAC_TAG, AUTHENTICATED_START,
+                ENCRYPTED_START, DATA_END);
+
+        assertFalse(params1.hashCode() == params2.hashCode());
+    }
+
+    public void testHashCode_MacKey_Failure() throws Exception {
+        ContainerEncryptionParams params1 = new ContainerEncryptionParams(ENC_ALGORITHM,
+                ENC_PARAMS, ENC_KEY, MAC_ALGORITHM, null, MAC_KEY, MAC_TAG, AUTHENTICATED_START,
+                ENCRYPTED_START, DATA_END);
+
+        ContainerEncryptionParams params2 = new ContainerEncryptionParams(
+                new String(ENC_ALGORITHM), new IvParameterSpec(IV_BYTES.clone()),
+                new SecretKeySpec(ENC_KEY_BYTES.clone(), "RAW"), new String(MAC_ALGORITHM), null,
+                new SecretKeySpec("FAKE_MAC_KEY".getBytes(), "RAW"), MAC_TAG, AUTHENTICATED_START,
+                ENCRYPTED_START, DATA_END);
+
+        assertFalse(params1.hashCode() == params2.hashCode());
+    }
+
+    public void testHashCode_MacTag_Failure() throws Exception {
+        ContainerEncryptionParams params1 = new ContainerEncryptionParams(ENC_ALGORITHM,
+                ENC_PARAMS, ENC_KEY, MAC_ALGORITHM, null, MAC_KEY, MAC_TAG, AUTHENTICATED_START,
+                ENCRYPTED_START, DATA_END);
+
+        ContainerEncryptionParams params2 = new ContainerEncryptionParams(
+                new String(ENC_ALGORITHM), new IvParameterSpec(IV_BYTES.clone()),
+                new SecretKeySpec(ENC_KEY_BYTES.clone(), "RAW"), new String(MAC_ALGORITHM), null,
+                new SecretKeySpec(MAC_KEY_BYTES.clone(), "RAW"), "broken".getBytes(),
+                AUTHENTICATED_START, ENCRYPTED_START, DATA_END);
+
+        assertFalse(params1.hashCode() == params2.hashCode());
+    }
+
+    public void testHashCode_AuthenticatedStart_Failure() throws Exception {
+        ContainerEncryptionParams params1 = new ContainerEncryptionParams(ENC_ALGORITHM,
+                ENC_PARAMS, ENC_KEY, MAC_ALGORITHM, null, MAC_KEY, MAC_TAG, AUTHENTICATED_START,
+                ENCRYPTED_START, DATA_END);
+
+        ContainerEncryptionParams params2 = new ContainerEncryptionParams(
+                new String(ENC_ALGORITHM), new IvParameterSpec(IV_BYTES.clone()),
+                new SecretKeySpec(ENC_KEY_BYTES.clone(), "RAW"), new String(MAC_ALGORITHM), null,
+                new SecretKeySpec(MAC_KEY_BYTES.clone(), "RAW"), MAC_TAG, AUTHENTICATED_START - 1,
+                ENCRYPTED_START, DATA_END);
+
+        assertFalse(params1.hashCode() == params2.hashCode());
+    }
+
+    public void testHashCode_EncryptedStart_Failure() throws Exception {
+        ContainerEncryptionParams params1 = new ContainerEncryptionParams(ENC_ALGORITHM,
+                ENC_PARAMS, ENC_KEY, MAC_ALGORITHM, null, MAC_KEY, MAC_TAG, AUTHENTICATED_START,
+                ENCRYPTED_START, DATA_END);
+
+        ContainerEncryptionParams params2 = new ContainerEncryptionParams(
+                new String(ENC_ALGORITHM), new IvParameterSpec(IV_BYTES.clone()),
+                new SecretKeySpec(ENC_KEY_BYTES.clone(), "RAW"), new String(MAC_ALGORITHM), null,
+                new SecretKeySpec(MAC_KEY_BYTES.clone(), "RAW"), MAC_TAG, AUTHENTICATED_START,
+                ENCRYPTED_START - 1, DATA_END);
+
+        assertFalse(params1.hashCode() == params2.hashCode());
+    }
+
+    public void testHashCode_DataEnd_Failure() throws Exception {
+        ContainerEncryptionParams params1 = new ContainerEncryptionParams(ENC_ALGORITHM,
+                ENC_PARAMS, ENC_KEY, MAC_ALGORITHM, null, MAC_KEY, MAC_TAG, AUTHENTICATED_START,
+                ENCRYPTED_START, DATA_END);
+
+        ContainerEncryptionParams params2 = new ContainerEncryptionParams(
+                new String(ENC_ALGORITHM), new IvParameterSpec(IV_BYTES.clone()),
+                new SecretKeySpec(ENC_KEY_BYTES.clone(), "RAW"), new String(MAC_ALGORITHM), null,
+                new SecretKeySpec(MAC_KEY_BYTES.clone(), "RAW"), MAC_TAG, AUTHENTICATED_START,
+                ENCRYPTED_START, DATA_END + 1);
+
+        assertFalse(params1.hashCode() == params2.hashCode());
+    }
+}
diff --git a/core/tests/coretests/src/android/content/pm/LimitedLengthInputStreamTest.java b/core/tests/coretests/src/android/content/pm/LimitedLengthInputStreamTest.java
new file mode 100644
index 0000000..0a0152b
--- /dev/null
+++ b/core/tests/coretests/src/android/content/pm/LimitedLengthInputStreamTest.java
@@ -0,0 +1,186 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.content.pm;
+
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.MediumTest;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Arrays;
+
+public class LimitedLengthInputStreamTest extends AndroidTestCase {
+    private final byte[] TEST_STRING1 = "This is a test".getBytes();
+
+    private InputStream mTestStream1;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        mTestStream1 = new ByteArrayInputStream(TEST_STRING1);
+    }
+
+    @MediumTest
+    public void testConstructor_NegativeOffset_Failure() throws Exception {
+        try {
+            InputStream is = new LimitedLengthInputStream(mTestStream1, -1, TEST_STRING1.length);
+            fail("Should throw IOException on negative index");
+        } catch (IOException e) {
+            // success
+        }
+    }
+
+    @MediumTest
+    public void testConstructor_NegativeLength_Failure() throws Exception {
+        try {
+            InputStream is = new LimitedLengthInputStream(mTestStream1, 0, -1);
+            fail("Should throw IOException on negative length");
+        } catch (IOException e) {
+            // success
+        }
+    }
+
+    @MediumTest
+    public void testConstructor_NullInputStream_Failure() throws Exception {
+        try {
+            InputStream is = new LimitedLengthInputStream(null, 0, 1);
+            fail("Should throw IOException on null input stream");
+        } catch (IOException e) {
+            // success
+        }
+    }
+
+    private void checkReadBytesWithOffsetAndLength_WithString1(int offset, int length)
+            throws Exception {
+        byte[] temp = new byte[TEST_STRING1.length];
+        byte[] expected = new byte[length];
+        byte[] actual = new byte[length];
+
+        System.arraycopy(TEST_STRING1, offset, expected, 0, length);
+
+        InputStream is = new LimitedLengthInputStream(mTestStream1, offset, length);
+        assertEquals(length, is.read(temp, 0, temp.length));
+
+        System.arraycopy(temp, 0, actual, 0, length);
+        assertTrue(Arrays.equals(expected, actual));
+
+        assertEquals(-1, is.read(temp, 0, temp.length));
+    }
+
+    @MediumTest
+    public void testReadBytesWithOffsetAndLength_ZeroOffset_PartialLength_Success()
+            throws Exception {
+        checkReadBytesWithOffsetAndLength_WithString1(0, 2);
+    }
+
+    @MediumTest
+    public void testReadBytesWithOffsetAndLength_NonZeroOffset_PartialLength_Success()
+            throws Exception {
+        checkReadBytesWithOffsetAndLength_WithString1(3, 2);
+    }
+
+    @MediumTest
+    public void testReadBytesWithOffsetAndLength_ZeroOffset_FullLength_Success() throws Exception {
+        checkReadBytesWithOffsetAndLength_WithString1(0, TEST_STRING1.length);
+    }
+
+    @MediumTest
+    public void testReadBytesWithOffsetAndLength_NonZeroOffset_FullLength_Success()
+            throws Exception {
+        checkReadBytesWithOffsetAndLength_WithString1(3, TEST_STRING1.length - 3);
+    }
+
+    @MediumTest
+    public void testReadBytesWithOffsetAndLength_ZeroOffset_PastEnd_Success() throws Exception {
+        byte[] temp = new byte[TEST_STRING1.length + 10];
+        InputStream is = new LimitedLengthInputStream(mTestStream1, 0, TEST_STRING1.length + 10);
+        assertEquals(TEST_STRING1.length, is.read(temp, 0, TEST_STRING1.length + 10));
+
+        byte[] actual = new byte[TEST_STRING1.length];
+        System.arraycopy(temp, 0, actual, 0, actual.length);
+        assertTrue(Arrays.equals(TEST_STRING1, actual));
+    }
+
+    private void checkReadBytes_WithString1(int offset, int length) throws Exception {
+        byte[] temp = new byte[TEST_STRING1.length];
+        byte[] expected = new byte[length];
+        byte[] actual = new byte[length];
+
+        System.arraycopy(TEST_STRING1, offset, expected, 0, length);
+
+        InputStream is = new LimitedLengthInputStream(mTestStream1, offset, length);
+        assertEquals(length, is.read(temp));
+
+        System.arraycopy(temp, 0, actual, 0, length);
+        assertTrue(Arrays.equals(expected, actual));
+
+        assertEquals(-1, is.read(temp));
+    }
+
+    @MediumTest
+    public void testReadBytes_ZeroOffset_PartialLength_Success() throws Exception {
+        checkReadBytesWithOffsetAndLength_WithString1(0, 2);
+    }
+
+    @MediumTest
+    public void testReadBytes_NonZeroOffset_PartialLength_Success() throws Exception {
+        checkReadBytesWithOffsetAndLength_WithString1(3, 2);
+    }
+
+    @MediumTest
+    public void testReadBytes_ZeroOffset_FullLength_Success() throws Exception {
+        checkReadBytesWithOffsetAndLength_WithString1(0, TEST_STRING1.length);
+    }
+
+    @MediumTest
+    public void testReadBytes_NonZeroOffset_FullLength_Success() throws Exception {
+        checkReadBytesWithOffsetAndLength_WithString1(3, TEST_STRING1.length - 3);
+    }
+
+    private void checkSingleByteRead_WithString1(int offset, int length) throws Exception {
+        InputStream is = new LimitedLengthInputStream(mTestStream1, offset, length);
+
+        for (int i = 0; i < length; i++) {
+            assertEquals(TEST_STRING1[offset + i], is.read());
+        }
+
+        assertEquals(-1, is.read());
+    }
+
+    @MediumTest
+    public void testSingleByteRead_ZeroOffset_PartialLength_Success() throws Exception {
+        checkSingleByteRead_WithString1(0, 2);
+    }
+
+    @MediumTest
+    public void testSingleByteRead_NonZeroOffset_PartialLength_Success() throws Exception {
+        checkSingleByteRead_WithString1(3, 2);
+    }
+
+    @MediumTest
+    public void testSingleByteRead_ZeroOffset_FullLength_Success() throws Exception {
+        checkSingleByteRead_WithString1(0, TEST_STRING1.length);
+    }
+
+    @MediumTest
+    public void testSingleByteRead_NonZeroOffset_FullLength_Success() throws Exception {
+        checkSingleByteRead_WithString1(3, TEST_STRING1.length - 3);
+    }
+
+}
diff --git a/core/tests/coretests/src/android/content/pm/MacAuthenticatedInputStreamTest.java b/core/tests/coretests/src/android/content/pm/MacAuthenticatedInputStreamTest.java
new file mode 100644
index 0000000..948e722
--- /dev/null
+++ b/core/tests/coretests/src/android/content/pm/MacAuthenticatedInputStreamTest.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.content.pm;
+
+import android.test.AndroidTestCase;
+
+import java.io.ByteArrayInputStream;
+import java.util.Arrays;
+
+import javax.crypto.Mac;
+import javax.crypto.SecretKey;
+import javax.crypto.spec.SecretKeySpec;
+
+import libcore.io.Streams;
+
+public class MacAuthenticatedInputStreamTest extends AndroidTestCase {
+
+    private static final SecretKey HMAC_KEY_1 = new SecretKeySpec("test_key_1".getBytes(), "HMAC");
+
+    private static final byte[] TEST_STRING_1 = "Hello, World!".getBytes();
+
+    /**
+     * Generated with:
+     *
+     * echo -n 'Hello, World!' | openssl dgst -hmac 'test_key_1' -binary -sha1 | recode ..//x1 |
+     *   sed 's/0x/(byte) 0x/g'
+     */
+    private static final byte[] TEST_STRING_1_MAC = {
+            (byte) 0x29, (byte) 0xB1, (byte) 0x87, (byte) 0x6B, (byte) 0xFE, (byte) 0x83,
+            (byte) 0x96, (byte) 0x51, (byte) 0x61, (byte) 0x02, (byte) 0xAF, (byte) 0x7B,
+            (byte) 0xBA, (byte) 0x05, (byte) 0xE6, (byte) 0xA4, (byte) 0xAB, (byte) 0x36,
+            (byte) 0x18, (byte) 0x02
+    };
+
+    /**
+     * Same as TEST_STRING_1_MAC but with the first byte as 0x28 instead of
+     * 0x29.
+     */
+    private static final byte[] TEST_STRING_1_MAC_BROKEN = {
+            (byte) 0x28, (byte) 0xB1, (byte) 0x87, (byte) 0x6B, (byte) 0xFE, (byte) 0x83,
+            (byte) 0x96, (byte) 0x51, (byte) 0x61, (byte) 0x02, (byte) 0xAF, (byte) 0x7B,
+            (byte) 0xBA, (byte) 0x05, (byte) 0xE6, (byte) 0xA4, (byte) 0xAB, (byte) 0x36,
+            (byte) 0x18, (byte) 0x02
+    };
+
+    private ByteArrayInputStream mTestStream1;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        mTestStream1 = new ByteArrayInputStream(TEST_STRING_1);
+    }
+
+    public void testString1Authenticate_Success() throws Exception {
+        Mac mac = Mac.getInstance("HMAC-SHA1");
+        mac.init(HMAC_KEY_1);
+
+        MacAuthenticatedInputStream is = new MacAuthenticatedInputStream(mTestStream1, mac);
+
+        assertTrue(Arrays.equals(TEST_STRING_1, Streams.readFully(is)));
+
+        assertTrue(is.isTagEqual(TEST_STRING_1_MAC));
+    }
+
+    public void testString1Authenticate_WrongTag_Failure() throws Exception {
+        Mac mac = Mac.getInstance("HMAC-SHA1");
+        mac.init(HMAC_KEY_1);
+
+        MacAuthenticatedInputStream is = new MacAuthenticatedInputStream(mTestStream1, mac);
+
+        assertTrue(Arrays.equals(TEST_STRING_1, Streams.readFully(is)));
+
+        assertFalse(is.isTagEqual(TEST_STRING_1_MAC_BROKEN));
+    }
+
+    public void testString1Authenticate_NullTag_Failure() throws Exception {
+        Mac mac = Mac.getInstance("HMAC-SHA1");
+        mac.init(HMAC_KEY_1);
+
+        MacAuthenticatedInputStream is = new MacAuthenticatedInputStream(mTestStream1, mac);
+
+        assertTrue(Arrays.equals(TEST_STRING_1, Streams.readFully(is)));
+
+        assertFalse(is.isTagEqual(null));
+    }
+
+    public void testString1Authenticate_ReadSingleByte_Success() throws Exception {
+        Mac mac = Mac.getInstance("HMAC-SHA1");
+        mac.init(HMAC_KEY_1);
+
+        MacAuthenticatedInputStream is = new MacAuthenticatedInputStream(mTestStream1, mac);
+
+        int numRead = 0;
+        while (is.read() != -1) {
+            numRead++;
+
+            if (numRead > TEST_STRING_1.length) {
+                fail("read too many bytes");
+            }
+        }
+        assertEquals(TEST_STRING_1.length, numRead);
+
+        assertTrue(is.isTagEqual(TEST_STRING_1_MAC));
+    }
+}
diff --git a/data/fonts/Android.mk b/data/fonts/Android.mk
index 13f2480..16a98d3 100644
--- a/data/fonts/Android.mk
+++ b/data/fonts/Android.mk
@@ -142,6 +142,8 @@
     Roboto-Bold.ttf \
     Roboto-Italic.ttf \
     Roboto-BoldItalic.ttf \
+    Roboto-Light.ttf \
+    Roboto-LightItalic.ttf \
     DroidNaskh-Regular.ttf \
     DroidNaskh-Regular-SystemUI.ttf \
     DroidSansDevanagari-Regular.ttf \
diff --git a/data/fonts/Roboto-Light.ttf b/data/fonts/Roboto-Light.ttf
new file mode 100644
index 0000000..b50399e
--- /dev/null
+++ b/data/fonts/Roboto-Light.ttf
Binary files differ
diff --git a/data/fonts/Roboto-LightItalic.ttf b/data/fonts/Roboto-LightItalic.ttf
new file mode 100644
index 0000000..a1fdc8d
--- /dev/null
+++ b/data/fonts/Roboto-LightItalic.ttf
Binary files differ
diff --git a/data/fonts/fonts.mk b/data/fonts/fonts.mk
index 7a84df6..397ccda 100644
--- a/data/fonts/fonts.mk
+++ b/data/fonts/fonts.mk
@@ -24,6 +24,8 @@
     Roboto-Bold.ttf \
     Roboto-Italic.ttf \
     Roboto-BoldItalic.ttf \
+    Roboto-Light.ttf \
+    Roboto-LightItalic.ttf \
     DroidNaskh-Regular.ttf \
     DroidNaskh-Regular-SystemUI.ttf \
     DroidSansDevanagari-Regular.ttf \
diff --git a/data/fonts/system_fonts.xml b/data/fonts/system_fonts.xml
index d2fe546..95c4f70 100644
--- a/data/fonts/system_fonts.xml
+++ b/data/fonts/system_fonts.xml
@@ -36,6 +36,16 @@
 
     <family>
         <nameset>
+            <name>sans-serif-light</name>
+        </nameset>
+        <fileset>
+            <file>Roboto-Light.ttf</file>
+            <file>Roboto-LightItalic.ttf</file>
+        </fileset>
+    </family>
+
+    <family>
+        <nameset>
             <name>serif</name>
             <name>times</name>
             <name>times new roman</name>
diff --git a/drm/java/android/drm/DrmManagerClient.java b/drm/java/android/drm/DrmManagerClient.java
index 482ab0a..4b51994 100755
--- a/drm/java/android/drm/DrmManagerClient.java
+++ b/drm/java/android/drm/DrmManagerClient.java
@@ -242,6 +242,7 @@
     public DrmManagerClient(Context context) {
         mContext = context;
         mReleased = false;
+        createEventThreads();
 
         // save the unique id
         mUniqueId = _initialize();
@@ -283,21 +284,6 @@
         _release(mUniqueId);
     }
 
-
-    private void createListeners() {
-        if (mEventHandler == null && mInfoHandler == null) {
-            mInfoThread = new HandlerThread("DrmManagerClient.InfoHandler");
-            mInfoThread.start();
-            mInfoHandler = new InfoHandler(mInfoThread.getLooper());
-
-            mEventThread = new HandlerThread("DrmManagerClient.EventHandler");
-            mEventThread.start();
-            mEventHandler = new EventHandler(mEventThread.getLooper());
-            _setListeners(mUniqueId, new WeakReference<DrmManagerClient>(this));
-        }
-    }
-
-
     /**
      * Registers an {@link DrmManagerClient.OnInfoListener} callback, which is invoked when the 
      * DRM framework sends status or warning information during registration or rights acquisition.
@@ -878,5 +864,21 @@
     private native DrmConvertedStatus _closeConvertSession(int uniqueId, int convertId);
 
     private native DrmSupportInfo[] _getAllSupportInfo(int uniqueId);
+
+    private void createEventThreads() {
+        if (mEventHandler == null && mInfoHandler == null) {
+            mInfoThread = new HandlerThread("DrmManagerClient.InfoHandler");
+            mInfoThread.start();
+            mInfoHandler = new InfoHandler(mInfoThread.getLooper());
+
+            mEventThread = new HandlerThread("DrmManagerClient.EventHandler");
+            mEventThread.start();
+            mEventHandler = new EventHandler(mEventThread.getLooper());
+        }
+    }
+
+    private void createListeners() {
+        _setListeners(mUniqueId, new WeakReference<DrmManagerClient>(this));
+    }
 }
 
diff --git a/graphics/java/android/graphics/Canvas.java b/graphics/java/android/graphics/Canvas.java
index 7e92973..3949afd 100644
--- a/graphics/java/android/graphics/Canvas.java
+++ b/graphics/java/android/graphics/Canvas.java
@@ -1617,6 +1617,13 @@
      */
     public static native void freeCaches();
 
+    /**
+     * Free up text layout caches
+     *
+     * @hide
+     */
+    public static native void freeTextLayoutCaches();
+
     private static native int initRaster(int nativeBitmapOrZero);
     private static native void native_setBitmap(int nativeCanvas, int bitmap);
     private static native int native_saveLayer(int nativeCanvas, RectF bounds,
diff --git a/graphics/java/android/renderscript/Allocation.java b/graphics/java/android/renderscript/Allocation.java
index 6b1d66f..10ccb87 100644
--- a/graphics/java/android/renderscript/Allocation.java
+++ b/graphics/java/android/renderscript/Allocation.java
@@ -27,7 +27,7 @@
 import android.util.Log;
 import android.util.TypedValue;
 
-/** @deprecated renderscript is deprecated in J
+/**
  * <p>
  * Memory allocation class for renderscript.  An allocation combines a
  * {@link android.renderscript.Type} with the memory to provide storage for user data and objects.
@@ -93,7 +93,7 @@
     int mCurrentCount;
 
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * The usage of the allocation.  These signal to renderscript
      * where to place the allocation in memory.
      *
@@ -102,14 +102,14 @@
      */
     public static final int USAGE_SCRIPT = 0x0001;
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * GRAPHICS_TEXTURE The allocation will be used as a texture
      * source by one or more graphics programs.
      *
      */
     public static final int USAGE_GRAPHICS_TEXTURE = 0x0002;
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * GRAPHICS_VERTEX The allocation will be used as a graphics
      * mesh.
      *
@@ -117,21 +117,21 @@
     public static final int USAGE_GRAPHICS_VERTEX = 0x0004;
 
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * GRAPHICS_CONSTANTS The allocation will be used as the source
      * of shader constants by one or more programs.
      *
      */
     public static final int USAGE_GRAPHICS_CONSTANTS = 0x0008;
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * USAGE_GRAPHICS_RENDER_TARGET The allocation will be used as a
      * target for offscreen rendering
      *
      */
     public static final int USAGE_GRAPHICS_RENDER_TARGET = 0x0010;
 
-    /** @hide renderscript is deprecated in J
+    /**
      * USAGE_IO_INPUT The allocation will be used as SurfaceTexture
      * consumer.  This usage will cause the allocation to be created
      * read only.
@@ -139,7 +139,7 @@
      */
     public static final int USAGE_IO_INPUT = 0x0020;
 
-    /** @hide renderscript is deprecated in J
+    /**
      * USAGE_IO_OUTPUT The allocation will be used as a
      * SurfaceTexture producer.  The dimensions and format of the
      * SurfaceTexture will be forced to those of the allocation.
@@ -147,25 +147,25 @@
      */
     public static final int USAGE_IO_OUTPUT = 0x0040;
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Controls mipmap behavior when using the bitmap creation and
      * update functions.
      */
     public enum MipmapControl {
-        /** @deprecated renderscript is deprecated in J
+        /**
          * No mipmaps will be generated and the type generated from the
          * incoming bitmap will not contain additional LODs.
          */
         MIPMAP_NONE(0),
 
-        /** @deprecated renderscript is deprecated in J
+        /**
          * A Full mipmap chain will be created in script memory.  The
          * type of the allocation will contain a full mipmap chain.  On
          * upload to graphics the full chain will be transfered.
          */
         MIPMAP_FULL(1),
 
-        /** @deprecated renderscript is deprecated in J
+        /**
          * The type of the allocation will be the same as MIPMAP_NONE.
          * It will not contain mipmaps.  On upload to graphics the
          * graphics copy of the allocation data will contain a full
@@ -188,7 +188,7 @@
     }
 
 
-   /** @hide renderscript is deprecated in J
+   /**
      * Get the element of the type of the Allocation.
      *
      * @return Element that describes the structure of data in the
@@ -199,7 +199,7 @@
         return mType.getElement();
     }
 
-    /** @hide renderscript is deprecated in J
+    /**
      * Get the usage flags of the Allocation.
      *
      * @return usage flags associated with the allocation. e.g.
@@ -210,7 +210,7 @@
         return mUsage;
     }
 
-    /** @hide renderscript is deprecated in J
+    /**
      * Get the size of the Allocation in bytes.
      *
      * @return size of the Allocation in bytes.
@@ -326,7 +326,7 @@
         }
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Get the type of the Allocation.
      *
      * @return Type
@@ -336,7 +336,7 @@
         return mType;
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Propagate changes from one usage of the allocation to the
      * remaining usages of the allocation.
      *
@@ -355,7 +355,7 @@
         mRS.nAllocationSyncAll(getIDSafe(), srcLocation);
     }
 
-    /** @hide renderscript is deprecated in J
+    /**
      * Send a buffer to the output stream.  The contents of the
      * Allocation will be undefined after this operation.
      *
@@ -369,7 +369,7 @@
         mRS.nAllocationIoSend(getID(mRS));
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Delete once code is updated.
      * @hide
      */
@@ -377,7 +377,7 @@
         ioSend();
     }
 
-    /** @hide renderscript is deprecated in J
+    /**
      * Receive the latest input into the Allocation.
      *
      */
@@ -390,7 +390,7 @@
         mRS.nAllocationIoReceive(getID(mRS));
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Copy an array of RS objects to the allocation.
      *
      * @param d Source array.
@@ -461,7 +461,7 @@
         }
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Copy an allocation from an array.  This variant is not type
      * checked which allows an application to fill in structured
      * data from an array.
@@ -472,7 +472,7 @@
         mRS.validate();
         copy1DRangeFromUnchecked(0, mCurrentCount, d);
     }
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Copy an allocation from an array.  This variant is not type
      * checked which allows an application to fill in structured
      * data from an array.
@@ -483,7 +483,7 @@
         mRS.validate();
         copy1DRangeFromUnchecked(0, mCurrentCount, d);
     }
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Copy an allocation from an array.  This variant is not type
      * checked which allows an application to fill in structured
      * data from an array.
@@ -494,7 +494,7 @@
         mRS.validate();
         copy1DRangeFromUnchecked(0, mCurrentCount, d);
     }
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Copy an allocation from an array.  This variant is not type
      * checked which allows an application to fill in structured
      * data from an array.
@@ -506,7 +506,7 @@
         copy1DRangeFromUnchecked(0, mCurrentCount, d);
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Copy an allocation from an array.  This variant is type
      * checked and will generate exceptions if the Allocation type
      * is not a 32 bit integer type.
@@ -518,7 +518,7 @@
         copy1DRangeFrom(0, mCurrentCount, d);
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Copy an allocation from an array.  This variant is type
      * checked and will generate exceptions if the Allocation type
      * is not a 16 bit integer type.
@@ -530,7 +530,7 @@
         copy1DRangeFrom(0, mCurrentCount, d);
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Copy an allocation from an array.  This variant is type
      * checked and will generate exceptions if the Allocation type
      * is not a 8 bit integer type.
@@ -542,7 +542,7 @@
         copy1DRangeFrom(0, mCurrentCount, d);
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Copy an allocation from an array.  This variant is type
      * checked and will generate exceptions if the Allocation type
      * is not a 32 bit float type.
@@ -554,7 +554,7 @@
         copy1DRangeFrom(0, mCurrentCount, d);
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Copy an allocation from a bitmap.  The height, width, and
      * format of the bitmap must match the existing allocation.
      *
@@ -567,7 +567,7 @@
         mRS.nAllocationCopyFromBitmap(getID(mRS), b);
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * This is only intended to be used by auto-generate code reflected from the
      * renderscript script files.
      *
@@ -587,7 +587,7 @@
         copy1DRangeFromUnchecked(xoff, count, data);
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * This is only intended to be used by auto-generate code reflected from the
      * renderscript script files.
      *
@@ -634,7 +634,7 @@
         }
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Generate a mipmap chain.  Requires the type of the allocation
      * include mipmaps.
      *
@@ -648,7 +648,7 @@
         mRS.nAllocationGenerateMipmaps(getID(mRS));
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Copy part of an allocation from an array.  This variant is
      * not type checked which allows an application to fill in
      * structured data from an array.
@@ -662,7 +662,7 @@
         data1DChecks(off, count, d.length * 4, dataSize);
         mRS.nAllocationData1D(getIDSafe(), off, mSelectedLOD, count, d, dataSize);
     }
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Copy part of an allocation from an array.  This variant is
      * not type checked which allows an application to fill in
      * structured data from an array.
@@ -676,7 +676,7 @@
         data1DChecks(off, count, d.length * 2, dataSize);
         mRS.nAllocationData1D(getIDSafe(), off, mSelectedLOD, count, d, dataSize);
     }
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Copy part of an allocation from an array.  This variant is
      * not type checked which allows an application to fill in
      * structured data from an array.
@@ -690,7 +690,7 @@
         data1DChecks(off, count, d.length, dataSize);
         mRS.nAllocationData1D(getIDSafe(), off, mSelectedLOD, count, d, dataSize);
     }
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Copy part of an allocation from an array.  This variant is
      * not type checked which allows an application to fill in
      * structured data from an array.
@@ -705,7 +705,7 @@
         mRS.nAllocationData1D(getIDSafe(), off, mSelectedLOD, count, d, dataSize);
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Copy part of an allocation from an array.  This variant is
      * type checked and will generate exceptions if the Allocation
      * type is not a 32 bit integer type.
@@ -719,7 +719,7 @@
         copy1DRangeFromUnchecked(off, count, d);
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Copy part of an allocation from an array.  This variant is
      * type checked and will generate exceptions if the Allocation
      * type is not a 16 bit integer type.
@@ -733,7 +733,7 @@
         copy1DRangeFromUnchecked(off, count, d);
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Copy part of an allocation from an array.  This variant is
      * type checked and will generate exceptions if the Allocation
      * type is not a 8 bit integer type.
@@ -747,7 +747,7 @@
         copy1DRangeFromUnchecked(off, count, d);
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Copy part of an allocation from an array.  This variant is
      * type checked and will generate exceptions if the Allocation
      * type is not a 32 bit float type.
@@ -761,7 +761,7 @@
         copy1DRangeFromUnchecked(off, count, d);
     }
 
-     /** @deprecated renderscript is deprecated in J
+     /**
      * Copy part of an allocation from another allocation.
      *
      * @param off The offset of the first element to be copied.
@@ -794,7 +794,7 @@
         }
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Copy a rectangular region from the array into the allocation.
      * The incoming array is assumed to be tightly packed.
      *
@@ -811,8 +811,6 @@
                               w, h, data, data.length);
     }
 
-    /** @deprecated renderscript is deprecated in J
-     */
     public void copy2DRangeFrom(int xoff, int yoff, int w, int h, short[] data) {
         mRS.validate();
         validate2DRange(xoff, yoff, w, h);
@@ -820,8 +818,6 @@
                               w, h, data, data.length * 2);
     }
 
-    /** @deprecated renderscript is deprecated in J
-     */
     public void copy2DRangeFrom(int xoff, int yoff, int w, int h, int[] data) {
         mRS.validate();
         validate2DRange(xoff, yoff, w, h);
@@ -829,8 +825,6 @@
                               w, h, data, data.length * 4);
     }
 
-    /** @deprecated renderscript is deprecated in J
-     */
     public void copy2DRangeFrom(int xoff, int yoff, int w, int h, float[] data) {
         mRS.validate();
         validate2DRange(xoff, yoff, w, h);
@@ -838,7 +832,7 @@
                               w, h, data, data.length * 4);
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Copy a rectangular region into the allocation from another
      * allocation.
      *
@@ -860,7 +854,7 @@
                               data.mSelectedLOD, data.mSelectedFace.mID);
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Copy a bitmap into an allocation.  The height and width of
      * the update will use the height and width of the incoming
      * bitmap.
@@ -877,7 +871,7 @@
     }
 
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Copy from the Allocation into a Bitmap.  The bitmap must
      * match the dimensions of the Allocation.
      *
@@ -890,7 +884,7 @@
         mRS.nAllocationCopyToBitmap(getID(mRS), b);
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Copy from the Allocation into a byte array.  The array must
      * be at least as large as the Allocation.  The allocation must
      * be of an 8 bit elemental type.
@@ -903,7 +897,7 @@
         mRS.nAllocationRead(getID(mRS), d);
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Copy from the Allocation into a short array.  The array must
      * be at least as large as the Allocation.  The allocation must
      * be of an 16 bit elemental type.
@@ -916,7 +910,7 @@
         mRS.nAllocationRead(getID(mRS), d);
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Copy from the Allocation into a int array.  The array must be
      * at least as large as the Allocation.  The allocation must be
      * of an 32 bit elemental type.
@@ -929,7 +923,7 @@
         mRS.nAllocationRead(getID(mRS), d);
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Copy from the Allocation into a float array.  The array must
      * be at least as large as the Allocation.  The allocation must
      * be of an 32 bit float elemental type.
@@ -942,7 +936,7 @@
         mRS.nAllocationRead(getID(mRS), d);
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Resize a 1D allocation.  The contents of the allocation are
      * preserved.  If new elements are allocated objects are created
      * with null contents and the new region is otherwise undefined.
@@ -967,7 +961,7 @@
         updateCacheInfo(mType);
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Resize a 2D allocation.  The contents of the allocation are
      * preserved.  If new elements are allocated objects are created
      * with null contents and the new region is otherwise undefined.
@@ -1008,7 +1002,7 @@
         mBitmapOptions.inScaled = false;
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      *
      * @param type renderscript type describing data layout
      * @param mips specifies desired mipmap behaviour for the
@@ -1028,7 +1022,7 @@
         return new Allocation(id, rs, type, usage);
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Creates a renderscript allocation with the size specified by
      * the type and no mipmaps generated by default
      *
@@ -1043,7 +1037,7 @@
         return createTyped(rs, type, MipmapControl.MIPMAP_NONE, usage);
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Creates a renderscript allocation for use by the script with
      * the size specified by the type and no mipmaps generated by
      * default
@@ -1057,7 +1051,7 @@
         return createTyped(rs, type, MipmapControl.MIPMAP_NONE, USAGE_SCRIPT);
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Creates a renderscript allocation with a specified number of
      * given elements
      *
@@ -1083,7 +1077,7 @@
         return new Allocation(id, rs, t, usage);
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Creates a renderscript allocation with a specified number of
      * given elements
      *
@@ -1124,7 +1118,7 @@
         return tb.create();
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Creates a renderscript allocation from a bitmap
      *
      * @param rs Context to which the allocation will belong.
@@ -1150,7 +1144,7 @@
         return new Allocation(id, rs, t, usage);
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      *
      *
      * @hide
@@ -1168,7 +1162,7 @@
         return st;
     }
 
-    /** @hide renderscript is deprecated in J
+    /**
      * For allocations used with io operations, returns the handle
      * onto a raw buffer that is being managed by the screen
      * compositor.
@@ -1180,7 +1174,7 @@
         return new Surface(getSurfaceTexture());
     }
 
-    /** @hide renderscript is deprecated in J
+    /**
      * Associate a surface for io output with this allocation
      *
      * @param sur Surface to associate with allocation
@@ -1194,7 +1188,7 @@
         mRS.nAllocationSetSurface(getID(mRS), sur);
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * @hide
      */
     public void setSurfaceTexture(SurfaceTexture st) {
@@ -1207,7 +1201,7 @@
         mRS.nAllocationSetSurface(getID(mRS), s);
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Creates a non-mipmapped renderscript allocation to use as a
      * graphics texture
      *
@@ -1222,7 +1216,7 @@
                                 USAGE_GRAPHICS_TEXTURE);
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Creates a cubemap allocation from a bitmap containing the
      * horizontal list of cube faces. Each individual face must be
      * the same size and power of 2
@@ -1270,7 +1264,7 @@
         return new Allocation(id, rs, t, usage);
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Creates a non-mipmapped cubemap allocation for use as a
      * graphics texture from a bitmap containing the horizontal list
      * of cube faces. Each individual face must be the same size and
@@ -1289,7 +1283,7 @@
                                        USAGE_GRAPHICS_TEXTURE);
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Creates a cubemap allocation from 6 bitmaps containing
      * the cube faces. All the faces must be the same size and
      * power of 2
@@ -1356,7 +1350,7 @@
         return cubemap;
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Creates a non-mipmapped cubemap allocation for use as a
      * graphics texture from 6 bitmaps containing
      * the cube faces. All the faces must be the same size and
@@ -1385,7 +1379,7 @@
                                           USAGE_GRAPHICS_TEXTURE);
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Creates a renderscript allocation from the bitmap referenced
      * by resource id
      *
@@ -1413,7 +1407,7 @@
         return alloc;
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Creates a non-mipmapped renderscript allocation to use as a
      * graphics texture from the bitmap referenced by resource id
      *
@@ -1432,7 +1426,7 @@
                                         USAGE_GRAPHICS_TEXTURE);
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Creates a renderscript allocation containing string data
      * encoded in UTF-8 format
      *
diff --git a/graphics/java/android/renderscript/AllocationAdapter.java b/graphics/java/android/renderscript/AllocationAdapter.java
index 3b5993a..85d86e5 100644
--- a/graphics/java/android/renderscript/AllocationAdapter.java
+++ b/graphics/java/android/renderscript/AllocationAdapter.java
@@ -21,7 +21,7 @@
 import android.graphics.BitmapFactory;
 import android.util.TypedValue;
 
-/** @deprecated renderscript is deprecated in J
+/**
  *
  **/
 public class AllocationAdapter extends Allocation {
@@ -129,7 +129,7 @@
         mSelectedZ = 0;
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Set the active LOD.  The LOD must be within the range for the
      * type being adapted.  The base allocation must have mipmaps.
      *
@@ -149,7 +149,7 @@
         initLOD(lod);
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Set the active Face.  The base allocation must be of a type
      * that includes faces.
      *
@@ -169,7 +169,7 @@
         mSelectedFace = cf;
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Set the active Y.  The y value must be within the range for
      * the allocation being adapted.  The base allocation must
      * contain the Y dimension.
@@ -190,7 +190,7 @@
         mSelectedY = y;
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Set the active Z.  The z value must be within the range for
      * the allocation being adapted.  The base allocation must
      * contain the Z dimension.
@@ -211,8 +211,6 @@
         mSelectedZ = z;
     }
 
-    /** @deprecated renderscript is deprecated in J
-     */
     static public AllocationAdapter create1D(RenderScript rs, Allocation a) {
         rs.validate();
         AllocationAdapter aa = new AllocationAdapter(0, rs, a);
@@ -224,8 +222,6 @@
         return aa;
     }
 
-    /** @deprecated renderscript is deprecated in J
-     */
     static public AllocationAdapter create2D(RenderScript rs, Allocation a) {
         android.util.Log.e("rs", "create2d " + a);
         rs.validate();
@@ -239,7 +235,7 @@
     }
 
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Override the Allocation resize.  Resizing adapters is not
      * allowed and will throw a RSInvalidStateException.
      *
diff --git a/graphics/java/android/renderscript/BaseObj.java b/graphics/java/android/renderscript/BaseObj.java
index 0d74212..f464f9b 100644
--- a/graphics/java/android/renderscript/BaseObj.java
+++ b/graphics/java/android/renderscript/BaseObj.java
@@ -18,7 +18,7 @@
 
 import android.util.Log;
 
-/** @deprecated renderscript is deprecated in J
+/**
  * BaseObj is the base class for interfacing with native renderscript objects.
  * It primarly contains code for tracking the native object ID and forcably
  * disconecting the object from the native allocation for early cleanup.
@@ -39,7 +39,7 @@
         mID = id;
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Lookup the native object ID for this object.  Primarily used by the
      * generated reflected code.
      *
@@ -73,7 +73,7 @@
     private String mName;
     RenderScript mRS;
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * setName assigns a name to an object.  This object can later be looked up
      * by this name.  This name will also be retained if the object is written
      * to an A3D file.
@@ -103,7 +103,7 @@
         }
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * @return name of the renderscript object
      */
     public String getName() {
@@ -124,7 +124,7 @@
         super.finalize();
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * destroy disconnects the object from the native object effectively
      * rendering this java object dead.  The primary use is to force immediate
      * cleanup of resources when it is believed the GC will not respond quickly
@@ -138,7 +138,7 @@
         mRS.nObjDestroy(mID);
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * If an object came from an a3d file, java fields need to be
      * created with objects from the native layer
      */
@@ -147,7 +147,7 @@
         mName = mRS.nGetName(getID(mRS));
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Calculates the hash code value for a BaseObj.
      *
      * @return int
@@ -157,7 +157,7 @@
         return mID;
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Compare the current BaseObj with another BaseObj for equality.
      *
      * @param obj The object to check equality with.
diff --git a/graphics/java/android/renderscript/Byte2.java b/graphics/java/android/renderscript/Byte2.java
index 163b8bd..7df5f2e 100644
--- a/graphics/java/android/renderscript/Byte2.java
+++ b/graphics/java/android/renderscript/Byte2.java
@@ -20,7 +20,7 @@
 import android.util.Log;
 
 
-/** @deprecated renderscript is deprecated in J
+/**
  * Class for exposing the native Renderscript byte2 type back to the Android system.
  *
  **/
diff --git a/graphics/java/android/renderscript/Byte3.java b/graphics/java/android/renderscript/Byte3.java
index eaa1d5f9..02a01c1 100644
--- a/graphics/java/android/renderscript/Byte3.java
+++ b/graphics/java/android/renderscript/Byte3.java
@@ -20,7 +20,7 @@
 import android.util.Log;
 
 
-/** @deprecated renderscript is deprecated in J
+/**
  * Class for exposing the native Renderscript byte3 type back to the Android system.
  *
  **/
diff --git a/graphics/java/android/renderscript/Byte4.java b/graphics/java/android/renderscript/Byte4.java
index e162f9d..a55a696 100644
--- a/graphics/java/android/renderscript/Byte4.java
+++ b/graphics/java/android/renderscript/Byte4.java
@@ -20,7 +20,7 @@
 import android.util.Log;
 
 
-/** @deprecated renderscript is deprecated in J
+/**
  * Class for exposing the native Renderscript byte4 type back to the Android system.
  *
  **/
diff --git a/graphics/java/android/renderscript/Double2.java b/graphics/java/android/renderscript/Double2.java
index 0ef2f2b..9f4f328 100644
--- a/graphics/java/android/renderscript/Double2.java
+++ b/graphics/java/android/renderscript/Double2.java
@@ -20,7 +20,7 @@
 import android.util.Log;
 
 
-/** @deprecated renderscript is deprecated in J
+/**
  * Class for exposing the native Renderscript double2 type back
  * to the Android system.
  *
diff --git a/graphics/java/android/renderscript/Double3.java b/graphics/java/android/renderscript/Double3.java
index 09aba18..eb55142 100644
--- a/graphics/java/android/renderscript/Double3.java
+++ b/graphics/java/android/renderscript/Double3.java
@@ -20,7 +20,7 @@
 import android.util.Log;
 
 
-/** @deprecated renderscript is deprecated in J
+/**
  * Class for exposing the native Renderscript double3 type back
  * to the Android system.
  *
diff --git a/graphics/java/android/renderscript/Double4.java b/graphics/java/android/renderscript/Double4.java
index c5211be..4755a76 100644
--- a/graphics/java/android/renderscript/Double4.java
+++ b/graphics/java/android/renderscript/Double4.java
@@ -20,7 +20,7 @@
 import android.util.Log;
 
 
-/** @deprecated renderscript is deprecated in J
+/**
  * Class for exposing the native Renderscript double4 type back
  * to the Android system.
  *
diff --git a/graphics/java/android/renderscript/Element.java b/graphics/java/android/renderscript/Element.java
index 6872310..060f526 100644
--- a/graphics/java/android/renderscript/Element.java
+++ b/graphics/java/android/renderscript/Element.java
@@ -19,7 +19,7 @@
 import java.lang.reflect.Field;
 import android.util.Log;
 
-/** @deprecated renderscript is deprecated in J
+/**
  * <p>The most basic data type. An element represents one cell of a memory allocation.
  * Element is the basic data type of Renderscript. An element can be of two forms: Basic elements or Complex forms.
  * Examples of basic elements are:</p>
@@ -84,12 +84,12 @@
         }
     }
 
-    /** @hide renderscript is deprecated in J
+    /**
     * @return element size in bytes
     */
     public int getBytesSize() {return mSize;}
 
-    /** @hide renderscript is deprecated in J
+    /**
     * Returns the number of vector components. 2 for float2, 4 for
     * float4, etc.
     * @return element vector size
@@ -97,7 +97,7 @@
     public int getVectorSize() {return mVectorSize;}
 
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * DataType represents the basic type information for a basic element.  The
      * naming convention follows.  For numeric types it is FLOAT,
      * SIGNED, or UNSIGNED followed by the _BITS where BITS is the
@@ -114,8 +114,6 @@
      * RS_* objects.  32 bit opaque handles.
      */
     public enum DataType {
-        /** @hide
-        */
         NONE (0, 0),
         //FLOAT_16 (1, 2),
         FLOAT_32 (2, 4),
@@ -159,7 +157,7 @@
         }
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * The special interpretation of the data if required.  This is primarly
      * useful for graphical data.  USER indicates no special interpretation is
      * expected.  PIXEL is used in conjunction with the standard data types for
@@ -181,7 +179,7 @@
         }
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Return if a element is too complex for use as a data source for a Mesh or
      * a Program.
      *
@@ -199,7 +197,7 @@
         return false;
     }
 
-    /** @hide renderscript is deprecated in J
+    /**
     * Elements could be simple, such as an int or a float, or a
     * structure with multiple sub elements, such as a collection of
     * floats, float2, float4. This function returns zero for simple
@@ -213,7 +211,7 @@
         return mVisibleElementMap.length;
     }
 
-    /** @hide renderscript is deprecated in J
+    /**
     * For complex elements, this function will return the
     * sub-element at index
     * @param index index of the sub-element to return
@@ -229,7 +227,7 @@
         return mElements[mVisibleElementMap[index]];
     }
 
-    /** @hide renderscript is deprecated in J
+    /**
     * For complex elements, this function will return the
     * sub-element name at index
     * @param index index of the sub-element
@@ -245,7 +243,7 @@
         return mElementNames[mVisibleElementMap[index]];
     }
 
-    /** @hide renderscript is deprecated in J
+    /**
     * For complex elements, some sub-elements could be statically
     * sized arrays. This function will return the array size for
     * sub-element at index
@@ -262,7 +260,7 @@
         return mArraySizes[mVisibleElementMap[index]];
     }
 
-    /** @hide renderscript is deprecated in J
+    /**
     * This function specifies the location of a sub-element within
     * the element
     * @param index index of the sub-element
@@ -278,21 +276,21 @@
         return mOffsetInBytes[mVisibleElementMap[index]];
     }
 
-    /** @hide renderscript is deprecated in J
+    /**
     * @return element data type
     */
     public DataType getDataType() {
         return mType;
     }
 
-    /** @hide renderscript is deprecated in J
+    /**
     * @return element data kind
     */
     public DataKind getDataKind() {
         return mKind;
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Utility function for returning an Element containing a single Boolean.
      *
      * @param rs Context to which the element will belong.
@@ -306,7 +304,7 @@
         return rs.mElement_BOOLEAN;
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Utility function for returning an Element containing a single UNSIGNED_8.
      *
      * @param rs Context to which the element will belong.
@@ -320,7 +318,7 @@
         return rs.mElement_U8;
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Utility function for returning an Element containing a single SIGNED_8.
      *
      * @param rs Context to which the element will belong.
@@ -334,8 +332,6 @@
         return rs.mElement_I8;
     }
 
-    /** @deprecated renderscript is deprecated in J
-     */
     public static Element U16(RenderScript rs) {
         if(rs.mElement_U16 == null) {
             rs.mElement_U16 = createUser(rs, DataType.UNSIGNED_16);
@@ -343,8 +339,6 @@
         return rs.mElement_U16;
     }
 
-    /** @deprecated renderscript is deprecated in J
-     */
     public static Element I16(RenderScript rs) {
         if(rs.mElement_I16 == null) {
             rs.mElement_I16 = createUser(rs, DataType.SIGNED_16);
@@ -352,8 +346,6 @@
         return rs.mElement_I16;
     }
 
-    /** @deprecated renderscript is deprecated in J
-     */
     public static Element U32(RenderScript rs) {
         if(rs.mElement_U32 == null) {
             rs.mElement_U32 = createUser(rs, DataType.UNSIGNED_32);
@@ -361,8 +353,6 @@
         return rs.mElement_U32;
     }
 
-    /** @deprecated renderscript is deprecated in J
-     */
     public static Element I32(RenderScript rs) {
         if(rs.mElement_I32 == null) {
             rs.mElement_I32 = createUser(rs, DataType.SIGNED_32);
@@ -370,8 +360,6 @@
         return rs.mElement_I32;
     }
 
-    /** @deprecated renderscript is deprecated in J
-     */
     public static Element U64(RenderScript rs) {
         if(rs.mElement_U64 == null) {
             rs.mElement_U64 = createUser(rs, DataType.UNSIGNED_64);
@@ -379,8 +367,6 @@
         return rs.mElement_U64;
     }
 
-    /** @deprecated renderscript is deprecated in J
-     */
     public static Element I64(RenderScript rs) {
         if(rs.mElement_I64 == null) {
             rs.mElement_I64 = createUser(rs, DataType.SIGNED_64);
@@ -388,8 +374,6 @@
         return rs.mElement_I64;
     }
 
-    /** @deprecated renderscript is deprecated in J
-     */
     public static Element F32(RenderScript rs) {
         if(rs.mElement_F32 == null) {
             rs.mElement_F32 = createUser(rs, DataType.FLOAT_32);
@@ -397,8 +381,6 @@
         return rs.mElement_F32;
     }
 
-    /** @deprecated renderscript is deprecated in J
-     */
     public static Element F64(RenderScript rs) {
         if(rs.mElement_F64 == null) {
             rs.mElement_F64 = createUser(rs, DataType.FLOAT_64);
@@ -406,8 +388,6 @@
         return rs.mElement_F64;
     }
 
-    /** @deprecated renderscript is deprecated in J
-     */
     public static Element ELEMENT(RenderScript rs) {
         if(rs.mElement_ELEMENT == null) {
             rs.mElement_ELEMENT = createUser(rs, DataType.RS_ELEMENT);
@@ -415,8 +395,6 @@
         return rs.mElement_ELEMENT;
     }
 
-    /** @deprecated renderscript is deprecated in J
-     */
     public static Element TYPE(RenderScript rs) {
         if(rs.mElement_TYPE == null) {
             rs.mElement_TYPE = createUser(rs, DataType.RS_TYPE);
@@ -424,8 +402,6 @@
         return rs.mElement_TYPE;
     }
 
-    /** @deprecated renderscript is deprecated in J
-     */
     public static Element ALLOCATION(RenderScript rs) {
         if(rs.mElement_ALLOCATION == null) {
             rs.mElement_ALLOCATION = createUser(rs, DataType.RS_ALLOCATION);
@@ -433,8 +409,6 @@
         return rs.mElement_ALLOCATION;
     }
 
-    /** @deprecated renderscript is deprecated in J
-     */
     public static Element SAMPLER(RenderScript rs) {
         if(rs.mElement_SAMPLER == null) {
             rs.mElement_SAMPLER = createUser(rs, DataType.RS_SAMPLER);
@@ -442,8 +416,6 @@
         return rs.mElement_SAMPLER;
     }
 
-    /** @deprecated renderscript is deprecated in J
-     */
     public static Element SCRIPT(RenderScript rs) {
         if(rs.mElement_SCRIPT == null) {
             rs.mElement_SCRIPT = createUser(rs, DataType.RS_SCRIPT);
@@ -451,8 +423,6 @@
         return rs.mElement_SCRIPT;
     }
 
-    /** @deprecated renderscript is deprecated in J
-     */
     public static Element MESH(RenderScript rs) {
         if(rs.mElement_MESH == null) {
             rs.mElement_MESH = createUser(rs, DataType.RS_MESH);
@@ -460,8 +430,6 @@
         return rs.mElement_MESH;
     }
 
-    /** @deprecated renderscript is deprecated in J
-     */
     public static Element PROGRAM_FRAGMENT(RenderScript rs) {
         if(rs.mElement_PROGRAM_FRAGMENT == null) {
             rs.mElement_PROGRAM_FRAGMENT = createUser(rs, DataType.RS_PROGRAM_FRAGMENT);
@@ -469,8 +437,6 @@
         return rs.mElement_PROGRAM_FRAGMENT;
     }
 
-    /** @deprecated renderscript is deprecated in J
-     */
     public static Element PROGRAM_VERTEX(RenderScript rs) {
         if(rs.mElement_PROGRAM_VERTEX == null) {
             rs.mElement_PROGRAM_VERTEX = createUser(rs, DataType.RS_PROGRAM_VERTEX);
@@ -478,8 +444,6 @@
         return rs.mElement_PROGRAM_VERTEX;
     }
 
-    /** @deprecated renderscript is deprecated in J
-     */
     public static Element PROGRAM_RASTER(RenderScript rs) {
         if(rs.mElement_PROGRAM_RASTER == null) {
             rs.mElement_PROGRAM_RASTER = createUser(rs, DataType.RS_PROGRAM_RASTER);
@@ -487,8 +451,6 @@
         return rs.mElement_PROGRAM_RASTER;
     }
 
-    /** @deprecated renderscript is deprecated in J
-     */
     public static Element PROGRAM_STORE(RenderScript rs) {
         if(rs.mElement_PROGRAM_STORE == null) {
             rs.mElement_PROGRAM_STORE = createUser(rs, DataType.RS_PROGRAM_STORE);
@@ -496,8 +458,6 @@
         return rs.mElement_PROGRAM_STORE;
     }
 
-    /** @deprecated renderscript is deprecated in J
-     */
     public static Element FONT(RenderScript rs) {
         if(rs.mElement_FONT == null) {
             rs.mElement_FONT = createUser(rs, DataType.RS_FONT);
@@ -505,8 +465,7 @@
         return rs.mElement_FONT;
     }
 
-    /** @deprecated renderscript is deprecated in J
-     */
+
     public static Element A_8(RenderScript rs) {
         if(rs.mElement_A_8 == null) {
             rs.mElement_A_8 = createPixel(rs, DataType.UNSIGNED_8, DataKind.PIXEL_A);
@@ -514,8 +473,6 @@
         return rs.mElement_A_8;
     }
 
-    /** @deprecated renderscript is deprecated in J
-     */
     public static Element RGB_565(RenderScript rs) {
         if(rs.mElement_RGB_565 == null) {
             rs.mElement_RGB_565 = createPixel(rs, DataType.UNSIGNED_5_6_5, DataKind.PIXEL_RGB);
@@ -523,8 +480,6 @@
         return rs.mElement_RGB_565;
     }
 
-    /** @deprecated renderscript is deprecated in J
-     */
     public static Element RGB_888(RenderScript rs) {
         if(rs.mElement_RGB_888 == null) {
             rs.mElement_RGB_888 = createPixel(rs, DataType.UNSIGNED_8, DataKind.PIXEL_RGB);
@@ -532,8 +487,6 @@
         return rs.mElement_RGB_888;
     }
 
-    /** @deprecated renderscript is deprecated in J
-     */
     public static Element RGBA_5551(RenderScript rs) {
         if(rs.mElement_RGBA_5551 == null) {
             rs.mElement_RGBA_5551 = createPixel(rs, DataType.UNSIGNED_5_5_5_1, DataKind.PIXEL_RGBA);
@@ -541,8 +494,6 @@
         return rs.mElement_RGBA_5551;
     }
 
-    /** @deprecated renderscript is deprecated in J
-     */
     public static Element RGBA_4444(RenderScript rs) {
         if(rs.mElement_RGBA_4444 == null) {
             rs.mElement_RGBA_4444 = createPixel(rs, DataType.UNSIGNED_4_4_4_4, DataKind.PIXEL_RGBA);
@@ -550,8 +501,6 @@
         return rs.mElement_RGBA_4444;
     }
 
-    /** @deprecated renderscript is deprecated in J
-     */
     public static Element RGBA_8888(RenderScript rs) {
         if(rs.mElement_RGBA_8888 == null) {
             rs.mElement_RGBA_8888 = createPixel(rs, DataType.UNSIGNED_8, DataKind.PIXEL_RGBA);
@@ -559,8 +508,6 @@
         return rs.mElement_RGBA_8888;
     }
 
-    /** @deprecated renderscript is deprecated in J
-     */
     public static Element F32_2(RenderScript rs) {
         if(rs.mElement_FLOAT_2 == null) {
             rs.mElement_FLOAT_2 = createVector(rs, DataType.FLOAT_32, 2);
@@ -568,8 +515,6 @@
         return rs.mElement_FLOAT_2;
     }
 
-    /** @deprecated renderscript is deprecated in J
-     */
     public static Element F32_3(RenderScript rs) {
         if(rs.mElement_FLOAT_3 == null) {
             rs.mElement_FLOAT_3 = createVector(rs, DataType.FLOAT_32, 3);
@@ -577,8 +522,6 @@
         return rs.mElement_FLOAT_3;
     }
 
-    /** @deprecated renderscript is deprecated in J
-     */
     public static Element F32_4(RenderScript rs) {
         if(rs.mElement_FLOAT_4 == null) {
             rs.mElement_FLOAT_4 = createVector(rs, DataType.FLOAT_32, 4);
@@ -586,8 +529,6 @@
         return rs.mElement_FLOAT_4;
     }
 
-    /** @deprecated renderscript is deprecated in J
-     */
     public static Element F64_2(RenderScript rs) {
         if(rs.mElement_DOUBLE_2 == null) {
             rs.mElement_DOUBLE_2 = createVector(rs, DataType.FLOAT_64, 2);
@@ -595,8 +536,6 @@
         return rs.mElement_DOUBLE_2;
     }
 
-    /** @deprecated renderscript is deprecated in J
-     */
     public static Element F64_3(RenderScript rs) {
         if(rs.mElement_DOUBLE_3 == null) {
             rs.mElement_DOUBLE_3 = createVector(rs, DataType.FLOAT_64, 3);
@@ -604,8 +543,6 @@
         return rs.mElement_DOUBLE_3;
     }
 
-    /** @deprecated renderscript is deprecated in J
-     */
     public static Element F64_4(RenderScript rs) {
         if(rs.mElement_DOUBLE_4 == null) {
             rs.mElement_DOUBLE_4 = createVector(rs, DataType.FLOAT_64, 4);
@@ -613,8 +550,6 @@
         return rs.mElement_DOUBLE_4;
     }
 
-    /** @deprecated renderscript is deprecated in J
-     */
     public static Element U8_2(RenderScript rs) {
         if(rs.mElement_UCHAR_2 == null) {
             rs.mElement_UCHAR_2 = createVector(rs, DataType.UNSIGNED_8, 2);
@@ -622,8 +557,6 @@
         return rs.mElement_UCHAR_2;
     }
 
-    /** @deprecated renderscript is deprecated in J
-     */
     public static Element U8_3(RenderScript rs) {
         if(rs.mElement_UCHAR_3 == null) {
             rs.mElement_UCHAR_3 = createVector(rs, DataType.UNSIGNED_8, 3);
@@ -631,8 +564,6 @@
         return rs.mElement_UCHAR_3;
     }
 
-    /** @deprecated renderscript is deprecated in J
-     */
     public static Element U8_4(RenderScript rs) {
         if(rs.mElement_UCHAR_4 == null) {
             rs.mElement_UCHAR_4 = createVector(rs, DataType.UNSIGNED_8, 4);
@@ -640,8 +571,6 @@
         return rs.mElement_UCHAR_4;
     }
 
-    /** @deprecated renderscript is deprecated in J
-     */
     public static Element I8_2(RenderScript rs) {
         if(rs.mElement_CHAR_2 == null) {
             rs.mElement_CHAR_2 = createVector(rs, DataType.SIGNED_8, 2);
@@ -649,8 +578,6 @@
         return rs.mElement_CHAR_2;
     }
 
-    /** @deprecated renderscript is deprecated in J
-     */
     public static Element I8_3(RenderScript rs) {
         if(rs.mElement_CHAR_3 == null) {
             rs.mElement_CHAR_3 = createVector(rs, DataType.SIGNED_8, 3);
@@ -658,8 +585,6 @@
         return rs.mElement_CHAR_3;
     }
 
-    /** @deprecated renderscript is deprecated in J
-     */
     public static Element I8_4(RenderScript rs) {
         if(rs.mElement_CHAR_4 == null) {
             rs.mElement_CHAR_4 = createVector(rs, DataType.SIGNED_8, 4);
@@ -667,8 +592,6 @@
         return rs.mElement_CHAR_4;
     }
 
-    /** @deprecated renderscript is deprecated in J
-     */
     public static Element U16_2(RenderScript rs) {
         if(rs.mElement_USHORT_2 == null) {
             rs.mElement_USHORT_2 = createVector(rs, DataType.UNSIGNED_16, 2);
@@ -676,8 +599,6 @@
         return rs.mElement_USHORT_2;
     }
 
-    /** @deprecated renderscript is deprecated in J
-     */
     public static Element U16_3(RenderScript rs) {
         if(rs.mElement_USHORT_3 == null) {
             rs.mElement_USHORT_3 = createVector(rs, DataType.UNSIGNED_16, 3);
@@ -685,8 +606,6 @@
         return rs.mElement_USHORT_3;
     }
 
-    /** @deprecated renderscript is deprecated in J
-     */
     public static Element U16_4(RenderScript rs) {
         if(rs.mElement_USHORT_4 == null) {
             rs.mElement_USHORT_4 = createVector(rs, DataType.UNSIGNED_16, 4);
@@ -694,8 +613,6 @@
         return rs.mElement_USHORT_4;
     }
 
-    /** @deprecated renderscript is deprecated in J
-     */
     public static Element I16_2(RenderScript rs) {
         if(rs.mElement_SHORT_2 == null) {
             rs.mElement_SHORT_2 = createVector(rs, DataType.SIGNED_16, 2);
@@ -703,8 +620,6 @@
         return rs.mElement_SHORT_2;
     }
 
-    /** @deprecated renderscript is deprecated in J
-     */
     public static Element I16_3(RenderScript rs) {
         if(rs.mElement_SHORT_3 == null) {
             rs.mElement_SHORT_3 = createVector(rs, DataType.SIGNED_16, 3);
@@ -712,8 +627,6 @@
         return rs.mElement_SHORT_3;
     }
 
-    /** @deprecated renderscript is deprecated in J
-     */
     public static Element I16_4(RenderScript rs) {
         if(rs.mElement_SHORT_4 == null) {
             rs.mElement_SHORT_4 = createVector(rs, DataType.SIGNED_16, 4);
@@ -721,8 +634,6 @@
         return rs.mElement_SHORT_4;
     }
 
-    /** @deprecated renderscript is deprecated in J
-     */
     public static Element U32_2(RenderScript rs) {
         if(rs.mElement_UINT_2 == null) {
             rs.mElement_UINT_2 = createVector(rs, DataType.UNSIGNED_32, 2);
@@ -730,8 +641,6 @@
         return rs.mElement_UINT_2;
     }
 
-    /** @deprecated renderscript is deprecated in J
-     */
     public static Element U32_3(RenderScript rs) {
         if(rs.mElement_UINT_3 == null) {
             rs.mElement_UINT_3 = createVector(rs, DataType.UNSIGNED_32, 3);
@@ -739,8 +648,6 @@
         return rs.mElement_UINT_3;
     }
 
-    /** @deprecated renderscript is deprecated in J
-     */
     public static Element U32_4(RenderScript rs) {
         if(rs.mElement_UINT_4 == null) {
             rs.mElement_UINT_4 = createVector(rs, DataType.UNSIGNED_32, 4);
@@ -748,8 +655,6 @@
         return rs.mElement_UINT_4;
     }
 
-    /** @deprecated renderscript is deprecated in J
-     */
     public static Element I32_2(RenderScript rs) {
         if(rs.mElement_INT_2 == null) {
             rs.mElement_INT_2 = createVector(rs, DataType.SIGNED_32, 2);
@@ -757,8 +662,6 @@
         return rs.mElement_INT_2;
     }
 
-    /** @deprecated renderscript is deprecated in J
-     */
     public static Element I32_3(RenderScript rs) {
         if(rs.mElement_INT_3 == null) {
             rs.mElement_INT_3 = createVector(rs, DataType.SIGNED_32, 3);
@@ -766,8 +669,6 @@
         return rs.mElement_INT_3;
     }
 
-    /** @deprecated renderscript is deprecated in J
-     */
     public static Element I32_4(RenderScript rs) {
         if(rs.mElement_INT_4 == null) {
             rs.mElement_INT_4 = createVector(rs, DataType.SIGNED_32, 4);
@@ -775,8 +676,6 @@
         return rs.mElement_INT_4;
     }
 
-    /** @deprecated renderscript is deprecated in J
-     */
     public static Element U64_2(RenderScript rs) {
         if(rs.mElement_ULONG_2 == null) {
             rs.mElement_ULONG_2 = createVector(rs, DataType.UNSIGNED_64, 2);
@@ -784,8 +683,6 @@
         return rs.mElement_ULONG_2;
     }
 
-    /** @deprecated renderscript is deprecated in J
-     */
     public static Element U64_3(RenderScript rs) {
         if(rs.mElement_ULONG_3 == null) {
             rs.mElement_ULONG_3 = createVector(rs, DataType.UNSIGNED_64, 3);
@@ -793,8 +690,6 @@
         return rs.mElement_ULONG_3;
     }
 
-    /** @deprecated renderscript is deprecated in J
-     */
     public static Element U64_4(RenderScript rs) {
         if(rs.mElement_ULONG_4 == null) {
             rs.mElement_ULONG_4 = createVector(rs, DataType.UNSIGNED_64, 4);
@@ -802,8 +697,6 @@
         return rs.mElement_ULONG_4;
     }
 
-    /** @deprecated renderscript is deprecated in J
-     */
     public static Element I64_2(RenderScript rs) {
         if(rs.mElement_LONG_2 == null) {
             rs.mElement_LONG_2 = createVector(rs, DataType.SIGNED_64, 2);
@@ -811,8 +704,6 @@
         return rs.mElement_LONG_2;
     }
 
-    /** @deprecated renderscript is deprecated in J
-     */
     public static Element I64_3(RenderScript rs) {
         if(rs.mElement_LONG_3 == null) {
             rs.mElement_LONG_3 = createVector(rs, DataType.SIGNED_64, 3);
@@ -820,8 +711,6 @@
         return rs.mElement_LONG_3;
     }
 
-    /** @deprecated renderscript is deprecated in J
-     */
     public static Element I64_4(RenderScript rs) {
         if(rs.mElement_LONG_4 == null) {
             rs.mElement_LONG_4 = createVector(rs, DataType.SIGNED_64, 4);
@@ -829,22 +718,19 @@
         return rs.mElement_LONG_4;
     }
 
-    /** @deprecated renderscript is deprecated in J
-     */
     public static Element MATRIX_4X4(RenderScript rs) {
         if(rs.mElement_MATRIX_4X4 == null) {
             rs.mElement_MATRIX_4X4 = createUser(rs, DataType.MATRIX_4X4);
         }
         return rs.mElement_MATRIX_4X4;
     }
-    /** @deprecated renderscript is deprecated in J
-     */
+
+    /** @deprecated use MATRIX_4X4
+    */
     public static Element MATRIX4X4(RenderScript rs) {
         return MATRIX_4X4(rs);
     }
 
-    /** @deprecated renderscript is deprecated in J
-     */
     public static Element MATRIX_3X3(RenderScript rs) {
         if(rs.mElement_MATRIX_3X3 == null) {
             rs.mElement_MATRIX_3X3 = createUser(rs, DataType.MATRIX_3X3);
@@ -852,8 +738,6 @@
         return rs.mElement_MATRIX_3X3;
     }
 
-    /** @deprecated renderscript is deprecated in J
-     */
     public static Element MATRIX_2X2(RenderScript rs) {
         if(rs.mElement_MATRIX_2X2 == null) {
             rs.mElement_MATRIX_2X2 = createUser(rs, DataType.MATRIX_2X2);
@@ -943,7 +827,7 @@
         updateVisibleSubElements();
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Create a custom Element of the specified DataType.  The DataKind will be
      * set to USER and the vector size to 1 indicating non-vector.
      *
@@ -959,7 +843,7 @@
         return new Element(id, rs, dt, dk, norm, vecSize);
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Create a custom vector element of the specified DataType and vector size.
      * DataKind will be set to USER. Only primitive types (FLOAT_32, FLOAT_64,
      * SIGNED_8, SIGNED_16, SIGNED_32, SIGNED_64, UNSIGNED_8, UNSIGNED_16,
@@ -1003,7 +887,7 @@
         }
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Create a new pixel Element type.  A matching DataType and DataKind must
      * be provided.  The DataType and DataKind must contain the same number of
      * components.  Vector size will be set to 1.
@@ -1066,7 +950,7 @@
         return new Element(id, rs, dt, dk, norm, size);
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Check if the current Element is compatible with another Element.
      * Primitive Elements are compatible if they share the same underlying
      * size and type (i.e. U8 is compatible with A_8). User-defined Elements
@@ -1093,7 +977,7 @@
                 (mVectorSize == e.mVectorSize));
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Builder class for producing complex elements with matching field and name
      * pairs.  The builder starts empty.  The order in which elements are added
      * is retained for the layout in memory.
@@ -1107,7 +991,7 @@
         int mCount;
         int mSkipPadding;
 
-        /** @deprecated renderscript is deprecated in J
+        /**
          * Create a builder object.
          *
          * @param rs
@@ -1120,7 +1004,7 @@
             mArraySizes = new int[8];
         }
 
-        /** @deprecated renderscript is deprecated in J
+        /**
          * Add an array of elements to this element.
          *
          * @param element
@@ -1164,7 +1048,7 @@
             return this;
         }
 
-        /** @deprecated renderscript is deprecated in J
+        /**
          * Add a single element to this Element.
          *
          * @param element
@@ -1174,7 +1058,7 @@
             return add(element, name, 1);
         }
 
-        /** @deprecated renderscript is deprecated in J
+        /**
          * Create the element from this builder.
          *
          *
diff --git a/graphics/java/android/renderscript/FieldPacker.java b/graphics/java/android/renderscript/FieldPacker.java
index 9d36e33..a215a57 100644
--- a/graphics/java/android/renderscript/FieldPacker.java
+++ b/graphics/java/android/renderscript/FieldPacker.java
@@ -17,7 +17,7 @@
 package android.renderscript;
 
 
-/** @deprecated renderscript is deprecated in J
+/**
  * Utility class for packing arguments and structures from Android system objects to
  * Renderscript objects.
  *
diff --git a/graphics/java/android/renderscript/FileA3D.java b/graphics/java/android/renderscript/FileA3D.java
index 1158061..42b508b 100644
--- a/graphics/java/android/renderscript/FileA3D.java
+++ b/graphics/java/android/renderscript/FileA3D.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008 The Android Open Source Project
+ * Copyright (C) 2008-2012 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -27,7 +27,8 @@
 import android.util.Log;
 import android.util.TypedValue;
 
-/** @deprecated renderscript is deprecated in J
+/**
+ * @deprecated in API 16
  * FileA3D allows users to load Renderscript objects from files
  * or resources stored on disk. It could be used to load items
  * such as 3D geometry data converted to a Renderscript format from
@@ -40,17 +41,20 @@
  **/
 public class FileA3D extends BaseObj {
 
-    /** @deprecated renderscript is deprecated in J
+    /**
+    * @deprecated in API 16
     * Specifies what renderscript object type is contained within
     * the FileA3D IndexEntry
     **/
     public enum EntryType {
 
-        /** @deprecated renderscript is deprecated in J
+        /**
+        * @deprecated in API 16
         * Unknown or or invalid object, nothing will be loaded
         **/
         UNKNOWN (0),
-        /** @deprecated renderscript is deprecated in J
+        /**
+        * @deprecated in API 16
         * Renderscript Mesh object
         **/
         MESH (1);
@@ -65,7 +69,8 @@
         }
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
+    * @deprecated in API 16
     * IndexEntry contains information about one of the Renderscript
     * objects inside the file's index. It could be used to query the
     * object's type and also name and load the object itself if
@@ -79,7 +84,8 @@
         EntryType mEntryType;
         BaseObj mLoadedObj;
 
-        /** @deprecated renderscript is deprecated in J
+        /**
+        * @deprecated in API 16
         * Returns the name of a renderscript object the index entry
         * describes
         *
@@ -91,7 +97,8 @@
             return mName;
         }
 
-        /** @deprecated renderscript is deprecated in J
+        /**
+        * @deprecated in API 16
         * Returns the type of a renderscript object the index entry
         * describes
         * @return type of a renderscript object the index entry
@@ -101,7 +108,8 @@
             return mEntryType;
         }
 
-        /** @deprecated renderscript is deprecated in J
+        /**
+        * @deprecated in API 16
         * Used to load the object described by the index entry
         * @return base renderscript object described by the entry
         */
@@ -111,7 +119,8 @@
             return obj;
         }
 
-        /** @deprecated renderscript is deprecated in J
+        /**
+        * @deprecated in API 16
         * Used to load the mesh described by the index entry, object
         * described by the index entry must be a renderscript mesh
         *
@@ -181,7 +190,8 @@
         }
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
+    * @deprecated in API 16
     * Returns the number of objects stored inside the a3d file
     *
     * @return the number of objects stored inside the a3d file
@@ -193,7 +203,8 @@
         return mFileEntries.length;
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
+    * @deprecated in API 16
     * Returns an index entry from the list of all objects inside
     * FileA3D
     *
@@ -208,7 +219,8 @@
         return mFileEntries[index];
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
+    * @deprecated in API 16
     * Creates a FileA3D object from an asset stored on disk
     *
     * @param rs Context to which the object will belong.
@@ -229,7 +241,8 @@
         return fa3d;
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
+    * @deprecated in API 16
     * Creates a FileA3D object from a file stored on disk
     *
     * @param rs Context to which the object will belong.
@@ -248,7 +261,8 @@
         return fa3d;
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
+    * @deprecated in API 16
     * Creates a FileA3D object from a file stored on disk
     *
     * @param rs Context to which the object will belong.
@@ -260,7 +274,8 @@
         return createFromFile(rs, path.getAbsolutePath());
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
+    * @deprecated in API 16
     * Creates a FileA3D object from an application resource
     *
     * @param rs Context to which the object will belong.
diff --git a/graphics/java/android/renderscript/Float2.java b/graphics/java/android/renderscript/Float2.java
index a89a5df9..1d4ce36 100644
--- a/graphics/java/android/renderscript/Float2.java
+++ b/graphics/java/android/renderscript/Float2.java
@@ -20,7 +20,7 @@
 import android.util.Log;
 
 
-/** @deprecated renderscript is deprecated in J
+/**
  * Class for exposing the native Renderscript float2 type back to the Android system.
  *
  **/
diff --git a/graphics/java/android/renderscript/Float3.java b/graphics/java/android/renderscript/Float3.java
index 909a897..ffd1135 100644
--- a/graphics/java/android/renderscript/Float3.java
+++ b/graphics/java/android/renderscript/Float3.java
@@ -20,7 +20,7 @@
 import android.util.Log;
 
 
-/** @deprecated renderscript is deprecated in J
+/**
  * Class for exposing the native Renderscript float2 type back to the Android system.
  *
  **/
diff --git a/graphics/java/android/renderscript/Float4.java b/graphics/java/android/renderscript/Float4.java
index 3be6dbca..c7cc3ae 100644
--- a/graphics/java/android/renderscript/Float4.java
+++ b/graphics/java/android/renderscript/Float4.java
@@ -20,7 +20,7 @@
 import android.util.Log;
 
 
-/** @deprecated renderscript is deprecated in J
+/**
  * Class for exposing the native Renderscript float2 type back to the Android system.
  *
  **/
diff --git a/graphics/java/android/renderscript/Font.java b/graphics/java/android/renderscript/Font.java
index cd1010c..8a49abb 100644
--- a/graphics/java/android/renderscript/Font.java
+++ b/graphics/java/android/renderscript/Font.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008 The Android Open Source Project
+ * Copyright (C) 2008-2012 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -29,8 +29,9 @@
 import android.util.Log;
 import android.util.TypedValue;
 
-/** @deprecated renderscript is deprecated in J
- * <p>This class gives users a simple way to draw hardware accelerated text.
+/**
+ * @deprecated in API 16
+ * <p>This class gives users a simple way to draw hardware accelerated text. 
  * Internally, the glyphs are rendered using the Freetype library and an internal cache of
  * rendered glyph bitmaps is maintained. Each font object represents a combination of a typeface,
  * and point size. You can create multiple font objects to represent styles such as bold or italic text,
@@ -42,7 +43,7 @@
  * render large batches of text in sequence. It is also more efficient to render multiple
  * characters at once instead of one by one to improve draw call batching.</p>
  * <p>Font color and transparency are not part of the font object and you can freely modify
- * them in the script to suit the user's rendering needs. Font colors work as a state machine.
+ * them in the script to suit the user's rendering needs. Font colors work as a state machine. 
  * Every new call to draw text uses the last color set in the script.</p>
  **/
 public class Font extends BaseObj {
@@ -71,20 +72,25 @@
 
     private static Map<String, FontFamily> sFontFamilyMap;
 
-    /** @deprecated renderscript is deprecated in J
+    /**
+     * @deprecated in API 16
      */
     public enum Style {
-        /** @deprecated renderscript is deprecated in J
-        */
+        /**
+         * @deprecated in API 16
+         */
         NORMAL,
-        /** @deprecated renderscript is deprecated in J
-        */
+        /**
+         * @deprecated in API 16
+         */
         BOLD,
-        /** @deprecated renderscript is deprecated in J
-        */
+        /**
+         * @deprecated in API 16
+         */
         ITALIC,
-        /** @deprecated renderscript is deprecated in J
-        */
+        /**
+         * @deprecated in API 16
+         */
         BOLD_ITALIC;
     }
 
@@ -148,7 +154,8 @@
         super(id, rs);
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
+     * @deprecated in API 16
      * Takes a specific file name as an argument
      */
     static public Font createFromFile(RenderScript rs, Resources res, String path, float pointSize) {
@@ -164,13 +171,15 @@
         return rsFont;
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
+     * @deprecated in API 16
      */
     static public Font createFromFile(RenderScript rs, Resources res, File path, float pointSize) {
         return createFromFile(rs, res, path.getAbsolutePath(), pointSize);
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
+     * @deprecated in API 16
      */
     static public Font createFromAsset(RenderScript rs, Resources res, String path, float pointSize) {
         rs.validate();
@@ -185,7 +194,8 @@
         return rsFont;
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
+     * @deprecated in API 16
      */
     static public Font createFromResource(RenderScript rs, Resources res, int id, float pointSize) {
         String name = "R." + Integer.toString(id);
@@ -215,7 +225,8 @@
         return rsFont;
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
+     * @deprecated in API 16
      * Accepts one of the following family names as an argument
      * and will attempt to produce the best match with a system font:
      *
diff --git a/graphics/java/android/renderscript/Int2.java b/graphics/java/android/renderscript/Int2.java
index 4e2d344..434af21 100644
--- a/graphics/java/android/renderscript/Int2.java
+++ b/graphics/java/android/renderscript/Int2.java
@@ -20,7 +20,7 @@
 import android.util.Log;
 
 
-/** @deprecated renderscript is deprecated in J
+/**
  * Class for exposing the native Renderscript int2 type back to the Android system.
  *
  **/
diff --git a/graphics/java/android/renderscript/Int3.java b/graphics/java/android/renderscript/Int3.java
index 1ffc129..333ccf8 100644
--- a/graphics/java/android/renderscript/Int3.java
+++ b/graphics/java/android/renderscript/Int3.java
@@ -20,7 +20,7 @@
 import android.util.Log;
 
 
-/** @deprecated renderscript is deprecated in J
+/**
  * Class for exposing the native Renderscript int3 type back to the Android system.
  *
  **/
diff --git a/graphics/java/android/renderscript/Int4.java b/graphics/java/android/renderscript/Int4.java
index 555d431..8734c95 100644
--- a/graphics/java/android/renderscript/Int4.java
+++ b/graphics/java/android/renderscript/Int4.java
@@ -20,7 +20,7 @@
 import android.util.Log;
 
 
-/** @deprecated renderscript is deprecated in J
+/**
  * Class for exposing the native Renderscript int4 type back to the Android system.
  *
  **/
diff --git a/graphics/java/android/renderscript/Long2.java b/graphics/java/android/renderscript/Long2.java
index aad6bd6..95ea18c 100644
--- a/graphics/java/android/renderscript/Long2.java
+++ b/graphics/java/android/renderscript/Long2.java
@@ -20,7 +20,7 @@
 import android.util.Log;
 
 
-/** @deprecated renderscript is deprecated in J
+/**
  * Class for exposing the native Renderscript long2 type back to the Android system.
  **/
 public class Long2 {
diff --git a/graphics/java/android/renderscript/Long3.java b/graphics/java/android/renderscript/Long3.java
index 9c03d5c..96ee885 100644
--- a/graphics/java/android/renderscript/Long3.java
+++ b/graphics/java/android/renderscript/Long3.java
@@ -20,7 +20,7 @@
 import android.util.Log;
 
 
-/** @deprecated renderscript is deprecated in J
+/**
  * Class for exposing the native Renderscript long3 type back to the Android system.
  **/
 public class Long3 {
diff --git a/graphics/java/android/renderscript/Long4.java b/graphics/java/android/renderscript/Long4.java
index 6611cdf..50e664c 100644
--- a/graphics/java/android/renderscript/Long4.java
+++ b/graphics/java/android/renderscript/Long4.java
@@ -20,7 +20,7 @@
 import android.util.Log;
 
 
-/** @deprecated renderscript is deprecated in J
+/**
  * Class for exposing the native Renderscript long4 type back to the Android system.
  **/
 public class Long4 {
diff --git a/graphics/java/android/renderscript/Matrix2f.java b/graphics/java/android/renderscript/Matrix2f.java
index 38b5316..acc5bd8 100644
--- a/graphics/java/android/renderscript/Matrix2f.java
+++ b/graphics/java/android/renderscript/Matrix2f.java
@@ -20,13 +20,13 @@
 import android.util.Log;
 
 
-/** @deprecated renderscript is deprecated in J
+/**
  * Class for exposing the native Renderscript rs_matrix2x2 type back to the Android system.
  *
  **/
 public class Matrix2f {
 
-    /** @deprecated renderscript is deprecated in J
+    /**
     * Creates a new identity 2x2 matrix
     */
     public Matrix2f() {
@@ -34,7 +34,7 @@
         loadIdentity();
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
     * Creates a new matrix and sets its values from the given
     * parameter
     *
@@ -46,7 +46,7 @@
         System.arraycopy(dataArray, 0, mMat, 0, mMat.length);
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
     * Return a reference to the internal array representing matrix
     * values. Modifying this array will also change the matrix
     *
@@ -56,7 +56,7 @@
         return mMat;
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
     * Returns the value for a given row and column
     *
     * @param i row of the value to return
@@ -68,7 +68,7 @@
         return mMat[i*2 + j];
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
     * Sets the value for a given row and column
     *
     * @param i row of the value to set
@@ -78,7 +78,7 @@
         mMat[i*2 + j] = v;
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
     * Sets the matrix values to identity
     */
     public void loadIdentity() {
@@ -89,7 +89,7 @@
         mMat[3] = 1;
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
     * Sets the values of the matrix to those of the parameter
     *
     * @param src matrix to load the values from
@@ -98,7 +98,7 @@
         System.arraycopy(src.getArray(), 0, mMat, 0, mMat.length);
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
     * Sets current values to be a rotation matrix of given angle
     *
     * @param rot rotation angle
@@ -114,7 +114,7 @@
         mMat[3] = c;
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
     * Sets current values to be a scale matrix of given dimensions
     *
     * @param x scale component x
@@ -126,7 +126,7 @@
         mMat[3] = y;
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
     * Sets current values to be the result of multiplying two given
     * matrices
     *
@@ -147,7 +147,7 @@
         }
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
     * Post-multiplies the current matrix by a given parameter
     *
     * @param rhs right hand side to multiply by
@@ -157,7 +157,7 @@
         tmp.loadMultiply(this, rhs);
         load(tmp);
     }
-    /** @deprecated renderscript is deprecated in J
+    /**
     * Modifies the current matrix by post-multiplying it with a
     * rotation matrix of given angle
     *
@@ -168,7 +168,7 @@
         tmp.loadRotate(rot);
         multiply(tmp);
     }
-    /** @deprecated renderscript is deprecated in J
+    /**
     * Modifies the current matrix by post-multiplying it with a
     * scale matrix of given dimensions
     *
@@ -180,7 +180,7 @@
         tmp.loadScale(x, y);
         multiply(tmp);
     }
-    /** @deprecated renderscript is deprecated in J
+    /**
     * Sets the current matrix to its transpose
     */
     public void transpose() {
diff --git a/graphics/java/android/renderscript/Matrix3f.java b/graphics/java/android/renderscript/Matrix3f.java
index b821742..253506df 100644
--- a/graphics/java/android/renderscript/Matrix3f.java
+++ b/graphics/java/android/renderscript/Matrix3f.java
@@ -20,13 +20,13 @@
 import android.util.Log;
 
 
-/** @deprecated renderscript is deprecated in J
+/**
  * Class for exposing the native Renderscript rs_matrix3x3 type back to the Android system.
  *
  **/
 public class Matrix3f {
 
-    /** @deprecated renderscript is deprecated in J
+    /**
     * Creates a new identity 3x3 matrix
     */
     public Matrix3f() {
@@ -34,7 +34,7 @@
         loadIdentity();
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
     * Creates a new matrix and sets its values from the given
     * parameter
     *
@@ -46,7 +46,7 @@
         System.arraycopy(dataArray, 0, mMat, 0, mMat.length);
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
     * Return a reference to the internal array representing matrix
     * values. Modifying this array will also change the matrix
     *
@@ -56,7 +56,7 @@
         return mMat;
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
     * Returns the value for a given row and column
     *
     * @param i row of the value to return
@@ -68,7 +68,7 @@
         return mMat[i*3 + j];
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
     * Sets the value for a given row and column
     *
     * @param i row of the value to set
@@ -78,7 +78,7 @@
         mMat[i*3 + j] = v;
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
     * Sets the matrix values to identity
     */
     public void loadIdentity() {
@@ -95,7 +95,7 @@
         mMat[8] = 1;
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
     * Sets the values of the matrix to those of the parameter
     *
     * @param src matrix to load the values from
@@ -104,7 +104,7 @@
         System.arraycopy(src.getArray(), 0, mMat, 0, mMat.length);
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
     * Sets current values to be a rotation matrix of certain angle
     * about a given axis
     *
@@ -144,7 +144,7 @@
         mMat[8] = z*z*nc +  c;
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
     * Makes the upper 2x2 a rotation matrix of the given angle
     *
     * @param rot rotation angle
@@ -161,7 +161,7 @@
         mMat[4] = c;
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
     * Makes the upper 2x2 a scale matrix of given dimensions
     *
     * @param x scale component x
@@ -173,7 +173,7 @@
         mMat[4] = y;
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
     * Sets current values to be a scale matrix of given dimensions
     *
     * @param x scale component x
@@ -187,7 +187,7 @@
         mMat[8] = z;
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
     * Sets current values to be a translation matrix of given
     * dimensions
     *
@@ -200,7 +200,7 @@
         mMat[7] = y;
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
     * Sets current values to be the result of multiplying two given
     * matrices
     *
@@ -224,7 +224,7 @@
         }
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
     * Post-multiplies the current matrix by a given parameter
     *
     * @param rhs right hand side to multiply by
@@ -235,7 +235,7 @@
         load(tmp);
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
     * Modifies the current matrix by post-multiplying it with a
     * rotation matrix of certain angle about a given axis
     *
@@ -250,7 +250,7 @@
         multiply(tmp);
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
     * Modifies the upper 2x2 of the current matrix by
     * post-multiplying it with a rotation matrix of given angle
     *
@@ -262,7 +262,7 @@
         multiply(tmp);
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
     * Modifies the upper 2x2 of the current matrix by
     * post-multiplying it with a scale matrix of given dimensions
     *
@@ -275,7 +275,7 @@
         multiply(tmp);
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
     * Modifies the current matrix by post-multiplying it with a
     * scale matrix of given dimensions
     *
@@ -289,7 +289,7 @@
         multiply(tmp);
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
     * Modifies the current matrix by post-multiplying it with a
     * translation matrix of given dimensions
     *
@@ -302,7 +302,7 @@
         multiply(tmp);
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
     * Sets the current matrix to its transpose
     */
     public void transpose() {
diff --git a/graphics/java/android/renderscript/Matrix4f.java b/graphics/java/android/renderscript/Matrix4f.java
index 8b7a0df..adc1806 100644
--- a/graphics/java/android/renderscript/Matrix4f.java
+++ b/graphics/java/android/renderscript/Matrix4f.java
@@ -20,13 +20,13 @@
 import android.util.Log;
 
 
-/** @deprecated renderscript is deprecated in J
+/**
  * Class for exposing the native Renderscript rs_matrix4x4 type back to the Android system.
  *
  **/
 public class Matrix4f {
 
-    /** @deprecated renderscript is deprecated in J
+    /**
     * Creates a new identity 4x4 matrix
     */
     public Matrix4f() {
@@ -34,7 +34,7 @@
         loadIdentity();
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
     * Creates a new matrix and sets its values from the given
     * parameter
     *
@@ -46,7 +46,7 @@
         System.arraycopy(dataArray, 0, mMat, 0, mMat.length);
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
     * Return a reference to the internal array representing matrix
     * values. Modifying this array will also change the matrix
     *
@@ -56,7 +56,7 @@
         return mMat;
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
     * Returns the value for a given row and column
     *
     * @param i row of the value to return
@@ -68,7 +68,7 @@
         return mMat[i*4 + j];
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
     * Sets the value for a given row and column
     *
     * @param i row of the value to set
@@ -78,7 +78,7 @@
         mMat[i*4 + j] = v;
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
     * Sets the matrix values to identity
     */
     public void loadIdentity() {
@@ -103,7 +103,7 @@
         mMat[15] = 1;
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
     * Sets the values of the matrix to those of the parameter
     *
     * @param src matrix to load the values from
@@ -112,7 +112,7 @@
         System.arraycopy(src.getArray(), 0, mMat, 0, mMat.length);
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
     * Sets current values to be a rotation matrix of certain angle
     * about a given axis
     *
@@ -159,7 +159,7 @@
         mMat[10] = z*z*nc +  c;
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
     * Sets current values to be a scale matrix of given dimensions
     *
     * @param x scale component x
@@ -173,7 +173,7 @@
         mMat[10] = z;
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
     * Sets current values to be a translation matrix of given
     * dimensions
     *
@@ -188,7 +188,7 @@
         mMat[14] = z;
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
     * Sets current values to be the result of multiplying two given
     * matrices
     *
@@ -215,7 +215,7 @@
         }
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
     * Set current values to be an orthographic projection matrix
     *
     * @param l location of the left vertical clipping plane
@@ -235,7 +235,7 @@
         mMat[14]= -(f + n) / (f - n);
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
     * Set current values to be an orthographic projection matrix
     * with the right and bottom clipping planes set to the given
     * values. Left and top clipping planes are set to 0. Near and
@@ -249,7 +249,7 @@
         loadOrtho(0,w, h,0, -1,1);
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
     * Sets current values to be a perspective projection matrix
     *
     * @param l location of the left vertical clipping plane
@@ -272,7 +272,7 @@
         mMat[15]= 0;
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
     * Sets current values to be a perspective projection matrix
     *
     * @param fovy vertical field of view angle in degrees
@@ -288,7 +288,7 @@
         loadFrustum(left, right, bottom, top, near, far);
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
     * Helper function to set the current values to a perspective
     * projection matrix with aspect ratio defined by the parameters
     * and (near, far), (bottom, top) mapping to (-1, 1) at z = 0
@@ -321,7 +321,7 @@
         load(m1);
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
     * Post-multiplies the current matrix by a given parameter
     *
     * @param rhs right hand side to multiply by
@@ -331,7 +331,7 @@
         tmp.loadMultiply(this, rhs);
         load(tmp);
     }
-    /** @deprecated renderscript is deprecated in J
+    /**
     * Modifies the current matrix by post-multiplying it with a
     * rotation matrix of certain angle about a given axis
     *
@@ -346,7 +346,7 @@
         multiply(tmp);
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
     * Modifies the current matrix by post-multiplying it with a
     * scale matrix of given dimensions
     *
@@ -360,7 +360,7 @@
         multiply(tmp);
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
     * Modifies the current matrix by post-multiplying it with a
     * translation matrix of given dimensions
     *
@@ -392,7 +392,7 @@
         return cofactor;
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
     * Sets the current matrix to its inverse
     */
     public boolean inverse() {
@@ -421,7 +421,7 @@
         return true;
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
     * Sets the current matrix to its inverse transpose
     */
     public boolean inverseTranspose() {
@@ -449,7 +449,7 @@
         return true;
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
     * Sets the current matrix to its transpose
     */
     public void transpose() {
diff --git a/graphics/java/android/renderscript/Mesh.java b/graphics/java/android/renderscript/Mesh.java
index bc32038..f49a24e 100644
--- a/graphics/java/android/renderscript/Mesh.java
+++ b/graphics/java/android/renderscript/Mesh.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008 The Android Open Source Project
+ * Copyright (C) 2008-2012 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -20,7 +20,7 @@
 
 import android.util.Log;
 
-/** @deprecated renderscript is deprecated in J
+/**
  * <p>This class is a container for geometric data displayed with
  * Renderscript. Internally, a mesh is a collection of allocations that
  * represent vertex data (positions, normals, texture
@@ -39,34 +39,34 @@
  **/
 public class Mesh extends BaseObj {
 
-    /** @deprecated renderscript is deprecated in J
+    /**
     * Describes the way mesh vertex data is interpreted when rendering
     *
     **/
     public enum Primitive {
-        /** @deprecated renderscript is deprecated in J
+        /**
         * Vertex data will be rendered as a series of points
         */
         POINT (0),
-        /** @deprecated renderscript is deprecated in J
+        /**
         * Vertex pairs will be rendered as lines
         */
         LINE (1),
-        /** @deprecated renderscript is deprecated in J
+        /**
         * Vertex data will be rendered as a connected line strip
         */
         LINE_STRIP (2),
-        /** @deprecated renderscript is deprecated in J
+        /**
         * Vertices will be rendered as individual triangles
         */
         TRIANGLE (3),
-        /** @deprecated renderscript is deprecated in J
+        /**
         * Vertices will be rendered as a connected triangle strip
         * defined by the first three vertices with each additional
         * triangle defined by a new vertex
         */
         TRIANGLE_STRIP (4),
-        /** @deprecated renderscript is deprecated in J
+        /**
         * Vertices will be rendered as a sequence of triangles that all
         * share first vertex as the origin
         */
@@ -86,7 +86,7 @@
         super(id, rs);
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
     * @return number of allocations containing vertex data
     *
     **/
@@ -96,7 +96,7 @@
         }
         return mVertexBuffers.length;
     }
-    /** @deprecated renderscript is deprecated in J
+    /**
     * @param slot index in the list of allocations to return
     * @return vertex data allocation at the given index
     *
@@ -105,7 +105,7 @@
         return mVertexBuffers[slot];
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
     * @return number of primitives or index sets in the mesh
     *
     **/
@@ -116,7 +116,7 @@
         return mIndexBuffers.length;
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
     * @param slot locaton within the list of index set allocation
     * @return allocation containing primtive index data or null if
     *         the index data is not specified explicitly
@@ -125,7 +125,7 @@
     public Allocation getIndexSetAllocation(int slot) {
         return mIndexBuffers[slot];
     }
-    /** @deprecated renderscript is deprecated in J
+    /**
     * @param slot locaiton within the list of index set primitives
     * @return index set primitive type
     *
@@ -167,7 +167,7 @@
         }
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
     * Mesh builder object. It starts empty and requires you to
     * add the types necessary to create vertex and index
     * allocations.
@@ -189,7 +189,7 @@
         Entry[] mVertexTypes;
         Vector mIndexTypes;
 
-        /** @deprecated renderscript is deprecated in J
+        /**
         * Creates builder object
         * @param rs Context to which the mesh will belong.
         * @param usage specifies how the mesh allocations are to be
@@ -204,7 +204,7 @@
             mIndexTypes = new Vector();
         }
 
-        /** @deprecated renderscript is deprecated in J
+        /**
         * @return internal index of the last vertex buffer type added to
         *         builder
         **/
@@ -212,7 +212,7 @@
             return mVertexTypeCount - 1;
         }
 
-        /** @deprecated renderscript is deprecated in J
+        /**
         * @return internal index of the last index set added to the
         *         builder
         **/
@@ -220,7 +220,7 @@
             return mIndexTypes.size() - 1;
         }
 
-        /** @deprecated renderscript is deprecated in J
+        /**
         * Adds a vertex data type to the builder object
         *
         * @param t type of the vertex data allocation to be created
@@ -239,7 +239,7 @@
             return this;
         }
 
-        /** @deprecated renderscript is deprecated in J
+        /**
         * Adds a vertex data type to the builder object
         *
         * @param e element describing the vertex data layout
@@ -260,7 +260,7 @@
             return this;
         }
 
-        /** @deprecated renderscript is deprecated in J
+        /**
         * Adds an index set data type to the builder object
         *
         * @param t type of the index set data, could be null
@@ -278,7 +278,7 @@
             return this;
         }
 
-        /** @deprecated renderscript is deprecated in J
+        /**
         * Adds an index set primitive type to the builder object
         *
         * @param p primitive type
@@ -295,7 +295,7 @@
             return this;
         }
 
-        /** @deprecated renderscript is deprecated in J
+        /**
         * Adds an index set data type to the builder object
         *
         * @param e element describing the index set data layout
@@ -320,7 +320,7 @@
             return tb.create();
         }
 
-        /** @deprecated renderscript is deprecated in J
+        /**
         * Create a Mesh object from the current state of the builder
         *
         **/
@@ -372,7 +372,8 @@
         }
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
+    * @deprecated in API 16
     * Mesh builder object. It starts empty and requires the user to
     * add all the vertex and index allocations that comprise the
     * mesh
@@ -391,8 +392,9 @@
 
         Vector mIndexTypes;
 
-        /** @deprecated renderscript is deprecated in J
-        */
+        /**
+        * @deprecated in API 16
+        **/
         public AllocationBuilder(RenderScript rs) {
             mRS = rs;
             mVertexTypeCount = 0;
@@ -400,7 +402,8 @@
             mIndexTypes = new Vector();
         }
 
-        /** @deprecated renderscript is deprecated in J
+        /**
+        * @deprecated in API 16
         * @return internal index of the last vertex buffer type added to
         *         builder
         **/
@@ -408,7 +411,8 @@
             return mVertexTypeCount - 1;
         }
 
-        /** @deprecated renderscript is deprecated in J
+        /**
+        * @deprecated in API 16
         * @return internal index of the last index set added to the
         *         builder
         **/
@@ -416,7 +420,8 @@
             return mIndexTypes.size() - 1;
         }
 
-        /** @deprecated renderscript is deprecated in J
+        /**
+        * @deprecated in API 16
         * Adds an allocation containing vertex buffer data to the
         * builder
         *
@@ -435,7 +440,8 @@
             return this;
         }
 
-        /** @deprecated renderscript is deprecated in J
+        /**
+        * @deprecated in API 16
         * Adds an allocation containing index buffer data and index type
         * to the builder
         *
@@ -452,7 +458,8 @@
             return this;
         }
 
-        /** @deprecated renderscript is deprecated in J
+        /**
+        * @deprecated in API 16
         * Adds an index set type to the builder
         *
         * @param p index set primitive type
@@ -467,7 +474,8 @@
             return this;
         }
 
-        /** @deprecated renderscript is deprecated in J
+        /**
+        * @deprecated in API 16
         * Create a Mesh object from the current state of the builder
         *
         **/
@@ -508,7 +516,8 @@
         }
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
+    * @deprecated in API 16
     * Builder that allows creation of a mesh object point by point
     * and triangle by triangle
     *
@@ -535,17 +544,21 @@
         int mVtxSize;
         int mFlags;
 
-        /** @deprecated renderscript is deprecated in J
-        */
+        /**
+        * @deprecated in API 16
+        **/
         public static final int COLOR = 0x0001;
-        /** @deprecated renderscript is deprecated in J
-        */
+        /**
+        * @deprecated in API 16
+        **/
         public static final int NORMAL = 0x0002;
-        /** @deprecated renderscript is deprecated in J
-        */
+        /**
+        * @deprecated in API 16
+        **/
         public static final int TEXTURE_0 = 0x0100;
 
-        /** @deprecated renderscript is deprecated in J
+        /**
+        * @deprecated in API 16
         * @param rs Context to which the mesh will belong.
         * @param vtxSize specifies whether the vertex is a float2 or
         *                float3
@@ -600,7 +613,8 @@
             mMaxIndex ++;
         }
 
-        /** @deprecated renderscript is deprecated in J
+        /**
+        * @deprecated in API 16
         * Adds a float2 vertex to the mesh
         *
         * @param x position x
@@ -620,7 +634,8 @@
             return this;
         }
 
-        /** @deprecated renderscript is deprecated in J
+        /**
+        * @deprecated in API 16
         * Adds a float3 vertex to the mesh
         *
         * @param x position x
@@ -643,7 +658,8 @@
             return this;
         }
 
-        /** @deprecated renderscript is deprecated in J
+        /**
+        * @deprecated in API 16
         * Sets the texture coordinate for the vertices that are added after this method call.
         *
         * @param s texture coordinate s
@@ -660,7 +676,8 @@
             return this;
         }
 
-        /** @deprecated renderscript is deprecated in J
+        /**
+        * @deprecated in API 16
         * Sets the normal vector for the vertices that are added after this method call.
         *
         * @param x normal vector x
@@ -679,7 +696,8 @@
             return this;
         }
 
-        /** @deprecated renderscript is deprecated in J
+        /**
+        * @deprecated in API 16
         * Sets the color for the vertices that are added after this method call.
         *
         * @param r red component
@@ -700,7 +718,8 @@
             return this;
         }
 
-        /** @deprecated renderscript is deprecated in J
+        /**
+        * @deprecated in API 16
         * Adds a new triangle to the mesh builder
         *
         * @param idx1 index of the first vertex in the triangle
@@ -726,7 +745,8 @@
             return this;
         }
 
-        /** @deprecated renderscript is deprecated in J
+        /**
+        * @deprecated in API 16
         * Creates the mesh object from the current state of the builder
         *
         * @param uploadToBufferObject specifies whether the vertex data
diff --git a/graphics/java/android/renderscript/Path.java b/graphics/java/android/renderscript/Path.java
index ec34d7c..9c4d41b 100644
--- a/graphics/java/android/renderscript/Path.java
+++ b/graphics/java/android/renderscript/Path.java
@@ -19,7 +19,7 @@
 import java.util.Vector;
 import android.util.Log;
 
-/** @deprecated renderscript is deprecated in J
+/**
  * @hide
  *
  */
diff --git a/graphics/java/android/renderscript/Program.java b/graphics/java/android/renderscript/Program.java
index 16186fa..d9f64c6 100644
--- a/graphics/java/android/renderscript/Program.java
+++ b/graphics/java/android/renderscript/Program.java
@@ -25,7 +25,7 @@
 import android.util.Log;
 
 
-/** @deprecated renderscript is deprecated in J
+/**
  *
  * Program is a base class for all the objects that modify
  * various stages of the graphics pipeline
@@ -37,18 +37,14 @@
     static final int MAX_CONSTANT = 8;
     static final int MAX_TEXTURE = 8;
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      *
      * TextureType specifies what textures are attached to Program
      * objects
      *
      **/
     public enum TextureType {
-        /** @deprecated renderscript is deprecated in J
-        */
         TEXTURE_2D (0),
-        /** @deprecated renderscript is deprecated in J
-        */
         TEXTURE_CUBE (1);
 
         int mID;
@@ -81,7 +77,7 @@
         super(id, rs);
     }
 
-    /** @hide renderscript is deprecated in J
+    /**
      * Program object can have zero or more constant allocations
      * associated with it. This method returns the total count.
      * @return number of constant input types
@@ -90,7 +86,7 @@
         return mConstants != null ? mConstants.length : 0;
     }
 
-    /** @hide renderscript is deprecated in J
+    /**
      * Returns the type of the constant buffer used in the program
      * object. It could be used to query internal elements or create
      * an allocation to store constant data.
@@ -104,7 +100,7 @@
         return mConstants[slot];
     }
 
-    /** @hide renderscript is deprecated in J
+    /**
      * Returns the number of textures used in this program object
      * @return number of texture inputs
      */
@@ -112,7 +108,7 @@
         return mTextureCount;
     }
 
-    /** @hide renderscript is deprecated in J
+    /**
      * Returns the type of texture at a given slot. e.g. 2D or Cube
      * @param slot index of the texture input
      * @return texture input type
@@ -124,7 +120,7 @@
         return mTextures[slot];
     }
 
-    /** @hide renderscript is deprecated in J
+    /**
      * Returns the name of the texture input at a given slot. e.g.
      * tex0, diffuse, spec
      * @param slot index of the texture input
@@ -137,7 +133,7 @@
         return mTextureNames[slot];
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Binds a constant buffer to be used as uniform inputs to the
      * program
      *
@@ -157,7 +153,7 @@
         mRS.nProgramBindConstants(getID(mRS), slot, id);
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Binds a texture to be used in the program
      *
      * @param va allocation containing texture data
@@ -179,7 +175,7 @@
         mRS.nProgramBindTexture(getID(mRS), slot, id);
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Binds an object that describes how a texture at the
      * corresponding location is sampled
      *
@@ -214,8 +210,7 @@
         int mTextureCount;
         String mShader;
 
-        /** @deprecated renderscript is deprecated in J
-        */
+
         protected BaseProgramBuilder(RenderScript rs) {
             mRS = rs;
             mInputs = new Element[MAX_INPUT];
@@ -229,7 +224,7 @@
             mTextureNames = new String[MAX_TEXTURE];
         }
 
-        /** @deprecated renderscript is deprecated in J
+        /**
          * Sets the GLSL shader code to be used in the program
          *
          * @param s GLSL shader string
@@ -240,7 +235,7 @@
             return this;
         }
 
-        /** @deprecated renderscript is deprecated in J
+        /**
          * Sets the GLSL shader code to be used in the program
          *
          * @param resources application resources
@@ -286,7 +281,7 @@
             return this;
         }
 
-        /** @deprecated renderscript is deprecated in J
+        /**
          * Queries the index of the last added constant buffer type
          *
          */
@@ -294,7 +289,7 @@
             return mConstantCount - 1;
         }
 
-        /** @deprecated renderscript is deprecated in J
+        /**
          * Queries the index of the last added texture type
          *
          */
@@ -302,7 +297,7 @@
             return mTextureCount - 1;
         }
 
-        /** @deprecated renderscript is deprecated in J
+        /**
          * Adds constant (uniform) inputs to the program
          *
          * @param t Type that describes the layout of the Allocation
@@ -322,7 +317,7 @@
             return this;
         }
 
-        /** @deprecated renderscript is deprecated in J
+        /**
          * Adds a texture input to the Program
          *
          * @param texType describes that the texture to append it (2D,
@@ -334,7 +329,7 @@
             return this;
         }
 
-        /** @hide renderscript is deprecated in J
+        /**
          * Adds a texture input to the Program
          *
          * @param texType describes that the texture to append it (2D,
@@ -354,8 +349,6 @@
             return this;
         }
 
-        /** @deprecated renderscript is deprecated in J
-        */
         protected void initProgram(Program p) {
             p.mInputs = new Element[mInputCount];
             System.arraycopy(mInputs, 0, p.mInputs, 0, mInputCount);
diff --git a/graphics/java/android/renderscript/ProgramFragment.java b/graphics/java/android/renderscript/ProgramFragment.java
index 0427c19..fa6e2d4 100644
--- a/graphics/java/android/renderscript/ProgramFragment.java
+++ b/graphics/java/android/renderscript/ProgramFragment.java
@@ -20,7 +20,7 @@
 import android.util.Log;
 
 
-/** @deprecated renderscript is deprecated in J
+/**
  * <p>The Renderscript fragment program, also known as fragment shader is responsible
  * for manipulating pixel data in a user defined way. It's constructed from a GLSL
  * shader string containing the program body, textures inputs, and a Type object
@@ -42,7 +42,7 @@
     }
 
     public static class Builder extends BaseProgramBuilder {
-        /** @deprecated renderscript is deprecated in J
+        /**
          * Create a builder object.
          *
          * @param rs Context to which the program will belong.
@@ -51,7 +51,7 @@
             super(rs);
         }
 
-        /** @deprecated renderscript is deprecated in J
+        /**
          * Creates ProgramFragment from the current state of the builder
          *
          * @return  ProgramFragment
diff --git a/graphics/java/android/renderscript/ProgramFragmentFixedFunction.java b/graphics/java/android/renderscript/ProgramFragmentFixedFunction.java
index 19fca58..848c5a3 100644
--- a/graphics/java/android/renderscript/ProgramFragmentFixedFunction.java
+++ b/graphics/java/android/renderscript/ProgramFragmentFixedFunction.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008 The Android Open Source Project
+ * Copyright (C) 2008-2012 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -20,7 +20,8 @@
 import android.util.Log;
 
 
-/** @deprecated renderscript is deprecated in J
+/**
+ * @deprecated in API 16
  * <p>ProgramFragmentFixedFunction is a helper class that provides
  * a way to make a simple fragment shader without writing any
  * GLSL code. This class allows for display of constant color, interpolated
@@ -34,11 +35,15 @@
     }
 
     static class InternalBuilder extends BaseProgramBuilder {
+        /**
+         * @deprecated in API 16
+         */
         public InternalBuilder(RenderScript rs) {
             super(rs);
         }
 
-        /** @deprecated renderscript is deprecated in J
+        /**
+         * @deprecated in API 16
          * Creates ProgramFragmentFixedFunction from the current state
          * of the builder
          *
@@ -75,9 +80,13 @@
         }
     }
 
+    /**
+     * @deprecated in API 16
+     */
     public static class Builder {
-        /** @deprecated renderscript is deprecated in J
-        */
+        /**
+         * @deprecated in API 16
+         */
         public static final int MAX_TEXTURE = 2;
         int mNumTextures;
         boolean mPointSpriteEnable;
@@ -85,20 +94,24 @@
         String mShader;
         RenderScript mRS;
 
-        /** @deprecated renderscript is deprecated in J
+        /**
+         * @deprecated in API 16
          * EnvMode describes how textures are combined with the existing
          * color in the fixed function fragment shader
          *
          **/
         public enum EnvMode {
-            /** @deprecated renderscript is deprecated in J
-            */
+            /**
+             * @deprecated in API 16
+             **/
             REPLACE (1),
-            /** @deprecated renderscript is deprecated in J
-            */
+            /**
+             * @deprecated in API 16
+             **/
             MODULATE (2),
-            /** @deprecated renderscript is deprecated in J
-            */
+            /**
+             * @deprecated in API 16
+             **/
             DECAL (3);
 
             int mID;
@@ -107,23 +120,28 @@
             }
         }
 
-        /** @deprecated renderscript is deprecated in J
+        /**
+         * @deprecated in API 16
          * Format describes the pixel format of textures in the fixed
          * function fragment shader and how they are sampled
          *
          **/
         public enum Format {
-            /** @deprecated renderscript is deprecated in J
-            */
+            /**
+             * @deprecated in API 16
+             **/
             ALPHA (1),
-            /** @deprecated renderscript is deprecated in J
-            */
+            /**
+             * @deprecated in API 16
+             **/
             LUMINANCE_ALPHA (2),
-            /** @deprecated renderscript is deprecated in J
-            */
+            /**
+             * @deprecated in API 16
+             **/
             RGB (3),
-            /** @deprecated renderscript is deprecated in J
-            */
+            /**
+             * @deprecated in API 16
+             **/
             RGBA (4);
 
             int mID;
@@ -206,7 +224,8 @@
             mShader += "}\n";
         }
 
-        /** @deprecated renderscript is deprecated in J
+        /**
+         * @deprecated
          * Creates a builder for fixed function fragment program
          *
          * @param rs Context to which the program will belong.
@@ -217,7 +236,8 @@
             mPointSpriteEnable = false;
         }
 
-        /** @deprecated renderscript is deprecated in J
+        /**
+         * @deprecated in API 16
          * Adds a texture to be fetched as part of the fixed function
          * fragment program
          *
@@ -239,7 +259,8 @@
             return this;
         }
 
-        /** @deprecated renderscript is deprecated in J
+        /**
+         * @deprecated in API 16
          * Specifies whether the texture coordinate passed from the
          * vertex program is replaced with an openGL internal point
          * sprite texture coordinate
@@ -250,7 +271,8 @@
             return this;
         }
 
-        /** @deprecated renderscript is deprecated in J
+        /**
+         * @deprecated in API 16
          * Specifies whether the varying color passed from the vertex
          * program or the constant color set on the fragment program is
          * used in the final color calculation in the fixed function
@@ -262,7 +284,8 @@
             return this;
         }
 
-        /** @deprecated renderscript is deprecated in J
+        /**
+         * @deprecated in API 16
         * Creates the fixed function fragment program from the current
         * state of the builder.
         *
diff --git a/graphics/java/android/renderscript/ProgramRaster.java b/graphics/java/android/renderscript/ProgramRaster.java
index 26fcafe..e40751f 100644
--- a/graphics/java/android/renderscript/ProgramRaster.java
+++ b/graphics/java/android/renderscript/ProgramRaster.java
@@ -20,23 +20,15 @@
 import android.util.Log;
 
 
-/** @deprecated renderscript is deprecated in J
+/**
  * Program raster is primarily used to specify whether point sprites are enabled and to control
  * the culling mode. By default, back faces are culled.
  **/
 public class ProgramRaster extends BaseObj {
 
-    /** @deprecated renderscript is deprecated in J
-     */
     public enum CullMode {
-        /** @deprecated renderscript is deprecated in J
-        */
         BACK (0),
-        /** @deprecated renderscript is deprecated in J
-        */
         FRONT (1),
-        /** @deprecated renderscript is deprecated in J
-        */
         NONE (2);
 
         int mID;
@@ -55,7 +47,7 @@
         mCullMode = CullMode.BACK;
     }
 
-    /** @hide renderscript is deprecated in J
+    /**
      * Specifies whether vertices are rendered as screen aligned
      * elements of a specified size
      * @return whether point sprites are enabled
@@ -64,7 +56,7 @@
         return mPointSprite;
     }
 
-    /** @hide renderscript is deprecated in J
+    /**
      * Specifies how triangles are culled based on their orientation
      * @return cull mode
      */
@@ -72,8 +64,6 @@
         return mCullMode;
     }
 
-    /** @deprecated renderscript is deprecated in J
-     */
     public static ProgramRaster CULL_BACK(RenderScript rs) {
         if(rs.mProgramRaster_CULL_BACK == null) {
             ProgramRaster.Builder builder = new ProgramRaster.Builder(rs);
@@ -83,8 +73,6 @@
         return rs.mProgramRaster_CULL_BACK;
     }
 
-    /** @deprecated renderscript is deprecated in J
-     */
     public static ProgramRaster CULL_FRONT(RenderScript rs) {
         if(rs.mProgramRaster_CULL_FRONT == null) {
             ProgramRaster.Builder builder = new ProgramRaster.Builder(rs);
@@ -94,8 +82,6 @@
         return rs.mProgramRaster_CULL_FRONT;
     }
 
-    /** @deprecated renderscript is deprecated in J
-     */
     public static ProgramRaster CULL_NONE(RenderScript rs) {
         if(rs.mProgramRaster_CULL_NONE == null) {
             ProgramRaster.Builder builder = new ProgramRaster.Builder(rs);
@@ -105,37 +91,27 @@
         return rs.mProgramRaster_CULL_NONE;
     }
 
-    /** @deprecated renderscript is deprecated in J
-     */
     public static class Builder {
         RenderScript mRS;
         boolean mPointSprite;
         CullMode mCullMode;
 
-        /** @deprecated renderscript is deprecated in J
-        */
         public Builder(RenderScript rs) {
             mRS = rs;
             mPointSprite = false;
             mCullMode = CullMode.BACK;
         }
 
-        /** @deprecated renderscript is deprecated in J
-        */
         public Builder setPointSpriteEnabled(boolean enable) {
             mPointSprite = enable;
             return this;
         }
 
-        /** @deprecated renderscript is deprecated in J
-        */
         public Builder setCullMode(CullMode m) {
             mCullMode = m;
             return this;
         }
 
-        /** @deprecated renderscript is deprecated in J
-        */
         public ProgramRaster create() {
             mRS.validate();
             int id = mRS.nProgramRasterCreate(mPointSprite, mCullMode.mID);
diff --git a/graphics/java/android/renderscript/ProgramStore.java b/graphics/java/android/renderscript/ProgramStore.java
index 20043f2..d0fd6e5 100644
--- a/graphics/java/android/renderscript/ProgramStore.java
+++ b/graphics/java/android/renderscript/ProgramStore.java
@@ -20,7 +20,7 @@
 import android.util.Log;
 
 
-/** @deprecated renderscript is deprecated in J
+/**
  * <p>ProgramStore contains a set of parameters that control how
  * the graphics hardware handles writes to the framebuffer.
  * It could be used to:</p>
@@ -35,7 +35,7 @@
  *
  **/
 public class ProgramStore extends BaseObj {
-    /** @deprecated renderscript is deprecated in J
+    /**
     * Specifies the function used to determine whether a fragment
     * will be drawn during the depth testing stage in the rendering
     * pipeline by comparing its value with that already in the depth
@@ -44,36 +44,36 @@
     */
     public enum DepthFunc {
 
-        /** @deprecated renderscript is deprecated in J
+        /**
         * Always drawn
         */
         ALWAYS (0),
-        /** @deprecated renderscript is deprecated in J
+        /**
         * Drawn if the incoming depth value is less than that in the
         * depth buffer
         */
         LESS (1),
-        /** @deprecated renderscript is deprecated in J
+        /**
         * Drawn if the incoming depth value is less or equal to that in
         * the depth buffer
         */
         LESS_OR_EQUAL (2),
-        /** @deprecated renderscript is deprecated in J
+        /**
         * Drawn if the incoming depth value is greater than that in the
         * depth buffer
         */
         GREATER (3),
-        /** @deprecated renderscript is deprecated in J
+        /**
         * Drawn if the incoming depth value is greater or equal to that
         * in the depth buffer
         */
         GREATER_OR_EQUAL (4),
-        /** @deprecated renderscript is deprecated in J
+        /**
         * Drawn if the incoming depth value is equal to that in the
         * depth buffer
         */
         EQUAL (5),
-        /** @deprecated renderscript is deprecated in J
+        /**
         * Drawn if the incoming depth value is not equal to that in the
         * depth buffer
         */
@@ -85,7 +85,7 @@
         }
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
     * Specifies the functions used to combine incoming pixels with
     * those already in the frame buffer.
     *
@@ -94,32 +94,14 @@
     *
     */
     public enum BlendSrcFunc {
-        /** @deprecated renderscript is deprecated in J
-        */
         ZERO (0),
-        /** @deprecated renderscript is deprecated in J
-        */
         ONE (1),
-        /** @deprecated renderscript is deprecated in J
-        */
         DST_COLOR (2),
-        /** @deprecated renderscript is deprecated in J
-        */
         ONE_MINUS_DST_COLOR (3),
-        /** @deprecated renderscript is deprecated in J
-        */
         SRC_ALPHA (4),
-        /** @deprecated renderscript is deprecated in J
-        */
         ONE_MINUS_SRC_ALPHA (5),
-        /** @deprecated renderscript is deprecated in J
-        */
         DST_ALPHA (6),
-        /** @deprecated renderscript is deprecated in J
-        */
         ONE_MINUS_DST_ALPHA (7),
-        /** @deprecated renderscript is deprecated in J
-        */
         SRC_ALPHA_SATURATE (8);
 
         int mID;
@@ -128,7 +110,7 @@
         }
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
     * Specifies the functions used to combine incoming pixels with
     * those already in the frame buffer.
     *
@@ -138,29 +120,13 @@
     *
     */
     public enum BlendDstFunc {
-        /** @deprecated renderscript is deprecated in J
-        */
         ZERO (0),
-        /** @deprecated renderscript is deprecated in J
-        */
         ONE (1),
-        /** @deprecated renderscript is deprecated in J
-        */
         SRC_COLOR (2),
-        /** @deprecated renderscript is deprecated in J
-        */
         ONE_MINUS_SRC_COLOR (3),
-        /** @deprecated renderscript is deprecated in J
-        */
         SRC_ALPHA (4),
-        /** @deprecated renderscript is deprecated in J
-        */
         ONE_MINUS_SRC_ALPHA (5),
-        /** @deprecated renderscript is deprecated in J
-        */
         DST_ALPHA (6),
-        /** @deprecated renderscript is deprecated in J
-        */
         ONE_MINUS_DST_ALPHA (7);
 
         int mID;
@@ -183,7 +149,7 @@
         super(id, rs);
     }
 
-    /** @hide renderscript is deprecated in J
+    /**
     * Returns the function used to test writing into the depth
     * buffer
     * @return depth function
@@ -192,7 +158,7 @@
         return mDepthFunc;
     }
 
-    /** @hide renderscript is deprecated in J
+    /**
     * Queries whether writes are enabled into the depth buffer
     * @return depth mask
     */
@@ -200,7 +166,7 @@
         return mDepthMask;
     }
 
-    /** @hide renderscript is deprecated in J
+    /**
     * Queries whether red channel is written
     * @return red color channel mask
     */
@@ -208,7 +174,7 @@
         return mColorMaskR;
     }
 
-    /** @hide renderscript is deprecated in J
+    /**
     * Queries whether green channel is written
     * @return green color channel mask
     */
@@ -216,7 +182,7 @@
         return mColorMaskG;
     }
 
-    /** @hide renderscript is deprecated in J
+    /**
     * Queries whether blue channel is written
     * @return blue color channel mask
     */
@@ -224,7 +190,7 @@
         return mColorMaskB;
     }
 
-    /** @hide renderscript is deprecated in J
+    /**
     * Queries whether alpha channel is written
     * @return alpha channel mask
     */
@@ -232,7 +198,7 @@
         return mColorMaskA;
     }
 
-    /** @hide renderscript is deprecated in J
+    /**
     * Specifies how the source blending factor is computed
     * @return source blend function
     */
@@ -240,7 +206,7 @@
         return mBlendSrc;
     }
 
-    /** @hide renderscript is deprecated in J
+    /**
     * Specifies how the destination blending factor is computed
     * @return destination blend function
     */
@@ -248,7 +214,7 @@
         return mBlendDst;
     }
 
-    /** @hide renderscript is deprecated in J
+    /**
     * Specifies whether colors are dithered before writing into the
     * framebuffer
     * @return whether dither is enabled
@@ -257,7 +223,7 @@
         return mDither;
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
     * Returns a pre-defined program store object with the following
     * characteristics:
     *  - incoming pixels are drawn if their depth value is less than
@@ -279,7 +245,7 @@
         }
         return rs.mProgramStore_BLEND_NONE_DEPTH_TEST;
     }
-    /** @deprecated renderscript is deprecated in J
+    /**
     * Returns a pre-defined program store object with the following
     * characteristics:
     *  - incoming pixels always pass the depth test and their value
@@ -300,7 +266,7 @@
         }
         return rs.mProgramStore_BLEND_NONE_DEPTH_NO_DEPTH;
     }
-    /** @deprecated renderscript is deprecated in J
+    /**
     * Returns a pre-defined program store object with the following
     * characteristics:
     *  - incoming pixels are drawn if their depth value is less than
@@ -324,7 +290,7 @@
         }
         return rs.mProgramStore_BLEND_ALPHA_DEPTH_TEST;
     }
-    /** @deprecated renderscript is deprecated in J
+    /**
     * Returns a pre-defined program store object with the following
     * characteristics:
     *  - incoming pixels always pass the depth test and their value
@@ -347,7 +313,7 @@
         return rs.mProgramStore_BLEND_ALPHA_DEPTH_NO_DEPTH;
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
     * Builder class for ProgramStore object. If the builder is left
     * empty, the equivalent of BLEND_NONE_DEPTH_NONE would be
     * returned
@@ -376,7 +342,7 @@
             mBlendDst = BlendDstFunc.ZERO;
         }
 
-        /** @deprecated renderscript is deprecated in J
+        /**
         * Specifies the depth testing behavior
         *
         * @param func function used for depth testing
@@ -388,7 +354,7 @@
             return this;
         }
 
-        /** @deprecated renderscript is deprecated in J
+        /**
         * Enables writes into the depth buffer
         *
         * @param enable specifies whether depth writes are
@@ -401,7 +367,7 @@
             return this;
         }
 
-        /** @deprecated renderscript is deprecated in J
+        /**
         * Enables writes into the color buffer
         *
         * @param r specifies whether red channel is written
@@ -419,7 +385,7 @@
             return this;
         }
 
-        /** @deprecated renderscript is deprecated in J
+        /**
         * Specifies how incoming pixels are combined with the pixels
         * stored in the framebuffer
         *
@@ -436,7 +402,7 @@
             return this;
         }
 
-        /** @deprecated renderscript is deprecated in J
+        /**
         * Enables dithering
         *
         * @param enable specifies whether dithering is enabled or
@@ -449,7 +415,7 @@
             return this;
         }
 
-        /** @deprecated renderscript is deprecated in J
+        /**
         * Creates a program store from the current state of the builder
         */
         public ProgramStore create() {
diff --git a/graphics/java/android/renderscript/ProgramVertex.java b/graphics/java/android/renderscript/ProgramVertex.java
index c13b9b0..74d666b 100644
--- a/graphics/java/android/renderscript/ProgramVertex.java
+++ b/graphics/java/android/renderscript/ProgramVertex.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
- /** @deprecated renderscript is deprecated in J
+ /**
  * <p>The Renderscript vertex program, also known as a vertex shader, describes a stage in
  * the graphics pipeline responsible for manipulating geometric data in a user-defined way.
  * The object is constructed by providing the Renderscript system with the following data:</p>
@@ -42,7 +42,7 @@
 import android.util.Log;
 
 
-/** @deprecated renderscript is deprecated in J
+/**
  * ProgramVertex, also know as a vertex shader, describes a
  * stage in the graphics pipeline responsible for manipulating
  * geometric data in a user-defined way.
@@ -54,14 +54,14 @@
         super(id, rs);
     }
 
-    /** @hide renderscript is deprecated in J
+    /**
      * @return number of input attribute elements
      */
     public int getInputCount() {
         return mInputs != null ? mInputs.length : 0;
     }
 
-    /** @hide renderscript is deprecated in J
+    /**
      * @param slot location of the input to return
      * @return input attribute element
      */
@@ -72,7 +72,7 @@
         return mInputs[slot];
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
     * Builder class for creating ProgramVertex objects.
     * The builder starts empty and the user must minimally provide
     * the GLSL shader code, and the varying inputs. Constant, or
@@ -81,7 +81,7 @@
     *
     **/
     public static class Builder extends BaseProgramBuilder {
-        /** @deprecated renderscript is deprecated in J
+        /**
          * Create a builder object.
          *
          * @param rs Context to which the program will belong.
@@ -90,7 +90,7 @@
             super(rs);
         }
 
-        /** @deprecated renderscript is deprecated in J
+        /**
          * Add varying inputs to the program
          *
          * @param e element describing the layout of the varying input
@@ -109,7 +109,7 @@
             return this;
         }
 
-        /** @deprecated renderscript is deprecated in J
+        /**
          * Creates ProgramVertex from the current state of the builder
          *
          * @return  ProgramVertex
diff --git a/graphics/java/android/renderscript/ProgramVertexFixedFunction.java b/graphics/java/android/renderscript/ProgramVertexFixedFunction.java
index 97444db..88cade4 100644
--- a/graphics/java/android/renderscript/ProgramVertexFixedFunction.java
+++ b/graphics/java/android/renderscript/ProgramVertexFixedFunction.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008 The Android Open Source Project
+ * Copyright (C) 2008-2012 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,7 +21,8 @@
 import android.util.Log;
 
 
-/** @deprecated renderscript is deprecated in J
+/**
+ * @deprecated in API 16
  * ProgramVertexFixedFunction is a helper class that provides a
  * simple way to create a fixed function emulation vertex shader
  * without writing any GLSL code.
@@ -33,7 +34,8 @@
         super(id, rs);
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
+     * @deprecated in API 16
      * Binds the constant buffer containing fixed function emulation
      * matrices
      *
@@ -45,10 +47,16 @@
     }
 
     static class InternalBuilder extends BaseProgramBuilder {
+        /**
+         * @deprecated in API 16
+         */
         public InternalBuilder(RenderScript rs) {
             super(rs);
         }
 
+        /**
+         * @deprecated in API 16
+         */
         public InternalBuilder addInput(Element e) throws IllegalStateException {
             // Should check for consistant and non-conflicting names...
             if(mInputCount >= MAX_INPUT) {
@@ -61,7 +69,8 @@
             return this;
         }
 
-        /** @deprecated renderscript is deprecated in J
+        /**
+         * @deprecated in API 16
          * Creates ProgramVertexFixedFunction from the current state of
          * the builder
          *
@@ -98,12 +107,16 @@
         }
     }
 
+    /**
+     * @deprecated in API 16
+     */
     public static class Builder {
         boolean mTextureMatrixEnable;
         String mShader;
         RenderScript mRS;
 
-        /** @deprecated renderscript is deprecated in J
+        /**
+         * @deprecated in API 16
          * Creates a builder for fixed function vertex program
          *
          * @param rs Context to which the program will belong.
@@ -112,7 +125,8 @@
             mRS = rs;
         }
 
-        /** @deprecated renderscript is deprecated in J
+        /**
+         * @deprecated in API 16
          * Specifies whether texture matrix calculations are to be added
          * to the shader
          *
@@ -152,7 +166,8 @@
             mShader += "}\n";
         }
 
-        /** @deprecated renderscript is deprecated in J
+        /**
+         * @deprecated in API 16
          * Creates ProgramVertexFixedFunction from the current state of
          * the builder
          *
@@ -176,7 +191,8 @@
         }
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
+     * @deprecated in API 16
      * Helper class to store modelview, projection and texture
      * matrices for ProgramVertexFixedFunction
      *
@@ -196,7 +212,8 @@
         }
         private FieldPacker mIOBuffer;
 
-        /** @deprecated renderscript is deprecated in J
+        /**
+        * @deprecated in API 16
         * Creates a buffer to store fixed function emulation matrices
         *
         * @param rs Context to which the allocation will belong.
@@ -215,7 +232,8 @@
             setTexture(new Matrix4f());
         }
 
-        /** @deprecated renderscript is deprecated in J
+        /**
+        * @deprecated in API 16
         * Forces deallocation of memory backing the contant matrices.
         * Normally, this is unnecessary and will be garbage collected
         *
@@ -233,7 +251,8 @@
             mAlloc.setFromFieldPacker(0, mIOBuffer);
         }
 
-        /** @deprecated renderscript is deprecated in J
+        /**
+        * @deprecated in API 16
         * Sets the modelview matrix in the fixed function matrix buffer
         *
         * @param m modelview matrix
@@ -243,7 +262,8 @@
             addToBuffer(MODELVIEW_OFFSET*4, m);
         }
 
-        /** @deprecated renderscript is deprecated in J
+        /**
+        * @deprecated in API 16
         * Sets the projection matrix in the fixed function matrix buffer
         *
         * @param m projection matrix
@@ -253,7 +273,8 @@
             addToBuffer(PROJECTION_OFFSET*4, m);
         }
 
-        /** @deprecated renderscript is deprecated in J
+        /**
+        * @deprecated in API 16
         * Sets the texture matrix in the fixed function matrix buffer.
         * Texture matrix must be enabled in the
         * ProgramVertexFixedFunction builder for the shader to utilize
diff --git a/graphics/java/android/renderscript/RSDriverException.java b/graphics/java/android/renderscript/RSDriverException.java
index 1784087..ce85b53 100644
--- a/graphics/java/android/renderscript/RSDriverException.java
+++ b/graphics/java/android/renderscript/RSDriverException.java
@@ -17,7 +17,7 @@
 package android.renderscript;
 
 
-/** @deprecated renderscript is deprecated in J
+/**
  * Base class for all exceptions thrown by the Android
  * Renderscript
  */
diff --git a/graphics/java/android/renderscript/RSIllegalArgumentException.java b/graphics/java/android/renderscript/RSIllegalArgumentException.java
index 039d8f5..954c0e8 100644
--- a/graphics/java/android/renderscript/RSIllegalArgumentException.java
+++ b/graphics/java/android/renderscript/RSIllegalArgumentException.java
@@ -17,13 +17,11 @@
 package android.renderscript;
 
 
-/** @deprecated renderscript is deprecated in J
+/**
  * Base class for all exceptions thrown by the Android
  * Renderscript
  */
 public class RSIllegalArgumentException extends RSRuntimeException {
-    /** @deprecated renderscript is deprecated in J
-    */
     public RSIllegalArgumentException(String string) {
         super(string);
     }
diff --git a/graphics/java/android/renderscript/RSInvalidStateException.java b/graphics/java/android/renderscript/RSInvalidStateException.java
index ccbaea1..691aeba 100644
--- a/graphics/java/android/renderscript/RSInvalidStateException.java
+++ b/graphics/java/android/renderscript/RSInvalidStateException.java
@@ -17,13 +17,11 @@
 package android.renderscript;
 
 
-/** @deprecated renderscript is deprecated in J
+/**
  * Base class for all exceptions thrown by the Android
  * Renderscript
  */
 public class RSInvalidStateException extends RSRuntimeException {
-    /** @deprecated renderscript is deprecated in J
-    */
     public RSInvalidStateException(String string) {
         super(string);
     }
diff --git a/graphics/java/android/renderscript/RSRuntimeException.java b/graphics/java/android/renderscript/RSRuntimeException.java
index 3fb1ea9..5a16478 100644
--- a/graphics/java/android/renderscript/RSRuntimeException.java
+++ b/graphics/java/android/renderscript/RSRuntimeException.java
@@ -17,14 +17,12 @@
 package android.renderscript;
 
 
-/** @deprecated renderscript is deprecated in J
+/**
  * Base class for all exceptions thrown by the Android
  * Renderscript
  */
 public class RSRuntimeException
   extends java.lang.RuntimeException {
-    /** @deprecated renderscript is deprecated in J
-    */
     public RSRuntimeException(String string) {
         super(string);
     }
diff --git a/graphics/java/android/renderscript/RSSurfaceView.java b/graphics/java/android/renderscript/RSSurfaceView.java
index 997b7d0..506f1af 100644
--- a/graphics/java/android/renderscript/RSSurfaceView.java
+++ b/graphics/java/android/renderscript/RSSurfaceView.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008 The Android Open Source Project
+ * Copyright (C) 2008-2012 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -29,7 +29,8 @@
 import android.view.SurfaceHolder;
 import android.view.SurfaceView;
 
-/** @deprecated renderscript is deprecated in J
+/**
+ * @deprecated in API 16
  * The Surface View for a graphics renderscript (RenderScriptGL) to draw on.
  *
  * <div class="special reference">
@@ -42,7 +43,8 @@
     private SurfaceHolder mSurfaceHolder;
     private RenderScriptGL mRS;
 
-    /** @deprecated renderscript is deprecated in J
+    /**
+     * @deprecated in API 16
      * Standard View constructor. In order to render something, you
      * must call {@link android.opengl.GLSurfaceView#setRenderer} to
      * register a renderer.
@@ -53,7 +55,8 @@
         //Log.v(RenderScript.LOG_TAG, "RSSurfaceView");
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
+     * @deprecated in API 16
      * Standard View constructor. In order to render something, you
      * must call {@link android.opengl.GLSurfaceView#setRenderer} to
      * register a renderer.
@@ -71,7 +74,8 @@
         holder.addCallback(this);
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
+     * @deprecated in API 16
      * This method is part of the SurfaceHolder.Callback interface, and is
      * not normally called or subclassed by clients of RSSurfaceView.
      */
@@ -79,7 +83,8 @@
         mSurfaceHolder = holder;
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
+     * @deprecated in API 16
      * This method is part of the SurfaceHolder.Callback interface, and is
      * not normally called or subclassed by clients of RSSurfaceView.
      */
@@ -92,7 +97,8 @@
         }
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
+     * @deprecated in API 16
      * This method is part of the SurfaceHolder.Callback interface, and is
      * not normally called or subclassed by clients of RSSurfaceView.
      */
@@ -104,7 +110,8 @@
         }
     }
 
-   /** @deprecated renderscript is deprecated in J
+   /**
+     * @deprecated in API 16
      * Inform the view that the activity is paused. The owner of this view must
      * call this method when the activity is paused. Calling this method will
      * pause the rendering thread.
@@ -116,7 +123,8 @@
         }
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
+     * @deprecated in API 16
      * Inform the view that the activity is resumed. The owner of this view must
      * call this method when the activity is resumed. Calling this method will
      * recreate the OpenGL display and resume the rendering
@@ -129,12 +137,18 @@
         }
     }
 
+    /**
+     * @deprecated in API 16
+     **/
     public RenderScriptGL createRenderScriptGL(RenderScriptGL.SurfaceConfig sc) {
       RenderScriptGL rs = new RenderScriptGL(this.getContext(), sc);
         setRenderScriptGL(rs);
         return rs;
     }
 
+    /**
+     * @deprecated in API 16
+     **/
     public void destroyRenderScriptGL() {
         synchronized (this) {
             mRS.destroy();
@@ -142,10 +156,16 @@
         }
     }
 
+    /**
+     * @deprecated in API 16
+     **/
     public void setRenderScriptGL(RenderScriptGL rs) {
         mRS = rs;
     }
 
+    /**
+     * @deprecated in API 16
+     **/
     public RenderScriptGL getRenderScriptGL() {
         return mRS;
     }
diff --git a/graphics/java/android/renderscript/RSTextureView.java b/graphics/java/android/renderscript/RSTextureView.java
index b40f73c..30b2f99 100644
--- a/graphics/java/android/renderscript/RSTextureView.java
+++ b/graphics/java/android/renderscript/RSTextureView.java
@@ -28,7 +28,7 @@
 import android.util.Log;
 import android.view.TextureView;
 
-/** @deprecated renderscript is deprecated in J
+/**
  * The Texture View for a graphics renderscript (RenderScriptGL)
  * to draw on.
  *
@@ -37,7 +37,7 @@
     private RenderScriptGL mRS;
     private SurfaceTexture mSurfaceTexture;
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Standard View constructor. In order to render something, you
      * must call {@link android.opengl.GLSurfaceView#setRenderer} to
      * register a renderer.
@@ -48,7 +48,7 @@
         //Log.v(RenderScript.LOG_TAG, "RSSurfaceView");
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Standard View constructor. In order to render something, you
      * must call {@link android.opengl.GLSurfaceView#setRenderer} to
      * register a renderer.
@@ -102,7 +102,7 @@
         mSurfaceTexture = surface;
     }
 
-   /** @deprecated renderscript is deprecated in J
+   /**
      * Inform the view that the activity is paused. The owner of this view must
      * call this method when the activity is paused. Calling this method will
      * pause the rendering thread.
@@ -114,7 +114,7 @@
         }
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Inform the view that the activity is resumed. The owner of this view must
      * call this method when the activity is resumed. Calling this method will
      * recreate the OpenGL display and resume the rendering
@@ -127,7 +127,7 @@
         }
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Create a new RenderScriptGL object and attach it to the
      * TextureView if present.
      *
@@ -145,7 +145,7 @@
         return rs;
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Destroy the RenderScriptGL object associated with this
      * TextureView.
      */
@@ -154,7 +154,7 @@
         mRS = null;
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Set a new RenderScriptGL object.  This also will attach the
      * new object to the TextureView if present.
      *
@@ -167,7 +167,7 @@
         }
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Returns the previously set RenderScriptGL object.
      *
      * @return RenderScriptGL
diff --git a/graphics/java/android/renderscript/RenderScript.java b/graphics/java/android/renderscript/RenderScript.java
index 46ad495..2032f67 100644
--- a/graphics/java/android/renderscript/RenderScript.java
+++ b/graphics/java/android/renderscript/RenderScript.java
@@ -32,7 +32,7 @@
 
 
 
-/** @deprecated renderscript is deprecated in J
+/**
  * Renderscript base master class.  An instance of this class creates native
  * worker threads for processing commands from this object.  This base class
  * does not provide any extended capabilities beyond simple data processing.
@@ -743,7 +743,7 @@
     ///////////////////////////////////////////////////////////////////////////////////
     //
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Base class application should derive from for handling RS messages
      * coming from their scripts.  When a script calls sendToClient the data
      * fields will be filled in and then the run method called by a message
@@ -758,7 +758,7 @@
         public void run() {
         }
     }
-    /** @deprecated renderscript is deprecated in J
+    /**
      * If an application is expecting messages it should set this field to an
      * instance of RSMessage.  This instance will receive all the user messages
      * sent from sendToClient by scripts from this context.
@@ -773,7 +773,7 @@
         return mMessageCallback;
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Runtime error base class.  An application should derive from this class
      * if it wishes to install an error handler.  When errors occur at runtime
      * the fields in this class will be filled and the run method called.
@@ -786,7 +786,7 @@
         }
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Application Error handler.  All runtime errors will be dispatched to the
      * instance of RSAsyncError set here.  If this field is null a
      * RSRuntimeException will instead be thrown with details about the error.
@@ -802,7 +802,7 @@
         return mErrorCallback;
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * RenderScript worker threads priority enumeration.  The default value is
      * NORMAL.  Applications wishing to do background processing such as
      * wallpapers should set their priority to LOW to avoid starving forground
@@ -825,7 +825,7 @@
     }
 
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Change the priority of the worker threads for this context.
      *
      * @param p New priority to be set.
@@ -922,7 +922,7 @@
         }
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Gets the application context associated with the RenderScript context.
      *
      * @return The application context.
@@ -931,7 +931,7 @@
         return mApplicationContext;
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Create a basic RenderScript context.
      *
      * @hide
@@ -951,7 +951,7 @@
         return rs;
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Create a basic RenderScript context.
      *
      * @param ctx The context.
@@ -962,7 +962,7 @@
         return create(ctx, v);
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Print the currently available debugging information about the state of
      * the RS context to the log.
      *
@@ -972,7 +972,7 @@
         nContextDump(0);
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Wait for any commands in the fifo between the java bindings and native to
      * be processed.
      *
@@ -981,7 +981,7 @@
         nContextFinish();
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Destroy this renderscript context.  Once this function is called its no
      * longer legal to use this or any objects created by this context.
      *
diff --git a/graphics/java/android/renderscript/RenderScriptGL.java b/graphics/java/android/renderscript/RenderScriptGL.java
index ac1a392..dbdbe3d 100644
--- a/graphics/java/android/renderscript/RenderScriptGL.java
+++ b/graphics/java/android/renderscript/RenderScriptGL.java
@@ -28,7 +28,7 @@
 import android.view.SurfaceHolder;
 import android.view.SurfaceView;
 
-/** @deprecated renderscript is deprecated in J
+/**
  * The Graphics derivitive of Renderscript.  Extends the basic context to add a
  * root script which is the display window for graphical output.  When the
  * system needs to update the display the currently bound root script will be
@@ -45,7 +45,7 @@
     int mWidth;
     int mHeight;
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Class which is used to describe a pixel format for a graphical buffer.
      * This is used to describe the intended format of the display surface.
      *
@@ -92,7 +92,7 @@
             }
         }
 
-        /** @deprecated renderscript is deprecated in J
+        /**
          * Set the per-component bit depth for color (red, green, blue).  This
          * configures the surface for an unsigned integer buffer type.
          *
@@ -105,7 +105,7 @@
             mColorPref = preferred;
         }
 
-        /** @deprecated renderscript is deprecated in J
+        /**
          * Set the bit depth for alpha. This configures the surface for
          * an unsigned integer buffer type.
          *
@@ -118,7 +118,7 @@
             mAlphaPref = preferred;
         }
 
-         /** @deprecated renderscript is deprecated in J
+         /**
          * Set the bit depth for the depth buffer. This configures the
          * surface for an unsigned integer buffer type.  If a minimum of 0
          * is specified then its possible no depth buffer will be
@@ -133,7 +133,7 @@
             mDepthPref = preferred;
         }
 
-        /** @deprecated renderscript is deprecated in J
+        /**
          * Configure the multisample rendering.
          *
          * @param minimum The required number of samples, must be at least 1.
@@ -156,7 +156,7 @@
 
     SurfaceConfig mSurfaceConfig;
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Construct a new RenderScriptGL context.
      *
      * @param ctx The context.
@@ -186,7 +186,7 @@
         mMessageThread.start();
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Bind an os surface
      *
      *
@@ -205,7 +205,8 @@
         nContextSetSurface(w, h, s);
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
+     * @deprecated in API 16
      * Bind an os surface
      *
      * @param w
@@ -221,7 +222,7 @@
         nContextSetSurfaceTexture(w, h, sur);
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * return the height of the last set surface.
      *
      * @return int
@@ -230,7 +231,7 @@
         return mHeight;
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * return the width of the last set surface.
      *
      * @return int
@@ -239,7 +240,7 @@
         return mWidth;
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Temporarly halt calls to the root rendering script.
      *
      */
@@ -248,7 +249,7 @@
         nContextPause();
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Resume calls to the root rendering script.
      *
      */
@@ -258,7 +259,7 @@
     }
 
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Set the script to handle calls to render the primary surface.
      *
      * @param s Graphics script to process rendering requests.
@@ -268,7 +269,7 @@
         nContextBindRootScript(safeID(s));
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Set the default ProgramStore object seen as the parent state by the root
      * rendering script.
      *
@@ -279,7 +280,7 @@
         nContextBindProgramStore(safeID(p));
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Set the default ProgramFragment object seen as the parent state by the
      * root rendering script.
      *
@@ -290,7 +291,7 @@
         nContextBindProgramFragment(safeID(p));
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Set the default ProgramRaster object seen as the parent state by the
      * root rendering script.
      *
@@ -301,7 +302,7 @@
         nContextBindProgramRaster(safeID(p));
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Set the default ProgramVertex object seen as the parent state by the
      * root rendering script.
      *
diff --git a/graphics/java/android/renderscript/Sampler.java b/graphics/java/android/renderscript/Sampler.java
index 6b258ab..0df1012 100644
--- a/graphics/java/android/renderscript/Sampler.java
+++ b/graphics/java/android/renderscript/Sampler.java
@@ -27,32 +27,18 @@
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
 
-/** @deprecated renderscript is deprecated in J
+/**
  * Sampler object which defines how data is extracted from textures. Samplers
  * are attached to Program objects (currently only ProgramFragment) when those objects
  * need to access texture data.
  **/
 public class Sampler extends BaseObj {
-    /** @deprecated renderscript is deprecated in J
-    */
     public enum Value {
-        /** @deprecated renderscript is deprecated in J
-        */
         NEAREST (0),
-        /** @deprecated renderscript is deprecated in J
-        */
         LINEAR (1),
-        /** @deprecated renderscript is deprecated in J
-        */
         LINEAR_MIP_LINEAR (2),
-        /** @deprecated renderscript is deprecated in J
-        */
         LINEAR_MIP_NEAREST (5),
-        /** @deprecated renderscript is deprecated in J
-        */
         WRAP (3),
-        /** @deprecated renderscript is deprecated in J
-        */
         CLAMP (4);
 
         int mID;
@@ -72,42 +58,42 @@
         super(id, rs);
     }
 
-    /** @hide renderscript is deprecated in J
+    /**
      * @return minification setting for the sampler
      */
     public Value getMinification() {
         return mMin;
     }
 
-    /** @hide renderscript is deprecated in J
+    /**
      * @return magnification setting for the sampler
      */
     public Value getMagnification() {
         return mMag;
     }
 
-    /** @hide renderscript is deprecated in J
+    /**
      * @return S wrapping mode for the sampler
      */
     public Value getWrapS() {
         return mWrapS;
     }
 
-    /** @hide renderscript is deprecated in J
+    /**
      * @return T wrapping mode for the sampler
      */
     public Value getWrapT() {
         return mWrapT;
     }
 
-    /** @hide renderscript is deprecated in J
+    /**
      * @return anisotropy setting for the sampler
      */
     public float getAnisotropy() {
         return mAniso;
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Retrieve a sampler with min and mag set to nearest and wrap modes set to
      * clamp.
      *
@@ -127,7 +113,7 @@
         return rs.mSampler_CLAMP_NEAREST;
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Retrieve a sampler with min and mag set to linear and wrap modes set to
      * clamp.
      *
@@ -147,7 +133,7 @@
         return rs.mSampler_CLAMP_LINEAR;
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Retrieve a sampler with ag set to linear, min linear mipmap linear, and
      * to and wrap modes set to clamp.
      *
@@ -167,7 +153,7 @@
         return rs.mSampler_CLAMP_LINEAR_MIP_LINEAR;
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Retrieve a sampler with min and mag set to nearest and wrap modes set to
      * wrap.
      *
@@ -187,7 +173,7 @@
         return rs.mSampler_WRAP_NEAREST;
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Retrieve a sampler with min and mag set to nearest and wrap modes set to
      * wrap.
      *
@@ -207,7 +193,7 @@
         return rs.mSampler_WRAP_LINEAR;
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Retrieve a sampler with ag set to linear, min linear mipmap linear, and
      * to and wrap modes set to wrap.
      *
@@ -228,7 +214,7 @@
     }
 
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Builder for creating non-standard samplers.  Usefull if mix and match of
      * wrap modes is necesary or if anisotropic filtering is desired.
      *
diff --git a/graphics/java/android/renderscript/Script.java b/graphics/java/android/renderscript/Script.java
index 56893ac..bbf5e7e 100644
--- a/graphics/java/android/renderscript/Script.java
+++ b/graphics/java/android/renderscript/Script.java
@@ -16,11 +16,11 @@
 
 package android.renderscript;
 
-/** @deprecated renderscript is deprecated in J
+/**
  *
  **/
 public class Script extends BaseObj {
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Only intended for use by generated reflected code.
      *
      * @param slot
@@ -29,7 +29,7 @@
         mRS.nScriptInvoke(getID(mRS), slot);
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Only intended for use by generated reflected code.
      *
      * @param slot
@@ -43,7 +43,7 @@
         }
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Only intended for use by generated reflected code.
      *
      * @param slot
@@ -77,7 +77,7 @@
     }
 
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Only intended for use by generated reflected code.
      *
      * @param va
@@ -92,7 +92,7 @@
         }
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Only intended for use by generated reflected code.
      *
      * @param index
@@ -102,7 +102,7 @@
         mRS.nScriptSetVarF(getID(mRS), index, v);
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Only intended for use by generated reflected code.
      *
      * @param index
@@ -112,7 +112,7 @@
         mRS.nScriptSetVarD(getID(mRS), index, v);
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Only intended for use by generated reflected code.
      *
      * @param index
@@ -122,7 +122,7 @@
         mRS.nScriptSetVarI(getID(mRS), index, v);
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Only intended for use by generated reflected code.
      *
      * @param index
@@ -132,7 +132,7 @@
         mRS.nScriptSetVarJ(getID(mRS), index, v);
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Only intended for use by generated reflected code.
      *
      * @param index
@@ -142,7 +142,7 @@
         mRS.nScriptSetVarI(getID(mRS), index, v ? 1 : 0);
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Only intended for use by generated reflected code.
      *
      * @param index
@@ -152,7 +152,7 @@
         mRS.nScriptSetVarObj(getID(mRS), index, (o == null) ? 0 : o.getID(mRS));
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Only intended for use by generated reflected code.
      *
      * @param index
@@ -162,7 +162,7 @@
         mRS.nScriptSetVarV(getID(mRS), index, v.getData());
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Only intended for use by generated reflected code.
      *
      * @param index
@@ -174,8 +174,6 @@
         mRS.nScriptSetVarVE(getID(mRS), index, v.getData(), e.getID(mRS), dims);
     }
 
-    /** @deprecated renderscript is deprecated in J
-    */
     public void setTimeZone(String timeZone) {
         mRS.validate();
         try {
diff --git a/graphics/java/android/renderscript/ScriptC.java b/graphics/java/android/renderscript/ScriptC.java
index b1d1fa5..108b230 100644
--- a/graphics/java/android/renderscript/ScriptC.java
+++ b/graphics/java/android/renderscript/ScriptC.java
@@ -29,13 +29,13 @@
 import java.lang.reflect.Field;
 import java.lang.reflect.Modifier;
 
-/** @deprecated renderscript is deprecated in J
+/**
  *
  **/
 public class ScriptC extends Script {
     private static final String TAG = "ScriptC";
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Only intended for use by the generated derived classes.
      *
      * @param id
@@ -45,7 +45,7 @@
         super(id, rs);
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Only intended for use by the generated derived classes.
      *
      *
diff --git a/graphics/java/android/renderscript/Short2.java b/graphics/java/android/renderscript/Short2.java
index 21c5f05..617f1f5 100644
--- a/graphics/java/android/renderscript/Short2.java
+++ b/graphics/java/android/renderscript/Short2.java
@@ -20,7 +20,7 @@
 import android.util.Log;
 
 
-/** @deprecated renderscript is deprecated in J
+/**
  * Class for exposing the native Renderscript Short2 type back to the Android system.
  *
  **/
diff --git a/graphics/java/android/renderscript/Short3.java b/graphics/java/android/renderscript/Short3.java
index 81a2954..b9ca49b 100644
--- a/graphics/java/android/renderscript/Short3.java
+++ b/graphics/java/android/renderscript/Short3.java
@@ -20,7 +20,7 @@
 import android.util.Log;
 
 
-/** @deprecated renderscript is deprecated in J
+/**
  * Class for exposing the native Renderscript short3 type back to the Android system.
  *
  **/
diff --git a/graphics/java/android/renderscript/Short4.java b/graphics/java/android/renderscript/Short4.java
index 861c3d7..d5f2db5 100644
--- a/graphics/java/android/renderscript/Short4.java
+++ b/graphics/java/android/renderscript/Short4.java
@@ -20,7 +20,7 @@
 import android.util.Log;
 
 
-/** @deprecated renderscript is deprecated in J
+/**
  * Class for exposing the native Renderscript short4 type back to the Android system.
  *
  **/
diff --git a/graphics/java/android/renderscript/Type.java b/graphics/java/android/renderscript/Type.java
index 9f630e7..a707df2 100644
--- a/graphics/java/android/renderscript/Type.java
+++ b/graphics/java/android/renderscript/Type.java
@@ -20,7 +20,7 @@
 import java.lang.reflect.Field;
 import android.util.Log;
 
-/** @deprecated renderscript is deprecated in J
+/**
  * <p>Type is an allocation template. It consists of an Element and one or more
  * dimensions. It describes only the layout of memory but does not allocate any
  * storage for the data that is described.</p>
@@ -70,7 +70,7 @@
         }
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Return the element associated with this Type.
      *
      * @return Element
@@ -79,7 +79,7 @@
         return mElement;
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Return the value of the X dimension.
      *
      * @return int
@@ -88,7 +88,7 @@
         return mDimX;
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Return the value of the Y dimension or 0 for a 1D allocation.
      *
      * @return int
@@ -97,7 +97,7 @@
         return mDimY;
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Return the value of the Z dimension or 0 for a 1D or 2D allocation.
      *
      * @return int
@@ -106,7 +106,7 @@
         return mDimZ;
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Return if the Type has a mipmap chain.
      *
      * @return boolean
@@ -115,7 +115,7 @@
         return mDimMipmaps;
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Return if the Type is a cube map.
      *
      * @return boolean
@@ -124,7 +124,7 @@
         return mDimFaces;
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Return the total number of accessable cells in the Type.
      *
      * @return int
@@ -196,7 +196,7 @@
         calcElementCount();
     }
 
-    /** @deprecated renderscript is deprecated in J
+    /**
      * Builder class for Type.
      *
      */
@@ -210,7 +210,7 @@
 
         Element mElement;
 
-        /** @deprecated renderscript is deprecated in J
+        /**
          * Create a new builder object.
          *
          * @param rs
@@ -222,7 +222,7 @@
             mElement = e;
         }
 
-        /** @deprecated renderscript is deprecated in J
+        /**
          * Add a dimension to the Type.
          *
          *
@@ -255,7 +255,7 @@
         }
 
 
-        /** @deprecated renderscript is deprecated in J
+        /**
          * Validate structure and create a new type.
          *
          * @return Type
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 80db693..da2192f 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -247,7 +247,6 @@
 }
 
 void OpenGLRenderer::detachFunctor(Functor* functor) {
-    ALOGD("OGLR %p detachFunctor %p", this, functor);
     mFunctors.remove(functor);
 }
 
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index 2174d06..1892fce 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -55,6 +55,7 @@
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.SystemProperties;
+import android.os.Vibrator;
 import android.provider.Settings;
 import android.provider.Settings.System;
 import android.telephony.PhoneStateListener;
@@ -119,19 +120,18 @@
     private static final int MSG_PERSIST_VOLUME = 1;
     private static final int MSG_PERSIST_MASTER_VOLUME = 2;
     private static final int MSG_PERSIST_RINGER_MODE = 3;
-    private static final int MSG_PERSIST_VIBRATE_SETTING = 4;
-    private static final int MSG_MEDIA_SERVER_DIED = 5;
-    private static final int MSG_MEDIA_SERVER_STARTED = 6;
-    private static final int MSG_PLAY_SOUND_EFFECT = 7;
-    private static final int MSG_BTA2DP_DOCK_TIMEOUT = 8;
-    private static final int MSG_LOAD_SOUND_EFFECTS = 9;
-    private static final int MSG_SET_FORCE_USE = 10;
-    private static final int MSG_PERSIST_MEDIABUTTONRECEIVER = 11;
-    private static final int MSG_BT_HEADSET_CNCT_FAILED = 12;
-    private static final int MSG_RCDISPLAY_CLEAR = 13;
-    private static final int MSG_RCDISPLAY_UPDATE = 14;
-    private static final int MSG_SET_ALL_VOLUMES = 15;
-    private static final int MSG_PERSIST_MASTER_VOLUME_MUTE = 16;
+    private static final int MSG_MEDIA_SERVER_DIED = 4;
+    private static final int MSG_MEDIA_SERVER_STARTED = 5;
+    private static final int MSG_PLAY_SOUND_EFFECT = 6;
+    private static final int MSG_BTA2DP_DOCK_TIMEOUT = 7;
+    private static final int MSG_LOAD_SOUND_EFFECTS = 8;
+    private static final int MSG_SET_FORCE_USE = 9;
+    private static final int MSG_PERSIST_MEDIABUTTONRECEIVER = 10;
+    private static final int MSG_BT_HEADSET_CNCT_FAILED = 11;
+    private static final int MSG_RCDISPLAY_CLEAR = 12;
+    private static final int MSG_RCDISPLAY_UPDATE = 13;
+    private static final int MSG_SET_ALL_VOLUMES = 14;
+    private static final int MSG_PERSIST_MASTER_VOLUME_MUTE = 15;
 
 
     // flags for MSG_PERSIST_VOLUME indicating if current and/or last audible volume should be
@@ -241,6 +241,20 @@
     };
     private int[] mStreamVolumeAlias;
 
+    // stream names used by dumpStreamStates()
+    private final String[] STREAM_NAMES = new String[] {
+            "STREAM_VOICE_CALL",
+            "STREAM_SYSTEM",
+            "STREAM_RING",
+            "STREAM_MUSIC",
+            "STREAM_ALARM",
+            "STREAM_NOTIFICATION",
+            "STREAM_BLUETOOTH_SCO",
+            "STREAM_SYSTEM_ENFORCED",
+            "STREAM_DTMF",
+            "STREAM_TTS"
+    };
+
     private final AudioSystem.ErrorCallback mAudioSystemCallback = new AudioSystem.ErrorCallback() {
         public void onError(int error) {
             switch (error) {
@@ -282,14 +296,15 @@
     private int mMuteAffectedStreams;
 
     /**
-     * Has multiple bits per vibrate type to indicate the type's vibrate
-     * setting. See {@link #setVibrateSetting(int, int)}.
-     * <p>
-     * NOTE: This is not the final decision of whether vibrate is on/off for the
-     * type since it depends on the ringer mode. See {@link #shouldVibrate(int)}.
+     * NOTE: setVibrateSetting(), getVibrateSetting(), shouldVibrate() are deprecated.
+     * mVibrateSetting is just maintained during deprecation period but vibration policy is
+     * now only controlled by mHasVibrator and mRingerMode
      */
     private int mVibrateSetting;
 
+    // Is there a vibrator
+    private final boolean mHasVibrator;
+
     // Broadcast receiver for device connections intent broadcasts
     private final BroadcastReceiver mReceiver = new AudioServiceBroadcastReceiver();
 
@@ -388,6 +403,9 @@
         PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
         mMediaEventWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "mediaKeyEvent");
 
+        Vibrator vibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
+        mHasVibrator = vibrator == null ? false : vibrator.hasVibrator();
+
        // Intialized volume
         MAX_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] = SystemProperties.getInt(
             "ro.config.vc_call_vol_steps",
@@ -507,6 +525,16 @@
         }
     }
 
+    private void dumpStreamStates(PrintWriter pw) {
+        pw.println("\nStream volumes (device: index)");
+        int numStreamTypes = AudioSystem.getNumStreamTypes();
+        for (int i = 0; i < numStreamTypes; i++) {
+            pw.println("- "+STREAM_NAMES[i]+":");
+            mStreamStates[i].dump(pw);
+            pw.println("");
+        }
+    }
+
 
     private void updateStreamVolumeAlias(boolean updateVolumes) {
         int dtmfStreamAlias;
@@ -538,18 +566,34 @@
     private void readPersistedSettings() {
         final ContentResolver cr = mContentResolver;
 
-        int ringerMode = System.getInt(cr, System.MODE_RINGER, AudioManager.RINGER_MODE_NORMAL);
+        int ringerModeFromSettings =
+                System.getInt(cr, System.MODE_RINGER, AudioManager.RINGER_MODE_NORMAL);
+        int ringerMode = ringerModeFromSettings;
         // sanity check in case the settings are restored from a device with incompatible
         // ringer modes
         if (!AudioManager.isValidRingerMode(ringerMode)) {
             ringerMode = AudioManager.RINGER_MODE_NORMAL;
+        }
+        if ((ringerMode == AudioManager.RINGER_MODE_VIBRATE) && !mHasVibrator) {
+            ringerMode = AudioManager.RINGER_MODE_SILENT;
+        }
+        if (ringerMode != ringerModeFromSettings) {
             System.putInt(cr, System.MODE_RINGER, ringerMode);
         }
         synchronized(mSettingsLock) {
             mRingerMode = ringerMode;
         }
 
-        mVibrateSetting = System.getInt(cr, System.VIBRATE_ON, 0);
+        // System.VIBRATE_ON is not used any more but defaults for mVibrateSetting
+        // are still needed while setVibrateSetting() and getVibrateSetting() are being deprecated.
+        mVibrateSetting = getValueForVibrateSetting(0,
+                                        AudioManager.VIBRATE_TYPE_NOTIFICATION,
+                                        mHasVibrator ? AudioManager.VIBRATE_SETTING_ONLY_SILENT
+                                                        : AudioManager.VIBRATE_SETTING_OFF);
+        mVibrateSetting = getValueForVibrateSetting(mVibrateSetting,
+                                        AudioManager.VIBRATE_TYPE_RINGER,
+                                        mHasVibrator ? AudioManager.VIBRATE_SETTING_ONLY_SILENT
+                                                        : AudioManager.VIBRATE_SETTING_OFF);
 
         // make sure settings for ringer mode are consistent with device type: non voice capable
         // devices (tablets) include media stream in silent mode whereas phones don't.
@@ -639,8 +683,7 @@
         // If either the client forces allowing ringer modes for this adjustment,
         // or the stream type is one that is affected by ringer modes
         if (((flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0) ||
-                streamTypeAlias == AudioSystem.STREAM_RING ||
-                (!mVoiceCapable && streamTypeAlias == AudioSystem.STREAM_MUSIC)) {
+                (streamTypeAlias == getMasterStreamType())) {
             int ringerMode = getRingerMode();
             // do not vibrate if already in vibrate mode
             if (ringerMode == AudioManager.RINGER_MODE_VIBRATE) {
@@ -648,7 +691,7 @@
             }
             // Check if the ringer mode changes with this volume adjustment. If
             // it does, it will handle adjusting the volume, so we won't below
-            adjustVolume = checkForRingerModeChange(oldIndex, direction, streamTypeAlias);
+            adjustVolume = checkForRingerModeChange(oldIndex, direction);
         }
 
         // If stream is muted, adjust last audible index only
@@ -724,9 +767,8 @@
                 (mStreamVolumeAlias[streamType] == getMasterStreamType())) {
             int newRingerMode;
             if (index == 0) {
-                newRingerMode = System.getInt(mContentResolver, System.VIBRATE_IN_SILENT, 1) == 1
-                    ? AudioManager.RINGER_MODE_VIBRATE
-                    : AudioManager.RINGER_MODE_SILENT;
+                newRingerMode = mHasVibrator ? AudioManager.RINGER_MODE_VIBRATE
+                                              : AudioManager.RINGER_MODE_SILENT;
                 setStreamVolumeInt(mStreamVolumeAlias[streamType],
                                    index,
                                    device,
@@ -1070,7 +1112,6 @@
                     // on voice capable devices
                     if (mVoiceCapable &&
                             mStreamVolumeAlias[streamType] == AudioSystem.STREAM_RING) {
-
                         Set set = mStreamStates[streamType].mLastAudibleIndex.entrySet();
                         Iterator i = set.iterator();
                         while (i.hasNext()) {
@@ -1111,6 +1152,7 @@
 
     /** @see AudioManager#shouldVibrate(int) */
     public boolean shouldVibrate(int vibrateType) {
+        if (!mHasVibrator) return false;
 
         switch (getVibrateSetting(vibrateType)) {
 
@@ -1131,21 +1173,20 @@
 
     /** @see AudioManager#getVibrateSetting(int) */
     public int getVibrateSetting(int vibrateType) {
+        if (!mHasVibrator) return AudioManager.VIBRATE_SETTING_OFF;
         return (mVibrateSetting >> (vibrateType * 2)) & 3;
     }
 
     /** @see AudioManager#setVibrateSetting(int, int) */
     public void setVibrateSetting(int vibrateType, int vibrateSetting) {
 
+        if (!mHasVibrator) return;
+
         mVibrateSetting = getValueForVibrateSetting(mVibrateSetting, vibrateType, vibrateSetting);
 
         // Broadcast change
         broadcastVibrateSetting(vibrateType);
 
-        // Post message to set ringer mode (it in turn will post a message
-        // to persist)
-        sendMsg(mAudioHandler, MSG_PERSIST_VIBRATE_SETTING, SENDMSG_NOOP, 0, 0,
-                null, 0);
     }
 
     /**
@@ -1967,48 +2008,56 @@
      * adjusting volume. If so, this will set the proper ringer mode and volume
      * indices on the stream states.
      */
-    private boolean checkForRingerModeChange(int oldIndex, int direction, int streamType) {
+    private boolean checkForRingerModeChange(int oldIndex, int direction) {
         boolean adjustVolumeIndex = true;
         int ringerMode = getRingerMode();
-        int newRingerMode = ringerMode;
         int uiIndex = (oldIndex + 5) / 10;
-        boolean vibeInSilent = System.getInt(mContentResolver, System.VIBRATE_IN_SILENT, 1) == 1;
 
-        if (ringerMode == RINGER_MODE_NORMAL) {
-            if ((direction == AudioManager.ADJUST_LOWER) && (uiIndex <= 1)) {
-                // enter silent mode if current index is the last audible one and not repeating a
-                // volume key down
-                if (vibeInSilent || mPrevVolDirection != AudioManager.ADJUST_LOWER) {
-                    // "silent mode", but which one?
-                    newRingerMode = vibeInSilent ? RINGER_MODE_VIBRATE : RINGER_MODE_SILENT;
-                }
-                if (uiIndex == 0 ||
-                        (!vibeInSilent &&
-                         mPrevVolDirection == AudioManager.ADJUST_LOWER &&
-                         mVoiceCapable && streamType == AudioSystem.STREAM_RING)) {
-                    adjustVolumeIndex = false;
+        switch (ringerMode) {
+        case RINGER_MODE_NORMAL:
+            if (direction == AudioManager.ADJUST_LOWER) {
+                if (mHasVibrator) {
+                    if (uiIndex == 1) {
+                        ringerMode = RINGER_MODE_VIBRATE;
+                    }
+                } else {
+                    if (uiIndex == 0 && mPrevVolDirection != AudioManager.ADJUST_LOWER) {
+                        ringerMode = RINGER_MODE_SILENT;
+                    }
                 }
             }
-        } else if (ringerMode == RINGER_MODE_VIBRATE) {
+            break;
+        case RINGER_MODE_VIBRATE:
+            if (!mHasVibrator) {
+                Log.e(TAG, "checkForRingerModeChange() current ringer mode is vibrate" +
+                        "but no vibrator is present");
+                break;
+            }
             if ((direction == AudioManager.ADJUST_LOWER)) {
-                // Set it to silent, if it wasn't a long-press
                 if (mPrevVolDirection != AudioManager.ADJUST_LOWER) {
-                    newRingerMode = RINGER_MODE_SILENT;
+                    ringerMode = RINGER_MODE_SILENT;
                 }
             } else if (direction == AudioManager.ADJUST_RAISE) {
-                newRingerMode = RINGER_MODE_NORMAL;
+                ringerMode = RINGER_MODE_NORMAL;
             }
             adjustVolumeIndex = false;
-        } else {
+            break;
+        case RINGER_MODE_SILENT:
             if (direction == AudioManager.ADJUST_RAISE) {
-                // exiting silent mode
-                // If VIBRATE_IN_SILENT, then go into vibrate mode
-                newRingerMode = vibeInSilent ? RINGER_MODE_VIBRATE : RINGER_MODE_NORMAL;
+                if (mHasVibrator) {
+                    ringerMode = RINGER_MODE_VIBRATE;
+                } else {
+                    ringerMode = RINGER_MODE_NORMAL;
+                }
             }
             adjustVolumeIndex = false;
+            break;
+        default:
+            Log.e(TAG, "checkForRingerModeChange() wrong ringer mode: "+ringerMode);
+            break;
         }
 
-        setRingerMode(newRingerMode);
+        setRingerMode(ringerMode);
 
         mPrevVolDirection = direction;
 
@@ -2217,9 +2266,6 @@
         }
 
         public void readSettings() {
-            boolean checkSilentVolume = (mRingerMode == AudioManager.RINGER_MODE_NORMAL) &&
-                                            isStreamAffectedByRingerMode(mStreamType);
-
             int remainingDevices = AudioSystem.DEVICE_OUT_ALL;
 
             for (int i = 0; remainingDevices != 0; i++) {
@@ -2248,12 +2294,13 @@
                                     index : AudioManager.DEFAULT_STREAM_VOLUME[mStreamType];
                 int lastAudibleIndex = Settings.System.getInt(mContentResolver, name, defaultIndex);
 
-                // a last audible index of 0 is never stored, except on non-voice capable devices
-                // (e.g. tablets) for the music stream type, where the music stream volume can reach
-                // 0 without the device being in silent mode
+                // a last audible index of 0 should never be stored for ring and notification
+                // streams on phones (voice capable devices).
+                // same for system stream on phones and tablets
                 if ((lastAudibleIndex == 0) &&
-                        (mVoiceCapable ||
-                         (mStreamVolumeAlias[mStreamType] != AudioSystem.STREAM_MUSIC))) {
+                        ((mVoiceCapable &&
+                                (mStreamVolumeAlias[mStreamType] == AudioSystem.STREAM_RING)) ||
+                         (mStreamVolumeAlias[mStreamType] == AudioSystem.STREAM_SYSTEM))) {
                     lastAudibleIndex = AudioManager.DEFAULT_STREAM_VOLUME[mStreamType];
                     // Correct the data base
                     sendMsg(mAudioHandler,
@@ -2265,12 +2312,13 @@
                             PERSIST_DELAY);
                 }
                 mLastAudibleIndex.put(device, getValidIndex(10 * lastAudibleIndex));
-                // the initial index should never be 0 for a stream affected by ringer mode if not
-                // in silent or vibrate mode.
-                // this is permitted on tablets for music stream type.
-                if (checkSilentVolume && (index == 0) &&
-                        (mVoiceCapable ||
-                         (mStreamVolumeAlias[mStreamType] != AudioSystem.STREAM_MUSIC))) {
+                // the initial index should never be 0 for ring and notification streams on phones
+                // (voice capable devices) if not in silent or vibrate mode.
+                // same for system stream on phones and tablets
+                if ((index == 0) && (mRingerMode == AudioManager.RINGER_MODE_NORMAL) &&
+                        ((mVoiceCapable &&
+                                (mStreamVolumeAlias[mStreamType] == AudioSystem.STREAM_RING)) ||
+                         (mStreamVolumeAlias[mStreamType] == AudioSystem.STREAM_SYSTEM))) {
                     index = lastAudibleIndex;
                     // Correct the data base
                     sendMsg(mAudioHandler,
@@ -2328,14 +2376,22 @@
                     mLastAudibleIndex.put(device, index);
                 }
                 // Apply change to all streams using this one as alias
+                // if changing volume of current device, also change volume of current
+                // device on aliased stream
+                boolean currentDevice = (device == getDeviceForStream(mStreamType));
                 int numStreamTypes = AudioSystem.getNumStreamTypes();
                 for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) {
-                    if (streamType != mStreamType && mStreamVolumeAlias[streamType] == mStreamType) {
-                        mStreamStates[streamType].setIndex(rescaleIndex(index,
-                                                                        mStreamType,
-                                                                        streamType),
-                                                           getDeviceForStream(streamType),
+                    if (streamType != mStreamType &&
+                            mStreamVolumeAlias[streamType] == mStreamType) {
+                        int scaledIndex = rescaleIndex(index, mStreamType, streamType);
+                        mStreamStates[streamType].setIndex(scaledIndex,
+                                                           device,
                                                            lastAudible);
+                        if (currentDevice) {
+                            mStreamStates[streamType].setIndex(scaledIndex,
+                                                               getDeviceForStream(streamType),
+                                                               lastAudible);
+                        }
                     }
                 }
                 return true;
@@ -2544,6 +2600,25 @@
                 return handler;
             }
         }
+
+        private void dump(PrintWriter pw) {
+            pw.print("   Current: ");
+            Set set = mIndex.entrySet();
+            Iterator i = set.iterator();
+            while (i.hasNext()) {
+                Map.Entry entry = (Map.Entry)i.next();
+                pw.print(Integer.toHexString(((Integer)entry.getKey()).intValue())
+                             + ": " + ((((Integer)entry.getValue()).intValue() + 5) / 10)+", ");
+            }
+            pw.print("\n   Last audible: ");
+            set = mLastAudibleIndex.entrySet();
+            i = set.iterator();
+            while (i.hasNext()) {
+                Map.Entry entry = (Map.Entry)i.next();
+                pw.print(Integer.toHexString(((Integer)entry.getKey()).intValue())
+                             + ": " + ((((Integer)entry.getValue()).intValue() + 5) / 10)+", ");
+            }
+        }
     }
 
     /** Thread that handles native AudioSystem control. */
@@ -2631,10 +2706,6 @@
             System.putInt(mContentResolver, System.MODE_RINGER, ringerMode);
         }
 
-        private void persistVibrateSetting() {
-            System.putInt(mContentResolver, System.VIBRATE_ON, mVibrateSetting);
-        }
-
         private void playSoundEffect(int effectType, int volume) {
             synchronized (mSoundEffectsLock) {
                 if (mSoundPool == null) {
@@ -2734,10 +2805,6 @@
                     persistRingerMode(getRingerMode());
                     break;
 
-                case MSG_PERSIST_VIBRATE_SETTING:
-                    persistVibrateSetting();
-                    break;
-
                 case MSG_MEDIA_SERVER_DIED:
                     if (!mMediaServerOk) {
                         Log.e(TAG, "Media server died.");
@@ -4366,5 +4433,6 @@
         // TODO probably a lot more to do here than just the audio focus and remote control stacks
         dumpFocusStack(pw);
         dumpRCStack(pw);
+        dumpStreamStates(pw);
     }
 }
diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java
index 9bafa5c..55071ec 100644
--- a/media/java/android/media/AudioSystem.java
+++ b/media/java/android/media/AudioSystem.java
@@ -260,6 +260,8 @@
     public static final String DEVICE_OUT_AUX_DIGITAL_NAME = "aux_digital";
     public static final String DEVICE_OUT_ANLG_DOCK_HEADSET_NAME = "analog_dock";
     public static final String DEVICE_OUT_DGTL_DOCK_HEADSET_NAME = "digital_dock";
+    public static final String DEVICE_OUT_USB_ACCESSORY_NAME = "usb_accessory";
+    public static final String DEVICE_OUT_USB_DEVICE_NAME = "usb_device";
 
     public static String getDeviceName(int device)
     {
@@ -290,6 +292,10 @@
             return DEVICE_OUT_ANLG_DOCK_HEADSET_NAME;
         case DEVICE_OUT_DGTL_DOCK_HEADSET:
             return DEVICE_OUT_DGTL_DOCK_HEADSET_NAME;
+        case DEVICE_OUT_USB_ACCESSORY:
+            return DEVICE_OUT_USB_ACCESSORY_NAME;
+        case DEVICE_OUT_USB_DEVICE:
+            return DEVICE_OUT_USB_DEVICE_NAME;
         case DEVICE_IN_DEFAULT:
         default:
             return "";
diff --git a/media/java/android/media/MediaCodec.java b/media/java/android/media/MediaCodec.java
index 1dbd48e..2debd57 100644
--- a/media/java/android/media/MediaCodec.java
+++ b/media/java/android/media/MediaCodec.java
@@ -94,6 +94,11 @@
  * be codec specific data marked as such using the flag {@link #BUFFER_FLAG_CODEC_CONFIG}
  * in a call to {@link #queueInputBuffer}.
  *
+ * Codec specific data included in the format passed to {@link #configure}
+ * (in ByteBuffer entries with keys "csd-0", "csd-1", ...) is automatically
+ * submitted to the codec, this data MUST NOT be submitted explicitly by the
+ * client.
+ *
  * Once the client reaches the end of the input data it signals the end of
  * the input stream by specifying a flag of {@link #BUFFER_FLAG_END_OF_STREAM} in the call to
  * {@link #queueInputBuffer}. The codec will continue to return output buffers
diff --git a/media/java/android/media/MediaExtractor.java b/media/java/android/media/MediaExtractor.java
index 58b30db..d3a00c2 100644
--- a/media/java/android/media/MediaExtractor.java
+++ b/media/java/android/media/MediaExtractor.java
@@ -225,11 +225,6 @@
      * If possible, seek to the sync sample closest to the specified time
      */
     public static final int SEEK_TO_CLOSEST_SYNC        = 2;
-    /**
-     * If possible, seek to a sample closest to the specified time, which may
-     * NOT be a sync sample!
-     */
-    public static final int SEEK_TO_CLOSEST             = 3;
 
     /**
      * All selected tracks seek near the requested time according to the
diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java
index 7540c6f..9f0fd48 100644
--- a/media/java/android/media/MediaPlayer.java
+++ b/media/java/android/media/MediaPlayer.java
@@ -743,9 +743,14 @@
         }
         Parcel request = Parcel.obtain();
         Parcel reply = Parcel.obtain();
-        request.writeInterfaceToken(IMEDIA_PLAYER);
-        request.writeInt(INVOKE_ID_SET_VIDEO_SCALE_MODE);
-        invoke(request, reply);
+        try {
+            request.writeInterfaceToken(IMEDIA_PLAYER);
+            request.writeInt(INVOKE_ID_SET_VIDEO_SCALE_MODE);
+            invoke(request, reply);
+        } finally {
+            request.recycle();
+            reply.recycle();
+        }
     }
 
     /**
@@ -1642,11 +1647,16 @@
     public TrackInfo[] getTrackInfo() throws IllegalStateException {
         Parcel request = Parcel.obtain();
         Parcel reply = Parcel.obtain();
-        request.writeInterfaceToken(IMEDIA_PLAYER);
-        request.writeInt(INVOKE_ID_GET_TRACK_INFO);
-        invoke(request, reply);
-        TrackInfo trackInfo[] = reply.createTypedArray(TrackInfo.CREATOR);
-        return trackInfo;
+        try {
+            request.writeInterfaceToken(IMEDIA_PLAYER);
+            request.writeInt(INVOKE_ID_GET_TRACK_INFO);
+            invoke(request, reply);
+            TrackInfo trackInfo[] = reply.createTypedArray(TrackInfo.CREATOR);
+            return trackInfo;
+        } finally {
+            request.recycle();
+            reply.recycle();
+        }
     }
 
     /* Do not change these values without updating their counterparts
@@ -1791,13 +1801,18 @@
 
         Parcel request = Parcel.obtain();
         Parcel reply = Parcel.obtain();
-        request.writeInterfaceToken(IMEDIA_PLAYER);
-        request.writeInt(INVOKE_ID_ADD_EXTERNAL_SOURCE_FD);
-        request.writeFileDescriptor(fd);
-        request.writeLong(offset);
-        request.writeLong(length);
-        request.writeString(mimeType);
-        invoke(request, reply);
+        try {
+            request.writeInterfaceToken(IMEDIA_PLAYER);
+            request.writeInt(INVOKE_ID_ADD_EXTERNAL_SOURCE_FD);
+            request.writeFileDescriptor(fd);
+            request.writeLong(offset);
+            request.writeLong(length);
+            request.writeString(mimeType);
+            invoke(request, reply);
+        } finally {
+            request.recycle();
+            reply.recycle();
+        }
     }
 
     /**
@@ -1854,10 +1869,15 @@
             throws IllegalStateException {
         Parcel request = Parcel.obtain();
         Parcel reply = Parcel.obtain();
-        request.writeInterfaceToken(IMEDIA_PLAYER);
-        request.writeInt(select? INVOKE_ID_SELECT_TRACK: INVOKE_ID_DESELECT_TRACK);
-        request.writeInt(index);
-        invoke(request, reply);
+        try {
+            request.writeInterfaceToken(IMEDIA_PLAYER);
+            request.writeInt(select? INVOKE_ID_SELECT_TRACK: INVOKE_ID_DESELECT_TRACK);
+            request.writeInt(index);
+            invoke(request, reply);
+        } finally {
+            request.recycle();
+            reply.recycle();
+        }
     }
 
 
diff --git a/media/jni/android_media_MediaCodec.cpp b/media/jni/android_media_MediaCodec.cpp
index acd81e1..e43e66e 100644
--- a/media/jni/android_media_MediaCodec.cpp
+++ b/media/jni/android_media_MediaCodec.cpp
@@ -212,6 +212,25 @@
     }
 
     jclass byteBufferClass = env->FindClass("java/nio/ByteBuffer");
+    CHECK(byteBufferClass != NULL);
+
+    jmethodID orderID = env->GetMethodID(
+            byteBufferClass,
+            "order",
+            "(Ljava/nio/ByteOrder;)Ljava/nio/ByteBuffer;");
+
+    CHECK(orderID != NULL);
+
+    jclass byteOrderClass = env->FindClass("java/nio/ByteOrder");
+    CHECK(byteOrderClass != NULL);
+
+    jmethodID nativeOrderID = env->GetStaticMethodID(
+            byteOrderClass, "nativeOrder", "()Ljava/nio/ByteOrder;");
+    CHECK(nativeOrderID != NULL);
+
+    jobject nativeByteOrderObj =
+        env->CallStaticObjectMethod(byteOrderClass, nativeOrderID);
+    CHECK(nativeByteOrderObj != NULL);
 
     *bufArray = (jobjectArray)env->NewObjectArray(
             buffers.size(), byteBufferClass, NULL);
@@ -224,6 +243,11 @@
                 buffer->base(),
                 buffer->capacity());
 
+        jobject me = env->CallObjectMethod(
+                byteBuffer, orderID, nativeByteOrderObj);
+        env->DeleteLocalRef(me);
+        me = NULL;
+
         env->SetObjectArrayElement(
                 *bufArray, i, byteBuffer);
 
@@ -231,6 +255,9 @@
         byteBuffer = NULL;
     }
 
+    env->DeleteLocalRef(nativeByteOrderObj);
+    nativeByteOrderObj = NULL;
+
     return OK;
 }
 
diff --git a/media/jni/android_media_MediaExtractor.cpp b/media/jni/android_media_MediaExtractor.cpp
index c93baf1..351ff04 100644
--- a/media/jni/android_media_MediaExtractor.cpp
+++ b/media/jni/android_media_MediaExtractor.cpp
@@ -313,7 +313,7 @@
     }
 
     if (mode < MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC
-            || mode > MediaSource::ReadOptions::SEEK_CLOSEST) {
+            || mode >= MediaSource::ReadOptions::SEEK_CLOSEST) {
         jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
         return;
     }
diff --git a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
index c709e40..17e5f4e 100644
--- a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
+++ b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
@@ -22,7 +22,10 @@
 
 import android.app.IntentService;
 import android.content.Intent;
+import android.content.pm.MacAuthenticatedInputStream;
+import android.content.pm.ContainerEncryptionParams;
 import android.content.pm.IPackageManager;
+import android.content.pm.LimitedLengthInputStream;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageInfoLite;
 import android.content.pm.PackageManager;
@@ -49,9 +52,21 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.security.DigestException;
+import java.security.GeneralSecurityException;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+
+import javax.crypto.Cipher;
+import javax.crypto.CipherInputStream;
+import javax.crypto.Mac;
+import javax.crypto.NoSuchPaddingException;
 
 import libcore.io.ErrnoException;
+import libcore.io.IoUtils;
 import libcore.io.Libcore;
+import libcore.io.Streams;
 import libcore.io.StructStatFs;
 
 /*
@@ -68,7 +83,7 @@
     private static final String LIB_DIR_NAME = "lib";
 
     private IMediaContainerService.Stub mBinder = new IMediaContainerService.Stub() {
-        /*
+        /**
          * Creates a new container and copies resource there.
          * @param paackageURI the uri of resource to be copied. Can be either
          * a content uri or a file uri
@@ -92,15 +107,19 @@
                     isExternal, isForwardLocked);
         }
 
-        /*
+        /**
          * Copy specified resource to output stream
+         *
          * @param packageURI the uri of resource to be copied. Should be a file
-         * uri
+         *            uri
+         * @param encryptionParams parameters describing the encryption used for
+         *            this file
          * @param outStream Remote file descriptor to be used for copying
-         * @return returns status code according to those in {@link
-         * PackageManager}
+         * @return returns status code according to those in
+         *         {@link PackageManager}
          */
-        public int copyResource(final Uri packageURI, ParcelFileDescriptor outStream) {
+        public int copyResource(final Uri packageURI, ContainerEncryptionParams encryptionParams,
+                ParcelFileDescriptor outStream) {
             if (packageURI == null || outStream == null) {
                 return PackageManager.INSTALL_FAILED_INVALID_URI;
             }
@@ -109,7 +128,7 @@
                     = new ParcelFileDescriptor.AutoCloseOutputStream(outStream);
 
             try {
-                copyFile(packageURI, autoOut);
+                copyFile(packageURI, autoOut, encryptionParams);
                 return PackageManager.INSTALL_SUCCEEDED;
             } catch (FileNotFoundException e) {
                 Slog.e(TAG, "Could not copy URI " + packageURI.toString() + " FNF: "
@@ -119,10 +138,14 @@
                 Slog.e(TAG, "Could not copy URI " + packageURI.toString() + " IO: "
                         + e.getMessage());
                 return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
+            } catch (DigestException e) {
+                Slog.e(TAG, "Could not copy URI " + packageURI.toString() + " Security: "
+                                + e.getMessage());
+                return PackageManager.INSTALL_FAILED_INVALID_APK;
             }
         }
 
-        /*
+        /**
          * Determine the recommended install location for package
          * specified by file uri location.
          * @param fileUri the uri of resource to be copied. Should be a
@@ -130,28 +153,24 @@
          * @return Returns PackageInfoLite object containing
          * the package info and recommended app location.
          */
-        public PackageInfoLite getMinimalPackageInfo(final Uri fileUri, int flags, long threshold) {
+        public PackageInfoLite getMinimalPackageInfo(final String packagePath, int flags,
+                long threshold) {
             PackageInfoLite ret = new PackageInfoLite();
-            if (fileUri == null) {
-                Slog.i(TAG, "Invalid package uri " + fileUri);
+
+            if (packagePath == null) {
+                Slog.i(TAG, "Invalid package file " + packagePath);
                 ret.recommendedInstallLocation = PackageHelper.RECOMMEND_FAILED_INVALID_APK;
                 return ret;
             }
-            String scheme = fileUri.getScheme();
-            if (scheme != null && !scheme.equals("file")) {
-                Slog.w(TAG, "Falling back to installing on internal storage only");
-                ret.recommendedInstallLocation = PackageHelper.RECOMMEND_INSTALL_INTERNAL;
-                return ret;
-            }
-            String archiveFilePath = fileUri.getPath();
+
             DisplayMetrics metrics = new DisplayMetrics();
             metrics.setToDefaults();
 
-            PackageParser.PackageLite pkg = PackageParser.parsePackageLite(archiveFilePath, 0);
+            PackageParser.PackageLite pkg = PackageParser.parsePackageLite(packagePath, 0);
             if (pkg == null) {
                 Slog.w(TAG, "Failed to parse package");
 
-                final File apkFile = new File(archiveFilePath);
+                final File apkFile = new File(packagePath);
                 if (!apkFile.exists()) {
                     ret.recommendedInstallLocation = PackageHelper.RECOMMEND_FAILED_INVALID_URI;
                 } else {
@@ -160,12 +179,13 @@
 
                 return ret;
             }
+
             ret.packageName = pkg.packageName;
             ret.installLocation = pkg.installLocation;
             ret.verifiers = pkg.verifiers;
 
             ret.recommendedInstallLocation = recommendAppInstallLocation(pkg.installLocation,
-                    archiveFilePath, flags, threshold);
+                    packagePath, flags, threshold);
 
             return ret;
         }
@@ -392,55 +412,195 @@
         }
     }
 
-    private static void copyToFile(File srcFile, OutputStream out)
-            throws FileNotFoundException, IOException {
-        InputStream inputStream = new BufferedInputStream(new FileInputStream(srcFile));
+    private void copyFile(Uri pPackageURI, OutputStream outStream,
+            ContainerEncryptionParams encryptionParams) throws FileNotFoundException, IOException,
+            DigestException {
+        String scheme = pPackageURI.getScheme();
+        InputStream inStream = null;
         try {
-            copyToFile(inputStream, out);
+            if (scheme == null || scheme.equals("file")) {
+                final InputStream is = new FileInputStream(new File(pPackageURI.getPath()));
+                inStream = new BufferedInputStream(is);
+            } else if (scheme.equals("content")) {
+                final ParcelFileDescriptor fd;
+                try {
+                    fd = getContentResolver().openFileDescriptor(pPackageURI, "r");
+                } catch (FileNotFoundException e) {
+                    Slog.e(TAG, "Couldn't open file descriptor from download service. "
+                            + "Failed with exception " + e);
+                    throw e;
+                }
+
+                if (fd == null) {
+                    Slog.e(TAG, "Provider returned no file descriptor for " +
+                            pPackageURI.toString());
+                    throw new FileNotFoundException("provider returned no file descriptor");
+                } else {
+                    if (localLOGV) {
+                        Slog.i(TAG, "Opened file descriptor from download service.");
+                    }
+                    inStream = new ParcelFileDescriptor.AutoCloseInputStream(fd);
+                }
+            } else {
+                Slog.e(TAG, "Package URI is not 'file:' or 'content:' - " + pPackageURI);
+                throw new FileNotFoundException("Package URI is not 'file:' or 'content:'");
+            }
+
+            /*
+             * If this resource is encrypted, get the decrypted stream version
+             * of it.
+             */
+            ApkContainer container = new ApkContainer(inStream, encryptionParams);
+
+            try {
+                /*
+                 * We copy the source package file to a temp file and then
+                 * rename it to the destination file in order to eliminate a
+                 * window where the package directory scanner notices the new
+                 * package file but it's not completely copied yet.
+                 */
+                copyToFile(container.getInputStream(), outStream);
+
+                if (!container.isAuthenticated()) {
+                    throw new DigestException();
+                }
+            } catch (GeneralSecurityException e) {
+                throw new DigestException("A problem occured copying the file.");
+            }
         } finally {
-            try { inputStream.close(); } catch (IOException e) {}
+            IoUtils.closeQuietly(inStream);
         }
     }
 
-    private void copyFile(Uri pPackageURI, OutputStream outStream) throws FileNotFoundException,
-            IOException {
-        String scheme = pPackageURI.getScheme();
-        if (scheme == null || scheme.equals("file")) {
-            final File srcPackageFile = new File(pPackageURI.getPath());
-            // We copy the source package file to a temp file and then rename it to the
-            // destination file in order to eliminate a window where the package directory
-            // scanner notices the new package file but it's not completely copied yet.
-            copyToFile(srcPackageFile, outStream);
-        } else if (scheme.equals("content")) {
-            ParcelFileDescriptor fd = null;
-            try {
-                fd = getContentResolver().openFileDescriptor(pPackageURI, "r");
-            } catch (FileNotFoundException e) {
-                Slog.e(TAG, "Couldn't open file descriptor from download service. "
-                        + "Failed with exception " + e);
-                throw e;
-            }
+    private static class ApkContainer {
+        private final InputStream mInStream;
 
-            if (fd == null) {
-                Slog.e(TAG, "Provider returned no file descriptor for " + pPackageURI.toString());
-                throw new FileNotFoundException("provider returned no file descriptor");
+        private MacAuthenticatedInputStream mAuthenticatedStream;
+
+        private byte[] mTag;
+
+        public ApkContainer(InputStream inStream, ContainerEncryptionParams encryptionParams)
+                throws IOException {
+            if (encryptionParams == null) {
+                mInStream = inStream;
             } else {
-                if (localLOGV) {
-                    Slog.i(TAG, "Opened file descriptor from download service.");
-                }
-                ParcelFileDescriptor.AutoCloseInputStream dlStream
-                        = new ParcelFileDescriptor.AutoCloseInputStream(fd);
-
-                // We copy the source package file to a temp file and then rename it to the
-                // destination file in order to eliminate a window where the package directory
-                // scanner notices the new package file but it's not completely
-                // copied
-                copyToFile(dlStream, outStream);
+                mInStream = getDecryptedStream(inStream, encryptionParams);
+                mTag = encryptionParams.getMacTag();
             }
-        } else {
-            Slog.e(TAG, "Package URI is not 'file:' or 'content:' - " + pPackageURI);
-            throw new FileNotFoundException("Package URI is not 'file:' or 'content:'");
         }
+
+        public boolean isAuthenticated() {
+            if (mAuthenticatedStream == null) {
+                return true;
+            }
+
+            return mAuthenticatedStream.isTagEqual(mTag);
+        }
+
+        private Mac getMacInstance(ContainerEncryptionParams encryptionParams) throws IOException {
+            final Mac m;
+            try {
+                final String macAlgo = encryptionParams.getMacAlgorithm();
+
+                if (macAlgo != null) {
+                    m = Mac.getInstance(macAlgo);
+                    m.init(encryptionParams.getMacKey(), encryptionParams.getMacSpec());
+                } else {
+                    m = null;
+                }
+
+                return m;
+            } catch (NoSuchAlgorithmException e) {
+                throw new IOException(e);
+            } catch (InvalidKeyException e) {
+                throw new IOException(e);
+            } catch (InvalidAlgorithmParameterException e) {
+                throw new IOException(e);
+            }
+        }
+
+        public InputStream getInputStream() {
+            return mInStream;
+        }
+
+        private InputStream getDecryptedStream(InputStream inStream,
+                ContainerEncryptionParams encryptionParams) throws IOException {
+            final Cipher c;
+            try {
+                c = Cipher.getInstance(encryptionParams.getEncryptionAlgorithm());
+                c.init(Cipher.DECRYPT_MODE, encryptionParams.getEncryptionKey(),
+                        encryptionParams.getEncryptionSpec());
+            } catch (NoSuchAlgorithmException e) {
+                throw new IOException(e);
+            } catch (NoSuchPaddingException e) {
+                throw new IOException(e);
+            } catch (InvalidKeyException e) {
+                throw new IOException(e);
+            } catch (InvalidAlgorithmParameterException e) {
+                throw new IOException(e);
+            }
+
+            final int encStart = encryptionParams.getEncryptedDataStart();
+            final int end = encryptionParams.getDataEnd();
+            if (end < encStart) {
+                throw new IOException("end <= encStart");
+            }
+
+            final Mac mac = getMacInstance(encryptionParams);
+            if (mac != null) {
+                final int macStart = encryptionParams.getAuthenticatedDataStart();
+
+                final int furtherOffset;
+                if (macStart >= 0 && encStart >= 0 && macStart < encStart) {
+                    /*
+                     * If there is authenticated data at the beginning, read
+                     * that into our MAC first.
+                     */
+                    final int authenticatedLength = encStart - macStart;
+                    final byte[] authenticatedData = new byte[authenticatedLength];
+
+                    Streams.readFully(inStream, authenticatedData, macStart, authenticatedLength);
+                    mac.update(authenticatedData, 0, authenticatedLength);
+
+                    furtherOffset = 0;
+                } else {
+                    /*
+                     * No authenticated data at the beginning. Just skip the
+                     * required number of bytes to the beginning of the stream.
+                     */
+                    if (encStart > 0) {
+                        furtherOffset = encStart;
+                    } else {
+                        furtherOffset = 0;
+                    }
+                }
+
+                /*
+                 * If there is data at the end of the stream we want to ignore,
+                 * wrap this in a LimitedLengthInputStream.
+                 */
+                if (furtherOffset >= 0 && end > furtherOffset) {
+                    inStream = new LimitedLengthInputStream(inStream, furtherOffset, end - encStart);
+                } else if (furtherOffset > 0) {
+                    inStream.skip(furtherOffset);
+                }
+
+                mAuthenticatedStream = new MacAuthenticatedInputStream(inStream, mac);
+
+                inStream = mAuthenticatedStream;
+            } else {
+                if (encStart >= 0) {
+                    if (end > encStart) {
+                        inStream = new LimitedLengthInputStream(inStream, encStart, end - encStart);
+                    } else {
+                        inStream.skip(encStart);
+                    }
+                }
+            }
+
+            return new CipherInputStream(inStream, c);
+        }
+
     }
 
     private static final int PREFER_INTERNAL = 1;
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
index abf713b..b0939de 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
@@ -63,7 +63,7 @@
     // database gets upgraded properly. At a minimum, please confirm that 'upgradeVersion'
     // is properly propagated through your change.  Not doing so will result in a loss of user
     // settings.
-    private static final int DATABASE_VERSION = 76;
+    private static final int DATABASE_VERSION = 78;
 
     private Context mContext;
 
@@ -657,7 +657,7 @@
 
             upgradeVersion = 53;
         }
-        
+
         if (upgradeVersion == 53) {
             /*
              * New settings for set install location UI no longer initiated here.
@@ -1031,6 +1031,29 @@
             upgradeVersion = 76;
         }
 
+        /************* The following are Jelly Bean changes ************/
+
+        if (upgradeVersion == 76) {
+            // Removed VIBRATE_IN_SILENT setting
+            db.beginTransaction();
+            try {
+                db.execSQL("DELETE FROM system WHERE name='"
+                                + Settings.System.VIBRATE_IN_SILENT + "'");
+                db.setTransactionSuccessful();
+            } finally {
+                db.endTransaction();
+            }
+
+            upgradeVersion = 77;
+        }
+
+        if (upgradeVersion == 77) {
+            // Introduce "vibrate when ringing" setting
+            loadVibrateWhenRingingSetting(db);
+
+            upgradeVersion = 78;
+        }
+
         // *** Remember to update DATABASE_VERSION above!
 
         if (upgradeVersion != currentVersion) {
@@ -1124,7 +1147,7 @@
             try {
                 stmt = db.compileStatement("INSERT OR REPLACE INTO system(name,value)"
                         + " VALUES(?,?);");
-    
+
                 // Set the timeout to 30 minutes in milliseconds
                 loadSetting(stmt, Settings.System.SCREEN_OFF_TIMEOUT,
                         Integer.toString(30 * 60 * 1000));
@@ -1286,7 +1309,7 @@
         try {
             stmt = db.compileStatement("INSERT OR IGNORE INTO system(name,value)"
                     + " VALUES(?,?);");
-    
+
             loadSetting(stmt, Settings.System.VOLUME_MUSIC,
                     AudioManager.DEFAULT_STREAM_VOLUME[AudioManager.STREAM_MUSIC]);
             loadSetting(stmt, Settings.System.VOLUME_RING,
@@ -1307,12 +1330,10 @@
                     stmt,
                     Settings.System.VOLUME_BLUETOOTH_SCO,
                     AudioManager.DEFAULT_STREAM_VOLUME[AudioManager.STREAM_BLUETOOTH_SCO]);
-    
+
             loadSetting(stmt, Settings.System.MODE_RINGER,
                     AudioManager.RINGER_MODE_NORMAL);
-    
-            loadVibrateSetting(db, false);
-    
+
             // By default:
             // - ringtones, notification, system and music streams are affected by ringer mode
             // on non voice capable devices (tablets)
@@ -1337,6 +1358,8 @@
         } finally {
             if (stmt != null) stmt.close();
         }
+
+        loadVibrateWhenRingingSetting(db);
     }
 
     private void loadVibrateSetting(SQLiteDatabase db, boolean deleteOld) {
@@ -1348,7 +1371,7 @@
         try {
             stmt = db.compileStatement("INSERT OR IGNORE INTO system(name,value)"
                     + " VALUES(?,?);");
-    
+
             // Vibrate on by default for ringer, on for notification
             int vibrate = 0;
             vibrate = AudioService.getValueForVibrateSetting(vibrate,
@@ -1362,6 +1385,24 @@
         }
     }
 
+    private void loadVibrateWhenRingingSetting(SQLiteDatabase db) {
+        // The default should be off. VIBRATE_SETTING_ONLY_SILENT should also be ignored here.
+        // Phone app should separately check whether AudioManager#getRingerMode() returns
+        // RINGER_MODE_VIBRATE, with which the device should vibrate anyway.
+        int vibrateSetting = getIntValueFromSystem(db, Settings.System.VIBRATE_ON,
+                AudioManager.VIBRATE_SETTING_OFF);
+        boolean vibrateWhenRinging = ((vibrateSetting & 3) == AudioManager.VIBRATE_SETTING_ON);
+
+        SQLiteStatement stmt = null;
+        try {
+            stmt = db.compileStatement("INSERT OR IGNORE INTO system(name,value)"
+                    + " VALUES(?,?);");
+            loadSetting(stmt, Settings.System.VIBRATE_WHEN_RINGING, vibrateWhenRinging ? 1 : 0);
+        } finally {
+            if (stmt != null) stmt.close();
+        }
+    }
+
     private void loadSettings(SQLiteDatabase db) {
         loadSystemSettings(db);
         loadSecureSettings(db);
@@ -1372,7 +1413,7 @@
         try {
             stmt = db.compileStatement("INSERT OR IGNORE INTO system(name,value)"
                     + " VALUES(?,?);");
-    
+
             loadBooleanSetting(stmt, Settings.System.DIM_SCREEN,
                     R.bool.def_dim_screen);
             loadSetting(stmt, Settings.System.STAY_ON_WHILE_PLUGGED_IN,
@@ -1381,31 +1422,31 @@
                      ? 1 : 0);
             loadIntegerSetting(stmt, Settings.System.SCREEN_OFF_TIMEOUT,
                     R.integer.def_screen_off_timeout);
-    
+
             // Set default cdma emergency tone
             loadSetting(stmt, Settings.System.EMERGENCY_TONE, 0);
-    
+
             // Set default cdma call auto retry
             loadSetting(stmt, Settings.System.CALL_AUTO_RETRY, 0);
-    
+
             // Set default cdma DTMF type
             loadSetting(stmt, Settings.System.DTMF_TONE_TYPE_WHEN_DIALING, 0);
-    
+
             // Set default hearing aid
             loadSetting(stmt, Settings.System.HEARING_AID, 0);
-    
+
             // Set default tty mode
             loadSetting(stmt, Settings.System.TTY_MODE, 0);
-    
+
             loadBooleanSetting(stmt, Settings.System.AIRPLANE_MODE_ON,
                     R.bool.def_airplane_mode_on);
-    
+
             loadStringSetting(stmt, Settings.System.AIRPLANE_MODE_RADIOS,
                     R.string.def_airplane_mode_radios);
-    
+
             loadStringSetting(stmt, Settings.System.AIRPLANE_MODE_TOGGLEABLE_RADIOS,
                     R.string.airplane_mode_toggleable_radios);
-    
+
             loadBooleanSetting(stmt, Settings.System.AUTO_TIME,
                     R.bool.def_auto_time); // Sync time to NITZ
 
@@ -1414,17 +1455,17 @@
 
             loadIntegerSetting(stmt, Settings.System.SCREEN_BRIGHTNESS,
                     R.integer.def_screen_brightness);
-    
+
             loadBooleanSetting(stmt, Settings.System.SCREEN_BRIGHTNESS_MODE,
                     R.bool.def_screen_brightness_automatic_mode);
-    
+
             loadDefaultAnimationSettings(stmt);
-    
+
             loadBooleanSetting(stmt, Settings.System.ACCELEROMETER_ROTATION,
                     R.bool.def_accelerometer_rotation);
-    
+
             loadDefaultHapticSettings(stmt);
-    
+
             loadBooleanSetting(stmt, Settings.System.NOTIFICATION_LIGHT_PULSE,
                     R.bool.def_notification_pulse);
             loadSetting(stmt, Settings.Secure.SET_INSTALL_LOCATION, 0);
@@ -1433,9 +1474,6 @@
 
             loadUISoundEffectsSettings(stmt);
 
-            loadBooleanSetting(stmt, Settings.System.VIBRATE_IN_SILENT,
-                    R.bool.def_vibrate_in_silent);
-
             loadIntegerSetting(stmt, Settings.System.POINTER_SPEED,
                     R.integer.def_pointer_speed);
 
@@ -1492,41 +1530,41 @@
         try {
             stmt = db.compileStatement("INSERT OR IGNORE INTO secure(name,value)"
                     + " VALUES(?,?);");
-    
+
             loadBooleanSetting(stmt, Settings.Secure.BLUETOOTH_ON,
                     R.bool.def_bluetooth_on);
-    
+
             // Data roaming default, based on build
             loadSetting(stmt, Settings.Secure.DATA_ROAMING,
                     "true".equalsIgnoreCase(
                             SystemProperties.get("ro.com.android.dataroaming",
                                     "false")) ? 1 : 0);
-    
+
             loadBooleanSetting(stmt, Settings.Secure.INSTALL_NON_MARKET_APPS,
                     R.bool.def_install_non_market_apps);
-    
+
             loadStringSetting(stmt, Settings.Secure.LOCATION_PROVIDERS_ALLOWED,
                     R.string.def_location_providers_allowed);
-    
+
             loadBooleanSetting(stmt, Settings.Secure.ASSISTED_GPS_ENABLED,
                     R.bool.assisted_gps_enabled);
-    
+
             loadIntegerSetting(stmt, Settings.Secure.NETWORK_PREFERENCE,
                     R.integer.def_network_preference);
-    
+
             loadBooleanSetting(stmt, Settings.Secure.USB_MASS_STORAGE_ENABLED,
                     R.bool.def_usb_mass_storage_enabled);
-    
+
             loadBooleanSetting(stmt, Settings.Secure.WIFI_ON,
                     R.bool.def_wifi_on);
             loadBooleanSetting(stmt, Settings.Secure.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON,
                     R.bool.def_networks_available_notification_on);
-    
+
             String wifiWatchList = SystemProperties.get("ro.com.android.wifi-watchlist");
             if (!TextUtils.isEmpty(wifiWatchList)) {
                 loadSetting(stmt, Settings.Secure.WIFI_WATCHDOG_WATCH_LIST, wifiWatchList);
             }
-    
+
             // Set the preferred network mode to 0 = Global, CDMA default
             int type;
             if (BaseCommands.getLteOnCdmaModeStatic() == Phone.LTE_ON_CDMA_TRUE) {
@@ -1536,30 +1574,30 @@
                         RILConstants.PREFERRED_NETWORK_MODE);
             }
             loadSetting(stmt, Settings.Secure.PREFERRED_NETWORK_MODE, type);
-    
+
             // Enable or disable Cell Broadcast SMS
             loadSetting(stmt, Settings.Secure.CDMA_CELL_BROADCAST_SMS,
                     RILConstants.CDMA_CELL_BROADCAST_SMS_DISABLED);
-    
+
             // Don't do this.  The SystemServer will initialize ADB_ENABLED from a
             // persistent system property instead.
             //loadSetting(stmt, Settings.Secure.ADB_ENABLED, 0);
-    
+
             // Allow mock locations default, based on build
             loadSetting(stmt, Settings.Secure.ALLOW_MOCK_LOCATION,
                     "1".equals(SystemProperties.get("ro.allow.mock.location")) ? 1 : 0);
-    
+
             loadSecure35Settings(stmt);
-    
+
             loadBooleanSetting(stmt, Settings.Secure.MOUNT_PLAY_NOTIFICATION_SND,
                     R.bool.def_mount_play_notification_snd);
-    
+
             loadBooleanSetting(stmt, Settings.Secure.MOUNT_UMS_AUTOSTART,
                     R.bool.def_mount_ums_autostart);
-    
+
             loadBooleanSetting(stmt, Settings.Secure.MOUNT_UMS_PROMPT,
                     R.bool.def_mount_ums_prompt);
-    
+
             loadBooleanSetting(stmt, Settings.Secure.MOUNT_UMS_NOTIFY_ENABLED,
                     R.bool.def_mount_ums_notify_enabled);
 
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
index 3e7d86a..18e7faa 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
@@ -43,9 +43,6 @@
     private IContentService mContentService;
     private IPowerManager mPowerManager;
 
-    private boolean mSilent;
-    private boolean mVibrate;
-
     public SettingsHelper(Context context) {
         mContext = context;
         mAudioManager = (AudioManager) context
@@ -119,18 +116,6 @@
         }
     }
 
-    private void setRingerMode() {
-        if (mSilent) {
-            mAudioManager.setRingerMode(mVibrate ? AudioManager.RINGER_MODE_VIBRATE :
-                AudioManager.RINGER_MODE_SILENT);
-        } else {
-            mAudioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
-            mAudioManager.setVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER,
-                    mVibrate ? AudioManager.VIBRATE_SETTING_ON
-                            : AudioManager.VIBRATE_SETTING_OFF);
-        }
-    }
-
     byte[] getLocaleData() {
         Configuration conf = mContext.getResources().getConfiguration();
         final Locale loc = conf.locale;
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_notify_clear_normal.png b/packages/SystemUI/res/drawable-hdpi/ic_notify_clear_normal.png
index babddb1..a54761f 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_notify_clear_normal.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_notify_clear_normal.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_notify_clear_pressed.png b/packages/SystemUI/res/drawable-hdpi/ic_notify_clear_pressed.png
index 56cd6f9..f3f336c 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_notify_clear_pressed.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_notify_clear_pressed.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_notify_quicksettings_normal.png b/packages/SystemUI/res/drawable-hdpi/ic_notify_quicksettings_normal.png
index 23ce001..3ed7418 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_notify_quicksettings_normal.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_notify_quicksettings_normal.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_notify_quicksettings_pressed.png b/packages/SystemUI/res/drawable-hdpi/ic_notify_quicksettings_pressed.png
index d0754a39..5e20eea 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_notify_quicksettings_pressed.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_notify_quicksettings_pressed.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_notify_rotation_off_normal.png b/packages/SystemUI/res/drawable-hdpi/ic_notify_rotation_off_normal.png
new file mode 100644
index 0000000..4ca1ab8
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_notify_rotation_off_normal.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_notify_rotation_off_pressed.png b/packages/SystemUI/res/drawable-hdpi/ic_notify_rotation_off_pressed.png
new file mode 100644
index 0000000..85a4cd2
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_notify_rotation_off_pressed.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_notify_rotation_on_normal.png b/packages/SystemUI/res/drawable-hdpi/ic_notify_rotation_on_normal.png
new file mode 100644
index 0000000..d0cb0870
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_notify_rotation_on_normal.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_notify_rotation_on_pressed.png b/packages/SystemUI/res/drawable-hdpi/ic_notify_rotation_on_pressed.png
new file mode 100644
index 0000000..c1c9e16
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_notify_rotation_on_pressed.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/notification_panel_bg.9.png b/packages/SystemUI/res/drawable-hdpi/notification_panel_bg.9.png
new file mode 100644
index 0000000..8a0a30f
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/notification_panel_bg.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/status_bar_close_off.9.png b/packages/SystemUI/res/drawable-hdpi/status_bar_close_off.9.png
new file mode 100644
index 0000000..bc6462b
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/status_bar_close_off.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/status_bar_close_on.9.png b/packages/SystemUI/res/drawable-hdpi/status_bar_close_on.9.png
index 69f3543..f4e28ae 100644
--- a/packages/SystemUI/res/drawable-hdpi/status_bar_close_on.9.png
+++ b/packages/SystemUI/res/drawable-hdpi/status_bar_close_on.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_notify_clear_normal.png b/packages/SystemUI/res/drawable-mdpi/ic_notify_clear_normal.png
index bf1bad5..b44b527 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_notify_clear_normal.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_notify_clear_normal.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_notify_clear_pressed.png b/packages/SystemUI/res/drawable-mdpi/ic_notify_clear_pressed.png
index 320d92d..94c8165 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_notify_clear_pressed.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_notify_clear_pressed.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_notify_quicksettings_normal.png b/packages/SystemUI/res/drawable-mdpi/ic_notify_quicksettings_normal.png
index b58e4dc..44cfc5b 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_notify_quicksettings_normal.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_notify_quicksettings_normal.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_notify_quicksettings_pressed.png b/packages/SystemUI/res/drawable-mdpi/ic_notify_quicksettings_pressed.png
index 604eb75..0c3fdcd 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_notify_quicksettings_pressed.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_notify_quicksettings_pressed.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_notify_rotation_off_normal.png b/packages/SystemUI/res/drawable-mdpi/ic_notify_rotation_off_normal.png
new file mode 100644
index 0000000..77da014
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_notify_rotation_off_normal.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_notify_rotation_off_pressed.png b/packages/SystemUI/res/drawable-mdpi/ic_notify_rotation_off_pressed.png
new file mode 100644
index 0000000..f132d5c
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_notify_rotation_off_pressed.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_notify_rotation_on_normal.png b/packages/SystemUI/res/drawable-mdpi/ic_notify_rotation_on_normal.png
new file mode 100644
index 0000000..1637209
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_notify_rotation_on_normal.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_notify_rotation_on_pressed.png b/packages/SystemUI/res/drawable-mdpi/ic_notify_rotation_on_pressed.png
new file mode 100644
index 0000000..4d8fbde
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_notify_rotation_on_pressed.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/notification_panel_bg.9.png b/packages/SystemUI/res/drawable-mdpi/notification_panel_bg.9.png
new file mode 100644
index 0000000..25f15e6
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/notification_panel_bg.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/status_bar_close_off.9.png b/packages/SystemUI/res/drawable-mdpi/status_bar_close_off.9.png
new file mode 100644
index 0000000..4f5bba5
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/status_bar_close_off.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/status_bar_close_on.9.png b/packages/SystemUI/res/drawable-mdpi/status_bar_close_on.9.png
index fb30982..ef7afb8 100644
--- a/packages/SystemUI/res/drawable-mdpi/status_bar_close_on.9.png
+++ b/packages/SystemUI/res/drawable-mdpi/status_bar_close_on.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/notification_panel_bg.9.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/notification_panel_bg.9.png
new file mode 100644
index 0000000..2ff93d3
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/notification_panel_bg.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/notification_panel_bg.9.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/notification_panel_bg.9.png
new file mode 100644
index 0000000..430f913
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/notification_panel_bg.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/notification_panel_bg.9.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/notification_panel_bg.9.png
new file mode 100644
index 0000000..807241a
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/notification_panel_bg.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/notification_panel_bg.9.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/notification_panel_bg.9.png
new file mode 100644
index 0000000..2ff93d3
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw720dp-hdpi/notification_panel_bg.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-mdpi/notification_panel_bg.9.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/notification_panel_bg.9.png
new file mode 100644
index 0000000..430f913
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw720dp-mdpi/notification_panel_bg.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/notification_panel_bg.9.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/notification_panel_bg.9.png
new file mode 100644
index 0000000..807241a
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw720dp-xhdpi/notification_panel_bg.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_notify_clear_normal.png b/packages/SystemUI/res/drawable-xhdpi/ic_notify_clear_normal.png
index cf9bd8e..870beb4 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_notify_clear_normal.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_notify_clear_normal.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_notify_clear_pressed.png b/packages/SystemUI/res/drawable-xhdpi/ic_notify_clear_pressed.png
index 8eee4d9..94a4646 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_notify_clear_pressed.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_notify_clear_pressed.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_notify_quicksettings_normal.png b/packages/SystemUI/res/drawable-xhdpi/ic_notify_quicksettings_normal.png
index 5e67545..80fdb79 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_notify_quicksettings_normal.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_notify_quicksettings_normal.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_notify_quicksettings_pressed.png b/packages/SystemUI/res/drawable-xhdpi/ic_notify_quicksettings_pressed.png
index e56aeda..ac7c1a7 100644
--- a/packages/SystemUI/res/drawable-xhdpi/ic_notify_quicksettings_pressed.png
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_notify_quicksettings_pressed.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_notify_rotation_off_normal.png b/packages/SystemUI/res/drawable-xhdpi/ic_notify_rotation_off_normal.png
new file mode 100644
index 0000000..cebd6d8
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_notify_rotation_off_normal.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_notify_rotation_off_pressed.png b/packages/SystemUI/res/drawable-xhdpi/ic_notify_rotation_off_pressed.png
new file mode 100644
index 0000000..ef4d9a1
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_notify_rotation_off_pressed.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_notify_rotation_on_normal.png b/packages/SystemUI/res/drawable-xhdpi/ic_notify_rotation_on_normal.png
new file mode 100644
index 0000000..01146aa
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_notify_rotation_on_normal.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_notify_rotation_on_pressed.png b/packages/SystemUI/res/drawable-xhdpi/ic_notify_rotation_on_pressed.png
new file mode 100644
index 0000000..e8f01c5
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_notify_rotation_on_pressed.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/notification_panel_bg.9.png b/packages/SystemUI/res/drawable-xhdpi/notification_panel_bg.9.png
new file mode 100644
index 0000000..60e7418
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/notification_panel_bg.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/status_bar_close_off.9.png b/packages/SystemUI/res/drawable-xhdpi/status_bar_close_off.9.png
new file mode 100644
index 0000000..e243e50
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/status_bar_close_off.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/status_bar_close_on.9.png b/packages/SystemUI/res/drawable-xhdpi/status_bar_close_on.9.png
index fe2c642..cdad949 100644
--- a/packages/SystemUI/res/drawable-xhdpi/status_bar_close_on.9.png
+++ b/packages/SystemUI/res/drawable-xhdpi/status_bar_close_on.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable/ic_notify_quicksettings.xml b/packages/SystemUI/res/drawable/ic_notify_quicksettings.xml
index b37dc39..d8ea524 100644
--- a/packages/SystemUI/res/drawable/ic_notify_quicksettings.xml
+++ b/packages/SystemUI/res/drawable/ic_notify_quicksettings.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 The Android Open Source Project
+<!-- Copyright (C) 2012 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -16,6 +16,8 @@
 
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
     <item android:state_pressed="true"
-        android:drawable="@drawable/ic_notify_quicksettings_pressed" />
-    <item android:drawable="@drawable/ic_notify_quicksettings_normal" />
+         android:drawable="@drawable/ic_notify_quicksettings_pressed" />
+    <item
+         android:drawable="@drawable/ic_notify_quicksettings_normal" />
 </selector>
+
diff --git a/packages/SystemUI/res/drawable/ic_notify_rotation.xml b/packages/SystemUI/res/drawable/ic_notify_rotation.xml
new file mode 100644
index 0000000..11bc22c
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_notify_rotation.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:constantSize="true">
+    <item android:state_checked="true" android:state_pressed="true">
+        <bitmap android:src="@drawable/ic_notify_rotation_on_pressed"
+                android:gravity="center" />
+    </item>
+    <item android:state_checked="true">
+        <bitmap android:src="@drawable/ic_notify_rotation_on_normal"
+                android:gravity="center" />
+    </item>
+    <item android:state_pressed="true">
+        <bitmap android:src="@drawable/ic_notify_rotation_off_pressed"
+                android:gravity="center" />
+    </item>
+    <item>
+        <bitmap android:src="@drawable/ic_notify_rotation_off_normal"
+                android:gravity="center" />
+    </item>
+</selector>
+
diff --git a/tools/localize/testdata/merge_xx_old.xml b/packages/SystemUI/res/drawable/status_bar_close.xml
similarity index 65%
copy from tools/localize/testdata/merge_xx_old.xml
copy to packages/SystemUI/res/drawable/status_bar_close.xml
index 9d3a7d8..2efc3c3a 100644
--- a/tools/localize/testdata/merge_xx_old.xml
+++ b/packages/SystemUI/res/drawable/status_bar_close.xml
@@ -1,12 +1,12 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2007 The Android Open Source Project
+<!-- Copyright (C) 2012 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -14,8 +14,10 @@
      limitations under the License.
 -->
 
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="changed_in_xx">aaa</string>
-    <string name="previously_translated">CCC</string>
-</resources>
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_pressed="true"
+         android:drawable="@drawable/status_bar_close_on" />
+    <item
+         android:drawable="@drawable/status_bar_close_off" />
+</selector>
 
diff --git a/packages/SystemUI/res/layout/status_bar_expanded.xml b/packages/SystemUI/res/layout/status_bar_expanded.xml
index 1de4ab8..f69aac8 100644
--- a/packages/SystemUI/res/layout/status_bar_expanded.xml
+++ b/packages/SystemUI/res/layout/status_bar_expanded.xml
@@ -25,70 +25,67 @@
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:orientation="vertical"
-    android:background="@drawable/notification_tracking_bg"
-    android:paddingTop="@*android:dimen/status_bar_height"
+    android:background="@drawable/notification_panel_bg"
+    android:paddingTop="@dimen/notification_panel_padding_top"
     android:layout_marginLeft="@dimen/notification_panel_margin_left"
     >
 
-    <RelativeLayout
+    <LinearLayout
         android:layout_width="match_parent"
-        android:layout_height="52dp"
-        android:paddingTop="3dp"
-        android:paddingBottom="5dp"
-        android:paddingRight="3dp"
+        android:layout_height="wrap_content"
+        android:paddingTop="@dimen/notification_panel_header_padding_top"
         android:background="@drawable/notification_header_bg"
+        android:orientation="horizontal"
+        android:gravity="center_vertical"
+        android:baselineAligned="false"
         >
-        <com.android.systemui.statusbar.policy.DateView android:id="@+id/date"
-            android:textAppearance="@style/TextAppearance.StatusBar.Date"
+        <com.android.systemui.statusbar.policy.Clock
+            android:id="@+id/clock"
             android:layout_width="wrap_content"
-            android:layout_height="match_parent"
-            android:layout_alignParentLeft="true"
-            android:singleLine="true"
-            android:gravity="center_vertical|left"
-            android:paddingLeft="16dp"
-            />
-        <!--
-        <com.android.systemui.statusbar.phone.CarrierLabel
-            android:layout_width="0dp"
             android:layout_height="wrap_content"
-            android:layout_weight="1"
-            android:layout_marginTop="1dp"
-            android:layout_marginLeft="5dp"
-            android:layout_gravity="center_vertical"
-            android:paddingBottom="1dp"
-            android:paddingLeft="4dp"
-            android:textAppearance="?android:attr/textAppearanceLarge"
-            android:textColor="?android:attr/textColorSecondary"
+            android:layout_marginLeft="8dp"
+            android:singleLine="true"
+            android:textAppearance="@style/TextAppearance.StatusBar.Expanded.Clock"
             />
-        -->
+
+        <com.android.systemui.statusbar.policy.DateView android:id="@+id/date"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginLeft="8dp"
+            android:layout_marginRight="8dp"
+            android:textAppearance="@style/TextAppearance.StatusBar.Expanded.Date"
+            />
+
+        <com.android.systemui.statusbar.RotationToggle android:id="@+id/rotation_lock_button"
+            android:layout_width="32dp"
+            android:layout_height="32dp"
+            android:layout_margin="8dp"
+            android:button="@drawable/ic_notify_rotation"
+            android:contentDescription="@string/accessibility_rotation_lock_off"
+            />
 
         <ImageView android:id="@+id/settings_button"
-            android:layout_width="wrap_content"
-            android:layout_height="match_parent"
-            android:layout_toRightOf="@id/date"
-            android:paddingLeft="8dp"
-            android:paddingRight="8dp"
+            android:layout_width="48dp"
+            android:layout_height="48dp"
+            android:scaleType="center"
             android:src="@drawable/ic_notify_quicksettings"
             android:contentDescription="@string/accessibility_settings_button"
             />
 
+        <Space
+            android:layout_width="0dp"
+            android:layout_height="0dp"
+            android:layout_weight="1"
+            />
+
         <ImageView android:id="@+id/clear_all_button"
-            android:layout_width="wrap_content"
-            android:layout_height="match_parent"
-            android:layout_alignParentRight="true"
-            android:paddingLeft="8dp"
-            android:paddingRight="8dp"
+            android:layout_width="48dp"
+            android:layout_height="48dp"
+            android:scaleType="center"
             android:src="@drawable/ic_notify_clear"
             android:contentDescription="@string/accessibility_clear_all"
             />            
-    </RelativeLayout>
-
-    <View
-        android:layout_width="match_parent"
-        android:layout_height="2dp"
-        android:layout_marginTop="52dp"
-        android:background="@drawable/status_bar_hr"
-        />
+    </LinearLayout>
 
     <ScrollView
         android:id="@+id/scroll"
@@ -96,8 +93,8 @@
         android:layout_height="match_parent"
         android:fadingEdge="none"
         android:overScrollMode="ifContentScrolls"
-		android:layout_marginTop="54dp"
-		android:layout_marginBottom="34dp"
+        android:layout_marginTop="@dimen/notification_panel_header_height"
+        android:layout_marginBottom="@dimen/close_handle_underlap"
         >
         <com.android.systemui.statusbar.policy.NotificationRowLayout
             android:id="@+id/latestItems"
@@ -107,14 +104,6 @@
             />
     </ScrollView>
 
-    <ImageView
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:src="@drawable/title_bar_shadow"
-		android:layout_marginTop="54dp"
-        android:scaleType="fitXY"
-    />
-
     <com.android.systemui.statusbar.phone.CloseDragHandle android:id="@+id/close"
         android:layout_width="match_parent"
         android:layout_height="@dimen/close_handle_height"
@@ -123,10 +112,10 @@
         >
         <ImageView
             android:layout_width="match_parent"
-            android:layout_height="34dp"
+            android:layout_height="@dimen/close_handle_height"
             android:layout_gravity="bottom"
             android:scaleType="fitXY"
-            android:src="@drawable/status_bar_close_on"
+            android:src="@drawable/status_bar_close"
             />
 
     </com.android.systemui.statusbar.phone.CloseDragHandle>
diff --git a/packages/SystemUI/res/layout/status_bar_tracking.xml b/packages/SystemUI/res/layout/status_bar_tracking.xml
deleted file mode 100644
index c1b0066..0000000
--- a/packages/SystemUI/res/layout/status_bar_tracking.xml
+++ /dev/null
@@ -1,60 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-    Copyright (C) 2008 The Android Open Source Project
-
-    Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-
-<com.android.systemui.statusbar.phone.TrackingView
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:orientation="vertical"
-    android:visibility="gone"
-    android:focusable="true"
-    android:descendantFocusability="afterDescendants"
-    android:paddingBottom="0px"
-    android:paddingLeft="0px"
-    android:paddingRight="0px"
-    >
-
-    <FrameLayout
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:layout_weight="1"
-        android:background="@drawable/notification_tracking_bg"
-        >
-        <com.android.systemui.statusbar.phone.CarrierLabel
-            android:textAppearance="@style/TextAppearance.StatusBar.Clock"
-            android:layout_height="wrap_content"
-            android:layout_width="match_parent"
-            android:layout_gravity="bottom"
-            android:gravity="center"
-            android:paddingBottom="20dp"
-            />
-    </FrameLayout>
-
-    <com.android.systemui.statusbar.phone.CloseDragHandle android:id="@+id/close"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:orientation="vertical"
-        >
-        <ImageView
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:layout_gravity="bottom"
-            android:scaleType="fitXY"
-            android:src="@drawable/status_bar_close_on"
-            />
-
-    </com.android.systemui.statusbar.phone.CloseDragHandle>
-
-</com.android.systemui.statusbar.phone.TrackingView>
diff --git a/packages/SystemUI/res/values-sw600dp/dimens.xml b/packages/SystemUI/res/values-sw600dp/dimens.xml
index 50a61b1..2ff62a5 100644
--- a/packages/SystemUI/res/values-sw600dp/dimens.xml
+++ b/packages/SystemUI/res/values-sw600dp/dimens.xml
@@ -16,8 +16,8 @@
 */
 -->
 <resources>
-    <!-- The width of the notification panel window -->
-    <dimen name="notification_panel_width">446dp</dimen>
+    <!-- The width of the notification panel window: 446 + 16 + 16 (padding in the bg drawable) -->
+    <dimen name="notification_panel_width">478dp</dimen>
 
     <!-- Layout parameters for the notification panel -->
     <dimen name="notification_panel_margin_bottom">192dp</dimen>
@@ -36,4 +36,7 @@
     <!-- Height of search panel including navigation bar height -->
     <dimen name="navbar_search_panel_height">300dip</dimen>
 
+    <!-- Extra space above the clock in the panel; on this device, zero -->
+    <dimen name="notification_panel_header_padding_top">0dp</dimen>
+
 </resources>
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index 9257195..ac2779f 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -20,11 +20,11 @@
     <drawable name="notification_number_text_color">#ffffffff</drawable>
     <drawable name="ticker_background_color">#ff1d1d1d</drawable>
     <drawable name="status_bar_background">#ff000000</drawable>
+    <color name="notification_panel_solid_background">#ff000000</color>
     <drawable name="status_bar_recents_app_thumbnail_background">#88000000</drawable>
     <color name="status_bar_recents_app_label_color">#ffffffff</color>
     <drawable name="status_bar_notification_row_background_color">#ff090909</drawable>
     <drawable name="notification_header_bg">#FF000000</drawable>
-    <drawable name="notification_tracking_bg">#66000000</drawable>
     <color name="notification_list_shadow_top">#80000000</color>
     <drawable name="recents_callout_line">#99ffffff</drawable>
     <drawable name="notification_item_background_legacy_color">#ffaaaaaa</drawable>
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 1f22507..5548445 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -53,5 +53,8 @@
 
     <!-- When true, show 1/2G networks as 3G. -->
     <bool name="config_showMin3G">false</bool>
+
+    <!-- Show rotation lock button in phone-style notification panel. -->
+    <bool name="config_showRotationLock">true</bool>
 </resources>
 
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 276d74b..b908188 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -125,7 +125,19 @@
     <dimen name="navbar_search_panel_height">230dip</dimen>
 
     <!-- Height of the draggable handle at the bottom of the phone notification panel -->
-    <dimen name="close_handle_height">34dp</dimen>
+    <dimen name="close_handle_height">32dp</dimen>
+
+    <!-- Amount of close_handle that will not overlap the notification list -->
+    <dimen name="close_handle_underlap">18dp</dimen>
+
+    <!-- Height of the notification panel header bar -->
+    <dimen name="notification_panel_header_height">48dp</dimen>
+
+    <!-- Height of the notification panel header bar -->
+    <dimen name="notification_panel_padding_top">@*android:dimen/status_bar_height</dimen>
+
+    <!-- Extra space above the clock in the panel; half of (notification_panel_header_height - 32) -->
+    <dimen name="notification_panel_header_padding_top">0dp</dimen>
 
     <!-- Layout parameters for the notification panel -->
     <dimen name="notification_panel_margin_bottom">0dp</dimen>
diff --git a/packages/SystemUI/res/values/donottranslate.xml b/packages/SystemUI/res/values/donottranslate.xml
index 4ca2116..089a54d 100644
--- a/packages/SystemUI/res/values/donottranslate.xml
+++ b/packages/SystemUI/res/values/donottranslate.xml
@@ -21,6 +21,6 @@
          We show both (DOW on one line, then the date) but this can be overridden for locales as
          necessary.
          -->
-    <string name="status_bar_date_formatter">%2$s</string>
+    <string name="status_bar_date_formatter">%1$s\n%2$s</string>
 
 </resources>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index d79ba42..1eb353f 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -377,4 +377,12 @@
     <!-- Content text for do-not-disturb mode notification -->
     <string name="notifications_off_text">Tap here to turn notifications back on.</string>
 
+    <!-- Description of the button in the phone-style notification panel that controls auto-rotation, when auto-rotation is on. [CHAR LIMIT=NONE] -->
+    <string name="accessibility_rotation_lock_off">Screen will rotate automatically.</string>
+
+    <!-- Description of the button in the phone-style notification panel that controls auto-rotation, when auto-rotation is off. [CHAR LIMIT=NONE] -->
+    <string name="accessibility_rotation_lock_on_landscape">Screen is locked in landscape orientation.</string>
+
+    <!-- Description of the button in the phone-style notification panel that controls auto-rotation, when auto-rotation is off. [CHAR LIMIT=NONE] -->
+    <string name="accessibility_rotation_lock_on_portrait">Screen is locked in portrait orientation.</string>
 </resources>
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index 02411d4..144760e 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -53,6 +53,21 @@
         <item name="android:textColor">@android:color/holo_blue_light</item>
     </style>
 
+    <style name="TextAppearance.StatusBar.Expanded" parent="@*android:style/TextAppearance.StatusBar" />
+
+    <style name="TextAppearance.StatusBar.Expanded.Clock">
+        <item name="android:textSize">32dp</item>
+        <item name="android:textStyle">normal</item>
+        <item name="android:textColor">#ffffff</item>
+    </style>
+
+    <style name="TextAppearance.StatusBar.Expanded.Date">
+        <item name="android:textSize">12dp</item>
+        <item name="android:textStyle">normal</item>
+        <item name="android:textColor">#666666</item>
+        <item name="android:textAllCaps">true</item>
+    </style>
+
     <style name="Animation" />
 
     <style name="Animation.ShirtPocketPanel">
diff --git a/packages/SystemUI/src/com/android/systemui/ExpandHelper.java b/packages/SystemUI/src/com/android/systemui/ExpandHelper.java
index 5387bf5..c5928f1 100644
--- a/packages/SystemUI/src/com/android/systemui/ExpandHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/ExpandHelper.java
@@ -41,6 +41,13 @@
     private static final long EXPAND_DURATION = 250;
     private static final long GLOW_DURATION = 150;
 
+    // Set to false to disable focus-based gestures (two-finger pull).
+    private static final boolean USE_DRAG = true;
+    // Set to false to disable scale-based gestures (both horizontal and vertical).
+    private static final boolean USE_SPAN = true;
+    // Both gestures types may be active at the same time.
+    // At least one gesture type should be active.
+    // A variant of the screwdriver gesture will emerge from either gesture type.
 
     // amount of overstretch for maximum brightness expressed in U
     // 2f: maximum brightness is stretching a 1U to 3U, or a 4U to 6U
@@ -59,6 +66,7 @@
     private View mCurrViewBottomGlow;
     private float mOldHeight;
     private float mNaturalHeight;
+    private float mInitialTouchFocusY;
     private float mInitialTouchSpan;
     private Callback mCallback;
     private ScaleGestureDetector mDetector;
@@ -83,7 +91,7 @@
             ViewGroup.LayoutParams lp = mView.getLayoutParams();
             lp.height = (int)h;
             mView.setLayoutParams(lp);
-	    mView.requestLayout();
+            mView.requestLayout();
         }
         public float getHeight() {
             int height = mView.getLayoutParams().height;
@@ -94,15 +102,15 @@
         }
         public int getNaturalHeight(int maximum) {
             ViewGroup.LayoutParams lp = mView.getLayoutParams();
-	    if (DEBUG) Log.v(TAG, "Inspecting a child of type: " + mView.getClass().getName());
+            if (DEBUG) Log.v(TAG, "Inspecting a child of type: " + mView.getClass().getName());
             int oldHeight = lp.height;
             lp.height = ViewGroup.LayoutParams.WRAP_CONTENT;
             mView.setLayoutParams(lp);
             mView.measure(
                     View.MeasureSpec.makeMeasureSpec(mView.getMeasuredWidth(),
-						     View.MeasureSpec.EXACTLY),
+                                                     View.MeasureSpec.EXACTLY),
                     View.MeasureSpec.makeMeasureSpec(maximum,
-						     View.MeasureSpec.AT_MOST));
+                                                     View.MeasureSpec.AT_MOST));
             lp.height = oldHeight;
             mView.setLayoutParams(lp);
             return mView.getMeasuredHeight();
@@ -135,8 +143,9 @@
                 View v = mCallback.getChildAtPosition(detector.getFocusX(), detector.getFocusY());
 
                 // your fingers have to be somewhat close to the bounds of the view in question
-                mInitialTouchSpan = Math.abs(detector.getCurrentSpanY());
-                if (DEBUG) Log.d(TAG, "got mInitialTouchSpan: " + mInitialTouchSpan);
+                mInitialTouchFocusY = detector.getFocusY();
+                mInitialTouchSpan = Math.abs(detector.getCurrentSpan());
+                if (DEBUG) Log.d(TAG, "got mInitialTouchSpan: (" + mInitialTouchSpan + ")");
 
                 mStretching = initScale(v);
                 return mStretching;
@@ -145,16 +154,25 @@
             @Override
             public boolean onScale(ScaleGestureDetector detector) {
                 if (DEBUG) Log.v(TAG, "onscale() on " + mCurrView);
-                float h = Math.abs(detector.getCurrentSpanY());
-                if (DEBUG) Log.d(TAG, "current span is: " + h);
-                h = h + mOldHeight - mInitialTouchSpan;
-                float target = h;
+
+                // are we scaling or dragging?
+                float span = Math.abs(detector.getCurrentSpan()) - mInitialTouchSpan;
+                span *= USE_SPAN ? 1f : 0f;
+                float drag = detector.getFocusY() - mInitialTouchFocusY;
+                drag *= USE_DRAG ? 1f : 0f;
+                float pull = Math.abs(drag) + Math.abs(span) + 1f;
+                float hand = drag * Math.abs(drag) / pull + span * Math.abs(span) / pull;
+                if (DEBUG) Log.d(TAG, "current span handle is: " + hand);
+                hand = hand + mOldHeight;
+                float target = hand;
                 if (DEBUG) Log.d(TAG, "target is: " + target);
-                h = h<mSmallSize?mSmallSize:(h>mLargeSize?mLargeSize:h);
-                h = h>mNaturalHeight?mNaturalHeight:h;
-                if (DEBUG) Log.d(TAG, "scale continues: h=" + h);
-                mScaler.setHeight(h);
-                float stretch = (float) Math.abs((target - h) / mMaximumStretch);
+                hand = hand < mSmallSize ? mSmallSize : (hand > mLargeSize ? mLargeSize : hand);
+                hand = hand > mNaturalHeight ? mNaturalHeight : hand;
+                if (DEBUG) Log.d(TAG, "scale continues: hand =" + hand);
+                mScaler.setHeight(hand);
+
+                // glow if overscale
+                float stretch = (float) Math.abs((target - hand) / mMaximumStretch);
                 float strength = 1f / (1f + (float) Math.pow(Math.E, -1 * ((8f * stretch) - 5f)));
                 if (DEBUG) Log.d(TAG, "stretch: " + stretch + " strength: " + strength);
                 setGlow(GLOW_BASE + strength * (1f - GLOW_BASE));
@@ -171,7 +189,10 @@
         });
     }
     public void setGlow(float glow) {
-        if (!mGlowAnimationSet.isRunning()) {
+        if (!mGlowAnimationSet.isRunning() || glow == 0f) {
+            if (mGlowAnimationSet.isRunning()) {
+                mGlowAnimationSet.cancel();
+            }
             if (mCurrViewTopGlow != null && mCurrViewBottomGlow != null) {
                 if (glow == 0f || mCurrViewTopGlow.getAlpha() == 0f) { 
                     // animate glow in and out
@@ -251,6 +272,7 @@
         mScaleAnimation.start();
         mStretching = false;
         setGlow(0f);
+        if (DEBUG) Log.d(TAG, "scale was finished on view: " + mCurrView);
         clearView();
     }
 
@@ -261,12 +283,12 @@
     }
 
     private void setView(View v) {
-        mCurrView = null;
+        mCurrView = v;
         if (v instanceof ViewGroup) {
             ViewGroup g = (ViewGroup) v;
             mCurrViewTopGlow = g.findViewById(R.id.top_glow);
             mCurrViewBottomGlow = g.findViewById(R.id.bottom_glow);
-	    if (DEBUG) {
+            if (DEBUG) {
                 String debugLog = "Looking for glows: " + 
                         (mCurrViewTopGlow != null ? "found top " : "didn't find top") +
                         (mCurrViewBottomGlow != null ? "found bottom " : "didn't find bottom");
diff --git a/packages/SystemUI/src/com/android/systemui/SearchPanelView.java b/packages/SystemUI/src/com/android/systemui/SearchPanelView.java
index 185ca5b..57f15a8 100644
--- a/packages/SystemUI/src/com/android/systemui/SearchPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/SearchPanelView.java
@@ -146,7 +146,7 @@
         }
     }
 
-    public void show(boolean show, boolean animate) {
+    public void show(final boolean show, boolean animate) {
         if (animate) {
             if (mShowing != show) {
                 mShowing = show;
@@ -156,21 +156,24 @@
             mShowing = show;
             onAnimationEnd(null);
         }
-        setVisibility(show ? View.VISIBLE : View.GONE);
-        if (show) {
-            setFocusable(true);
-            setFocusableInTouchMode(true);
-            requestFocus();
-        }
+        postDelayed(new Runnable() {
+            public void run() {
+                setVisibility(show ? View.VISIBLE : View.INVISIBLE);
+                if (show) {
+                    setFocusable(true);
+                    setFocusableInTouchMode(true);
+                    requestFocus();
+                }
+            }
+        }, show ? 0 : 100);
     }
 
     public void hide(boolean animate) {
-        if (!animate) {
-            setVisibility(View.GONE);
-        }
         if (mBar != null) {
             // This will indirectly cause show(false, ...) to get called
             mBar.animateCollapse();
+        } else {
+            setVisibility(View.INVISIBLE);
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/RotationToggle.java b/packages/SystemUI/src/com/android/systemui/statusbar/RotationToggle.java
new file mode 100644
index 0000000..c5a7354
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/RotationToggle.java
@@ -0,0 +1,30 @@
+package com.android.systemui.statusbar;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.widget.CompoundButton;
+
+import com.android.systemui.statusbar.policy.AutoRotateController;
+
+public class RotationToggle extends CompoundButton {
+    AutoRotateController mRotater;
+
+    public RotationToggle(Context context) {
+        super(context);
+        mRotater = new AutoRotateController(context, this);
+        setClickable(true);
+    }
+
+    public RotationToggle(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        mRotater = new AutoRotateController(context, this);
+        setClickable(true);
+    }
+
+    public RotationToggle(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+        mRotater = new AutoRotateController(context, this);
+        setClickable(true);
+    }
+
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index 1561e27..db7969e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -63,6 +63,7 @@
 import android.view.animation.AccelerateInterpolator;
 import android.view.animation.Animation;
 import android.view.animation.AnimationUtils;
+import android.widget.CompoundButton;
 import android.widget.FrameLayout;
 import android.widget.ImageView;
 import android.widget.LinearLayout;
@@ -77,8 +78,10 @@
 import com.android.systemui.statusbar.BaseStatusBar;
 import com.android.systemui.statusbar.NotificationData;
 import com.android.systemui.statusbar.NotificationData.Entry;
+import com.android.systemui.statusbar.RotationToggle;
 import com.android.systemui.statusbar.SignalClusterView;
 import com.android.systemui.statusbar.StatusBarIconView;
+import com.android.systemui.statusbar.policy.AutoRotateController;
 import com.android.systemui.statusbar.policy.BatteryController;
 import com.android.systemui.statusbar.policy.DateView;
 import com.android.systemui.statusbar.policy.IntruderAlertView;
@@ -103,6 +106,7 @@
             = "com.android.internal.policy.statusbar.START";
 
     private static final boolean ENABLE_INTRUDERS = false;
+    private static final boolean DIM_BEHIND_EXPANDED_PANEL = false;
 
     static final int EXPANDED_LEAVE_ALONE = -10000;
     static final int EXPANDED_FULL_OPEN = -10001;
@@ -169,6 +173,7 @@
     // top bar
     View mClearButton;
     View mSettingsButton;
+    RotationToggle mRotationButton;
 
     // drag bar
     CloseDragHandle mCloseView;
@@ -208,6 +213,7 @@
 
     Choreographer mChoreographer;
     boolean mAnimating;
+    boolean mClosing; // only valid when mAnimating; indicates the initial acceleration
     float mAnimY;
     float mAnimVel;
     float mAnimAccel;
@@ -299,6 +305,19 @@
 
         mStatusBarView = (PhoneStatusBarView) mStatusBarWindow.findViewById(R.id.status_bar);
         mNotificationPanel = mStatusBarWindow.findViewById(R.id.notification_panel);
+        // don't allow clicks on the panel to pass through to the background where they will cause the panel to close
+        mNotificationPanel.setOnTouchListener(new View.OnTouchListener() {
+            @Override
+            public boolean onTouch(View v, MotionEvent event) {
+                return true;
+            }
+        });
+
+        if (!ActivityManager.isHighEndGfx(mDisplay)) {
+            mStatusBarWindow.setBackground(null);
+            mNotificationPanel.setBackgroundColor(context.getResources().getColor(
+                    R.color.notification_panel_solid_background));
+        }
 
         if (ENABLE_INTRUDERS) {
             mIntruderAlertView = (IntruderAlertView) View.inflate(context, R.layout.intruder_alert, null);
@@ -344,6 +363,8 @@
         mDateView = (DateView)mStatusBarWindow.findViewById(R.id.date);
         mSettingsButton = mStatusBarWindow.findViewById(R.id.settings_button);
         mSettingsButton.setOnClickListener(mSettingsButtonListener);
+        mRotationButton = (RotationToggle) mStatusBarWindow.findViewById(R.id.rotation_lock_button);
+
         mScrollView = (ScrollView)mStatusBarWindow.findViewById(R.id.scroll);
         mScrollView.setVerticalScrollBarEnabled(false); // less drawing during pulldowns
 
@@ -461,7 +482,6 @@
         WindowManager.LayoutParams lp =
             (android.view.WindowManager.LayoutParams) mNavigationBarView.getLayoutParams();
         lp.flags &= ~WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
-        lp.flags &= ~WindowManager.LayoutParams.FLAG_SLIPPERY;
         WindowManagerImpl.getDefault().updateViewLayout(mNavigationBarView, lp);
     }
 
@@ -471,7 +491,6 @@
         WindowManager.LayoutParams lp =
             (android.view.WindowManager.LayoutParams) mNavigationBarView.getLayoutParams();
         lp.flags |= WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
-        lp.flags |= WindowManager.LayoutParams.FLAG_SLIPPERY;
         WindowManagerImpl.getDefault().updateViewLayout(mNavigationBarView, lp);
     }
 
@@ -552,8 +571,7 @@
                     | WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING
                     | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                     | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
-                    | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH
-                    | WindowManager.LayoutParams.FLAG_SLIPPERY,
+                    | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
                 PixelFormat.OPAQUE);
         // this will allow the navbar to run in an overlay on devices that support this
         if (ActivityManager.isHighEndGfx(mDisplay)) {
@@ -1257,14 +1275,26 @@
         }
     }
 
+    void resetLastAnimTime() {
+        mAnimLastTimeNanos = System.nanoTime();
+        if (SPEW) {
+            Throwable t = new Throwable();
+            t.fillInStackTrace();
+            Slog.d(TAG, "resetting last anim time=" + mAnimLastTimeNanos, t);
+        }
+    }
+
     void doAnimation(long frameTimeNanos) {
         if (mAnimating) {
-            if (SPEW) Slog.d(TAG, "doAnimation");
+            if (SPEW) Slog.d(TAG, "doAnimation dt=" + (frameTimeNanos - mAnimLastTimeNanos));
             if (SPEW) Slog.d(TAG, "doAnimation before mAnimY=" + mAnimY);
             incrementAnim(frameTimeNanos);
-            if (SPEW) Slog.d(TAG, "doAnimation after  mAnimY=" + mAnimY);
+            if (SPEW) {
+                Slog.d(TAG, "doAnimation after  mAnimY=" + mAnimY);
+                Slog.d(TAG, "doAnimation expandedViewMax=" + getExpandedViewMaxHeight());
+            }
 
-            if (mAnimY >= getExpandedViewMaxHeight()-1) {
+            if (mAnimY >= getExpandedViewMaxHeight()-1 && !mClosing) {
                 if (SPEW) Slog.d(TAG, "Animation completed to expanded state.");
                 mAnimating = false;
                 updateExpandedViewPos(EXPANDED_FULL_OPEN);
@@ -1272,14 +1302,14 @@
                 return;
             }
 
-            if (mAnimY == 0 && mAnimAccel == 0 && mAnimVel == 0) {
+            if (mAnimY == 0 && mAnimAccel == 0 && mClosing) {
                 if (SPEW) Slog.d(TAG, "Animation completed to collapsed state.");
                 mAnimating = false;
                 performCollapse();
                 return;
             }
 
-            if (mAnimY < getStatusBarHeight()) {
+            if (mAnimY < getStatusBarHeight() && mClosing) {
                 // Draw one more frame with the bar positioned at the top of the screen
                 // before ending the animation so that the user sees the bar in
                 // its final position.  The call to performCollapse() causes a window
@@ -1301,6 +1331,7 @@
         mPile.setLayerType(View.LAYER_TYPE_NONE, null);
         mVelocityTracker.recycle();
         mVelocityTracker = null;
+        mCloseView.setPressed(false);
     }
 
     void incrementAnim(long frameTimeNanos) {
@@ -1317,6 +1348,9 @@
     }
     
     void doRevealAnimation(long frameTimeNanos) {
+        if (SPEW) {
+            Slog.d(TAG, "doRevealAnimation: dt=" + (frameTimeNanos - mAnimLastTimeNanos));
+        }
         final int h = getCloseViewHeight() + getStatusBarHeight();
         if (mAnimatingReveal && mAnimating && mAnimY < h) {
             incrementAnim(frameTimeNanos);
@@ -1336,6 +1370,8 @@
             Slog.d(TAG, "panel: beginning to track the user's touch, y=" + y + " opening=" + opening);
         }
 
+        mCloseView.setPressed(true);
+
         mTracking = true;
         mPile.setLayerType(View.LAYER_TYPE_HARDWARE, null);
         mVelocityTracker = VelocityTracker.obtain();
@@ -1346,7 +1382,7 @@
             updateExpandedViewPos((int)mAnimY);
             mAnimating = true;
             mAnimatingReveal = true;
-            mAnimLastTimeNanos = System.nanoTime();
+            resetLastAnimTime();
             mChoreographer.removeCallbacks(Choreographer.CALLBACK_ANIMATION,
                     mAnimationCallback, null);
             mChoreographer.removeCallbacks(Choreographer.CALLBACK_ANIMATION,
@@ -1420,8 +1456,9 @@
         //Slog.d(TAG, "mAnimY=" + mAnimY + " mAnimVel=" + mAnimVel
         //        + " mAnimAccel=" + mAnimAccel);
 
-        mAnimLastTimeNanos = System.nanoTime();
+        resetLastAnimTime();
         mAnimating = true;
+        mClosing = mAnimAccel < 0;
 
         mChoreographer.removeCallbacks(Choreographer.CALLBACK_ANIMATION,
                 mAnimationCallback, null);
@@ -1461,8 +1498,8 @@
             if (!mExpanded) {
                 mViewDelta = statusBarSize - y;
             } else {
-//                mCloseView.getLocationOnScreen(mAbsPos)...?
-//                mViewDelta = mAbsPos[1] + mTrackingView.getHeight() - y;
+                mCloseView.getLocationOnScreen(mAbsPos);
+                mViewDelta = mAbsPos[1] + statusBarSize + getCloseViewHeight() - y; // XXX: not closeViewHeight, but paddingBottom from the 9patch
             }
             if ((!mExpanded && y < hitSize) ||
                     // @@ add taps outside the panel if it's not full-screen
@@ -1974,11 +2011,14 @@
             Slog.v(TAG, "updated cropView height=" + panelh + " grav=" + lp.gravity);
         }
         mNotificationPanel.setLayoutParams(lp);
-        // woo, special effects
-        final int barh = getCloseViewHeight() + getStatusBarHeight();
-        final float frac = saturate((float)(panelh - barh) / (disph - barh));
-        final int color = ((int)(0xB0 * Math.sin(frac * 1.57f))) << 24;
-        mStatusBarWindow.setBackgroundColor(color);
+
+        if (DIM_BEHIND_EXPANDED_PANEL && ActivityManager.isHighEndGfx(mDisplay)) {
+            // woo, special effects
+            final int barh = getCloseViewHeight() + getStatusBarHeight();
+            final float frac = saturate((float)(panelh - barh) / (disph - barh));
+            final int color = ((int)(0xB0 * Math.sin(frac * 1.57f))) << 24;
+            mStatusBarWindow.setBackgroundColor(color);
+        }
     }
 
     void updateDisplaySize() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
index 5f18b5d..374226d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
@@ -122,8 +122,7 @@
                     action.equals(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED)) {
                 updateBluetooth(intent);
             }
-            else if (action.equals(AudioManager.RINGER_MODE_CHANGED_ACTION) ||
-                    action.equals(AudioManager.VIBRATE_SETTING_CHANGED_ACTION)) {
+            else if (action.equals(AudioManager.RINGER_MODE_CHANGED_ACTION)) {
                 updateVolume();
             }
             else if (action.equals(TelephonyIntents.ACTION_SIM_STATE_CHANGED)) {
@@ -144,7 +143,6 @@
         filter.addAction(Intent.ACTION_ALARM_CHANGED);
         filter.addAction(Intent.ACTION_SYNC_STATE_CHANGED);
         filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION);
-        filter.addAction(AudioManager.VIBRATE_SETTING_CHANGED_ACTION);
         filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
         filter.addAction(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED);
         filter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
@@ -238,7 +236,7 @@
 
         final int iconId;
         String contentDescription = null;
-        if (audioManager.shouldVibrate(AudioManager.VIBRATE_TYPE_RINGER)) {
+        if (ringerMode == AudioManager.RINGER_MODE_VIBRATE) {
             iconId = R.drawable.stat_sys_ringer_vibrate;
             contentDescription = mContext.getString(R.string.accessibility_ringer_vibrate);
         } else {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/VolumeController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/VolumeController.java
index c9da01a..43cb85e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/VolumeController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/VolumeController.java
@@ -20,6 +20,7 @@
 import android.content.Context;
 import android.os.RemoteException;
 import android.os.ServiceManager;
+import android.os.Vibrator;
 import android.media.AudioManager;
 import android.provider.Settings;
 import android.util.Slog;
@@ -36,10 +37,16 @@
 
     private boolean mMute;
     private int mVolume;
+    // Is there a vibrator
+    private final boolean mHasVibrator;
 
     public VolumeController(Context context, ToggleSlider control) {
         mContext = context;
         mControl = control;
+
+        Vibrator vibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
+        mHasVibrator = vibrator == null ? false : vibrator.hasVibrator();
+
         mAudioManager = (AudioManager)context.getSystemService(Context.AUDIO_SERVICE);
 
         mMute = mAudioManager.getRingerMode() != AudioManager.RINGER_MODE_NORMAL;
@@ -54,10 +61,8 @@
     public void onChanged(ToggleSlider view, boolean tracking, boolean mute, int level) {
         if (!tracking) {
             if (mute) {
-                boolean vibeInSilent = (1 == Settings.System.getInt(mContext.getContentResolver(),
-                        Settings.System.VIBRATE_IN_SILENT, 1));
                 mAudioManager.setRingerMode(
-                        vibeInSilent ? AudioManager.RINGER_MODE_VIBRATE
+                        mHasVibrator ? AudioManager.RINGER_MODE_VIBRATE
                                      : AudioManager.RINGER_MODE_SILENT);
             } else {
                 mAudioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
index a394596..b0830ee 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
@@ -704,7 +704,6 @@
         WindowManager.LayoutParams lp =
             (android.view.WindowManager.LayoutParams) mStatusBarView.getLayoutParams();
         lp.flags &= ~WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
-        lp.flags &= ~WindowManager.LayoutParams.FLAG_SLIPPERY;
         WindowManagerImpl.getDefault().updateViewLayout(mStatusBarView, lp);
     }
 
@@ -714,7 +713,6 @@
         WindowManager.LayoutParams lp =
             (android.view.WindowManager.LayoutParams) mStatusBarView.getLayoutParams();
         lp.flags |= WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
-        lp.flags |= WindowManager.LayoutParams.FLAG_SLIPPERY;
         WindowManagerImpl.getDefault().updateViewLayout(mStatusBarView, lp);
     }
 
diff --git a/policy/src/com/android/internal/policy/impl/FaceUnlock.java b/policy/src/com/android/internal/policy/impl/FaceUnlock.java
index 6e09b7f..6590fb3 100644
--- a/policy/src/com/android/internal/policy/impl/FaceUnlock.java
+++ b/policy/src/com/android/internal/policy/impl/FaceUnlock.java
@@ -28,6 +28,7 @@
 import android.content.ServiceConnection;
 import android.os.Handler;
 import android.os.IBinder;
+import android.os.Looper;
 import android.os.Message;
 import android.os.RemoteException;
 import android.telephony.TelephonyManager;
@@ -112,10 +113,14 @@
 
     /**
      * Sets the Face Unlock view to visible, hiding it after the specified amount of time.  If
-     * timeoutMillis is 0, no hide is performed.
+     * timeoutMillis is 0, no hide is performed.  Called on the UI thread.
      */
     public void show(long timeoutMillis) {
         if (DEBUG) Log.d(TAG, "show()");
+        if (mHandler.getLooper() != Looper.myLooper()) {
+            Log.e(TAG, "show() called off of the UI thread");
+        }
+
         removeDisplayMessages();
         if (mFaceUnlockView != null) {
             mFaceUnlockView.setVisibility(View.VISIBLE);
@@ -138,9 +143,14 @@
     /**
      * Binds to the Face Unlock service.  Face Unlock will be started when the bind completes.  The
      * Face Unlock view is displayed to hide the backup lock while the service is starting up.
+     * Called on the UI thread.
      */
     public boolean start() {
         if (DEBUG) Log.d(TAG, "start()");
+        if (mHandler.getLooper() != Looper.myLooper()) {
+            Log.e(TAG, "start() called off of the UI thread");
+        }
+
         if (mIsRunning) {
             Log.w(TAG, "start() called when already running");
         }
@@ -170,10 +180,14 @@
     }
 
     /**
-     * Stops Face Unlock and unbinds from the service.
+     * Stops Face Unlock and unbinds from the service.  Called on the UI thread.
      */
     public boolean stop() {
         if (DEBUG) Log.d(TAG, "stop()");
+        if (mHandler.getLooper() != Looper.myLooper()) {
+            Log.e(TAG, "stop() called off of the UI thread");
+        }
+
         boolean mWasRunning = mIsRunning;
         stopUi();
 
diff --git a/policy/src/com/android/internal/policy/impl/LockScreen.java b/policy/src/com/android/internal/policy/impl/LockScreen.java
index 8b0d858..c7a30e2 100644
--- a/policy/src/com/android/internal/policy/impl/LockScreen.java
+++ b/policy/src/com/android/internal/policy/impl/LockScreen.java
@@ -34,6 +34,7 @@
 import android.content.Intent;
 import android.content.res.Configuration;
 import android.content.res.Resources;
+import android.os.Vibrator;
 import android.view.KeyEvent;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -82,6 +83,8 @@
     private boolean mCameraDisabled;
     private boolean mSearchDisabled;
     private SearchManager mSearchManager;
+    // Is there a vibrator
+    private final boolean mHasVibrator;
 
     InfoCallbackImpl mInfoCallback = new InfoCallbackImpl() {
 
@@ -385,11 +388,7 @@
         // toggle silent mode
         mSilentMode = !mSilentMode;
         if (mSilentMode) {
-            final boolean vibe = (Settings.System.getInt(
-                mContext.getContentResolver(),
-                Settings.System.VIBRATE_IN_SILENT, 1) == 1);
-
-            mAudioManager.setRingerMode(vibe
+            mAudioManager.setRingerMode(mHasVibrator
                 ? AudioManager.RINGER_MODE_VIBRATE
                 : AudioManager.RINGER_MODE_SILENT);
         } else {
@@ -451,6 +450,8 @@
         setFocusableInTouchMode(true);
         setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
 
+        Vibrator vibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
+        mHasVibrator = vibrator == null ? false : vibrator.hasVibrator();
         mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
         mSilentMode = isSilentMode();
         mUnlockWidget = findViewById(R.id.unlock_widget);
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindow.java b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
index 610d566..ba5034e 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindow.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
@@ -2100,7 +2100,6 @@
             if (widthMode == AT_MOST) {
                 final TypedValue tvw = isPortrait ? mFixedWidthMinor : mFixedWidthMajor;
                 if (tvw != null && tvw.type != TypedValue.TYPE_NULL) {
-                    fixedWidth = true;
                     final int w;
                     if (tvw.type == TypedValue.TYPE_DIMENSION) {
                         w = (int) tvw.getDimension(metrics);
@@ -2114,6 +2113,7 @@
                         final int widthSize = MeasureSpec.getSize(widthMeasureSpec);
                         widthMeasureSpec = MeasureSpec.makeMeasureSpec(
                                 Math.min(w, widthSize), EXACTLY);
+                        fixedWidth = true;
                     }
                 }
             }
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index b3ca171..6348d37 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -553,8 +553,6 @@
             resolver.registerContentObserver(Settings.System.getUriFor(
                     Settings.System.SCREEN_OFF_TIMEOUT), false, this);
             resolver.registerContentObserver(Settings.System.getUriFor(
-                    Settings.System.WINDOW_ORIENTATION_LISTENER_LOG), false, this);
-            resolver.registerContentObserver(Settings.System.getUriFor(
                     Settings.System.POINTER_LOCATION), false, this);
             resolver.registerContentObserver(Settings.Secure.getUriFor(
                     Settings.Secure.DEFAULT_INPUT_METHOD), false, this);
@@ -1098,10 +1096,6 @@
                 updateOrientationListenerLp();
             }
 
-            mOrientationListener.setLogEnabled(
-                    Settings.System.getInt(resolver,
-                            Settings.System.WINDOW_ORIENTATION_LISTENER_LOG, 0) != 0);
-
             if (mSystemReady) {
                 int pointerLocation = Settings.System.getInt(resolver,
                         Settings.System.POINTER_LOCATION, 0);
diff --git a/services/input/EventHub.cpp b/services/input/EventHub.cpp
index f80ac18..50bfee6 100644
--- a/services/input/EventHub.cpp
+++ b/services/input/EventHub.cpp
@@ -16,7 +16,7 @@
 
 #define LOG_TAG "EventHub"
 
-// #define LOG_NDEBUG 0
+#define LOG_NDEBUG 0
 
 #include "EventHub.h"
 
@@ -767,11 +767,7 @@
                     size_t count = size_t(readSize) / sizeof(struct input_event);
                     for (size_t i = 0; i < count; i++) {
                         const struct input_event& iev = readBuffer[i];
-                        ALOGV("%s got: t0=%d, t1=%d, type=%d, code=%d, value=%d",
-                                device->path.string(),
-                                (int) iev.time.tv_sec, (int) iev.time.tv_usec,
-                                iev.type, iev.code, iev.value);
-
+                        nsecs_t delta = 0; 
 #ifdef HAVE_POSIX_CLOCKS
                         // Use the time specified in the event instead of the current time
                         // so that downstream code can get more accurate estimates of
@@ -786,10 +782,23 @@
                         // system call that also queries ktime_get_ts().
                         event->when = nsecs_t(iev.time.tv_sec) * 1000000000LL
                                 + nsecs_t(iev.time.tv_usec) * 1000LL;
-                        ALOGV("event time %lld, now %lld", event->when, now);
+                        delta = now - event->when;
+
+                        // Only log verbose if events are older that 1ms
+                        if (delta > 1 * 1000000LL) {
+                            ALOGV("event time %lld, now %lld, delta %lldus", event->when, now, delta / 1000LL);
+                        }
 #else
                         event->when = now;
 #endif
+                        if (delta > 1 * 1000000LL) {
+                            ALOGV("%s got: t0=%d, t1=%d, type=%d, code=%d, value=%d",
+                                  device->path.string(),
+                                  (int) iev.time.tv_sec, (int) iev.time.tv_usec,
+                                  iev.type, iev.code, iev.value);
+                        }
+
+
                         event->deviceId = deviceId;
                         event->type = iev.type;
                         event->code = iev.code;
diff --git a/services/input/InputDispatcher.cpp b/services/input/InputDispatcher.cpp
index dad4ef4..ada9d9e 100644
--- a/services/input/InputDispatcher.cpp
+++ b/services/input/InputDispatcher.cpp
@@ -185,7 +185,7 @@
     mPolicy(policy),
     mPendingEvent(NULL), mAppSwitchSawKeyDown(false), mAppSwitchDueTime(LONG_LONG_MAX),
     mNextUnblockedEvent(NULL),
-    mDispatchEnabled(true), mDispatchFrozen(false), mInputFilterEnabled(false),
+    mDispatchEnabled(false), mDispatchFrozen(false), mInputFilterEnabled(false),
     mInputTargetWaitCause(INPUT_TARGET_WAIT_CAUSE_NONE) {
     mLooper = new Looper(false);
 
diff --git a/services/java/com/android/server/InputMethodManagerService.java b/services/java/com/android/server/InputMethodManagerService.java
index 8e3b825..a49ccf7 100644
--- a/services/java/com/android/server/InputMethodManagerService.java
+++ b/services/java/com/android/server/InputMethodManagerService.java
@@ -1142,6 +1142,10 @@
         if (mCurToken != null) {
             try {
                 if (DEBUG) Slog.v(TAG, "Removing window token: " + mCurToken);
+                if ((mImeWindowVis & InputMethodService.IME_ACTIVE) != 0) {
+                    // The current IME is shown. Hence an IME switch (transition) is happening.
+                    mWindowManagerService.saveLastInputMethodWindowForTransition();
+                }
                 mIWindowManager.removeWindowToken(mCurToken);
             } catch (RemoteException e) {
             }
@@ -2410,17 +2414,63 @@
         }
     }
 
-    private static class ImeSubtypeListItem {
+    private static class ImeSubtypeListItem implements Comparable<ImeSubtypeListItem> {
         public final CharSequence mImeName;
         public final CharSequence mSubtypeName;
         public final InputMethodInfo mImi;
         public final int mSubtypeId;
+        private final boolean mIsSystemLocale;
+        private final boolean mIsSystemLanguage;
+
         public ImeSubtypeListItem(CharSequence imeName, CharSequence subtypeName,
-                InputMethodInfo imi, int subtypeId) {
+                InputMethodInfo imi, int subtypeId, String subtypeLocale, String systemLocale) {
             mImeName = imeName;
             mSubtypeName = subtypeName;
             mImi = imi;
             mSubtypeId = subtypeId;
+            if (TextUtils.isEmpty(subtypeLocale)) {
+                mIsSystemLocale = false;
+                mIsSystemLanguage = false;
+            } else {
+                mIsSystemLocale = subtypeLocale.equals(systemLocale);
+                mIsSystemLanguage = mIsSystemLocale
+                        || subtypeLocale.startsWith(systemLocale.substring(0, 2));
+            }
+        }
+
+        @Override
+        public int compareTo(ImeSubtypeListItem other) {
+            if (TextUtils.isEmpty(mImeName)) {
+                return 1;
+            }
+            if (TextUtils.isEmpty(other.mImeName)) {
+                return -1;
+            }
+            if (!TextUtils.equals(mImeName, other.mImeName)) {
+                return mImeName.toString().compareTo(other.mImeName.toString());
+            }
+            if (TextUtils.equals(mSubtypeName, other.mSubtypeName)) {
+                return 0;
+            }
+            if (mIsSystemLocale) {
+                return -1;
+            }
+            if (other.mIsSystemLocale) {
+                return 1;
+            }
+            if (mIsSystemLanguage) {
+                return -1;
+            }
+            if (other.mIsSystemLanguage) {
+                return 1;
+            }
+            if (TextUtils.isEmpty(mSubtypeName)) {
+                return 1;
+            }
+            if (TextUtils.isEmpty(other.mSubtypeName)) {
+                return -1;
+            }
+            return mSubtypeName.toString().compareTo(other.mSubtypeName.toString());
         }
     }
 
@@ -2619,7 +2669,11 @@
         return getSubtypeIdFromHashCode(imi, subtypeId);
     }
 
-    private int getSubtypeIdFromHashCode(InputMethodInfo imi, int subtypeHashCode) {
+    private static boolean isValidSubtypeId(InputMethodInfo imi, int subtypeHashCode) {
+        return getSubtypeIdFromHashCode(imi, subtypeHashCode) != NOT_A_SUBTYPE_ID;
+    }
+
+    private static int getSubtypeIdFromHashCode(InputMethodInfo imi, int subtypeHashCode) {
         if (imi != null) {
             final int subtypeCount = imi.getSubtypeCount();
             for (int i = 0; i < subtypeCount; ++i) {
@@ -2844,6 +2898,9 @@
      */
     @Override
     public InputMethodSubtype getCurrentInputMethodSubtype() {
+        if (mCurMethodId == null) {
+            return null;
+        }
         boolean subtypeIsSelected = false;
         try {
             subtypeIsSelected = Settings.Secure.getInt(mContext.getContentResolver(),
@@ -2851,36 +2908,35 @@
         } catch (SettingNotFoundException e) {
         }
         synchronized (mMethodMap) {
-            if (!subtypeIsSelected || mCurrentSubtype == null) {
-                String lastInputMethodId = Settings.Secure.getString(
-                        mContext.getContentResolver(), Settings.Secure.DEFAULT_INPUT_METHOD);
-                int subtypeId = getSelectedInputMethodSubtypeId(lastInputMethodId);
+            final InputMethodInfo imi = mMethodMap.get(mCurMethodId);
+            if (imi == null || imi.getSubtypeCount() == 0) {
+                return null;
+            }
+            if (!subtypeIsSelected || mCurrentSubtype == null
+                    || !isValidSubtypeId(imi, mCurrentSubtype.hashCode())) {
+                int subtypeId = getSelectedInputMethodSubtypeId(mCurMethodId);
                 if (subtypeId == NOT_A_SUBTYPE_ID) {
-                    InputMethodInfo imi = mMethodMap.get(lastInputMethodId);
-                    if (imi != null) {
-                        // If there are no selected subtypes, the framework will try to find
-                        // the most applicable subtype from explicitly or implicitly enabled
-                        // subtypes.
-                        List<InputMethodSubtype> explicitlyOrImplicitlyEnabledSubtypes =
-                                getEnabledInputMethodSubtypeList(imi, true);
-                        // If there is only one explicitly or implicitly enabled subtype,
-                        // just returns it.
-                        if (explicitlyOrImplicitlyEnabledSubtypes.size() == 1) {
-                            mCurrentSubtype = explicitlyOrImplicitlyEnabledSubtypes.get(0);
-                        } else if (explicitlyOrImplicitlyEnabledSubtypes.size() > 1) {
+                    // If there are no selected subtypes, the framework will try to find
+                    // the most applicable subtype from explicitly or implicitly enabled
+                    // subtypes.
+                    List<InputMethodSubtype> explicitlyOrImplicitlyEnabledSubtypes =
+                            getEnabledInputMethodSubtypeList(imi, true);
+                    // If there is only one explicitly or implicitly enabled subtype,
+                    // just returns it.
+                    if (explicitlyOrImplicitlyEnabledSubtypes.size() == 1) {
+                        mCurrentSubtype = explicitlyOrImplicitlyEnabledSubtypes.get(0);
+                    } else if (explicitlyOrImplicitlyEnabledSubtypes.size() > 1) {
+                        mCurrentSubtype = findLastResortApplicableSubtypeLocked(
+                                mRes, explicitlyOrImplicitlyEnabledSubtypes,
+                                SUBTYPE_MODE_KEYBOARD, null, true);
+                        if (mCurrentSubtype == null) {
                             mCurrentSubtype = findLastResortApplicableSubtypeLocked(
-                                    mRes, explicitlyOrImplicitlyEnabledSubtypes,
-                                    SUBTYPE_MODE_KEYBOARD, null, true);
-                            if (mCurrentSubtype == null) {
-                                mCurrentSubtype = findLastResortApplicableSubtypeLocked(
-                                        mRes, explicitlyOrImplicitlyEnabledSubtypes, null, null,
-                                        true);
-                            }
+                                    mRes, explicitlyOrImplicitlyEnabledSubtypes, null, null,
+                                    true);
                         }
                     }
                 } else {
-                    mCurrentSubtype =
-                            getSubtypes(mMethodMap.get(lastInputMethodId)).get(subtypeId);
+                    mCurrentSubtype = getSubtypes(imi).get(subtypeId);
                 }
             }
             return mCurrentSubtype;
@@ -2946,10 +3002,13 @@
         private final Context mContext;
         private final PackageManager mPm;
         private final InputMethodManagerService mImms;
+        private final String mSystemLocaleStr;
         public InputMethodAndSubtypeListManager(Context context, InputMethodManagerService imms) {
             mContext = context;
             mPm = context.getPackageManager();
             mImms = imms;
+            mSystemLocaleStr =
+                    imms.mLastSystemLocale != null ? imms.mLastSystemLocale.toString() : "";
         }
 
         private final TreeMap<InputMethodInfo, List<InputMethodSubtype>> mSortedImmis =
@@ -2979,7 +3038,7 @@
             }
             final int N = imList.size();
             final int currentSubtypeId = subtype != null
-                    ? mImms.getSubtypeIdFromHashCode(imi, subtype.hashCode())
+                    ? getSubtypeIdFromHashCode(imi, subtype.hashCode())
                     : NOT_A_SUBTYPE_ID;
             for (int i = 0; i < N; ++i) {
                 final ImeSubtypeListItem isli = imList.get(i);
@@ -3037,7 +3096,8 @@
                                     subtype.overridesImplicitlyEnabledSubtype() ? null
                                             : subtype.getDisplayName(mContext, imi.getPackageName(),
                                                     imi.getServiceInfo().applicationInfo);
-                            imList.add(new ImeSubtypeListItem(imeLabel, subtypeLabel, imi, j));
+                            imList.add(new ImeSubtypeListItem(imeLabel, subtypeLabel, imi, j,
+                                    subtype.getLocale(), mSystemLocaleStr));
 
                             // Removing this subtype from enabledSubtypeSet because we no longer
                             // need to add an entry of this subtype to imList to avoid duplicated
@@ -3046,9 +3106,11 @@
                         }
                     }
                 } else {
-                    imList.add(new ImeSubtypeListItem(imeLabel, null, imi, NOT_A_SUBTYPE_ID));
+                    imList.add(new ImeSubtypeListItem(imeLabel, null, imi, NOT_A_SUBTYPE_ID,
+                            null, mSystemLocaleStr));
                 }
             }
+            Collections.sort(imList);
             return imList;
         }
     }
@@ -3356,10 +3418,10 @@
             for (Pair<String, ArrayList<String>> enabledIme: enabledImes) {
                 if (enabledIme.first.equals(imeId)) {
                     final ArrayList<String> explicitlyEnabledSubtypes = enabledIme.second;
+                    final InputMethodInfo imi = mMethodMap.get(imeId);
                     if (explicitlyEnabledSubtypes.size() == 0) {
                         // If there are no explicitly enabled subtypes, applicable subtypes are
                         // enabled implicitly.
-                        InputMethodInfo imi = mMethodMap.get(imeId);
                         // If IME is enabled and no subtypes are enabled, applicable subtypes
                         // are enabled implicitly, so needs to treat them to be enabled.
                         if (imi != null && imi.getSubtypeCount() > 0) {
@@ -3379,7 +3441,17 @@
                         for (String s: explicitlyEnabledSubtypes) {
                             if (s.equals(subtypeHashCode)) {
                                 // If both imeId and subtypeId are enabled, return subtypeId.
-                                return s;
+                                try {
+                                    final int hashCode = Integer.valueOf(subtypeHashCode);
+                                    // Check whether the subtype id is valid or not
+                                    if (isValidSubtypeId(imi, hashCode)) {
+                                        return s;
+                                    } else {
+                                        return NOT_A_SUBTYPE_ID_STR;
+                                    }
+                                } catch (NumberFormatException e) {
+                                    return NOT_A_SUBTYPE_ID_STR;
+                                }
                             }
                         }
                     }
diff --git a/services/java/com/android/server/NotificationManagerService.java b/services/java/com/android/server/NotificationManagerService.java
index 663a031..52ba665 100755
--- a/services/java/com/android/server/NotificationManagerService.java
+++ b/services/java/com/android/server/NotificationManagerService.java
@@ -1046,7 +1046,7 @@
                 final boolean useDefaultVibrate =
                     (notification.defaults & Notification.DEFAULT_VIBRATE) != 0;
                 if ((useDefaultVibrate || notification.vibrate != null)
-                        && audioManager.shouldVibrate(AudioManager.VIBRATE_TYPE_NOTIFICATION)) {
+                        && !(audioManager.getRingerMode() == AudioManager.RINGER_MODE_SILENT)) {
                     mVibrateNotification = r;
 
                     mVibrator.vibrate(useDefaultVibrate ? DEFAULT_VIBRATE_PATTERN
diff --git a/services/java/com/android/server/NsdService.java b/services/java/com/android/server/NsdService.java
index f33bf8b..cc8e6a4 100644
--- a/services/java/com/android/server/NsdService.java
+++ b/services/java/com/android/server/NsdService.java
@@ -20,7 +20,7 @@
 import android.content.ContentResolver;
 import android.content.Intent;
 import android.content.pm.PackageManager;
-import android.net.nsd.DnsSdServiceInfo;
+import android.net.nsd.NsdServiceInfo;
 import android.net.nsd.DnsSdTxtRecord;
 import android.net.nsd.INsdManager;
 import android.net.nsd.NsdManager;
@@ -32,6 +32,7 @@
 import android.os.IBinder;
 import android.provider.Settings;
 import android.util.Slog;
+import android.util.SparseArray;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
@@ -72,13 +73,16 @@
      */
     private HashMap<Messenger, ClientInfo> mClients = new HashMap<Messenger, ClientInfo>();
 
+    /* A map from unique id to client info */
+    private SparseArray<ClientInfo> mIdToClientInfoMap= new SparseArray<ClientInfo>();
+
     private AsyncChannel mReplyChannel = new AsyncChannel();
 
     private int INVALID_ID = 0;
     private int mUniqueId = 1;
 
     private static final int BASE = Protocol.BASE_NSD_MANAGER;
-    private static final int CMD_TO_STRING_COUNT = NsdManager.STOP_RESOLVE - BASE + 1;
+    private static final int CMD_TO_STRING_COUNT = NsdManager.RESOLVE_SERVICE - BASE + 1;
     private static String[] sCmdToString = new String[CMD_TO_STRING_COUNT];
 
     static {
@@ -87,7 +91,6 @@
         sCmdToString[NsdManager.REGISTER_SERVICE - BASE] = "REGISTER";
         sCmdToString[NsdManager.UNREGISTER_SERVICE - BASE] = "UNREGISTER";
         sCmdToString[NsdManager.RESOLVE_SERVICE - BASE] = "RESOLVE";
-        sCmdToString[NsdManager.STOP_RESOLVE - BASE] = "STOP-RESOLVE";
     }
 
     private static String cmdToString(int cmd) {
@@ -101,9 +104,9 @@
 
     private class NsdStateMachine extends StateMachine {
 
-        private DefaultState mDefaultState = new DefaultState();
-        private DisabledState mDisabledState = new DisabledState();
-        private EnabledState mEnabledState = new EnabledState();
+        private final DefaultState mDefaultState = new DefaultState();
+        private final DisabledState mDisabledState = new DisabledState();
+        private final EnabledState mEnabledState = new EnabledState();
 
         @Override
         protected String getMessageInfo(Message msg) {
@@ -151,29 +154,26 @@
                         ac.connect(mContext, getHandler(), msg.replyTo);
                         break;
                     case NsdManager.DISCOVER_SERVICES:
-                        mReplyChannel.replyToMessage(msg, NsdManager.DISCOVER_SERVICES_FAILED,
-                                NsdManager.BUSY);
+                        replyToMessage(msg, NsdManager.DISCOVER_SERVICES_FAILED,
+                                NsdManager.FAILURE_INTERNAL_ERROR);
                        break;
                     case NsdManager.STOP_DISCOVERY:
-                            mReplyChannel.replyToMessage(msg, NsdManager.STOP_DISCOVERY_FAILED,
-                                    NsdManager.ERROR);
+                       replyToMessage(msg, NsdManager.STOP_DISCOVERY_FAILED,
+                               NsdManager.FAILURE_INTERNAL_ERROR);
                         break;
                     case NsdManager.REGISTER_SERVICE:
-                        mReplyChannel.replyToMessage(msg, NsdManager.REGISTER_SERVICE_FAILED,
-                                NsdManager.ERROR);
+                        replyToMessage(msg, NsdManager.REGISTER_SERVICE_FAILED,
+                                NsdManager.FAILURE_INTERNAL_ERROR);
                         break;
                     case NsdManager.UNREGISTER_SERVICE:
-                        mReplyChannel.replyToMessage(msg, NsdManager.UNREGISTER_SERVICE_FAILED,
-                                NsdManager.ERROR);
+                        replyToMessage(msg, NsdManager.UNREGISTER_SERVICE_FAILED,
+                                NsdManager.FAILURE_INTERNAL_ERROR);
                         break;
                     case NsdManager.RESOLVE_SERVICE:
-                        mReplyChannel.replyToMessage(msg, NsdManager.RESOLVE_SERVICE_FAILED,
-                                NsdManager.ERROR);
+                        replyToMessage(msg, NsdManager.RESOLVE_SERVICE_FAILED,
+                                NsdManager.FAILURE_INTERNAL_ERROR);
                         break;
-                    case NsdManager.STOP_RESOLVE:
-                        mReplyChannel.replyToMessage(msg, NsdManager.STOP_RESOLVE_FAILED,
-                                NsdManager.ERROR);
-                        break;
+                    case NsdManager.NATIVE_DAEMON_EVENT:
                     default:
                         Slog.e(TAG, "Unhandled " + msg);
                         return NOT_HANDLED;
@@ -217,11 +217,30 @@
                 }
             }
 
+            private boolean requestLimitReached(ClientInfo clientInfo) {
+                if (clientInfo.mClientIds.size() >= ClientInfo.MAX_LIMIT) {
+                    if (DBG) Slog.d(TAG, "Exceeded max outstanding requests " + clientInfo);
+                    return true;
+                }
+                return false;
+            }
+
+            private void storeRequestMap(int clientId, int globalId, ClientInfo clientInfo) {
+                clientInfo.mClientIds.put(clientId, globalId);
+                mIdToClientInfoMap.put(globalId, clientInfo);
+            }
+
+            private void removeRequestMap(int clientId, int globalId, ClientInfo clientInfo) {
+                clientInfo.mClientIds.remove(clientId);
+                mIdToClientInfoMap.remove(globalId);
+            }
+
             @Override
             public boolean processMessage(Message msg) {
                 ClientInfo clientInfo;
-                DnsSdServiceInfo servInfo;
+                NsdServiceInfo servInfo;
                 boolean result = HANDLED;
+                int id;
                 switch (msg.what) {
                   case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED:
                         //First client
@@ -244,111 +263,112 @@
                         break;
                     case NsdManager.DISCOVER_SERVICES:
                         if (DBG) Slog.d(TAG, "Discover services");
-                        servInfo = (DnsSdServiceInfo) msg.obj;
+                        servInfo = (NsdServiceInfo) msg.obj;
                         clientInfo = mClients.get(msg.replyTo);
-                        if (clientInfo.mDiscoveryId != INVALID_ID) {
-                            //discovery already in progress
-                            if (DBG) Slog.d(TAG, "discovery in progress");
-                            mReplyChannel.replyToMessage(msg, NsdManager.DISCOVER_SERVICES_FAILED,
-                                    NsdManager.ALREADY_ACTIVE);
+
+                        if (requestLimitReached(clientInfo)) {
+                            replyToMessage(msg, NsdManager.DISCOVER_SERVICES_FAILED,
+                                    NsdManager.FAILURE_MAX_LIMIT);
                             break;
                         }
-                        clientInfo.mDiscoveryId = getUniqueId();
-                        if (discoverServices(clientInfo.mDiscoveryId, servInfo.getServiceType())) {
-                            mReplyChannel.replyToMessage(msg, NsdManager.DISCOVER_SERVICES_STARTED);
+
+                        id = getUniqueId();
+                        if (discoverServices(id, servInfo.getServiceType())) {
+                            if (DBG) {
+                                Slog.d(TAG, "Discover " + msg.arg2 + " " + id +
+                                        servInfo.getServiceType());
+                            }
+                            storeRequestMap(msg.arg2, id, clientInfo);
+                            replyToMessage(msg, NsdManager.DISCOVER_SERVICES_STARTED, servInfo);
                         } else {
-                            mReplyChannel.replyToMessage(msg, NsdManager.DISCOVER_SERVICES_FAILED,
-                                    NsdManager.ERROR);
-                            clientInfo.mDiscoveryId = INVALID_ID;
+                            stopServiceDiscovery(id);
+                            replyToMessage(msg, NsdManager.DISCOVER_SERVICES_FAILED,
+                                    NsdManager.FAILURE_INTERNAL_ERROR);
                         }
                         break;
                     case NsdManager.STOP_DISCOVERY:
                         if (DBG) Slog.d(TAG, "Stop service discovery");
                         clientInfo = mClients.get(msg.replyTo);
-                        if (clientInfo.mDiscoveryId == INVALID_ID) {
-                            //already stopped
-                            if (DBG) Slog.d(TAG, "discovery already stopped");
-                            mReplyChannel.replyToMessage(msg, NsdManager.STOP_DISCOVERY_FAILED,
-                                    NsdManager.ALREADY_ACTIVE);
+
+                        try {
+                            id = clientInfo.mClientIds.get(msg.arg2).intValue();
+                        } catch (NullPointerException e) {
+                            replyToMessage(msg, NsdManager.STOP_DISCOVERY_FAILED,
+                                    NsdManager.FAILURE_INTERNAL_ERROR);
                             break;
                         }
-                        if (stopServiceDiscovery(clientInfo.mDiscoveryId)) {
-                            clientInfo.mDiscoveryId = INVALID_ID;
-                            mReplyChannel.replyToMessage(msg, NsdManager.STOP_DISCOVERY_SUCCEEDED);
+                        removeRequestMap(msg.arg2, id, clientInfo);
+                        if (stopServiceDiscovery(id)) {
+                            replyToMessage(msg, NsdManager.STOP_DISCOVERY_SUCCEEDED);
                         } else {
-                            mReplyChannel.replyToMessage(msg, NsdManager.STOP_DISCOVERY_FAILED,
-                                    NsdManager.ERROR);
+                            replyToMessage(msg, NsdManager.STOP_DISCOVERY_FAILED,
+                                    NsdManager.FAILURE_INTERNAL_ERROR);
                         }
                         break;
                     case NsdManager.REGISTER_SERVICE:
                         if (DBG) Slog.d(TAG, "Register service");
                         clientInfo = mClients.get(msg.replyTo);
-                        if (clientInfo.mRegisteredIds.size() >= ClientInfo.MAX_REG) {
-                            if (DBG) Slog.d(TAG, "register service exceeds limit");
-                            mReplyChannel.replyToMessage(msg, NsdManager.REGISTER_SERVICE_FAILED,
-                                    NsdManager.MAX_REGS_REACHED);
+                        if (requestLimitReached(clientInfo)) {
+                            replyToMessage(msg, NsdManager.REGISTER_SERVICE_FAILED,
+                                    NsdManager.FAILURE_MAX_LIMIT);
+                            break;
                         }
 
-                        int id = getUniqueId();
-                        if (registerService(id, (DnsSdServiceInfo) msg.obj)) {
-                            clientInfo.mRegisteredIds.add(id);
+                        id = getUniqueId();
+                        if (registerService(id, (NsdServiceInfo) msg.obj)) {
+                            if (DBG) Slog.d(TAG, "Register " + msg.arg2 + " " + id);
+                            storeRequestMap(msg.arg2, id, clientInfo);
+                            // Return success after mDns reports success
                         } else {
-                            mReplyChannel.replyToMessage(msg, NsdManager.REGISTER_SERVICE_FAILED,
-                                    NsdManager.ERROR);
+                            unregisterService(id);
+                            replyToMessage(msg, NsdManager.REGISTER_SERVICE_FAILED,
+                                    NsdManager.FAILURE_INTERNAL_ERROR);
                         }
                         break;
                     case NsdManager.UNREGISTER_SERVICE:
                         if (DBG) Slog.d(TAG, "unregister service");
                         clientInfo = mClients.get(msg.replyTo);
-                        int regId = msg.arg1;
-                        if (clientInfo.mRegisteredIds.remove(new Integer(regId)) &&
-                                unregisterService(regId)) {
-                            mReplyChannel.replyToMessage(msg,
-                                    NsdManager.UNREGISTER_SERVICE_SUCCEEDED);
-                        } else {
-                            mReplyChannel.replyToMessage(msg, NsdManager.UNREGISTER_SERVICE_FAILED,
-                                    NsdManager.ERROR);
+                        try {
+                            id = clientInfo.mClientIds.get(msg.arg2).intValue();
+                        } catch (NullPointerException e) {
+                            replyToMessage(msg, NsdManager.UNREGISTER_SERVICE_FAILED,
+                                    NsdManager.FAILURE_INTERNAL_ERROR);
+                            break;
                         }
-                        break;
-                    case NsdManager.UPDATE_SERVICE:
-                        if (DBG) Slog.d(TAG, "Update service");
-                        //TODO: implement
-                        mReplyChannel.replyToMessage(msg, NsdManager.UPDATE_SERVICE_FAILED);
+                        removeRequestMap(msg.arg2, id, clientInfo);
+                        if (unregisterService(id)) {
+                            replyToMessage(msg, NsdManager.UNREGISTER_SERVICE_SUCCEEDED);
+                        } else {
+                            replyToMessage(msg, NsdManager.UNREGISTER_SERVICE_FAILED,
+                                    NsdManager.FAILURE_INTERNAL_ERROR);
+                        }
                         break;
                     case NsdManager.RESOLVE_SERVICE:
                         if (DBG) Slog.d(TAG, "Resolve service");
-                        servInfo = (DnsSdServiceInfo) msg.obj;
+                        servInfo = (NsdServiceInfo) msg.obj;
                         clientInfo = mClients.get(msg.replyTo);
-                        if (clientInfo.mResolveId != INVALID_ID) {
-                            //first cancel existing resolve
-                            stopResolveService(clientInfo.mResolveId);
-                        }
 
-                        clientInfo.mResolveId = getUniqueId();
-                        if (!resolveService(clientInfo.mResolveId, servInfo)) {
-                            mReplyChannel.replyToMessage(msg, NsdManager.RESOLVE_SERVICE_FAILED,
-                                    NsdManager.ERROR);
-                            clientInfo.mResolveId = INVALID_ID;
-                        }
-                        break;
-                    case NsdManager.STOP_RESOLVE:
-                        if (DBG) Slog.d(TAG, "Stop resolve");
-                        clientInfo = mClients.get(msg.replyTo);
-                        if (clientInfo.mResolveId == INVALID_ID) {
-                            //already stopped
-                            if (DBG) Slog.d(TAG, "resolve already stopped");
-                            mReplyChannel.replyToMessage(msg, NsdManager.STOP_RESOLVE_FAILED,
-                                    NsdManager.ALREADY_ACTIVE);
+
+                        if (clientInfo.mResolvedService != null) {
+                            replyToMessage(msg, NsdManager.RESOLVE_SERVICE_FAILED,
+                                    NsdManager.FAILURE_ALREADY_ACTIVE);
                             break;
                         }
-                        if (stopResolveService(clientInfo.mResolveId)) {
-                            clientInfo.mResolveId = INVALID_ID;
-                            mReplyChannel.replyToMessage(msg, NsdManager.STOP_RESOLVE_SUCCEEDED);
+
+                        id = getUniqueId();
+                        if (resolveService(id, servInfo)) {
+                            clientInfo.mResolvedService = new NsdServiceInfo();
+                            storeRequestMap(msg.arg2, id, clientInfo);
                         } else {
-                            mReplyChannel.replyToMessage(msg, NsdManager.STOP_RESOLVE_FAILED,
-                                    NsdManager.ERROR);
+                            replyToMessage(msg, NsdManager.RESOLVE_SERVICE_FAILED,
+                                    NsdManager.FAILURE_INTERNAL_ERROR);
                         }
                         break;
+                    case NsdManager.NATIVE_DAEMON_EVENT:
+                        NativeEvent event = (NativeEvent) msg.obj;
+                        handleNativeEvent(event.code, event.raw,
+                                NativeDaemonEvent.unescapeArgs(event.raw));
+                        break;
                     default:
                         result = NOT_HANDLED;
                         break;
@@ -439,121 +459,144 @@
         public static final int SERVICE_GET_ADDR_SUCCESS    =   612;
     }
 
+    private class NativeEvent {
+        int code;
+        String raw;
+
+        NativeEvent(int code, String raw) {
+            this.code = code;
+            this.raw = raw;
+        }
+    }
+
     class NativeCallbackReceiver implements INativeDaemonConnectorCallbacks {
         public void onDaemonConnected() {
             mNativeDaemonConnected.countDown();
         }
 
         public boolean onEvent(int code, String raw, String[] cooked) {
-            ClientInfo clientInfo;
-            DnsSdServiceInfo servInfo;
-            int id = Integer.parseInt(cooked[1]);
-            switch (code) {
-                case NativeResponseCode.SERVICE_FOUND:
-                    /* NNN uniqueId serviceName regType domain */
-                    if (DBG) Slog.d(TAG, "SERVICE_FOUND Raw: " + raw);
-                    clientInfo = getClientByDiscovery(id);
-                    if (clientInfo == null) break;
+            // TODO: NDC translates a message to a callback, we could enhance NDC to
+            // directly interact with a state machine through messages
+            NativeEvent event = new NativeEvent(code, raw);
+            mNsdStateMachine.sendMessage(NsdManager.NATIVE_DAEMON_EVENT, event);
+            return true;
+        }
+    }
 
-                    servInfo = new DnsSdServiceInfo(cooked[2], cooked[3], null);
-                    clientInfo.mChannel.sendMessage(NsdManager.SERVICE_FOUND, servInfo);
+    private void handleNativeEvent(int code, String raw, String[] cooked) {
+        NsdServiceInfo servInfo;
+        int id = Integer.parseInt(cooked[1]);
+        ClientInfo clientInfo = mIdToClientInfoMap.get(id);
+        if (clientInfo == null) {
+            Slog.e(TAG, "Unique id with no client mapping: " + id);
+            return;
+        }
+
+        /* This goes in response as msg.arg2 */
+        int clientId = -1;
+        int keyId = clientInfo.mClientIds.indexOfValue(id);
+        if (keyId != -1) {
+            clientId = clientInfo.mClientIds.keyAt(keyId);
+        }
+        switch (code) {
+            case NativeResponseCode.SERVICE_FOUND:
+                /* NNN uniqueId serviceName regType domain */
+                if (DBG) Slog.d(TAG, "SERVICE_FOUND Raw: " + raw);
+                servInfo = new NsdServiceInfo(cooked[2], cooked[3], null);
+                clientInfo.mChannel.sendMessage(NsdManager.SERVICE_FOUND, 0,
+                        clientId, servInfo);
+                break;
+            case NativeResponseCode.SERVICE_LOST:
+                /* NNN uniqueId serviceName regType domain */
+                if (DBG) Slog.d(TAG, "SERVICE_LOST Raw: " + raw);
+                servInfo = new NsdServiceInfo(cooked[2], cooked[3], null);
+                clientInfo.mChannel.sendMessage(NsdManager.SERVICE_LOST, 0,
+                        clientId, servInfo);
+                break;
+            case NativeResponseCode.SERVICE_DISCOVERY_FAILED:
+                /* NNN uniqueId errorCode */
+                if (DBG) Slog.d(TAG, "SERVICE_DISC_FAILED Raw: " + raw);
+                clientInfo.mChannel.sendMessage(NsdManager.DISCOVER_SERVICES_FAILED,
+                        NsdManager.FAILURE_INTERNAL_ERROR, clientId);
+                break;
+            case NativeResponseCode.SERVICE_REGISTERED:
+                /* NNN regId serviceName regType */
+                if (DBG) Slog.d(TAG, "SERVICE_REGISTERED Raw: " + raw);
+                servInfo = new NsdServiceInfo(cooked[2], null, null);
+                clientInfo.mChannel.sendMessage(NsdManager.REGISTER_SERVICE_SUCCEEDED,
+                        id, clientId, servInfo);
+                break;
+            case NativeResponseCode.SERVICE_REGISTRATION_FAILED:
+                /* NNN regId errorCode */
+                if (DBG) Slog.d(TAG, "SERVICE_REGISTER_FAILED Raw: " + raw);
+                clientInfo.mChannel.sendMessage(NsdManager.REGISTER_SERVICE_FAILED,
+                        NsdManager.FAILURE_INTERNAL_ERROR, clientId);
+                break;
+            case NativeResponseCode.SERVICE_UPDATED:
+                /* NNN regId */
+                break;
+            case NativeResponseCode.SERVICE_UPDATE_FAILED:
+                /* NNN regId errorCode */
+                break;
+            case NativeResponseCode.SERVICE_RESOLVED:
+                /* NNN resolveId fullName hostName port txtlen txtdata */
+                if (DBG) Slog.d(TAG, "SERVICE_RESOLVED Raw: " + raw);
+                int index = cooked[2].indexOf(".");
+                if (index == -1) {
+                    Slog.e(TAG, "Invalid service found " + raw);
                     break;
-                case NativeResponseCode.SERVICE_LOST:
-                    /* NNN uniqueId serviceName regType domain */
-                    if (DBG) Slog.d(TAG, "SERVICE_LOST Raw: " + raw);
-                    clientInfo = getClientByDiscovery(id);
-                    if (clientInfo == null) break;
+                }
+                String name = cooked[2].substring(0, index);
+                String rest = cooked[2].substring(index);
+                String type = rest.replace(".local.", "");
 
-                    servInfo = new DnsSdServiceInfo(cooked[2], cooked[3], null);
-                    clientInfo.mChannel.sendMessage(NsdManager.SERVICE_LOST, servInfo);
-                    break;
-                case NativeResponseCode.SERVICE_DISCOVERY_FAILED:
-                    /* NNN uniqueId errorCode */
-                    if (DBG) Slog.d(TAG, "SERVICE_DISC_FAILED Raw: " + raw);
-                    clientInfo = getClientByDiscovery(id);
-                    if (clientInfo == null) break;
+                clientInfo.mResolvedService.setServiceName(name);
+                clientInfo.mResolvedService.setServiceType(type);
+                clientInfo.mResolvedService.setPort(Integer.parseInt(cooked[4]));
 
-                    clientInfo.mChannel.sendMessage(NsdManager.DISCOVER_SERVICES_FAILED,
-                            NsdManager.ERROR);
-                    break;
-                case NativeResponseCode.SERVICE_REGISTERED:
-                    /* NNN regId serviceName regType */
-                    if (DBG) Slog.d(TAG, "SERVICE_REGISTERED Raw: " + raw);
-                    clientInfo = getClientByRegistration(id);
-                    if (clientInfo == null) break;
-
-                    servInfo = new DnsSdServiceInfo(cooked[2], null, null);
-                    clientInfo.mChannel.sendMessage(NsdManager.REGISTER_SERVICE_SUCCEEDED,
-                            id, 0, servInfo);
-                    break;
-                case NativeResponseCode.SERVICE_REGISTRATION_FAILED:
-                    /* NNN regId errorCode */
-                    if (DBG) Slog.d(TAG, "SERVICE_REGISTER_FAILED Raw: " + raw);
-                    clientInfo = getClientByRegistration(id);
-                    if (clientInfo == null) break;
-
-                    clientInfo.mChannel.sendMessage(NsdManager.REGISTER_SERVICE_FAILED,
-                            NsdManager.ERROR);
-                    break;
-                case NativeResponseCode.SERVICE_UPDATED:
-                    /* NNN regId */
-                    break;
-                case NativeResponseCode.SERVICE_UPDATE_FAILED:
-                    /* NNN regId errorCode */
-                    break;
-                case NativeResponseCode.SERVICE_RESOLVED:
-                    /* NNN resolveId fullName hostName port txtlen txtdata */
-                    if (DBG) Slog.d(TAG, "SERVICE_RESOLVED Raw: " + raw);
-                    clientInfo = getClientByResolve(id);
-                    if (clientInfo == null) break;
-
-                    int index = cooked[2].indexOf(".");
-                    if (index == -1) {
-                        Slog.e(TAG, "Invalid service found " + raw);
-                        break;
-                    }
-                    String name = cooked[2].substring(0, index);
-                    String rest = cooked[2].substring(index);
-                    String type = rest.replace(".local.", "");
-
-                    clientInfo.mResolvedService = new DnsSdServiceInfo(name, type, null);
-                    clientInfo.mResolvedService.setPort(Integer.parseInt(cooked[4]));
-
-                    stopResolveService(id);
-                    getAddrInfo(id, cooked[3]);
-                    break;
-                case NativeResponseCode.SERVICE_RESOLUTION_FAILED:
-                case NativeResponseCode.SERVICE_GET_ADDR_FAILED:
-                    /* NNN resolveId errorCode */
-                    if (DBG) Slog.d(TAG, "SERVICE_RESOLVE_FAILED Raw: " + raw);
-                    clientInfo = getClientByResolve(id);
-                    if (clientInfo == null) break;
-
+                stopResolveService(id);
+                if (!getAddrInfo(id, cooked[3])) {
                     clientInfo.mChannel.sendMessage(NsdManager.RESOLVE_SERVICE_FAILED,
-                            NsdManager.ERROR);
-                    break;
-                case NativeResponseCode.SERVICE_GET_ADDR_SUCCESS:
-                    /* NNN resolveId hostname ttl addr */
-                    if (DBG) Slog.d(TAG, "SERVICE_GET_ADDR_SUCCESS Raw: " + raw);
-                    clientInfo = getClientByResolve(id);
-                    if (clientInfo == null || clientInfo.mResolvedService == null) break;
-
-                    try {
-                        clientInfo.mResolvedService.setHost(InetAddress.getByName(cooked[4]));
-                        clientInfo.mChannel.sendMessage(NsdManager.RESOLVE_SERVICE_SUCCEEDED,
-                                clientInfo.mResolvedService);
-                        clientInfo.mResolvedService = null;
-                        clientInfo.mResolveId = INVALID_ID;
-                    } catch (java.net.UnknownHostException e) {
-                        clientInfo.mChannel.sendMessage(NsdManager.RESOLVE_SERVICE_FAILED,
-                                NsdManager.ERROR);
-                    }
-                    stopGetAddrInfo(id);
-                    break;
-                default:
-                    break;
-            }
-            return false;
+                            NsdManager.FAILURE_INTERNAL_ERROR, clientId);
+                    mIdToClientInfoMap.remove(id);
+                    clientInfo.mResolvedService = null;
+                }
+                break;
+            case NativeResponseCode.SERVICE_RESOLUTION_FAILED:
+                /* NNN resolveId errorCode */
+                if (DBG) Slog.d(TAG, "SERVICE_RESOLVE_FAILED Raw: " + raw);
+                stopResolveService(id);
+                mIdToClientInfoMap.remove(id);
+                clientInfo.mResolvedService = null;
+                clientInfo.mChannel.sendMessage(NsdManager.RESOLVE_SERVICE_FAILED,
+                        NsdManager.FAILURE_INTERNAL_ERROR, clientId);
+                break;
+            case NativeResponseCode.SERVICE_GET_ADDR_FAILED:
+                /* NNN resolveId errorCode */
+                stopGetAddrInfo(id);
+                mIdToClientInfoMap.remove(id);
+                clientInfo.mResolvedService = null;
+                if (DBG) Slog.d(TAG, "SERVICE_RESOLVE_FAILED Raw: " + raw);
+                clientInfo.mChannel.sendMessage(NsdManager.RESOLVE_SERVICE_FAILED,
+                        NsdManager.FAILURE_INTERNAL_ERROR, clientId);
+                break;
+            case NativeResponseCode.SERVICE_GET_ADDR_SUCCESS:
+                /* NNN resolveId hostname ttl addr */
+                if (DBG) Slog.d(TAG, "SERVICE_GET_ADDR_SUCCESS Raw: " + raw);
+                try {
+                    clientInfo.mResolvedService.setHost(InetAddress.getByName(cooked[4]));
+                    clientInfo.mChannel.sendMessage(NsdManager.RESOLVE_SERVICE_SUCCEEDED,
+                            0, clientId, clientInfo.mResolvedService);
+                } catch (java.net.UnknownHostException e) {
+                    clientInfo.mChannel.sendMessage(NsdManager.RESOLVE_SERVICE_FAILED,
+                            NsdManager.FAILURE_INTERNAL_ERROR, clientId);
+                }
+                stopGetAddrInfo(id);
+                mIdToClientInfoMap.remove(id);
+                clientInfo.mResolvedService = null;
+                break;
+            default:
+                break;
         }
     }
 
@@ -579,7 +622,7 @@
         return true;
     }
 
-    private boolean registerService(int regId, DnsSdServiceInfo service) {
+    private boolean registerService(int regId, NsdServiceInfo service) {
         if (DBG) Slog.d(TAG, "registerService: " + regId + " " + service);
         try {
             //Add txtlen and txtdata
@@ -637,7 +680,7 @@
         return true;
     }
 
-    private boolean resolveService(int resolveId, DnsSdServiceInfo service) {
+    private boolean resolveService(int resolveId, NsdServiceInfo service) {
         if (DBG) Slog.d(TAG, "resolveService: " + resolveId + " " + service);
         try {
             mNativeConnector.execute("mdnssd", "resolve", resolveId, service.getServiceName(),
@@ -700,49 +743,52 @@
         mNsdStateMachine.dump(fd, pw, args);
     }
 
-    private ClientInfo getClientByDiscovery(int discoveryId) {
-        for (ClientInfo c: mClients.values()) {
-            if (c.mDiscoveryId == discoveryId) {
-                return c;
-            }
-        }
-        return null;
+    /* arg2 on the source message has an id that needs to be retained in replies
+     * see NsdManager for details */
+    private Message obtainMessage(Message srcMsg) {
+        Message msg = Message.obtain();
+        msg.arg2 = srcMsg.arg2;
+        return msg;
     }
 
-    private ClientInfo getClientByResolve(int resolveId) {
-        for (ClientInfo c: mClients.values()) {
-            if (c.mResolveId == resolveId) {
-                return c;
-            }
-        }
-        return null;
+    private void replyToMessage(Message msg, int what) {
+        if (msg.replyTo == null) return;
+        Message dstMsg = obtainMessage(msg);
+        dstMsg.what = what;
+        mReplyChannel.replyToMessage(msg, dstMsg);
     }
 
-    private ClientInfo getClientByRegistration(int regId) {
-        for (ClientInfo c: mClients.values()) {
-            if (c.mRegisteredIds.contains(regId)) {
-                return c;
-            }
-        }
-        return null;
+    private void replyToMessage(Message msg, int what, int arg1) {
+        if (msg.replyTo == null) return;
+        Message dstMsg = obtainMessage(msg);
+        dstMsg.what = what;
+        dstMsg.arg1 = arg1;
+        mReplyChannel.replyToMessage(msg, dstMsg);
+    }
+
+    private void replyToMessage(Message msg, int what, Object obj) {
+        if (msg.replyTo == null) return;
+        Message dstMsg = obtainMessage(msg);
+        dstMsg.what = what;
+        dstMsg.obj = obj;
+        mReplyChannel.replyToMessage(msg, dstMsg);
     }
 
     /* Information tracked per client */
     private class ClientInfo {
 
-        private static final int MAX_REG = 5;
+        private static final int MAX_LIMIT = 10;
         private AsyncChannel mChannel;
         private Messenger mMessenger;
-        private int mDiscoveryId;
-        private int mResolveId;
         /* Remembers a resolved service until getaddrinfo completes */
-        private DnsSdServiceInfo mResolvedService;
-        private ArrayList<Integer> mRegisteredIds = new ArrayList<Integer>();
+        private NsdServiceInfo mResolvedService;
+
+        /* A map from client id to unique id sent to mDns */
+        private SparseArray<Integer> mClientIds = new SparseArray<Integer>();
 
         private ClientInfo(AsyncChannel c, Messenger m) {
             mChannel = c;
             mMessenger = m;
-            mDiscoveryId = mResolveId = INVALID_ID;
             if (DBG) Slog.d(TAG, "New client, channel: " + c + " messenger: " + m);
         }
 
@@ -751,11 +797,10 @@
             StringBuffer sb = new StringBuffer();
             sb.append("mChannel ").append(mChannel).append("\n");
             sb.append("mMessenger ").append(mMessenger).append("\n");
-            sb.append("mDiscoveryId ").append(mDiscoveryId).append("\n");
-            sb.append("mResolveId ").append(mResolveId).append("\n");
             sb.append("mResolvedService ").append(mResolvedService).append("\n");
-            for(int regId : mRegisteredIds) {
-                sb.append("regId ").append(regId).append("\n");
+            for(int i = 0; i< mClientIds.size(); i++) {
+                sb.append("clientId ").append(mClientIds.keyAt(i));
+                sb.append(" mDnsId ").append(mClientIds.valueAt(i)).append("\n");
             }
             return sb.toString();
         }
diff --git a/services/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/java/com/android/server/accessibility/AccessibilityManagerService.java
index fbe4a83..e447218 100644
--- a/services/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -1251,7 +1251,6 @@
                         mContext, 0, new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS), 0));
             } else {
                 mCanRetrieveScreenContent = true;
-                mIncludeNotImportantViews = true;
                 mCanHandleGestures = true;
             }
             setDynamicallyConfigurableProperties(accessibilityServiceInfo);
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 1f7aeb0..40f64bf 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -4098,6 +4098,10 @@
         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
                 SystemClock.uptimeMillis());
         mWindowManager.enableScreenAfterBoot();
+
+        synchronized (this) {
+            updateEventDispatchingLocked();
+        }
     }
 
     public void showBootMessage(final CharSequence msg, final boolean always) {
@@ -6686,7 +6690,7 @@
 
         synchronized(this) {
             mWentToSleep = true;
-            mWindowManager.setEventDispatching(false);
+            updateEventDispatchingLocked();
 
             if (!mSleeping) {
                 mSleeping = true;
@@ -6712,7 +6716,7 @@
         
         synchronized(this) {
             mShuttingDown = true;
-            mWindowManager.setEventDispatching(false);
+            updateEventDispatchingLocked();
 
             if (mMainStack.mResumedActivity != null) {
                 mMainStack.stopIfSleepingLocked();
@@ -6776,11 +6780,15 @@
 
         synchronized(this) {
             mWentToSleep = false;
-            mWindowManager.setEventDispatching(true);
+            updateEventDispatchingLocked();
             comeOutOfSleepIfNeededLocked();
         }
     }
 
+    private void updateEventDispatchingLocked() {
+        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
+    }
+
     public void setLockScreenShown(boolean shown) {
         if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
                 != PackageManager.PERMISSION_GRANTED) {
@@ -11049,7 +11057,7 @@
                     updateOomAdjLocked(r.app);
                 }
                 int flags = 0;
-                if (si.deliveryCount > 0) {
+                if (si.deliveryCount > 1) {
                     flags |= Service.START_FLAG_RETRY;
                 }
                 if (si.doneExecutingCount > 0) {
@@ -13484,7 +13492,7 @@
                         parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK ||
                         parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP ||
                         (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
-                    parent.deliverNewIntentLocked(srec.app.uid, destIntent);
+                    parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent);
                 } else {
                     try {
                         ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo(
diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java
index 1e14f5b..c300411 100755
--- a/services/java/com/android/server/am/ActivityStack.java
+++ b/services/java/com/android/server/am/ActivityStack.java
@@ -1794,10 +1794,6 @@
                 mService.mWindowManager.prepareAppTransition(
                         WindowManagerPolicy.TRANSIT_NONE, keepCurTransition);
                 mNoAnimActivities.add(r);
-            } else if ((r.intent.getFlags()&Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0) {
-                mService.mWindowManager.prepareAppTransition(
-                        WindowManagerPolicy.TRANSIT_TASK_OPEN, keepCurTransition);
-                mNoAnimActivities.remove(r);
             } else {
                 mService.mWindowManager.prepareAppTransition(newTask
                         ? WindowManagerPolicy.TRANSIT_TASK_OPEN
diff --git a/services/java/com/android/server/location/GpsLocationProvider.java b/services/java/com/android/server/location/GpsLocationProvider.java
index 65b9627..ce53499 100755
--- a/services/java/com/android/server/location/GpsLocationProvider.java
+++ b/services/java/com/android/server/location/GpsLocationProvider.java
@@ -192,6 +192,11 @@
     // stop trying if we do not receive a fix within 60 seconds
     private static final int NO_FIX_TIMEOUT = 60 * 1000;
 
+    // if the fix interval is below this we leave GPS on,
+    // if above then we cycle the GPS driver.
+    // Typical hot TTTF is ~5 seconds, so 10 seconds seems sane.
+    private static final int GPS_POLLING_THRESHOLD_INTERVAL = 10 * 1000;
+
     // true if we are enabled
     private volatile boolean mEnabled;
     
@@ -842,7 +847,18 @@
     }
 
     public String getInternalState() {
-        return native_get_internal_state();
+        StringBuilder s = new StringBuilder();
+        s.append("  mFixInterval=").append(mFixInterval).append("\n");
+        s.append("  mEngineCapabilities=0x").append(Integer.toHexString(mEngineCapabilities)).append(" (");
+        if (hasCapability(GPS_CAPABILITY_SCHEDULING)) s.append("SCHED ");
+        if (hasCapability(GPS_CAPABILITY_MSB)) s.append("MSB ");
+        if (hasCapability(GPS_CAPABILITY_MSA)) s.append("MSA ");
+        if (hasCapability(GPS_CAPABILITY_SINGLE_SHOT)) s.append("SINGLE_SHOT ");
+        if (hasCapability(GPS_CAPABILITY_ON_DEMAND_TIME)) s.append("ON_DEMAND_TIME ");
+        s.append(")\n");
+
+        s.append(native_get_internal_state());
+        return s.toString();
     }
 
     private final class Listener implements IBinder.DeathRecipient {
@@ -1131,7 +1147,8 @@
             updateStatus(LocationProvider.AVAILABLE, mSvCount);
         }
 
-       if (!hasCapability(GPS_CAPABILITY_SCHEDULING) && mStarted && mFixInterval > 1000) {
+       if (!hasCapability(GPS_CAPABILITY_SCHEDULING) && mStarted &&
+               mFixInterval > GPS_POLLING_THRESHOLD_INTERVAL) {
             if (DEBUG) Log.d(TAG, "got fix, hibernating");
             hibernate();
         }
diff --git a/services/java/com/android/server/pm/PackageManagerService.java b/services/java/com/android/server/pm/PackageManagerService.java
index b5d0b60..7c14d49 100644
--- a/services/java/com/android/server/pm/PackageManagerService.java
+++ b/services/java/com/android/server/pm/PackageManagerService.java
@@ -53,6 +53,7 @@
 import android.content.IntentSender.SendIntentException;
 import android.content.pm.ActivityInfo;
 import android.content.pm.ApplicationInfo;
+import android.content.pm.ContainerEncryptionParams;
 import android.content.pm.FeatureInfo;
 import android.content.pm.IPackageDataObserver;
 import android.content.pm.IPackageDeleteObserver;
@@ -116,7 +117,6 @@
 import java.io.FileReader;
 import java.io.FilenameFilter;
 import java.io.IOException;
-import java.io.InputStream;
 import java.io.PrintWriter;
 import java.security.NoSuchAlgorithmException;
 import java.security.PublicKey;
@@ -128,7 +128,6 @@
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.Date;
-import java.util.Enumeration;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
@@ -136,9 +135,6 @@
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Set;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipFile;
-import java.util.zip.ZipOutputStream;
 
 import libcore.io.ErrnoException;
 import libcore.io.IoUtils;
@@ -1054,7 +1050,7 @@
             mSystemInstallObserver.startWatching();
             scanDirLI(mSystemAppDir, PackageParser.PARSE_IS_SYSTEM
                     | PackageParser.PARSE_IS_SYSTEM_DIR, scanMode, 0);
-            
+
             // Collect all vendor packages.
             mVendorAppDir = new File("/vendor/app");
             mVendorInstallObserver = new AppDirObserver(
@@ -1067,23 +1063,51 @@
             mInstaller.moveFiles();
 
             // Prune any system packages that no longer exist.
+            final List<String> possiblyDeletedSystemApps = new ArrayList<String>();
             if (!mOnlyCore) {
                 Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
                 while (psit.hasNext()) {
                     PackageSetting ps = psit.next();
-                    if ((ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) != 0
-                            && !mPackages.containsKey(ps.name)
-                            && !mSettings.mDisabledSysPackages.containsKey(ps.name)) {
+
+                    /*
+                     * If this is not a system app, it can't be a
+                     * disable system app.
+                     */
+                    if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
+                        continue;
+                    }
+
+                    /*
+                     * If the package is scanned, it's not erased.
+                     */
+                    if (mPackages.containsKey(ps.name)) {
+                        /*
+                         * If the system app is both scanned and in the
+                         * disabled packages list, then it must have been
+                         * added via OTA. Remove it from the currently
+                         * scanned package so the previously user-installed
+                         * application can be scanned.
+                         */
+                        if (mSettings.isDisabledSystemPackageLPr(ps.name)) {
+                            mPackages.remove(ps.name);
+                        }
+
+                        continue;
+                    }
+
+                    if (!mSettings.isDisabledSystemPackageLPr(ps.name)) {
                         psit.remove();
                         String msg = "System package " + ps.name
                                 + " no longer exists; wiping its data";
                         reportSettingsProblem(Log.WARN, msg);
                         mInstaller.remove(ps.name, 0);
                         sUserManager.removePackageForAllUsers(ps.name);
+                    } else {
+                        possiblyDeletedSystemApps.add(ps.name);
                     }
                 }
             }
-            
+
             mAppInstallDir = new File(dataDir, "app");
             //look for any incomplete package installations
             ArrayList<PackageSetting> deletePkgsList = mSettings.getListOfIncompleteInstallPackagesLPr();
@@ -1108,6 +1132,21 @@
                 mDrmAppInstallObserver.startWatching();
                 scanDirLI(mDrmAppPrivateInstallDir, PackageParser.PARSE_FORWARD_LOCK,
                         scanMode, 0);
+
+                /**
+                 * Remove disable package settings for any system apps
+                 * that were removed via an OTA.
+                 */
+                for (String deletedAppName : possiblyDeletedSystemApps) {
+                    PackageParser.Package deletedPkg = mPackages.get(deletedAppName);
+                    if (deletedPkg != null) {
+                        mSettings.removeDisabledSystemPackageLPw(deletedAppName);
+                        deletedPkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM;
+
+                        PackageSetting deletedPs = mSettings.mPackages.get(deletedAppName);
+                        deletedPs.pkgFlags &= ~ApplicationInfo.FLAG_SYSTEM;
+                    }
+                }
             } else {
                 mAppInstallObserver = null;
                 mDrmAppInstallObserver = null;
@@ -3047,8 +3086,7 @@
             // Check to see if this package could be hiding/updating a system
             // package.  Must look for it either under the original or real
             // package name depending on our state.
-            updatedPkg = mSettings.mDisabledSysPackages.get(
-                    ps != null ? ps.name : pkg.packageName);
+            updatedPkg = mSettings.getDisabledSystemPkgLPr(ps != null ? ps.name : pkg.packageName);
         }
         // First check if this is a system package that may involve an update
         if (updatedPkg != null && (parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0) {
@@ -3080,15 +3118,21 @@
                             + "reverting from " + ps.codePathString
                             + ": new version " + pkg.mVersionCode
                             + " better than installed " + ps.versionCode);
-                    InstallArgs args = new FileInstallArgs(ps.codePathString,
+                    InstallArgs args = createInstallArgs(ps.pkgFlags, ps.codePathString,
                             ps.resourcePathString, ps.nativeLibraryPathString);
-                    args.cleanUpResourcesLI();
-                    mSettings.enableSystemPackageLPw(ps.name);
+                    synchronized (mInstaller) {
+                        args.cleanUpResourcesLI();
+                    }
+                    synchronized (mPackages) {
+                        mSettings.enableSystemPackageLPw(ps.name);
+                    }
                 }
             }
         }
+
         if (updatedPkg != null) {
-            // An updated system app will not have the PARSE_IS_SYSTEM flag set initially
+            // An updated system app will not have the PARSE_IS_SYSTEM flag set
+            // initially
             parseFlags |= PackageParser.PARSE_IS_SYSTEM;
         }
         // Verify certificates against what was last scanned
@@ -3096,6 +3140,49 @@
             Slog.w(TAG, "Failed verifying certificates for package:" + pkg.packageName);
             return null;
         }
+
+        /*
+         * A new system app appeared, but we already had a non-system one of the
+         * same name installed earlier.
+         */
+        boolean shouldHideSystemApp = false;
+        if (updatedPkg == null && ps != null
+                && (parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0 && !isSystemApp(ps)) {
+            /*
+             * Check to make sure the signatures match first. If they don't,
+             * wipe the installed application and its data.
+             */
+            if (compareSignatures(ps.signatures.mSignatures, pkg.mSignatures)
+                    != PackageManager.SIGNATURE_MATCH) {
+                deletePackageLI(pkg.packageName, true, 0, null, false);
+                ps = null;
+            } else {
+                /*
+                 * If the newly-added system app is an older version than the
+                 * already installed version, hide it. It will be scanned later
+                 * and re-added like an update.
+                 */
+                if (pkg.mVersionCode < ps.versionCode) {
+                    shouldHideSystemApp = true;
+                } else {
+                    /*
+                     * The newly found system app is a newer version that the
+                     * one previously installed. Simply remove the
+                     * already-installed application and replace it with our own
+                     * while keeping the application data.
+                     */
+                    Slog.w(TAG, "Package " + ps.name + " at " + scanFile + "reverting from "
+                            + ps.codePathString + ": new version " + pkg.mVersionCode
+                            + " better than installed " + ps.versionCode);
+                    InstallArgs args = createInstallArgs(ps.pkgFlags, ps.codePathString,
+                            ps.resourcePathString, ps.nativeLibraryPathString);
+                    synchronized (mInstaller) {
+                        args.cleanUpResourcesLI();
+                    }
+                }
+            }
+        }
+
         // The apk is forward locked (not public) if its code and resources
         // are kept in different files.
         // TODO grab this value from PackageSettings
@@ -3119,7 +3206,27 @@
         // Set application objects path explicitly.
         setApplicationInfoPaths(pkg, codePath, resPath);
         // Note that we invoke the following method only if we are about to unpack an application
-        return scanPackageLI(pkg, parseFlags, scanMode | SCAN_UPDATE_SIGNATURE, currentTime);
+        PackageParser.Package scannedPkg = scanPackageLI(pkg, parseFlags, scanMode
+                | SCAN_UPDATE_SIGNATURE, currentTime);
+
+        /*
+         * If the system app should be overridden by a previously installed
+         * data, hide the system app now and let the /data/app scan pick it up
+         * again.
+         */
+        if (shouldHideSystemApp) {
+            synchronized (mPackages) {
+                /*
+                 * We have to grant systems permissions before we hide, because
+                 * grantPermissions will assume the package update is trying to
+                 * expand its permissions.
+                 */
+                grantPermissionsLPw(pkg, true);
+                mSettings.disableSystemPackageLPw(pkg.packageName);
+            }
+        }
+
+        return scannedPkg;
     }
 
     private static void setApplicationInfoPaths(PackageParser.Package pkg, String destCodePath,
@@ -3527,7 +3634,7 @@
                 mTransferedPackages.add(pkg.packageName);
             }
             
-            if (mSettings.mDisabledSysPackages.get(pkg.packageName) != null) {
+            if (mSettings.isDisabledSystemPackageLPr(pkg.packageName)) {
                 pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
             }
 
@@ -5133,13 +5240,13 @@
             final Uri packageURI, final IPackageInstallObserver observer, final int flags,
             final String installerPackageName) {
         installPackageWithVerification(packageURI, observer, flags, installerPackageName, null,
-                null);
+                null, null);
     }
 
     @Override
     public void installPackageWithVerification(Uri packageURI, IPackageInstallObserver observer,
             int flags, String installerPackageName, Uri verificationURI,
-            ManifestDigest manifestDigest) {
+            ManifestDigest manifestDigest, ContainerEncryptionParams encryptionParams) {
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null);
 
         final int uid = Binder.getCallingUid();
@@ -5157,7 +5264,7 @@
 
         final Message msg = mHandler.obtainMessage(INIT_COPY);
         msg.obj = new InstallParams(packageURI, observer, filteredFlags, installerPackageName,
-                verificationURI, manifestDigest);
+                verificationURI, manifestDigest, encryptionParams);
         mHandler.sendMessage(msg);
     }
 
@@ -5560,22 +5667,27 @@
     class InstallParams extends HandlerParams {
         final IPackageInstallObserver observer;
         int flags;
-        final Uri packageURI;
+
+        private final Uri mPackageURI;
         final String installerPackageName;
         final Uri verificationURI;
         final ManifestDigest manifestDigest;
         private InstallArgs mArgs;
         private int mRet;
+        private File mTempPackage;
+        final ContainerEncryptionParams encryptionParams;
 
         InstallParams(Uri packageURI,
                 IPackageInstallObserver observer, int flags,
-                String installerPackageName, Uri verificationURI, ManifestDigest manifestDigest) {
-            this.packageURI = packageURI;
+                String installerPackageName, Uri verificationURI, ManifestDigest manifestDigest,
+                ContainerEncryptionParams encryptionParams) {
+            this.mPackageURI = packageURI;
             this.flags = flags;
             this.observer = observer;
             this.installerPackageName = installerPackageName;
             this.verificationURI = verificationURI;
             this.manifestDigest = manifestDigest;
+            this.encryptionParams = encryptionParams;
         }
 
         private int installLocationPolicy(PackageInfoLite pkgLite, int flags) {
@@ -5655,16 +5767,51 @@
                     lowThreshold = dsm.getMemoryLowThreshold();
                 }
 
-                // Remote call to find out default install location
                 try {
-                    mContext.grantUriPermission(DEFAULT_CONTAINER_PACKAGE, packageURI,
+                    mContext.grantUriPermission(DEFAULT_CONTAINER_PACKAGE, mPackageURI,
                             Intent.FLAG_GRANT_READ_URI_PERMISSION);
-                    pkgLite = mContainerService.getMinimalPackageInfo(packageURI, flags,
-                            lowThreshold);
-                } finally {
-                    mContext.revokeUriPermission(packageURI, Intent.FLAG_GRANT_READ_URI_PERMISSION);
-                }
 
+                    final File packageFile;
+                    if (encryptionParams != null || !"file".equals(mPackageURI.getScheme())) {
+                        ParcelFileDescriptor out = null;
+
+                        mTempPackage = createTempPackageFile(mDrmAppPrivateInstallDir);
+                        if (mTempPackage != null) {
+                            try {
+                                out = ParcelFileDescriptor.open(mTempPackage,
+                                        ParcelFileDescriptor.MODE_READ_WRITE);
+                            } catch (FileNotFoundException e) {
+                                Slog.e(TAG, "Failed to create temporary file for : " + mPackageURI);
+                            }
+
+                            // Make a temporary file for decryption.
+                            ret = mContainerService
+                                    .copyResource(mPackageURI, encryptionParams, out);
+
+                            packageFile = mTempPackage;
+
+                            FileUtils.setPermissions(packageFile.getAbsolutePath(),
+                                    FileUtils.S_IRUSR | FileUtils.S_IWUSR | FileUtils.S_IROTH,
+                                    -1, -1);
+                        } else {
+                            packageFile = null;
+                        }
+                    } else {
+                        packageFile = new File(mPackageURI.getPath());
+                    }
+
+                    if (packageFile != null) {
+                        // Remote call to find out default install location
+                        pkgLite = mContainerService.getMinimalPackageInfo(
+                                packageFile.getAbsolutePath(), flags, lowThreshold);
+                    }
+                } finally {
+                    mContext.revokeUriPermission(mPackageURI,
+                            Intent.FLAG_GRANT_READ_URI_PERMISSION);
+                }
+            }
+
+            if (ret == PackageManager.INSTALL_SUCCEEDED) {
                 int loc = pkgLite.recommendedInstallLocation;
                 if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION) {
                     ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
@@ -5708,8 +5855,9 @@
                 final int requiredUid = mRequiredVerifierPackage == null ? -1
                         : getPackageUid(mRequiredVerifierPackage, 0);
                 if (requiredUid != -1 && isVerificationEnabled()) {
-                    final Intent verification = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
-                    verification.setDataAndType(packageURI, PACKAGE_MIME_TYPE);
+                    final Intent verification = new Intent(
+                            Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
+                    verification.setDataAndType(getPackageUri(), PACKAGE_MIME_TYPE);
                     verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
 
                     final List<ResolveInfo> receivers = queryIntentReceivers(verification, null,
@@ -5812,6 +5960,13 @@
             if (mArgs != null) {
                 processPendingInstall(mArgs, mRet);
             }
+
+            if (mTempPackage != null) {
+                if (!mTempPackage.delete()) {
+                    Slog.w(TAG, "Couldn't delete temporary file: "
+                            + mTempPackage.getAbsolutePath());
+                }
+            }
         }
 
         @Override
@@ -5823,6 +5978,14 @@
         public boolean isForwardLocked() {
             return (flags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
         }
+
+        public Uri getPackageUri() {
+            if (mTempPackage != null) {
+                return Uri.fromFile(mTempPackage);
+            } else {
+                return mPackageURI;
+            }
+        }
     }
 
     /*
@@ -6037,8 +6200,8 @@
         boolean created = false;
 
         FileInstallArgs(InstallParams params) {
-            super(params.packageURI, params.observer, params.flags, params.installerPackageName,
-                    params.manifestDigest);
+            super(params.getPackageUri(), params.observer, params.flags,
+                    params.installerPackageName, params.manifestDigest);
         }
 
         FileInstallArgs(String fullCodePath, String fullResourcePath, String nativeLibraryPath) {
@@ -6128,7 +6291,7 @@
             try {
                 mContext.grantUriPermission(DEFAULT_CONTAINER_PACKAGE, packageURI,
                         Intent.FLAG_GRANT_READ_URI_PERMISSION);
-                ret = imcs.copyResource(packageURI, out);
+                ret = imcs.copyResource(packageURI, null, out);
             } finally {
                 IoUtils.closeQuietly(out);
                 mContext.revokeUriPermission(packageURI, Intent.FLAG_GRANT_READ_URI_PERMISSION);
@@ -6315,8 +6478,8 @@
         String libraryPath;
 
         AsecInstallArgs(InstallParams params) {
-            super(params.packageURI, params.observer, params.flags, params.installerPackageName,
-                    params.manifestDigest);
+            super(params.getPackageUri(), params.observer, params.flags,
+                    params.installerPackageName, params.manifestDigest);
         }
 
         AsecInstallArgs(String fullCodePath, String fullResourcePath, String nativeLibraryPath,
@@ -7105,6 +7268,10 @@
         return (info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
     }
 
+    private static boolean isSystemApp(PackageSetting ps) {
+        return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0;
+    }
+
     private static boolean isUpdatedSystemApp(PackageParser.Package pkg) {
         return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
     }
diff --git a/services/java/com/android/server/pm/Settings.java b/services/java/com/android/server/pm/Settings.java
index c79f815..da0ec33 100644
--- a/services/java/com/android/server/pm/Settings.java
+++ b/services/java/com/android/server/pm/Settings.java
@@ -102,7 +102,7 @@
     final HashMap<String, PackageSetting> mPackages =
             new HashMap<String, PackageSetting>();
     // List of replaced system applications
-    final HashMap<String, PackageSetting> mDisabledSysPackages =
+    private final HashMap<String, PackageSetting> mDisabledSysPackages =
         new HashMap<String, PackageSetting>();
 
     // These are the last platform API version we were using for
@@ -280,6 +280,14 @@
         return ret;
     }
 
+    boolean isDisabledSystemPackageLPr(String name) {
+        return mDisabledSysPackages.containsKey(name);
+    }
+
+    void removeDisabledSystemPackageLPw(String name) {
+        mDisabledSysPackages.remove(name);
+    }
+
     PackageSetting addPackageLPw(String name, String realName, File codePath, File resourcePath,
             String nativeLibraryPathString, int uid, int vc, int pkgFlags) {
         PackageSetting p = mPackages.get(name);
diff --git a/services/java/com/android/server/wm/InputMonitor.java b/services/java/com/android/server/wm/InputMonitor.java
index c28cfa2..c4bb519 100644
--- a/services/java/com/android/server/wm/InputMonitor.java
+++ b/services/java/com/android/server/wm/InputMonitor.java
@@ -41,7 +41,9 @@
     private boolean mInputDispatchFrozen;
     
     // When true, input dispatch proceeds normally.  Otherwise all events are dropped.
-    private boolean mInputDispatchEnabled = true;
+    // Initially false, so that input does not get dispatched until boot is finished at
+    // which point the ActivityManager will enable dispatching.
+    private boolean mInputDispatchEnabled;
 
     // When true, need to call updateInputWindowsLw().
     private boolean mUpdateInputWindowsNeeded = true;
diff --git a/services/java/com/android/server/wm/WindowAnimator.java b/services/java/com/android/server/wm/WindowAnimator.java
index 2e817ca..5536559 100644
--- a/services/java/com/android/server/wm/WindowAnimator.java
+++ b/services/java/com/android/server/wm/WindowAnimator.java
@@ -85,6 +85,15 @@
         mPolicy = policy;
     }
 
+    void hideWallpapersLocked() {
+        for (final WindowToken token : mService.mWallpaperTokens) {
+            for (final WindowState wallpaper : token.windows) {
+                wallpaper.mWinAnimator.hide();
+            }
+            token.hidden = true;
+        }
+    }
+
     private void testWallpaperAndBackgroundLocked() {
         if (mWindowDetachedWallpaper != mDetachedWallpaper) {
             if (WindowManagerService.DEBUG_WALLPAPER) Slog.v(TAG,
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index 8eda9ca..8957edf 100755
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -3430,9 +3430,6 @@
         synchronized(mWindowMap) {
             WindowToken wtoken = mTokenMap.remove(token);
             if (wtoken != null) {
-                if (wtoken.windowType == TYPE_INPUT_METHOD && mInputMethodWindow != null) {
-                    mPolicy.setLastInputMethodWindowLw(mInputMethodWindow, mInputMethodTarget);
-                }
                 boolean delayed = false;
                 if (!wtoken.hidden) {
                     wtoken.hidden = true;
@@ -3825,7 +3822,8 @@
         synchronized(mWindowMap) {
             if (DEBUG_APP_TRANSITIONS) Slog.v(
                     TAG, "Prepare app transition: transit=" + transit
-                    + " mNextAppTransition=" + mNextAppTransition);
+                    + " mNextAppTransition=" + mNextAppTransition
+                    + "\nCallers=" + Debug.getCallers(3));
             if (okToDisplay()) {
                 if (mNextAppTransition == WindowManagerPolicy.TRANSIT_UNSET
                         || mNextAppTransition == WindowManagerPolicy.TRANSIT_NONE) {
@@ -4237,7 +4235,7 @@
                     e = new RuntimeException();
                     e.fillInStackTrace();
                 }
-                Slog.v(TAG, "setAppVisibility(" + token + ", " + visible
+                Slog.v(TAG, "setAppVisibility(" + token + ", visible=" + visible
                         + "): mNextAppTransition=" + mNextAppTransition
                         + " hidden=" + wtoken.hidden
                         + " hiddenRequested=" + wtoken.hiddenRequested, e);
@@ -5149,7 +5147,7 @@
                     //Slog.i(TAG, "******* TELLING SURFACE FLINGER WE ARE BOOTED!");
                     Parcel data = Parcel.obtain();
                     data.writeInterfaceToken("android.ui.ISurfaceComposer");
-                    surfaceFlinger.transact(IBinder.FIRST_CALL_TRANSACTION,
+                    surfaceFlinger.transact(IBinder.FIRST_CALL_TRANSACTION, // BOOT_FINISHED
                                             data, null, 0);
                     data.recycle();
                 }
@@ -6673,8 +6671,7 @@
         public static final int SET_TRANSPARENT_REGION = ANIMATOR_WHAT_OFFSET + 1;
         public static final int SET_WALLPAPER_OFFSET = ANIMATOR_WHAT_OFFSET + 2;
         public static final int SET_DIM_PARAMETERS = ANIMATOR_WHAT_OFFSET + 3;
-        public static final int SET_MOVE_ANIMATION = ANIMATOR_WHAT_OFFSET + 4;
-        public static final int CLEAR_PENDING_ACTIONS = ANIMATOR_WHAT_OFFSET + 5;
+        public static final int CLEAR_PENDING_ACTIONS = ANIMATOR_WHAT_OFFSET + 4;
 
         private Session mLastReportedHold;
 
@@ -7158,18 +7155,6 @@
                     break;
                 }
 
-                case SET_MOVE_ANIMATION: {
-                    WindowAnimator.SetAnimationParams params =
-                            (WindowAnimator.SetAnimationParams) msg.obj;
-                    WindowStateAnimator winAnimator = params.mWinAnimator;
-                    winAnimator.setAnimation(params.mAnimation);
-                    winAnimator.mAnimDw = params.mAnimDw;
-                    winAnimator.mAnimDh = params.mAnimDh;
-
-                    scheduleAnimationLocked();
-                    break;
-                }
-
                 case CLEAR_PENDING_ACTIONS: {
                     mAnimator.clearPendingActions();
                     break;
@@ -7866,8 +7851,10 @@
                 mToTopApps.clear();
             }
 
+            // if wallpaper is animating in or out set oldWallpaper to null else to wallpaper
             WindowState oldWallpaper =
                     mWallpaperTarget != null && mWallpaperTarget.mWinAnimator.isAnimating()
+                        && !mWallpaperTarget.mWinAnimator.isDummyAnimation()
                     ? null : mWallpaperTarget;
 
             adjustWallpaperWindowsLocked();
@@ -8415,9 +8402,6 @@
                     winAnimator.setAnimation(a);
                     winAnimator.mAnimDw = w.mLastFrame.left - w.mFrame.left;
                     winAnimator.mAnimDh = w.mLastFrame.top - w.mFrame.top;
-                } else {
-                    winAnimator.mAnimDw = innerDw;
-                    winAnimator.mAnimDh = innerDh;
                 }
 
                 //Slog.i(TAG, "Window " + this + " clearing mContentChanged - done placing");
@@ -9266,6 +9250,15 @@
         }
     }
 
+    // It is assumed that this method is called only by InputMethodManagerService.
+    public void saveLastInputMethodWindowForTransition() {
+        synchronized (mWindowMap) {
+            if (mInputMethodWindow != null) {
+                mPolicy.setLastInputMethodWindowLw(mInputMethodWindow, mInputMethodTarget);
+            }
+        }
+    }
+
     @Override
     public boolean hasNavigationBar() {
         return mPolicy.hasNavigationBar();
diff --git a/services/java/com/android/server/wm/WindowStateAnimator.java b/services/java/com/android/server/wm/WindowStateAnimator.java
index 4f08d92..642de73 100644
--- a/services/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/java/com/android/server/wm/WindowStateAnimator.java
@@ -177,6 +177,13 @@
                                 || atoken.inPendingTransaction));
     }
 
+    /** Is the window animating the DummyAnimation? */
+    boolean isDummyAnimation() {
+        final AppWindowToken atoken = mWin.mAppToken;
+        return atoken != null
+                && atoken.mAppAnimator.animation == AppWindowAnimator.sDummyAnimation;
+    }
+
     /** Is this window currently animating? */
     boolean isWindowAnimating() {
         return mAnimation != null;
@@ -363,19 +370,33 @@
             mWin.mDestroying = true;
             if (WindowState.SHOW_TRANSACTIONS) WindowManagerService.logSurface(
                 mWin, "HIDE (finishExit)", null);
-            mSurfaceShown = false;
-            try {
-                mSurface.hide();
-            } catch (RuntimeException e) {
-                Slog.w(TAG, "Error hiding surface in " + this, e);
-            }
-            mLastHidden = true;
+            hide();
         }
         mWin.mExiting = false;
         if (mWin.mRemoveOnExit) {
             mService.mPendingRemove.add(mWin);
             mWin.mRemoveOnExit = false;
         }
+        if (mService.mWallpaperTarget == mWin) {
+            mAnimator.hideWallpapersLocked();
+        }
+    }
+
+    void hide() {
+        if (!mLastHidden) {
+            //dump();
+            mLastHidden = true;
+            if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(mWin,
+                    "HIDE (performLayout)", null);
+            if (mSurface != null) {
+                mSurfaceShown = false;
+                try {
+                    mSurface.hide();
+                } catch (RuntimeException e) {
+                    Slog.w(TAG, "Exception hiding surface in " + mWin);
+                }
+            }
+        }
     }
 
     boolean finishDrawingLocked() {
@@ -987,20 +1008,7 @@
         setSurfaceBoundaries(recoveringMemory);
 
         if (w.mAttachedHidden || !w.isReadyForDisplay()) {
-            if (!mLastHidden) {
-                //dump();
-                mLastHidden = true;
-                if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(w,
-                        "HIDE (performLayout)", null);
-                if (mSurface != null) {
-                    mSurfaceShown = false;
-                    try {
-                        mSurface.hide();
-                    } catch (RuntimeException e) {
-                        Slog.w(TAG, "Exception hiding surface in " + w);
-                    }
-                }
-            }
+            hide();
             // If we are waiting for this window to handle an
             // orientation change, well, it is hidden, so
             // doesn't really matter.  Note that this does
diff --git a/telephony/java/android/telephony/PhoneNumberUtils.java b/telephony/java/android/telephony/PhoneNumberUtils.java
index 5afe56c..f740718 100644
--- a/telephony/java/android/telephony/PhoneNumberUtils.java
+++ b/telephony/java/android/telephony/PhoneNumberUtils.java
@@ -1711,12 +1711,8 @@
             return false;
         }
 
-        // STOPSHIP: remove this after figuring out issue 5914560, 6383850.
         Log.d(LOG_TAG, "System property doesn't provide any emergency numbers."
-                + " Use embedded logic for determining emergency numbers."
-                + " number: " + toLogSafePhoneNumber(number)
-                + ", Iso: " + defaultCountryIso
-                + ", useExactMatch: " + useExactMatch);
+                + " Use embedded logic for determining ones.");
 
         // No ecclist system property, so use our own list.
         if (defaultCountryIso != null) {
@@ -1735,21 +1731,6 @@
         }
     }
 
-    private static String toLogSafePhoneNumber(String number) {
-        // Do exactly same thing as Uri#toSafeString() does, which will enable us to compare
-        // sanitized phone numbers.
-        StringBuilder builder = new StringBuilder();
-        for (int i = 0; i < number.length(); i++) {
-            char c = number.charAt(i);
-            if (c == '-' || c == '@' || c == '.') {
-                builder.append(c);
-            } else {
-                builder.append('x');
-            }
-        }
-        return builder.toString();
-    }
-
     /**
      * Checks if a given number is an emergency number for the country that the user is in. The
      * current country is determined using the CountryDetector.
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaLteServiceStateTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaLteServiceStateTracker.java
index 297c2ac..0a40c75 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaLteServiceStateTracker.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaLteServiceStateTracker.java
@@ -343,10 +343,16 @@
                 // new ERI text
                 if (ss.getState() == ServiceState.STATE_IN_SERVICE) {
                     eriText = phone.getCdmaEriText();
+                } else if (ss.getState() == ServiceState.STATE_POWER_OFF) {
+                    eriText = phone.mIccRecords.getServiceProviderName();
+                    if (TextUtils.isEmpty(eriText)) {
+                        // Sets operator alpha property by retrieving from
+                        // build-time system property
+                        eriText = SystemProperties.get("ro.cdma.home.operator.alpha");
+                    }
                 } else {
                     // Note that ServiceState.STATE_OUT_OF_SERVICE is valid used
-                    // for
-                    // mRegistrationState 0,2,3 and 4
+                    // for mRegistrationState 0,2,3 and 4
                     eriText = phone.getContext()
                             .getText(com.android.internal.R.string.roamingTextSearching).toString();
                 }
diff --git a/test-runner/src/android/test/mock/MockContentProvider.java b/test-runner/src/android/test/mock/MockContentProvider.java
index a8c388e..1e41416 100644
--- a/test-runner/src/android/test/mock/MockContentProvider.java
+++ b/test-runner/src/android/test/mock/MockContentProvider.java
@@ -21,7 +21,6 @@
 import android.content.ContentProviderResult;
 import android.content.ContentValues;
 import android.content.Context;
-import android.content.ICancellationSignal;
 import android.content.IContentProvider;
 import android.content.OperationApplicationException;
 import android.content.pm.PathPermission;
@@ -31,6 +30,7 @@
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.IBinder;
+import android.os.ICancellationSignal;
 import android.os.ParcelFileDescriptor;
 import android.os.RemoteException;
 
diff --git a/test-runner/src/android/test/mock/MockIContentProvider.java b/test-runner/src/android/test/mock/MockIContentProvider.java
index 1aa0448..9fcfc22 100644
--- a/test-runner/src/android/test/mock/MockIContentProvider.java
+++ b/test-runner/src/android/test/mock/MockIContentProvider.java
@@ -21,12 +21,12 @@
 import android.content.ContentValues;
 import android.content.EntityIterator;
 import android.content.IContentProvider;
-import android.content.ICancellationSignal;
 import android.content.res.AssetFileDescriptor;
 import android.database.Cursor;
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.IBinder;
+import android.os.ICancellationSignal;
 import android.os.ParcelFileDescriptor;
 import android.os.RemoteException;
 
diff --git a/test-runner/src/android/test/mock/MockPackageManager.java b/test-runner/src/android/test/mock/MockPackageManager.java
index 5610134..86689f3 100644
--- a/test-runner/src/android/test/mock/MockPackageManager.java
+++ b/test-runner/src/android/test/mock/MockPackageManager.java
@@ -22,6 +22,7 @@
 import android.content.IntentSender;
 import android.content.pm.ActivityInfo;
 import android.content.pm.ApplicationInfo;
+import android.content.pm.ContainerEncryptionParams;
 import android.content.pm.FeatureInfo;
 import android.content.pm.IPackageDataObserver;
 import android.content.pm.IPackageDeleteObserver;
@@ -29,6 +30,7 @@
 import android.content.pm.IPackageMoveObserver;
 import android.content.pm.IPackageStatsObserver;
 import android.content.pm.InstrumentationInfo;
+import android.content.pm.ManifestDigest;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.PermissionGroupInfo;
@@ -36,16 +38,12 @@
 import android.content.pm.ProviderInfo;
 import android.content.pm.ResolveInfo;
 import android.content.pm.ServiceInfo;
-import android.content.pm.Signature;
 import android.content.pm.UserInfo;
-import android.content.pm.ManifestDigest;
 import android.content.pm.VerifierDeviceIdentity;
-import android.content.pm.VerifierInfo;
 import android.content.res.Resources;
 import android.content.res.XmlResourceParser;
 import android.graphics.drawable.Drawable;
 import android.net.Uri;
-import android.os.RemoteException;
 
 import java.util.List;
 
@@ -565,7 +563,7 @@
     @Override
     public void installPackageWithVerification(Uri packageURI, IPackageInstallObserver observer,
             int flags, String installerPackageName, Uri verificationURI,
-            ManifestDigest manifestDigest) {
+            ManifestDigest manifestDigest, ContainerEncryptionParams encryptionParams) {
         throw new UnsupportedOperationException();
     }
 
diff --git a/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java
index 16f1575..9aed8c8 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java
@@ -307,6 +307,11 @@
     }
 
     @LayoutlibDelegate
+    /*package*/ static void freeTextLayoutCaches() {
+        // nothing to be done here yet.
+    }
+
+    @LayoutlibDelegate
     /*package*/ static int initRaster(int nativeBitmapOrZero) {
         if (nativeBitmapOrZero > 0) {
             // get the Bitmap from the int
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContentProvider.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContentProvider.java
index e28866e..f770ccc 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContentProvider.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContentProvider.java
@@ -19,7 +19,6 @@
 import android.content.ContentProviderOperation;
 import android.content.ContentProviderResult;
 import android.content.ContentValues;
-import android.content.ICancellationSignal;
 import android.content.IContentProvider;
 import android.content.OperationApplicationException;
 import android.content.res.AssetFileDescriptor;
@@ -27,6 +26,7 @@
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.IBinder;
+import android.os.ICancellationSignal;
 import android.os.ParcelFileDescriptor;
 import android.os.RemoteException;
 
diff --git a/tools/localize/Android.mk b/tools/localize/Android.mk
deleted file mode 100644
index 5ec9feb..0000000
--- a/tools/localize/Android.mk
+++ /dev/null
@@ -1,55 +0,0 @@
-# 
-# Copyright 2006 The Android Open Source Project
-#
-# Android Asset Packaging Tool
-#
-
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := \
-    file_utils.cpp \
-    localize.cpp \
-    merge_res_and_xliff.cpp \
-    res_check.cpp \
-    xmb.cpp \
-    Configuration.cpp \
-    Perforce.cpp \
-    SourcePos.cpp \
-    Values.cpp \
-    ValuesFile.cpp \
-    XLIFFFile.cpp \
-    XMLHandler.cpp
-
-LOCAL_C_INCLUDES := \
-    external/expat/lib \
-    build/libs/host/include
-
-LOCAL_CFLAGS += -g -O0
-
-LOCAL_STATIC_LIBRARIES := \
-    libexpat \
-    libhost \
-    libutils \
-	libcutils
-    
-ifeq ($(HOST_OS),linux)
-LOCAL_LDLIBS += -lrt -ldl -lpthread
-endif
-
-
-LOCAL_MODULE := localize
-
-ifeq (a,a)
-    LOCAL_CFLAGS += -DLOCALIZE_WITH_TESTS
-    LOCAL_SRC_FILES += \
-        test.cpp \
-        localize_test.cpp \
-        merge_res_and_xliff_test.cpp \
-        Perforce_test.cpp \
-        ValuesFile_test.cpp \
-        XLIFFFile_test.cpp \
-        XMLHandler_test.cpp
-endif
-
-include $(BUILD_HOST_EXECUTABLE)
diff --git a/tools/localize/Configuration.cpp b/tools/localize/Configuration.cpp
deleted file mode 100644
index 56addbd..0000000
--- a/tools/localize/Configuration.cpp
+++ /dev/null
@@ -1,76 +0,0 @@
-#include "Configuration.h"
-#include <string.h>
-
-int
-Configuration::Compare(const Configuration& that) const
-{
-    int n;
-
-    n = locale.compare(that.locale);
-    if (n != 0) return n;
-
-    n = vendor.compare(that.vendor);
-    if (n != 0) return n;
-
-    n = orientation.compare(that.orientation);
-    if (n != 0) return n;
-
-    n = density.compare(that.density);
-    if (n != 0) return n;
-
-    n = touchscreen.compare(that.touchscreen);
-    if (n != 0) return n;
-
-    n = keyboard.compare(that.keyboard);
-    if (n != 0) return n;
-
-    n = navigation.compare(that.navigation);
-    if (n != 0) return n;
-
-    n = screenSize.compare(that.screenSize);
-    if (n != 0) return n;
-
-    return 0;
-}
-
-string
-Configuration::ToString() const
-{
-    string s;
-    if (locale.length() > 0) {
-        if (s.length() > 0) {
-            s += "-";
-        }
-        s += locale;
-    }
-    return s;
-}
-
-bool
-split_locale(const string& in, string* language, string* region)
-{
-    const int len = in.length();
-    if (len == 2) {
-        if (isalpha(in[0]) && isalpha(in[1])) {
-            *language = in;
-            region->clear();
-            return true;
-        } else {
-            return false;
-        }
-    }
-    else if (len == 5) {
-        if (isalpha(in[0]) && isalpha(in[1]) && (in[2] == '_' || in[2] == '-')
-                && isalpha(in[3]) && isalpha(in[4])) {
-            language->assign(in.c_str(), 2);
-            region->assign(in.c_str()+3, 2);
-            return true;
-        } else {
-            return false;
-        }
-    }
-    else {
-        return false;
-    }
-}
-
diff --git a/tools/localize/Configuration.h b/tools/localize/Configuration.h
deleted file mode 100644
index f91bf04..0000000
--- a/tools/localize/Configuration.h
+++ /dev/null
@@ -1,38 +0,0 @@
-#ifndef CONFIGURATION_H
-#define CONFIGURATION_H
-
-#include <string>
-
-using namespace std;
-
-struct Configuration
-{
-    string locale;
-    string vendor;
-    string orientation;
-    string density;
-    string touchscreen;
-    string keyboard;
-    string navigation;
-    string screenSize;
-
-    // Compare two configurations
-    int Compare(const Configuration& that) const;
-
-    inline bool operator<(const Configuration& that) const { return Compare(that) < 0; }
-    inline bool operator<=(const Configuration& that) const { return Compare(that) <= 0; }
-    inline bool operator==(const Configuration& that) const { return Compare(that) == 0; }
-    inline bool operator!=(const Configuration& that) const { return Compare(that) != 0; }
-    inline bool operator>=(const Configuration& that) const { return Compare(that) >= 0; }
-    inline bool operator>(const Configuration& that) const { return Compare(that) > 0; }
-
-    // Parse a directory name, like "values-en-rUS".  Return the first segment in resType.
-    bool ParseDiectoryName(const string& dir, string* resType);
-
-    string ToString() const;
-};
-
-bool split_locale(const string& in, string* language, string* region);
-
-
-#endif // CONFIGURATION_H
diff --git a/tools/localize/Perforce.cpp b/tools/localize/Perforce.cpp
deleted file mode 100644
index ae11231..0000000
--- a/tools/localize/Perforce.cpp
+++ /dev/null
@@ -1,234 +0,0 @@
-#include "Perforce.h"
-#include "log.h"
-#include <string.h>
-#include <cstdio>
-#include <stdlib.h>
-#include <sstream>
-#include <sys/types.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/wait.h>
-#include <cstdio>
-
-using namespace std;
-
-extern char** environ;
-
-int
-Perforce::RunCommand(const string& cmd, string* result, bool printOnFailure)
-{
-    int err;
-    int outPipe[2];
-    int errPipe[2];
-    pid_t pid;
-
-    log_printf("Perforce::RunCommand: %s\n", cmd.c_str());
-
-    err = pipe(outPipe);
-    err |= pipe(errPipe);
-    if (err == -1) {
-        printf("couldn't create pipe. exiting.\n");
-        exit(1);
-        return -1;
-    }
-
-    pid = fork();
-    if (pid == -1) {
-        printf("couldn't fork. eixiting\n");
-        exit(1);
-        return -1;
-    }
-    else if (pid == 0) {
-        char const* args[] = {
-            "/bin/sh",
-            "-c",
-            cmd.c_str(),
-            NULL
-        };
-        close(outPipe[0]);
-        close(errPipe[0]);
-        dup2(outPipe[1], 1);
-        dup2(errPipe[1], 2);
-        execve(args[0], (char* const*)args, environ);
-        // done
-    }
-
-    close(outPipe[1]);
-    close(errPipe[1]);
-
-    result->clear();
-
-    char buf[1024];
-
-    // stdout
-    while (true) {
-        size_t amt = read(outPipe[0], buf, sizeof(buf));
-        result->append(buf, amt);
-        if (amt <= 0) {
-            break;
-        }
-    }
-
-    // stderr -- the messages are short so it ought to just fit in the buffer
-    string error;
-    while (true) {
-        size_t amt = read(errPipe[0], buf, sizeof(buf));
-        error.append(buf, amt);
-        if (amt <= 0) {
-            break;
-        }
-    }
-
-    close(outPipe[0]);
-    close(errPipe[0]);
-
-    waitpid(pid, &err, 0);
-    if (WIFEXITED(err)) {
-        err = WEXITSTATUS(err);
-    } else {
-        err = -1;
-    }
-    if (err != 0 && printOnFailure) {
-        write(2, error.c_str(), error.length());
-    }
-    return err;
-}
-
-int
-Perforce::GetResourceFileNames(const string& version, const string& base,
-                                const vector<string>& apps, vector<string>* results,
-                                bool printOnFailure)
-{
-    int err;
-    string text;
-    stringstream cmd;
-
-    cmd << "p4 files";
-
-    const size_t I = apps.size();
-    for (size_t i=0; i<I; i++) {
-        cmd << " \"" << base << '/' << apps[i] << "/res/values/strings.xml@" << version << '"';
-    }
-
-    err = RunCommand(cmd.str(), &text, printOnFailure);
-
-    const char* str = text.c_str();
-    while (*str) {
-        const char* lineend = strchr(str, '\n');
-        if (lineend == str) {
-            str++;
-            continue;
-        }
-        if (lineend-str > 1023) {
-            fprintf(stderr, "line too long!\n");
-            return 1;
-        }
-
-        string s(str, lineend-str);
-
-        char filename[1024];
-        char edit[1024];
-        int count = sscanf(str, "%[^#]#%*d - %s change %*d %*[^\n]\n", filename, edit);
-
-        if (count == 2 && 0 != strcmp("delete", edit)) {
-            results->push_back(string(filename));
-        }
-
-        str = lineend + 1;
-    }
-
-    return err;
-}
-
-int
-Perforce::GetFile(const string& file, const string& version, string* result,
-        bool printOnFailure)
-{
-    stringstream cmd;
-    cmd << "p4 print -q \"" << file << '@' << version << '"';
-    return RunCommand(cmd.str(), result, printOnFailure);
-}
-
-string
-Perforce::GetCurrentChange(bool printOnFailure)
-{
-    int err;
-    string text;
-
-    err = RunCommand("p4 changes -m 1 \\#have", &text, printOnFailure);
-    if (err != 0) {
-        return "";
-    }
-
-    long long n;
-    int count = sscanf(text.c_str(), "Change %lld on", &n);
-    if (count != 1) {
-        return "";
-    }
-
-    char result[100];
-    sprintf(result, "%lld", n);
-
-    return string(result);
-}
-
-static int
-do_files(const string& op, const vector<string>& files, bool printOnFailure)
-{
-    string text;
-    stringstream cmd;
-
-    cmd << "p4 " << op;
-
-    const size_t I = files.size();
-    for (size_t i=0; i<I; i++) {
-        cmd << " \"" << files[i] << "\"";
-    }
-
-    return Perforce::RunCommand(cmd.str(), &text, printOnFailure);
-}
-
-int
-Perforce::EditFiles(const vector<string>& files, bool printOnFailure)
-{
-    return do_files("edit", files, printOnFailure);
-}
-
-int
-Perforce::AddFiles(const vector<string>& files, bool printOnFailure)
-{
-    return do_files("add", files, printOnFailure);
-}
-
-int
-Perforce::DeleteFiles(const vector<string>& files, bool printOnFailure)
-{
-    return do_files("delete", files, printOnFailure);
-}
-
-string
-Perforce::Where(const string& depotPath, bool printOnFailure)
-{
-    int err;
-    string text;
-    string cmd = "p4 where ";
-    cmd += depotPath;
-
-    err = RunCommand(cmd, &text, printOnFailure);
-    if (err != 0) {
-        return "";
-    }
-
-    size_t index = text.find(' ');
-    if (index == text.npos) {
-        return "";
-    }
-    index = text.find(' ', index+1)+1;
-    if (index == text.npos) {
-        return "";
-    }
-
-    return text.substr(index, text.length()-index-1);
-}
-
diff --git a/tools/localize/Perforce.h b/tools/localize/Perforce.h
deleted file mode 100644
index 522797d..0000000
--- a/tools/localize/Perforce.h
+++ /dev/null
@@ -1,25 +0,0 @@
-#ifndef PERFORCE_H
-#define PERFORCE_H
-
-#include <string>
-#include <vector>
-
-using namespace std;
-
-class Perforce
-{
-public:
-    static int RunCommand(const string& cmd, string* result, bool printOnFailure);
-    static int GetResourceFileNames(const string& version, const string& base,
-                                const vector<string>& apps, vector<string>* result,
-                                bool printOnFailure);
-    static int GetFile(const string& file, const string& version, string* result,
-                                bool printOnFailure);
-    static string GetCurrentChange(bool printOnFailure);
-    static int EditFiles(const vector<string>& filename, bool printOnFailure);
-    static int AddFiles(const vector<string>& files, bool printOnFailure);
-    static int DeleteFiles(const vector<string>& files, bool printOnFailure);
-    static string Where(const string& depotPath, bool printOnFailure);
-};
-
-#endif // PERFORCE_H
diff --git a/tools/localize/Perforce_test.cpp b/tools/localize/Perforce_test.cpp
deleted file mode 100644
index 142b20e..0000000
--- a/tools/localize/Perforce_test.cpp
+++ /dev/null
@@ -1,62 +0,0 @@
-#include "Perforce.h"
-#include <stdio.h>
-
-static int
-RunCommand_test()
-{
-    string result;
-    int err = Perforce::RunCommand("p4 help csommands", &result, true);
-    printf("err=%d result=[[%s]]\n", err, result.c_str());
-    return 0;
-}
-
-static int
-GetResourceFileNames_test()
-{
-    vector<string> results;
-    vector<string> apps;
-    apps.push_back("apps/common");
-    apps.push_back("apps/Contacts");
-    int err = Perforce::GetResourceFileNames("43019", "//device", apps, &results, true);
-    if (err != 0) {
-        return err;
-    }
-    if (results.size() != 2) {
-        return 1;
-    }
-    if (results[0] != "//device/apps/common/res/values/strings.xml") {
-        return 1;
-    }
-    if (results[1] != "//device/apps/Contacts/res/values/strings.xml") {
-        return 1;
-    }
-    if (false) {
-        for (size_t i=0; i<results.size(); i++) {
-            printf("[%zd] '%s'\n", i, results[i].c_str());
-        }
-    }
-    return 0;
-}
-
-static int
-GetFile_test()
-{
-    string result;
-    int err = Perforce::GetFile("//device/Makefile", "296", &result, true);
-    printf("err=%d result=[[%s]]\n", err, result.c_str());
-    return 0;
-}
-
-int
-Perforce_test()
-{
-    bool all = false;
-    int err = 0;
-
-    if (all) err |= RunCommand_test();
-    if (all) err |= GetResourceFileNames_test();
-    if (all) err |= GetFile_test();
-
-    return err;
-}
-
diff --git a/tools/localize/SourcePos.cpp b/tools/localize/SourcePos.cpp
deleted file mode 100644
index 184bfe0a..0000000
--- a/tools/localize/SourcePos.cpp
+++ /dev/null
@@ -1,168 +0,0 @@
-#include "SourcePos.h"
-
-#include <stdarg.h>
-#include <cstdio>
-#include <set>
-#include <cstdio>
-
-using namespace std;
-
-const SourcePos GENERATED_POS("<generated>", -1);
-
-// ErrorPos
-// =============================================================================
-struct ErrorPos
-{
-    string file;
-    int line;
-    string error;
-
-    ErrorPos();
-    ErrorPos(const ErrorPos& that);
-    ErrorPos(const string& file, int line, const string& error);
-    ~ErrorPos();
-    bool operator<(const ErrorPos& rhs) const;
-    bool operator==(const ErrorPos& rhs) const;
-    ErrorPos& operator=(const ErrorPos& rhs);
-
-    void Print(FILE* to) const;
-};
-
-static set<ErrorPos> g_errors;
-
-ErrorPos::ErrorPos()
-{
-}
-
-ErrorPos::ErrorPos(const ErrorPos& that)
-    :file(that.file),
-     line(that.line),
-     error(that.error)
-{
-}
-
-ErrorPos::ErrorPos(const string& f, int l, const string& e)
-    :file(f),
-     line(l),
-     error(e)
-{
-}
-
-ErrorPos::~ErrorPos()
-{
-}
-
-bool
-ErrorPos::operator<(const ErrorPos& rhs) const
-{
-    if (this->file < rhs.file) return true;
-    if (this->file == rhs.file) {
-        if (this->line < rhs.line) return true;
-        if (this->line == rhs.line) {
-            if (this->error < rhs.error) return true;
-        }
-    }
-    return false;
-}
-
-bool
-ErrorPos::operator==(const ErrorPos& rhs) const
-{
-    return this->file == rhs.file
-            && this->line == rhs.line
-            && this->error == rhs.error;
-}
-
-ErrorPos&
-ErrorPos::operator=(const ErrorPos& rhs)
-{
-    this->file = rhs.file;
-    this->line = rhs.line;
-    this->error = rhs.error;
-    return *this;
-}
-
-void
-ErrorPos::Print(FILE* to) const
-{
-    if (this->line >= 0) {
-        fprintf(to, "%s:%d: %s\n", this->file.c_str(), this->line, this->error.c_str());
-    } else {
-        fprintf(to, "%s: %s\n", this->file.c_str(), this->error.c_str());
-    }
-}
-
-// SourcePos
-// =============================================================================
-SourcePos::SourcePos(const string& f, int l)
-    : file(f), line(l)
-{
-}
-
-SourcePos::SourcePos(const SourcePos& that)
-    : file(that.file), line(that.line)
-{
-}
-
-SourcePos::SourcePos()
-    : file("???", 0)
-{
-}
-
-SourcePos::~SourcePos()
-{
-}
-
-string
-SourcePos::ToString() const
-{
-    char buf[1024];
-    if (this->line >= 0) {
-        snprintf(buf, sizeof(buf)-1, "%s:%d", this->file.c_str(), this->line);
-    } else {
-        snprintf(buf, sizeof(buf)-1, "%s:", this->file.c_str());
-    }
-    buf[sizeof(buf)-1] = '\0';
-    return string(buf);
-}
-
-int
-SourcePos::Error(const char* fmt, ...) const
-{
-    int retval=0;
-    char buf[1024];
-    va_list ap;
-    va_start(ap, fmt);
-    retval = vsnprintf(buf, sizeof(buf), fmt, ap);
-    va_end(ap);
-    char* p = buf + retval - 1;
-    while (p > buf && *p == '\n') {
-        *p = '\0';
-        p--;
-    }
-    ErrorPos err(this->file, this->line, string(buf));
-    if (g_errors.find(err) == g_errors.end()) {
-        err.Print(stderr);
-        g_errors.insert(err);
-    }
-    return retval;
-}
-
-bool
-SourcePos::HasErrors()
-{
-    return g_errors.size() > 0;
-}
-
-void
-SourcePos::PrintErrors(FILE* to)
-{
-    set<ErrorPos>::const_iterator it;
-    for (it=g_errors.begin(); it!=g_errors.end(); it++) {
-        it->Print(to);
-    }
-}
-
-
-
-
diff --git a/tools/localize/SourcePos.h b/tools/localize/SourcePos.h
deleted file mode 100644
index 5027129..0000000
--- a/tools/localize/SourcePos.h
+++ /dev/null
@@ -1,28 +0,0 @@
-#ifndef SOURCEPOS_H
-#define SOURCEPOS_H
-
-#include <string>
-
-using namespace std;
-
-class SourcePos
-{
-public:
-    string file;
-    int line;
-
-    SourcePos(const string& f, int l);
-    SourcePos(const SourcePos& that);
-    SourcePos();
-    ~SourcePos();
-
-    string ToString() const;
-    int Error(const char* fmt, ...) const;
-
-    static bool HasErrors();
-    static void PrintErrors(FILE* to);
-};
-
-extern const SourcePos GENERATED_POS;
-
-#endif // SOURCEPOS_H
diff --git a/tools/localize/Values.cpp b/tools/localize/Values.cpp
deleted file mode 100644
index 8623b97..0000000
--- a/tools/localize/Values.cpp
+++ /dev/null
@@ -1,135 +0,0 @@
-#include "Values.h"
-#include <stdlib.h>
-#include <cstdio>
-
-
-// =====================================================================================
-StringResource::StringResource(const SourcePos& p, const string& f, const Configuration& c, 
-                    const string& i, int ix, XMLNode* v, const int ve, const string& vs,
-                    const string& cmnt)
-    :pos(p),
-     file(f),
-     config(c),
-     id(i),
-     index(ix),
-     value(v),
-     version(ve),
-     versionString(vs),
-     comment(cmnt)
-{
-}
-
-StringResource::StringResource()
-    :pos(),
-     file(),
-     config(),
-     id(),
-     index(-1),
-     value(NULL),
-     version(),
-     versionString(),
-     comment()
-{
-}
-
-StringResource::StringResource(const StringResource& that)
-    :pos(that.pos),
-     file(that.file),
-     config(that.config),
-     id(that.id),
-     index(that.index),
-     value(that.value),
-     version(that.version),
-     versionString(that.versionString),
-     comment(that.comment)
-{
-}
-
-int
-StringResource::Compare(const StringResource& that) const
-{
-    if (file != that.file) {
-        return file < that.file ? -1 : 1;
-    }
-    if (id != that.id) {
-        return id < that.id ? -1 : 1;
-    }
-    if (index != that.index) {
-        return index - that.index;
-    }
-    if (config != that.config) {
-        return config < that.config ? -1 : 1;
-    }
-    if (version != that.version) {
-        return version < that.version ? -1 : 1;
-    }
-    return 0;
-}
-
-string
-StringResource::TypedID() const
-{
-    string result;
-    if (index < 0) {
-        result = "string:";
-    } else {
-        char n[20];
-        sprintf(n, "%d:", index);
-        result = "array:";
-        result += n;
-    }
-    result += id;
-    return result;
-}
-
-static void
-split(const string& raw, vector<string>*parts)
-{
-    size_t index = 0;
-    while (true) {
-        size_t next = raw.find(':', index);
-        if (next != raw.npos) {
-            parts->push_back(string(raw, index, next-index));
-            index = next + 1;
-        } else {
-            parts->push_back(string(raw, index));
-            break;
-        }
-    }
-}
-
-bool
-StringResource::ParseTypedID(const string& raw, string* id, int* index)
-{
-    vector<string> parts;
-    split(raw, &parts);
-
-    const size_t N = parts.size();
-
-    for (size_t i=0; i<N; i++) {
-        if (parts[i].length() == 0) {
-            return false;
-        }
-    }
-
-    if (N == 2 && parts[0] == "string") {
-        *id = parts[1];
-        *index = -1;
-        return true;
-    }
-    else if (N == 3 && parts[0] == "array") {
-        char* p;
-        int n = (int)strtol(parts[1].c_str(), &p, 0);
-        if (*p == '\0') {
-            *id = parts[2];
-            *index = n;
-            return true;
-        } else {
-            return false;
-        }
-    }
-    else {
-        return false;
-    }
-}
-
diff --git a/tools/localize/Values.h b/tools/localize/Values.h
deleted file mode 100644
index 0a60b6d..0000000
--- a/tools/localize/Values.h
+++ /dev/null
@@ -1,48 +0,0 @@
-#ifndef VALUES_H
-#define VALUES_H
-
-#include "Configuration.h"
-#include "XMLHandler.h"
-
-#include <string>
-
-using namespace std;
-
-enum {
-    CURRENT_VERSION,
-    OLD_VERSION
-};
-
-struct StringResource
-{
-    StringResource();
-    StringResource(const SourcePos& pos, const string& file, const Configuration& config, 
-                    const string& id, int index, XMLNode* value,
-                    int version, const string& versionString, const string& comment = "");
-    StringResource(const StringResource& that);
-
-    // Compare two configurations
-    int Compare(const StringResource& that) const;
-
-    inline bool operator<(const StringResource& that) const { return Compare(that) < 0; }
-    inline bool operator<=(const StringResource& that) const { return Compare(that) <= 0; }
-    inline bool operator==(const StringResource& that) const { return Compare(that) == 0; }
-    inline bool operator!=(const StringResource& that) const { return Compare(that) != 0; }
-    inline bool operator>=(const StringResource& that) const { return Compare(that) >= 0; }
-    inline bool operator>(const StringResource& that) const { return Compare(that) > 0; }
-
-    string TypedID() const;
-    static bool ParseTypedID(const string& typed, string* id, int* index);
-
-    SourcePos pos;
-    string file;
-    Configuration config;
-    string id;
-    int index;
-    XMLNode* value;
-    int version;
-    string versionString;
-    string comment;
-};
-
-#endif // VALUES_H
diff --git a/tools/localize/ValuesFile.cpp b/tools/localize/ValuesFile.cpp
deleted file mode 100644
index bd6f494..0000000
--- a/tools/localize/ValuesFile.cpp
+++ /dev/null
@@ -1,266 +0,0 @@
-#include "ValuesFile.h"
-
-#include "XMLHandler.h"
-
-#include <algorithm>
-#include <fcntl.h>
-#include <expat.h>
-#include <unistd.h>
-#include <errno.h>
-
-using namespace std;
-
-const char* const ANDROID_XMLNS = "http://schemas.android.com/apk/res/android";
-const char* const XLIFF_XMLNS = "urn:oasis:names:tc:xliff:document:1.2";
-
-const char *const NS_MAP[] = {
-    "android", ANDROID_XMLNS,
-    "xliff", XLIFF_XMLNS,
-    NULL, NULL
-};
-
-const XMLNamespaceMap ANDROID_NAMESPACES(NS_MAP);
-
-
-// =====================================================================================
-class ArrayHandler : public XMLHandler
-{
-public:
-    ArrayHandler(ValuesFile* vf, int version, const string& versionString, const string& id);
-
-    virtual int OnStartElement(const SourcePos& pos, const string& ns, const string& name,
-                                const vector<XMLAttribute>& attrs, XMLHandler** next);
-    virtual int OnText(const SourcePos& pos, const string& text);
-    virtual int OnComment(const SourcePos& pos, const string& text);
-
-private:
-    ValuesFile* m_vf;
-    int m_version;
-    int m_index;
-    string m_versionString;
-    string m_id;
-    string m_comment;
-};
-
-ArrayHandler::ArrayHandler(ValuesFile* vf, int version, const string& versionString,
-                            const string& id)
-    :m_vf(vf),
-     m_version(version),
-     m_index(0),
-     m_versionString(versionString),
-     m_id(id)
-{
-}
-
-int
-ArrayHandler::OnStartElement(const SourcePos& pos, const string& ns, const string& name,
-                                const vector<XMLAttribute>& attrs, XMLHandler** next)
-{
-    if (ns == "" && name == "item") {
-        XMLNode* node = XMLNode::NewElement(pos, ns, name, attrs, XMLNode::EXACT);
-        m_vf->AddString(StringResource(pos, pos.file, m_vf->GetConfiguration(),
-                                            m_id, m_index, node, m_version, m_versionString,
-                                            trim_string(m_comment)));
-        *next = new NodeHandler(node, XMLNode::EXACT);
-        m_index++;
-        m_comment = "";
-        return 0;
-    } else {
-        pos.Error("invalid <%s> element inside <array>\n", name.c_str());
-        return 1;
-    }
-}
-
-int
-ArrayHandler::OnText(const SourcePos& pos, const string& text)
-{
-    return 0;
-}
-
-int
-ArrayHandler::OnComment(const SourcePos& pos, const string& text)
-{
-    m_comment += text;
-    return 0;
-}
-
-// =====================================================================================
-class ValuesHandler : public XMLHandler
-{
-public:
-    ValuesHandler(ValuesFile* vf, int version, const string& versionString);
-
-    virtual int OnStartElement(const SourcePos& pos, const string& ns, const string& name,
-                                const vector<XMLAttribute>& attrs, XMLHandler** next);
-    virtual int OnText(const SourcePos& pos, const string& text);
-    virtual int OnComment(const SourcePos& pos, const string& text);
-
-private:
-    ValuesFile* m_vf;
-    int m_version;
-    string m_versionString;
-    string m_comment;
-};
-
-ValuesHandler::ValuesHandler(ValuesFile* vf, int version, const string& versionString)
-    :m_vf(vf),
-     m_version(version),
-     m_versionString(versionString)
-{
-}
-
-int
-ValuesHandler::OnStartElement(const SourcePos& pos, const string& ns, const string& name,
-                                const vector<XMLAttribute>& attrs, XMLHandler** next)
-{
-    if (ns == "" && name == "string") {
-        string id = XMLAttribute::Find(attrs, "", "name", "");
-        XMLNode* node = XMLNode::NewElement(pos, ns, name, attrs, XMLNode::EXACT);
-        m_vf->AddString(StringResource(pos, pos.file, m_vf->GetConfiguration(),
-                                            id, -1, node, m_version, m_versionString,
-                                            trim_string(m_comment)));
-        *next = new NodeHandler(node, XMLNode::EXACT);
-    }
-    else if (ns == "" && name == "array") {
-        string id = XMLAttribute::Find(attrs, "", "name", "");
-        *next = new ArrayHandler(m_vf, m_version, m_versionString, id);
-    }
-    m_comment = "";
-    return 0;
-}
-
-int
-ValuesHandler::OnText(const SourcePos& pos, const string& text)
-{
-    return 0;
-}
-
-int
-ValuesHandler::OnComment(const SourcePos& pos, const string& text)
-{
-    m_comment += text;
-    return 0;
-}
-
-// =====================================================================================
-ValuesFile::ValuesFile(const Configuration& config)
-    :m_config(config),
-     m_strings(),
-     m_arrays()
-{
-}
-
-ValuesFile::~ValuesFile()
-{
-}
-
-ValuesFile*
-ValuesFile::ParseFile(const string& filename, const Configuration& config,
-                    int version, const string& versionString)
-{
-    ValuesFile* result = new ValuesFile(config);
-
-    TopElementHandler top("", "resources", new ValuesHandler(result, version, versionString));
-    XMLHandler::ParseFile(filename, &top);
-
-    return result;
-}
-
-ValuesFile*
-ValuesFile::ParseString(const string& filename, const string& text, const Configuration& config,
-                    int version, const string& versionString)
-{
-    ValuesFile* result = new ValuesFile(config);
-
-    TopElementHandler top("", "resources", new ValuesHandler(result, version, versionString));
-    XMLHandler::ParseString(filename, text, &top);
-
-    return result;
-}
-
-const Configuration&
-ValuesFile::GetConfiguration() const
-{
-    return m_config;
-}
-
-void
-ValuesFile::AddString(const StringResource& str)
-{
-    if (str.index < 0) {
-        m_strings.insert(str);
-    } else {
-        m_arrays[str.id].insert(str);
-    }
-}
-
-set<StringResource>
-ValuesFile::GetStrings() const
-{
-    set<StringResource> result = m_strings;
-
-    for (map<string,set<StringResource> >::const_iterator it = m_arrays.begin();
-            it != m_arrays.end(); it++) {
-        result.insert(it->second.begin(), it->second.end());
-    }
-
-    return result;
-}
-
-XMLNode*
-ValuesFile::ToXMLNode() const
-{
-    XMLNode* root;
-
-    // <resources>
-    {
-        vector<XMLAttribute> attrs;
-        ANDROID_NAMESPACES.AddToAttributes(&attrs);
-        root = XMLNode::NewElement(GENERATED_POS, "", "resources", attrs, XMLNode::PRETTY);
-    }
-
-    // <array>
-    for (map<string,set<StringResource> >::const_iterator it = m_arrays.begin();
-            it != m_arrays.end(); it++) {
-        vector<XMLAttribute> arrayAttrs;
-        arrayAttrs.push_back(XMLAttribute("", "name", it->first));
-        const set<StringResource>& items = it->second;
-        XMLNode* arrayNode = XMLNode::NewElement(items.begin()->pos, "", "array", arrayAttrs,
-                XMLNode::PRETTY);
-        root->EditChildren().push_back(arrayNode);
-
-        // <item>
-        for (set<StringResource>::const_iterator item = items.begin();
-                item != items.end(); item++) {
-            XMLNode* itemNode = item->value->Clone();
-            itemNode->SetName("", "item");
-            itemNode->EditAttributes().clear();
-            arrayNode->EditChildren().push_back(itemNode);
-        }
-    }
-
-    // <string>
-    for (set<StringResource>::const_iterator it=m_strings.begin(); it!=m_strings.end(); it++) {
-        const StringResource& str = *it;
-        vector<XMLAttribute> attrs;
-        XMLNode* strNode = str.value->Clone();
-        strNode->SetName("", "string");
-        strNode->EditAttributes().clear();
-        strNode->EditAttributes().push_back(XMLAttribute("", "name", str.id));
-        root->EditChildren().push_back(strNode);
-    }
-
-    return root;
-}
-
-string
-ValuesFile::ToString() const
-{
-    XMLNode* xml = ToXMLNode();
-    string s = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
-    s += xml->ToString(ANDROID_NAMESPACES);
-    delete xml;
-    s += '\n';
-    return s;
-}
-
diff --git a/tools/localize/ValuesFile.h b/tools/localize/ValuesFile.h
deleted file mode 100644
index 752fd78..0000000
--- a/tools/localize/ValuesFile.h
+++ /dev/null
@@ -1,52 +0,0 @@
-#ifndef VALUES_FILE_H
-#define VALUES_FILE_H
-
-#include "SourcePos.h"
-#include "Configuration.h"
-#include "XMLHandler.h"
-#include "Values.h"
-
-#include <string>
-#include <set>
-
-using namespace std;
-
-extern const XMLNamespaceMap ANDROID_NAMESPACES;
-
-class ValuesFile
-{
-public:
-    ValuesFile(const Configuration& config);
-
-    static ValuesFile* ParseFile(const string& filename, const Configuration& config,
-                                     int version, const string& versionString);
-    static ValuesFile* ParseString(const string& filename, const string& text,
-                                     const Configuration& config,
-                                     int version, const string& versionString);
-    ~ValuesFile();
-
-    const Configuration& GetConfiguration() const;
-
-    void AddString(const StringResource& str);
-    set<StringResource> GetStrings() const;
-
-    // exports this file as a n XMLNode, you own this object
-    XMLNode* ToXMLNode() const;
-
-    // writes the ValuesFile out to a string in the canonical format (i.e. writes the contents of
-    // ToXMLNode()).
-    string ToString() const;
-
-private:
-    class ParseState;
-    friend class ValuesFile::ParseState;
-    friend class StringHandler;
-
-    ValuesFile();
-
-    Configuration m_config;
-    set<StringResource> m_strings;
-    map<string,set<StringResource> > m_arrays;
-};
-
-#endif // VALUES_FILE_H
diff --git a/tools/localize/ValuesFile_test.cpp b/tools/localize/ValuesFile_test.cpp
deleted file mode 100644
index 56d2ec2..0000000
--- a/tools/localize/ValuesFile_test.cpp
+++ /dev/null
@@ -1,54 +0,0 @@
-#include "ValuesFile.h"
-#include <stdio.h>
-
-int
-ValuesFile_test()
-{
-    int err = 0;
-    Configuration config;
-    config.locale = "zz_ZZ";
-    ValuesFile* vf = ValuesFile::ParseFile("testdata/values/strings.xml", config,
-                                        OLD_VERSION, "1");
-
-    const set<StringResource>& strings = vf->GetStrings();
-    string canonical = vf->ToString();
-
-    if (false) {
-        printf("Strings (%zd)\n", strings.size());
-            for (set<StringResource>::const_iterator it=strings.begin();
-                    it!=strings.end(); it++) {
-            const StringResource& str = *it;
-            printf("%s: '%s'[%d]='%s' (%s) <!-- %s -->\n", str.pos.ToString().c_str(),
-                    str.id.c_str(), str.index,
-                    str.value->ContentsToString(ANDROID_NAMESPACES).c_str(),
-                    str.config.ToString().c_str(), str.comment.c_str());
-        }
-
-        printf("XML:[[%s]]\n", canonical.c_str());
-    }
-
-    const char * const EXPECTED =
-        "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
-        "<resources xmlns:android=\"http://schemas.android.com/apk/res/android\"\n"
-        "    xmlns:xliff=\"urn:oasis:names:tc:xliff:document:1.2\">\n"
-        "  <array name=\"emailAddressTypes\">\n"
-        "    <item>Email</item>\n"
-        "    <item>Home</item>\n"
-        "    <item>Work</item>\n"
-        "    <item>Other\\u2026</item>\n"
-        "  </array>\n"
-        "  <string name=\"test1\">Discard</string>\n"
-        "  <string name=\"test2\">a<b>b<i>c</i></b>d</string>\n"
-        "  <string name=\"test3\">a<xliff:g a=\"b\" xliff:a=\"asdf\">bBb</xliff:g>C</string>\n"
-        "</resources>\n";
-
-    if (canonical != EXPECTED) {
-        fprintf(stderr, "ValuesFile_test failed\n");
-        fprintf(stderr, "canonical=[[%s]]\n", canonical.c_str());
-        fprintf(stderr, "EXPECTED=[[%s]]\n", EXPECTED);
-        err = 1;
-    }
-
-    delete vf;
-    return err;
-}
diff --git a/tools/localize/XLIFFFile.cpp b/tools/localize/XLIFFFile.cpp
deleted file mode 100644
index 4e217d9..0000000
--- a/tools/localize/XLIFFFile.cpp
+++ /dev/null
@@ -1,610 +0,0 @@
-#include "XLIFFFile.h"
-
-#include <algorithm>
-#include <sys/time.h>
-#include <time.h>
-#include <cstdio>
-
-const char* const XLIFF_XMLNS = "urn:oasis:names:tc:xliff:document:1.2";
-
-const char *const NS_MAP[] = {
-    "", XLIFF_XMLNS,
-    "xml", XMLNS_XMLNS,
-    NULL, NULL
-};
-
-const XMLNamespaceMap XLIFF_NAMESPACES(NS_MAP);
-
-int
-XLIFFFile::File::Compare(const XLIFFFile::File& that) const
-{
-    if (filename != that.filename) {
-        return filename < that.filename ? -1 : 1;
-    }
-    return 0;
-}
-
-// =====================================================================================
-XLIFFFile::XLIFFFile()
-{
-}
-
-XLIFFFile::~XLIFFFile()
-{
-}
-
-static XMLNode*
-get_unique_node(const XMLNode* parent, const string& ns, const string& name, bool required)
-{
-    size_t count = parent->CountElementsByName(ns, name);
-    if (count == 1) {
-        return parent->GetElementByNameAt(ns, name, 0);
-    } else {
-        if (required) {
-            SourcePos pos = count == 0
-                                ? parent->Position()
-                                : parent->GetElementByNameAt(XLIFF_XMLNS, name, 1)->Position();
-            pos.Error("<%s> elements must contain exactly one <%s> element",
-                                parent->Name().c_str(), name.c_str());
-        }
-        return NULL;
-    }
-}
-
-XLIFFFile*
-XLIFFFile::Parse(const string& filename)
-{
-    XLIFFFile* result = new XLIFFFile();
-
-    XMLNode* root = NodeHandler::ParseFile(filename, XMLNode::PRETTY);
-    if (root == NULL) {
-        return NULL;
-    }
-
-    // <file>
-    vector<XMLNode*> files = root->GetElementsByName(XLIFF_XMLNS, "file");
-    for (size_t i=0; i<files.size(); i++) {
-        XMLNode* file = files[i];
-
-        string datatype = file->GetAttribute("", "datatype", "");
-        string originalFile = file->GetAttribute("", "original", "");
-
-        Configuration sourceConfig;
-        sourceConfig.locale = file->GetAttribute("", "source-language", "");
-        result->m_sourceConfig = sourceConfig;
-
-        Configuration targetConfig;
-        targetConfig.locale = file->GetAttribute("", "target-language", "");
-        result->m_targetConfig = targetConfig;
-
-        result->m_currentVersion = file->GetAttribute("", "build-num", "");
-        result->m_oldVersion = "old";
-
-        // <body>
-        XMLNode* body = get_unique_node(file, XLIFF_XMLNS, "body", true);
-        if (body == NULL) continue;
-
-        // <trans-unit>
-        vector<XMLNode*> transUnits = body->GetElementsByName(XLIFF_XMLNS, "trans-unit");
-        for (size_t j=0; j<transUnits.size(); j++) {
-            XMLNode* transUnit = transUnits[j];
-
-            string rawID = transUnit->GetAttribute("", "id", "");
-            if (rawID == "") {
-                transUnit->Position().Error("<trans-unit> tag requires an id");
-                continue;
-            }
-            string id;
-            int index;
-
-            if (!StringResource::ParseTypedID(rawID, &id, &index)) {
-                transUnit->Position().Error("<trans-unit> has invalid id '%s'\n", rawID.c_str());
-                continue;
-            }
-
-            // <source>
-            XMLNode* source = get_unique_node(transUnit, XLIFF_XMLNS, "source", false);
-            if (source != NULL) {
-                XMLNode* node = source->Clone();
-                node->SetPrettyRecursive(XMLNode::EXACT);
-                result->AddStringResource(StringResource(source->Position(), originalFile,
-                            sourceConfig, id, index, node, CURRENT_VERSION,
-                            result->m_currentVersion));
-            }
-
-            // <target>
-            XMLNode* target = get_unique_node(transUnit, XLIFF_XMLNS, "target", false);
-            if (target != NULL) {
-                XMLNode* node = target->Clone();
-                node->SetPrettyRecursive(XMLNode::EXACT);
-                result->AddStringResource(StringResource(target->Position(), originalFile,
-                            targetConfig, id, index, node, CURRENT_VERSION,
-                            result->m_currentVersion));
-            }
-
-            // <alt-trans>
-            XMLNode* altTrans = get_unique_node(transUnit, XLIFF_XMLNS, "alt-trans", false);
-            if (altTrans != NULL) {
-                // <source>
-                XMLNode* altSource = get_unique_node(altTrans, XLIFF_XMLNS, "source", false);
-                if (altSource != NULL) {
-                    XMLNode* node = altSource->Clone();
-                    node->SetPrettyRecursive(XMLNode::EXACT);
-                    result->AddStringResource(StringResource(altSource->Position(),
-                                originalFile, sourceConfig, id, index, node, OLD_VERSION,
-                                result->m_oldVersion));
-                }
-
-                // <target>
-                XMLNode* altTarget = get_unique_node(altTrans, XLIFF_XMLNS, "target", false);
-                if (altTarget != NULL) {
-                    XMLNode* node = altTarget->Clone();
-                    node->SetPrettyRecursive(XMLNode::EXACT);
-                    result->AddStringResource(StringResource(altTarget->Position(),
-                                originalFile, targetConfig, id, index, node, OLD_VERSION,
-                                result->m_oldVersion));
-                }
-            }
-        }
-    }
-    delete root;
-    return result;
-}
-
-XLIFFFile*
-XLIFFFile::Create(const Configuration& sourceConfig, const Configuration& targetConfig,
-                                const string& currentVersion)
-{
-    XLIFFFile* result = new XLIFFFile();
-        result->m_sourceConfig = sourceConfig;
-        result->m_targetConfig = targetConfig;
-        result->m_currentVersion = currentVersion;
-    return result;
-}
-
-set<string>
-XLIFFFile::Files() const
-{
-    set<string> result;
-    for (vector<File>::const_iterator f = m_files.begin(); f != m_files.end(); f++) {
-        result.insert(f->filename);
-    }
-    return result;
-}
-
-void
-XLIFFFile::AddStringResource(const StringResource& str)
-{
-    string id = str.TypedID();
-
-    File* f = NULL;
-    const size_t I = m_files.size();
-    for (size_t i=0; i<I; i++) {
-        if (m_files[i].filename == str.file) {
-            f = &m_files[i];
-            break;
-        }
-    }
-    if (f == NULL) {
-        File file;
-        file.filename = str.file;
-        m_files.push_back(file);
-        f = &m_files[I];
-    }
-
-    const size_t J = f->transUnits.size();
-    TransUnit* g = NULL;
-    for (size_t j=0; j<J; j++) {
-        if (f->transUnits[j].id == id) {
-            g = &f->transUnits[j];
-        }
-    }
-    if (g == NULL) {
-        TransUnit group;
-        group.id = id;
-        f->transUnits.push_back(group);
-        g = &f->transUnits[J];
-    }
-
-    StringResource* res = find_string_res(*g, str);
-    if (res == NULL) {
-        return ;
-    }
-    if (res->id != "") {
-        str.pos.Error("Duplicate string resource: %s", res->id.c_str());
-        res->pos.Error("Previous definition here");
-        return ;
-    }
-    *res = str;
-
-    m_strings.insert(str);
-}
-
-void
-XLIFFFile::Filter(bool (*func)(const string&,const TransUnit&,void*), void* cookie)
-{
-    const size_t I = m_files.size();
-    for (size_t ix=0, i=I-1; ix<I; ix++, i--) {
-        File& file = m_files[i];
-
-        const size_t J = file.transUnits.size();
-        for (size_t jx=0, j=J-1; jx<J; jx++, j--) {
-            TransUnit& tu = file.transUnits[j];
-
-            bool keep = func(file.filename, tu, cookie);
-            if (!keep) {
-                if (tu.source.id != "") {
-                    m_strings.erase(tu.source);
-                }
-                if (tu.target.id != "") {
-                    m_strings.erase(tu.target);
-                }
-                if (tu.altSource.id != "") {
-                    m_strings.erase(tu.altSource);
-                }
-                if (tu.altTarget.id != "") {
-                    m_strings.erase(tu.altTarget);
-                }
-                file.transUnits.erase(file.transUnits.begin()+j);
-            }
-        }
-        if (file.transUnits.size() == 0) {
-            m_files.erase(m_files.begin()+i);
-        }
-    }
-}
-
-void
-XLIFFFile::Map(void (*func)(const string&,TransUnit*,void*), void* cookie)
-{
-    const size_t I = m_files.size();
-    for (size_t i=0; i<I; i++) {
-        File& file = m_files[i];
-
-        const size_t J = file.transUnits.size();
-        for (size_t j=0; j<J; j++) {
-            func(file.filename, &(file.transUnits[j]), cookie);
-        }
-    }
-}
-
-TransUnit*
-XLIFFFile::EditTransUnit(const string& filename, const string& id)
-{
-    const size_t I = m_files.size();
-    for (size_t ix=0, i=I-1; ix<I; ix++, i--) {
-        File& file = m_files[i];
-        if (file.filename == filename) {
-            const size_t J = file.transUnits.size();
-            for (size_t jx=0, j=J-1; jx<J; jx++, j--) {
-                TransUnit& tu = file.transUnits[j];
-                if (tu.id == id) {
-                    return &tu;
-                }
-            }
-        }
-    }
-    return NULL;
-}
-
-StringResource*
-XLIFFFile::find_string_res(TransUnit& g, const StringResource& str)
-{
-    int index;
-    if (str.version == CURRENT_VERSION) {
-        index = 0;
-    }
-    else if (str.version == OLD_VERSION) {
-        index = 2;
-    }
-    else {
-        str.pos.Error("Internal Error %s:%d\n", __FILE__, __LINE__);
-        return NULL;
-    }
-    if (str.config == m_sourceConfig) {
-        // index += 0;
-    }
-    else if (str.config == m_targetConfig) {
-        index += 1;
-    }
-    else {
-        str.pos.Error("unknown config for string %s: %s", str.id.c_str(),
-                            str.config.ToString().c_str());
-        return NULL;
-    }
-    switch (index) {
-        case 0:
-            return &g.source;
-        case 1:
-            return &g.target;
-        case 2:
-            return &g.altSource;
-        case 3:
-            return &g.altTarget;
-    }
-    str.pos.Error("Internal Error %s:%d\n", __FILE__, __LINE__);
-    return NULL;
-}
-
-int
-convert_html_to_xliff(const XMLNode* original, const string& name, XMLNode* addTo, int* phID)
-{
-    int err = 0;
-    if (original->Type() == XMLNode::TEXT) {
-        addTo->EditChildren().push_back(original->Clone());
-        return 0;
-    } else {
-        string ctype;
-        if (original->Namespace() == "") {
-            if (original->Name() == "b") {
-                ctype = "bold";
-            }
-            else if (original->Name() == "i") {
-                ctype = "italic";
-            }
-            else if (original->Name() == "u") {
-                ctype = "underline";
-            }
-        }
-        if (ctype != "") {
-            vector<XMLAttribute> attrs;
-            attrs.push_back(XMLAttribute(XLIFF_XMLNS, "ctype", ctype));
-            XMLNode* copy = XMLNode::NewElement(original->Position(), XLIFF_XMLNS, "g",
-                                                attrs, XMLNode::EXACT);
-
-            const vector<XMLNode*>& children = original->Children();
-            size_t I = children.size();
-            for (size_t i=0; i<I; i++) {
-                err |= convert_html_to_xliff(children[i], name, copy, phID);
-            }
-            return err;
-        }
-        else {
-            if (original->Namespace() == XLIFF_XMLNS) {
-                addTo->EditChildren().push_back(original->Clone());
-                return 0;
-            } else {
-                if (original->Namespace() == "") {
-                    // flatten out the tag into ph tags -- but only if there is no namespace
-                    // that's still unsupported because propagating the xmlns attribute is hard.
-                    vector<XMLAttribute> attrs;
-                    char idStr[30];
-                    (*phID)++;
-                    sprintf(idStr, "id-%d", *phID);
-                    attrs.push_back(XMLAttribute(XLIFF_XMLNS, "id", idStr));
-
-                    if (original->Children().size() == 0) {
-                        XMLNode* ph = XMLNode::NewElement(original->Position(), XLIFF_XMLNS,
-                                "ph", attrs, XMLNode::EXACT);
-                        ph->EditChildren().push_back(
-                                XMLNode::NewText(original->Position(),
-                                    original->ToString(XLIFF_NAMESPACES),
-                                    XMLNode::EXACT));
-                        addTo->EditChildren().push_back(ph);
-                    } else {
-                        XMLNode* begin = XMLNode::NewElement(original->Position(), XLIFF_XMLNS,
-                                "bpt", attrs, XMLNode::EXACT);
-                        begin->EditChildren().push_back(
-                                XMLNode::NewText(original->Position(),
-                                    original->OpenTagToString(XLIFF_NAMESPACES, XMLNode::EXACT),
-                                    XMLNode::EXACT));
-                        XMLNode* end = XMLNode::NewElement(original->Position(), XLIFF_XMLNS,
-                                "ept", attrs, XMLNode::EXACT);
-                        string endText = "</";
-                            endText += original->Name();
-                            endText += ">";
-                        end->EditChildren().push_back(XMLNode::NewText(original->Position(),
-                                endText, XMLNode::EXACT));
-
-                        addTo->EditChildren().push_back(begin);
-
-                        const vector<XMLNode*>& children = original->Children();
-                        size_t I = children.size();
-                        for (size_t i=0; i<I; i++) {
-                            err |= convert_html_to_xliff(children[i], name, addTo, phID);
-                        }
-
-                        addTo->EditChildren().push_back(end);
-                    }
-                    return err;
-                } else {
-                    original->Position().Error("invalid <%s> element in <%s> tag\n",
-                                                original->Name().c_str(), name.c_str());
-                    return 1;
-                }
-            }
-        }
-    }
-}
-
-XMLNode*
-create_string_node(const StringResource& str, const string& name)
-{
-    vector<XMLAttribute> attrs;
-    attrs.push_back(XMLAttribute(XMLNS_XMLNS, "space", "preserve"));
-    XMLNode* node = XMLNode::NewElement(str.pos, XLIFF_XMLNS, name, attrs, XMLNode::EXACT);
-
-    const vector<XMLNode*>& children = str.value->Children();
-    size_t I = children.size();
-    int err = 0;
-    for (size_t i=0; i<I; i++) {
-        int phID = 0;
-        err |= convert_html_to_xliff(children[i], name, node, &phID);
-    }
-
-    if (err != 0) {
-        delete node;
-    }
-    return node;
-}
-
-static bool
-compare_id(const TransUnit& lhs, const TransUnit& rhs)
-{
-    string lid, rid;
-    int lindex, rindex;
-    StringResource::ParseTypedID(lhs.id, &lid, &lindex);
-    StringResource::ParseTypedID(rhs.id, &rid, &rindex);
-    if (lid < rid) return true;
-    if (lid == rid && lindex < rindex) return true;
-    return false;
-}
-
-XMLNode*
-XLIFFFile::ToXMLNode() const
-{
-    XMLNode* root;
-    size_t N;
-
-    // <xliff>
-    {
-        vector<XMLAttribute> attrs;
-        XLIFF_NAMESPACES.AddToAttributes(&attrs);
-        attrs.push_back(XMLAttribute(XLIFF_XMLNS, "version", "1.2"));
-        root = XMLNode::NewElement(GENERATED_POS, XLIFF_XMLNS, "xliff", attrs, XMLNode::PRETTY);
-    }
-
-    vector<TransUnit> groups;
-
-    // <file>
-    vector<File> files = m_files;
-    sort(files.begin(), files.end());
-    const size_t I = files.size();
-    for (size_t i=0; i<I; i++) {
-        const File& file = files[i];
-
-        vector<XMLAttribute> fileAttrs;
-        fileAttrs.push_back(XMLAttribute(XLIFF_XMLNS, "datatype", "x-android-res"));
-        fileAttrs.push_back(XMLAttribute(XLIFF_XMLNS, "original", file.filename));
-
-        struct timeval tv;
-        struct timezone tz;
-        gettimeofday(&tv, &tz);
-        fileAttrs.push_back(XMLAttribute(XLIFF_XMLNS, "date", trim_string(ctime(&tv.tv_sec))));
-
-        fileAttrs.push_back(XMLAttribute(XLIFF_XMLNS, "source-language", m_sourceConfig.locale));
-        fileAttrs.push_back(XMLAttribute(XLIFF_XMLNS, "target-language", m_targetConfig.locale));
-        fileAttrs.push_back(XMLAttribute(XLIFF_XMLNS, "build-num", m_currentVersion));
-
-        XMLNode* fileNode = XMLNode::NewElement(GENERATED_POS, XLIFF_XMLNS, "file", fileAttrs,
-                                                XMLNode::PRETTY);
-        root->EditChildren().push_back(fileNode);
-
-        // <body>
-        XMLNode* bodyNode = XMLNode::NewElement(GENERATED_POS, XLIFF_XMLNS, "body",
-                                                vector<XMLAttribute>(), XMLNode::PRETTY);
-        fileNode->EditChildren().push_back(bodyNode);
-
-        // <trans-unit>
-        vector<TransUnit> transUnits = file.transUnits;
-        sort(transUnits.begin(), transUnits.end(), compare_id);
-        const size_t J = transUnits.size();
-        for (size_t j=0; j<J; j++) {
-            const TransUnit& transUnit = transUnits[j];
-
-            vector<XMLAttribute> tuAttrs;
-
-            // strings start with string:
-            tuAttrs.push_back(XMLAttribute(XLIFF_XMLNS, "id", transUnit.id));
-            XMLNode* transUnitNode = XMLNode::NewElement(GENERATED_POS, XLIFF_XMLNS, "trans-unit",
-                                                         tuAttrs, XMLNode::PRETTY);
-            bodyNode->EditChildren().push_back(transUnitNode);
-
-            // <extradata>
-            if (transUnit.source.comment != "") {
-                vector<XMLAttribute> extradataAttrs;
-                XMLNode* extraNode = XMLNode::NewElement(GENERATED_POS, XLIFF_XMLNS, "extradata",
-                                                            extradataAttrs, XMLNode::EXACT);
-                transUnitNode->EditChildren().push_back(extraNode);
-                extraNode->EditChildren().push_back(
-                        XMLNode::NewText(GENERATED_POS, transUnit.source.comment,
-                                         XMLNode::PRETTY));
-            }
-
-            // <source>
-            if (transUnit.source.id != "") {
-                transUnitNode->EditChildren().push_back(
-                                    create_string_node(transUnit.source, "source"));
-            }
-            
-            // <target>
-            if (transUnit.target.id != "") {
-                transUnitNode->EditChildren().push_back(
-                                    create_string_node(transUnit.target, "target"));
-            }
-
-            // <alt-trans>
-            if (transUnit.altSource.id != "" || transUnit.altTarget.id != ""
-                    || transUnit.rejectComment != "") {
-                vector<XMLAttribute> altTransAttrs;
-                XMLNode* altTransNode = XMLNode::NewElement(GENERATED_POS, XLIFF_XMLNS, "alt-trans",
-                                                            altTransAttrs, XMLNode::PRETTY);
-                transUnitNode->EditChildren().push_back(altTransNode);
-
-                // <extradata>
-                if (transUnit.rejectComment != "") {
-                    vector<XMLAttribute> extradataAttrs;
-                    XMLNode* extraNode = XMLNode::NewElement(GENERATED_POS, XLIFF_XMLNS,
-                                                                "extradata", extradataAttrs,
-                                                                XMLNode::EXACT);
-                    altTransNode->EditChildren().push_back(extraNode);
-                    extraNode->EditChildren().push_back(
-                            XMLNode::NewText(GENERATED_POS, transUnit.rejectComment,
-                                             XMLNode::PRETTY));
-                }
-                
-                // <source>
-                if (transUnit.altSource.id != "") {
-                    altTransNode->EditChildren().push_back(
-                                        create_string_node(transUnit.altSource, "source"));
-                }
-                
-                // <target>
-                if (transUnit.altTarget.id != "") {
-                    altTransNode->EditChildren().push_back(
-                                        create_string_node(transUnit.altTarget, "target"));
-                }
-            }
-            
-        }
-    }
-
-    return root;
-}
-
-
-string
-XLIFFFile::ToString() const
-{
-    XMLNode* xml = ToXMLNode();
-    string s = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
-    s += xml->ToString(XLIFF_NAMESPACES);
-    delete xml;
-    s += '\n';
-    return s;
-}
-
-Stats
-XLIFFFile::GetStats(const string& config) const
-{
-    Stats stat;
-    stat.config = config;
-    stat.files = m_files.size();
-    stat.toBeTranslated = 0;
-    stat.noComments = 0;
-
-    for (vector<File>::const_iterator file=m_files.begin(); file!=m_files.end(); file++) {
-        stat.toBeTranslated += file->transUnits.size();
-
-        for (vector<TransUnit>::const_iterator tu=file->transUnits.begin();
-                    tu!=file->transUnits.end(); tu++) {
-            if (tu->source.comment == "") {
-                stat.noComments++;
-            }
-        }
-    }
-
-    stat.totalStrings = stat.toBeTranslated;
-
-    return stat;
-}
diff --git a/tools/localize/XLIFFFile.h b/tools/localize/XLIFFFile.h
deleted file mode 100644
index a93d479..0000000
--- a/tools/localize/XLIFFFile.h
+++ /dev/null
@@ -1,98 +0,0 @@
-#ifndef XLIFF_FILE_H
-#define XLIFF_FILE_H
-
-#include "Values.h"
-
-#include "Configuration.h"
-
-#include <set>
-
-using namespace std;
-
-extern const XMLNamespaceMap XLIFF_NAMESPACES;
-
-extern const char*const XLIFF_XMLNS;
-
-struct Stats
-{
-    string config;
-    size_t files;
-    size_t toBeTranslated;
-    size_t noComments;
-    size_t totalStrings;
-};
-
-struct TransUnit {
-    string id;
-    StringResource source;
-    StringResource target;
-    StringResource altSource;
-    StringResource altTarget;
-    string rejectComment;
-};
-
-class XLIFFFile
-{
-public:
-    static XLIFFFile* Parse(const string& filename);
-    static XLIFFFile* Create(const Configuration& sourceConfig, const Configuration& targetConfig,
-                                const string& currentVersion);
-    ~XLIFFFile();
-
-    inline const Configuration& SourceConfig() const                { return m_sourceConfig; }
-    inline const Configuration& TargetConfig() const                { return m_targetConfig; }
-
-    inline const string& CurrentVersion() const                     { return m_currentVersion; }
-    inline const string& OldVersion() const                         { return m_oldVersion; }
-
-    set<string> Files() const;
-
-    void AddStringResource(const StringResource& res);
-    inline set<StringResource> const& GetStringResources() const { return m_strings; }
-    bool FindStringResource(const string& filename, int version, bool source);
-
-    void Filter(bool (*func)(const string&,const TransUnit&,void*), void* cookie);
-    void Map(void (*func)(const string&,TransUnit*,void*), void* cookie);
-
-    TransUnit* EditTransUnit(const string& file, const string& id);
-
-    // exports this file as a n XMLNode, you own this object
-    XMLNode* ToXMLNode() const;
-
-    // writes the ValuesFile out to a string in the canonical format (i.e. writes the contents of
-    // ToXMLNode()).
-    string ToString() const;
-
-    Stats GetStats(const string& config) const;
-
-private:
-    struct File {
-        int Compare(const File& that) const;
-
-        inline bool operator<(const File& that) const { return Compare(that) < 0; }
-        inline bool operator<=(const File& that) const { return Compare(that) <= 0; }
-        inline bool operator==(const File& that) const { return Compare(that) == 0; }
-        inline bool operator!=(const File& that) const { return Compare(that) != 0; }
-        inline bool operator>=(const File& that) const { return Compare(that) >= 0; }
-        inline bool operator>(const File& that) const { return Compare(that) > 0; }
-
-        string filename;
-        vector<TransUnit> transUnits;
-    };
-
-    XLIFFFile();
-    StringResource* find_string_res(TransUnit& g, const StringResource& str);
-    
-    Configuration m_sourceConfig;
-    Configuration m_targetConfig;
-
-    string m_currentVersion;
-    string m_oldVersion;
-
-    set<StringResource> m_strings;
-    vector<File> m_files;
-};
-
-int convert_html_to_xliff(const XMLNode* original, const string& name, XMLNode* addTo, int* phID);
-
-#endif // XLIFF_FILE_H
diff --git a/tools/localize/XLIFFFile_test.cpp b/tools/localize/XLIFFFile_test.cpp
deleted file mode 100644
index 52ed4c3..0000000
--- a/tools/localize/XLIFFFile_test.cpp
+++ /dev/null
@@ -1,115 +0,0 @@
-#include "XLIFFFile.h"
-#include <stdio.h>
-#include "ValuesFile.h"
-
-XMLNode* create_string_node(const StringResource& str, const string& name);
-
-static int
-Parse_test()
-{
-    XLIFFFile* xf = XLIFFFile::Parse("testdata/xliff1.xliff");
-    if (xf == NULL) {
-        return 1;
-    }
-
-    set<StringResource> const& strings = xf->GetStringResources();
-
-    if (false) {
-        for (set<StringResource>::iterator it=strings.begin(); it!=strings.end(); it++) {
-            const StringResource& str = *it;
-            printf("STRING!!! id=%s index=%d value='%s' pos=%s file=%s version=%d(%s)\n",
-                    str.id.c_str(), str.index,
-                    str.value->ContentsToString(ANDROID_NAMESPACES).c_str(),
-                    str.pos.ToString().c_str(), str.file.c_str(), str.version,
-                    str.versionString.c_str());
-        }
-        printf("XML:[[%s]]\n", xf->ToString().c_str());
-    }
-
-    delete xf;
-    return 0;
-}
-
-static XMLNode*
-add_html_tag(XMLNode* addTo, const string& tag)
-{
-    vector<XMLAttribute> attrs;
-    XMLNode* node = XMLNode::NewElement(GENERATED_POS, "", tag, attrs, XMLNode::EXACT);
-    addTo->EditChildren().push_back(node);
-    return node;
-}
-
-static int
-create_string_node_test()
-{
-    int err = 0;
-    StringResource res;
-    vector<XMLAttribute> attrs;
-    res.value = XMLNode::NewElement(GENERATED_POS, "", "something", attrs, XMLNode::EXACT);
-    res.value->EditChildren().push_back(XMLNode::NewText(GENERATED_POS, " begin ", XMLNode::EXACT));
-
-    XMLNode* child;
-
-    child = add_html_tag(res.value, "b");
-    child->EditChildren().push_back(XMLNode::NewText(GENERATED_POS, "b", XMLNode::EXACT));
-
-    child = add_html_tag(res.value, "i");
-    child->EditChildren().push_back(XMLNode::NewText(GENERATED_POS, "i", XMLNode::EXACT));
-
-    child = add_html_tag(child, "b");
-    child->EditChildren().push_back(XMLNode::NewText(GENERATED_POS, "b", XMLNode::EXACT));
-
-    child = add_html_tag(res.value, "u");
-    child->EditChildren().push_back(XMLNode::NewText(GENERATED_POS, "u", XMLNode::EXACT));
-
-
-    res.value->EditChildren().push_back(XMLNode::NewText(GENERATED_POS, " end ", XMLNode::EXACT));
-
-    XMLNode* xliff = create_string_node(res, "blah");
-
-    string oldString = res.value->ToString(XLIFF_NAMESPACES);
-    string newString = xliff->ToString(XLIFF_NAMESPACES);
-
-    if (false) {
-        printf("OLD=\"%s\"\n", oldString.c_str());
-        printf("NEW=\"%s\"\n", newString.c_str());
-    }
-
-    const char* const EXPECTED_OLD
-                    = "<something> begin <b>b</b><i>i<b>b</b></i><u>u</u> end </something>";
-    if (oldString != EXPECTED_OLD) {
-        fprintf(stderr, "oldString mismatch:\n");
-        fprintf(stderr, "    expected='%s'\n", EXPECTED_OLD);
-        fprintf(stderr, "      actual='%s'\n", oldString.c_str());
-        err |= 1;
-    }
-
-    const char* const EXPECTED_NEW
-                    = "<blah xml:space=\"preserve\"> begin <g ctype=\"bold\">b</g>"
-                    "<g ctype=\"italic\">i<g ctype=\"bold\">b</g></g><g ctype=\"underline\">u</g>"
-                    " end </blah>";
-    if (newString != EXPECTED_NEW) {
-        fprintf(stderr, "newString mismatch:\n");
-        fprintf(stderr, "    expected='%s'\n", EXPECTED_NEW);
-        fprintf(stderr, "      actual='%s'\n", newString.c_str());
-        err |= 1;
-    }
-
-    if (err != 0) {
-        fprintf(stderr, "create_string_node_test failed\n");
-    }
-    return err;
-}
-
-int
-XLIFFFile_test()
-{
-    bool all = true;
-    int err = 0;
-
-    if (all) err |= Parse_test();
-    if (all) err |= create_string_node_test();
-
-    return err;
-}
-
diff --git a/tools/localize/XMLHandler.cpp b/tools/localize/XMLHandler.cpp
deleted file mode 100644
index 3fab211..0000000
--- a/tools/localize/XMLHandler.cpp
+++ /dev/null
@@ -1,793 +0,0 @@
-#include "XMLHandler.h"
-
-#include <algorithm>
-#include <expat.h>
-#include <stdio.h>
-#include <string.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <errno.h>
-
-#define NS_SEPARATOR 1
-#define MORE_INDENT "  "
-
-static string
-xml_text_escape(const string& s)
-{
-    string result;
-    const size_t N = s.length();
-    for (size_t i=0; i<N; i++) {
-        char c = s[i];
-        switch (c) {
-            case '<':
-                result += "&lt;";
-                break;
-            case '>':
-                result += "&gt;";
-                break;
-            case '&':
-                result += "&amp;";
-                break;
-            default:
-                result += c;
-                break;
-        }
-    }
-    return result;
-}
-
-static string
-xml_attr_escape(const string& s)
-{
-    string result;
-    const size_t N = s.length();
-    for (size_t i=0; i<N; i++) {
-        char c = s[i];
-        switch (c) {
-            case '\"':
-                result += "&quot;";
-                break;
-            default:
-                result += c;
-                break;
-        }
-    }
-    return result;
-}
-
-XMLNamespaceMap::XMLNamespaceMap()
-{
-}
-
-XMLNamespaceMap::XMLNamespaceMap(char const*const* nspaces)
-
-{
-    while (*nspaces) {
-        m_map[nspaces[1]] = nspaces[0];
-        nspaces += 2;
-    }
-}
-
-string
-XMLNamespaceMap::Get(const string& ns) const
-{
-    if (ns == "xml") {
-        return ns;
-    }
-    map<string,string>::const_iterator it = m_map.find(ns);
-    if (it == m_map.end()) {
-        return "";
-    } else {
-        return it->second;
-    }
-}
-
-string
-XMLNamespaceMap::GetPrefix(const string& ns) const
-{
-    if (ns == "") {
-        return "";
-    }
-    map<string,string>::const_iterator it = m_map.find(ns);
-    if (it != m_map.end()) {
-        if (it->second == "") {
-            return "";
-        } else {
-            return it->second + ":";
-        }
-    } else {
-        return ":"; // invalid
-    }
-}
-
-void
-XMLNamespaceMap::AddToAttributes(vector<XMLAttribute>* attrs) const
-{
-    map<string,string>::const_iterator it;
-    for (it=m_map.begin(); it!=m_map.end(); it++) {
-        if (it->second == "xml") {
-            continue;
-        }
-        XMLAttribute attr;
-        if (it->second == "") {
-            attr.name = "xmlns";
-        } else {
-            attr.name = "xmlns:";
-            attr.name += it->second;
-        }
-        attr.value = it->first;
-        attrs->push_back(attr);
-    }
-}
-
-XMLAttribute::XMLAttribute()
-{
-}
-
-XMLAttribute::XMLAttribute(const XMLAttribute& that)
-    :ns(that.ns),
-     name(that.name),
-     value(that.value)
-{
-}
-
-XMLAttribute::XMLAttribute(string n, string na, string v)
-    :ns(n),
-     name(na),
-     value(v)
-{
-}
-
-XMLAttribute::~XMLAttribute()
-{
-}
-
-int
-XMLAttribute::Compare(const XMLAttribute& that) const
-{
-    if (ns != that.ns) {
-        return ns < that.ns ? -1 : 1;
-    }
-    if (name != that.name) {
-        return name < that.name ? -1 : 1;
-    }
-    return 0;
-}
-
-string
-XMLAttribute::Find(const vector<XMLAttribute>& list, const string& ns, const string& name,
-                    const string& def)
-{
-    const size_t N = list.size();
-    for (size_t i=0; i<N; i++) {
-        const XMLAttribute& attr = list[i];
-        if (attr.ns == ns && attr.name == name) {
-            return attr.value;
-        }
-    }
-    return def;
-}
-
-struct xml_handler_data {
-    vector<XMLHandler*> stack;
-    XML_Parser parser;
-    vector<vector<XMLAttribute>*> attributes;
-    string filename;
-};
-
-XMLNode::XMLNode()
-{
-}
-
-XMLNode::~XMLNode()
-{
-//    for_each(m_children.begin(), m_children.end(), delete_object<XMLNode>);
-}
-
-XMLNode*
-XMLNode::Clone() const
-{
-    switch (m_type) {
-        case ELEMENT: {
-            XMLNode* e = XMLNode::NewElement(m_pos, m_ns, m_name, m_attrs, m_pretty);
-            const size_t N = m_children.size();
-            for (size_t i=0; i<N; i++) {
-                e->m_children.push_back(m_children[i]->Clone());
-            }
-            return e;
-        }
-        case TEXT: {
-            return XMLNode::NewText(m_pos, m_text, m_pretty);
-        }
-        default:
-            return NULL;
-    }
-}
-
-XMLNode*
-XMLNode::NewElement(const SourcePos& pos, const string& ns, const string& name,
-                        const vector<XMLAttribute>& attrs, int pretty)
-{
-    XMLNode* node = new XMLNode();
-        node->m_type = ELEMENT;
-        node->m_pretty = pretty;
-        node->m_pos = pos;
-        node->m_ns = ns;
-        node->m_name = name;
-        node->m_attrs = attrs;
-    return node;
-}
-
-XMLNode*
-XMLNode::NewText(const SourcePos& pos, const string& text, int pretty)
-{
-    XMLNode* node = new XMLNode();
-        node->m_type = TEXT;
-        node->m_pretty = pretty;
-        node->m_pos = pos;
-        node->m_text = text;
-    return node;
-}
-
-void
-XMLNode::SetPrettyRecursive(int value)
-{
-    m_pretty = value;
-    const size_t N = m_children.size();
-    for (size_t i=0; i<N; i++) {
-        m_children[i]->SetPrettyRecursive(value);
-    }
-}
-
-string
-XMLNode::ContentsToString(const XMLNamespaceMap& nspaces) const
-{
-    return contents_to_string(nspaces, "");
-}
-
-string
-XMLNode::ToString(const XMLNamespaceMap& nspaces) const
-{
-    return to_string(nspaces, "");
-}
-
-string
-XMLNode::OpenTagToString(const XMLNamespaceMap& nspaces, int pretty) const
-{
-    return open_tag_to_string(nspaces, "", pretty);
-}
-
-string
-XMLNode::contents_to_string(const XMLNamespaceMap& nspaces, const string& indent) const
-{
-    string result;
-    const size_t N = m_children.size();
-    for (size_t i=0; i<N; i++) {
-        const XMLNode* child = m_children[i];
-        switch (child->Type()) {
-        case ELEMENT:
-            if (m_pretty == PRETTY) {
-                result += '\n';
-                result += indent;
-            }
-        case TEXT:
-            result += child->to_string(nspaces, indent);
-            break;
-        }
-    }
-    return result;
-}
-
-string
-trim_string(const string& str)
-{
-    const char* p = str.c_str();
-    while (*p && isspace(*p)) {
-        p++;
-    }
-    const char* q = str.c_str() + str.length() - 1;
-    while (q > p && isspace(*q)) {
-        q--;
-    }
-    q++;
-    return string(p, q-p);
-}
-
-string
-XMLNode::open_tag_to_string(const XMLNamespaceMap& nspaces, const string& indent, int pretty) const
-{
-    if (m_type != ELEMENT) {
-        return "";
-    }
-    string result = "<";
-    result += nspaces.GetPrefix(m_ns);
-    result += m_name;
-
-    vector<XMLAttribute> attrs = m_attrs;
-
-    sort(attrs.begin(), attrs.end());
-
-    const size_t N = attrs.size();
-    for (size_t i=0; i<N; i++) {
-        const XMLAttribute& attr = attrs[i];
-        if (i == 0 || m_pretty == EXACT || pretty == EXACT) {
-            result += ' ';
-        }
-        else {
-            result += "\n";
-            result += indent;
-            result += MORE_INDENT;
-            result += MORE_INDENT;
-        }
-        result += nspaces.GetPrefix(attr.ns);
-        result += attr.name;
-        result += "=\"";
-        result += xml_attr_escape(attr.value);
-        result += '\"';
-    }
-
-    if (m_children.size() > 0) {
-        result += '>';
-    } else {
-        result += " />";
-    }
-    return result;
-}
-
-string
-XMLNode::to_string(const XMLNamespaceMap& nspaces, const string& indent) const
-{
-    switch (m_type)
-    {
-        case TEXT: {
-            if (m_pretty == EXACT) {
-                return xml_text_escape(m_text);
-            } else {
-                return xml_text_escape(trim_string(m_text));
-            }
-        }
-        case ELEMENT: {
-            string result = open_tag_to_string(nspaces, indent, PRETTY);
-            
-            if (m_children.size() > 0) {
-                result += contents_to_string(nspaces, indent + MORE_INDENT);
-
-                if (m_pretty == PRETTY && m_children.size() > 0) {
-                    result += '\n';
-                    result += indent;
-                }
-
-                result += "</";
-                result += nspaces.GetPrefix(m_ns);
-                result += m_name;
-                result += '>';
-            }
-            return result;
-        }
-        default:
-            return "";
-    }
-}
-
-string
-XMLNode::CollapseTextContents() const
-{
-    if (m_type == TEXT) {
-        return m_text;
-    }
-    else if (m_type == ELEMENT) {
-        string result;
-
-        const size_t N=m_children.size();
-        for (size_t i=0; i<N; i++) {
-            result += m_children[i]->CollapseTextContents();
-        }
-
-        return result;
-    }
-    else {
-        return "";
-    }
-}
-
-vector<XMLNode*>
-XMLNode::GetElementsByName(const string& ns, const string& name) const
-{
-    vector<XMLNode*> result;
-    const size_t N=m_children.size();
-    for (size_t i=0; i<N; i++) {
-        XMLNode* child = m_children[i];
-        if (child->m_type == ELEMENT && child->m_ns == ns && child->m_name == name) {
-            result.push_back(child);
-        }
-    }
-    return result;
-}
-
-XMLNode*
-XMLNode::GetElementByNameAt(const string& ns, const string& name, size_t index) const
-{
-    vector<XMLNode*> result;
-    const size_t N=m_children.size();
-    for (size_t i=0; i<N; i++) {
-        XMLNode* child = m_children[i];
-        if (child->m_type == ELEMENT && child->m_ns == ns && child->m_name == name) {
-            if (index == 0) {
-                return child;
-            } else {
-                index--;
-            }
-        }
-    }
-    return NULL;
-}
-
-size_t
-XMLNode::CountElementsByName(const string& ns, const string& name) const
-{
-    size_t result = 0;
-    const size_t N=m_children.size();
-    for (size_t i=0; i<N; i++) {
-        XMLNode* child = m_children[i];
-        if (child->m_type == ELEMENT && child->m_ns == ns && child->m_name == name) {
-            result++;
-        }
-    }
-    return result;
-}
-
-string
-XMLNode::GetAttribute(const string& ns, const string& name, const string& def) const
-{
-    return XMLAttribute::Find(m_attrs, ns, name, def);
-}
-
-static void
-parse_namespace(const char* data, string* ns, string* name)
-{
-    const char* p = strchr(data, NS_SEPARATOR);
-    if (p != NULL) {
-        ns->assign(data, p-data);
-        name->assign(p+1);
-    } else {
-        ns->assign("");
-        name->assign(data);
-    }
-}
-
-static void
-convert_attrs(const char** in, vector<XMLAttribute>* out)
-{
-    while (*in) {
-        XMLAttribute attr;
-        parse_namespace(in[0], &attr.ns, &attr.name);
-        attr.value = in[1];
-        out->push_back(attr);
-        in += 2;
-    }
-}
-
-static bool
-list_contains(const vector<XMLHandler*>& stack, XMLHandler* handler)
-{
-    const size_t N = stack.size();
-    for (size_t i=0; i<N; i++) {
-        if (stack[i] == handler) {
-            return true;
-        }
-    }
-    return false;
-}
-
-static void XMLCALL
-start_element_handler(void *userData, const char *name, const char **attrs)
-{
-    xml_handler_data* data = (xml_handler_data*)userData;
-
-    XMLHandler* handler = data->stack[data->stack.size()-1];
-
-    SourcePos pos(data->filename, (int)XML_GetCurrentLineNumber(data->parser));
-    string nsString;
-    string nameString;
-    XMLHandler* next = handler;
-    vector<XMLAttribute> attributes;
-
-    parse_namespace(name, &nsString, &nameString);
-    convert_attrs(attrs, &attributes);
-
-    handler->OnStartElement(pos, nsString, nameString, attributes, &next);
-
-    if (next == NULL) {
-        next = handler;
-    }
-
-    if (next != handler) {
-        next->elementPos = pos;
-        next->elementNamespace = nsString;
-        next->elementName = nameString;
-        next->elementAttributes = attributes;
-    }
-
-    data->stack.push_back(next);
-}
-
-static void XMLCALL
-end_element_handler(void *userData, const char *name)
-{
-    xml_handler_data* data = (xml_handler_data*)userData;
-
-    XMLHandler* handler = data->stack[data->stack.size()-1];
-    data->stack.pop_back();
-
-    SourcePos pos(data->filename, (int)XML_GetCurrentLineNumber(data->parser));
-
-    if (!list_contains(data->stack, handler)) {
-        handler->OnDone(pos);
-        if (data->stack.size() > 1) {
-            // not top one
-            delete handler;
-        }
-    }
-
-    handler = data->stack[data->stack.size()-1];
-
-    string nsString;
-    string nameString;
-
-    parse_namespace(name, &nsString, &nameString);
-
-    handler->OnEndElement(pos, nsString, nameString);
-}
-
-static void XMLCALL
-text_handler(void *userData, const XML_Char *s, int len)
-{
-    xml_handler_data* data = (xml_handler_data*)userData;
-    XMLHandler* handler = data->stack[data->stack.size()-1];
-    SourcePos pos(data->filename, (int)XML_GetCurrentLineNumber(data->parser));
-    handler->OnText(pos, string(s, len));
-}
-
-static void XMLCALL
-comment_handler(void *userData, const char *comment)
-{
-    xml_handler_data* data = (xml_handler_data*)userData;
-    XMLHandler* handler = data->stack[data->stack.size()-1];
-    SourcePos pos(data->filename, (int)XML_GetCurrentLineNumber(data->parser));
-    handler->OnComment(pos, string(comment));
-}
-
-bool
-XMLHandler::ParseFile(const string& filename, XMLHandler* handler)
-{
-    char buf[16384];
-    int fd = open(filename.c_str(), O_RDONLY);
-    if (fd < 0) {
-        SourcePos(filename, -1).Error("Unable to open file for read: %s", strerror(errno));
-        return false;
-    }
-
-    XML_Parser parser = XML_ParserCreateNS(NULL, NS_SEPARATOR);
-    xml_handler_data state;
-    state.stack.push_back(handler);
-    state.parser = parser;
-    state.filename = filename;
-
-    XML_SetUserData(parser, &state);
-    XML_SetElementHandler(parser, start_element_handler, end_element_handler);
-    XML_SetCharacterDataHandler(parser, text_handler);
-    XML_SetCommentHandler(parser, comment_handler);
-
-    ssize_t len;
-    bool done;
-    do {
-        len = read(fd, buf, sizeof(buf));
-        done = len < (ssize_t)sizeof(buf);
-        if (len < 0) {
-            SourcePos(filename, -1).Error("Error reading file: %s\n", strerror(errno));
-            close(fd);
-            return false;
-        }
-        if (XML_Parse(parser, buf, len, done) == XML_STATUS_ERROR) {
-            SourcePos(filename, (int)XML_GetCurrentLineNumber(parser)).Error(
-                    "Error parsing XML: %s\n", XML_ErrorString(XML_GetErrorCode(parser)));
-            close(fd);
-            return false;
-        }
-    } while (!done);
-
-    XML_ParserFree(parser);
-
-    close(fd);
-    
-    return true;
-}
-
-bool
-XMLHandler::ParseString(const string& filename, const string& text, XMLHandler* handler)
-{
-    XML_Parser parser = XML_ParserCreateNS(NULL, NS_SEPARATOR);
-    xml_handler_data state;
-    state.stack.push_back(handler);
-    state.parser = parser;
-    state.filename = filename;
-
-    XML_SetUserData(parser, &state);
-    XML_SetElementHandler(parser, start_element_handler, end_element_handler);
-    XML_SetCharacterDataHandler(parser, text_handler);
-    XML_SetCommentHandler(parser, comment_handler);
-
-    if (XML_Parse(parser, text.c_str(), text.size(), true) == XML_STATUS_ERROR) {
-        SourcePos(filename, (int)XML_GetCurrentLineNumber(parser)).Error(
-                "Error parsing XML: %s\n", XML_ErrorString(XML_GetErrorCode(parser)));
-        return false;
-    }
-
-    XML_ParserFree(parser);
-    
-    return true;
-}
-
-XMLHandler::XMLHandler()
-{
-}
-
-XMLHandler::~XMLHandler()
-{
-}
-
-int
-XMLHandler::OnStartElement(const SourcePos& pos, const string& ns, const string& name,
-                            const vector<XMLAttribute>& attrs, XMLHandler** next)
-{
-    return 0;
-}
-
-int
-XMLHandler::OnEndElement(const SourcePos& pos, const string& ns, const string& name)
-{
-    return 0;
-}
-
-int
-XMLHandler::OnText(const SourcePos& pos, const string& text)
-{
-    return 0;
-}
-
-int
-XMLHandler::OnComment(const SourcePos& pos, const string& text)
-{
-    return 0;
-}
-
-int
-XMLHandler::OnDone(const SourcePos& pos)
-{
-    return 0;
-}
-
-TopElementHandler::TopElementHandler(const string& ns, const string& name, XMLHandler* next)
-    :m_ns(ns),
-     m_name(name),
-     m_next(next)
-{
-}
-
-int
-TopElementHandler::OnStartElement(const SourcePos& pos, const string& ns, const string& name,
-                            const vector<XMLAttribute>& attrs, XMLHandler** next)
-{
-    *next = m_next;
-    return 0;
-}
-
-int
-TopElementHandler::OnEndElement(const SourcePos& pos, const string& ns, const string& name)
-{
-    return 0;
-}
-
-int
-TopElementHandler::OnText(const SourcePos& pos, const string& text)
-{
-    return 0;
-}
-
-int
-TopElementHandler::OnDone(const SourcePos& pos)
-{
-    return 0;
-}
-
-
-NodeHandler::NodeHandler(XMLNode* root, int pretty)
-    :m_root(root),
-     m_pretty(pretty)
-{
-    if (root != NULL) {
-        m_nodes.push_back(root);
-    }
-}
-
-NodeHandler::~NodeHandler()
-{
-}
-
-int
-NodeHandler::OnStartElement(const SourcePos& pos, const string& ns, const string& name,
-                            const vector<XMLAttribute>& attrs, XMLHandler** next)
-{
-    int pretty;
-    if (XMLAttribute::Find(attrs, XMLNS_XMLNS, "space", "") == "preserve") {
-        pretty = XMLNode::EXACT;
-    } else {
-        if (m_root == NULL) {
-            pretty = m_pretty;
-        } else {
-            pretty = m_nodes[m_nodes.size()-1]->Pretty();
-        }
-    }
-    XMLNode* n = XMLNode::NewElement(pos, ns, name, attrs, pretty);
-    if (m_root == NULL) {
-        m_root = n;
-    } else {
-        m_nodes[m_nodes.size()-1]->EditChildren().push_back(n);
-    }
-    m_nodes.push_back(n);
-    return 0;
-}
-
-int
-NodeHandler::OnEndElement(const SourcePos& pos, const string& ns, const string& name)
-{
-    m_nodes.pop_back();
-    return 0;
-}
-
-int
-NodeHandler::OnText(const SourcePos& pos, const string& text)
-{
-    if (m_root == NULL) {
-        return 1;
-    }
-    XMLNode* n = XMLNode::NewText(pos, text, m_nodes[m_nodes.size()-1]->Pretty());
-    m_nodes[m_nodes.size()-1]->EditChildren().push_back(n);
-    return 0;
-}
-
-int
-NodeHandler::OnComment(const SourcePos& pos, const string& text)
-{
-    return 0;
-}
-
-int
-NodeHandler::OnDone(const SourcePos& pos)
-{
-    return 0;
-}
-
-XMLNode*
-NodeHandler::ParseFile(const string& filename, int pretty)
-{
-    NodeHandler handler(NULL, pretty);
-    if (!XMLHandler::ParseFile(filename, &handler)) {
-        fprintf(stderr, "error parsing file: %s\n", filename.c_str());
-        return NULL;
-    }
-    return handler.Root();
-}
-
-XMLNode*
-NodeHandler::ParseString(const string& filename, const string& text, int pretty)
-{
-    NodeHandler handler(NULL, pretty);
-    if (!XMLHandler::ParseString(filename, text, &handler)) {
-        fprintf(stderr, "error parsing file: %s\n", filename.c_str());
-        return NULL;
-    }
-    return handler.Root();
-}
-
-
diff --git a/tools/localize/XMLHandler.h b/tools/localize/XMLHandler.h
deleted file mode 100644
index 324385f..0000000
--- a/tools/localize/XMLHandler.h
+++ /dev/null
@@ -1,198 +0,0 @@
-#ifndef XML_H
-#define XML_H
-
-#include "SourcePos.h"
-
-#include <algorithm>
-#include <string>
-#include <vector>
-#include <map>
-
-#define XMLNS_XMLNS "http://www.w3.org/XML/1998/namespace"
-
-using namespace std;
-
-string trim_string(const string& str);
-
-struct XMLAttribute
-{
-    string ns;
-    string name;
-    string value;
-
-    XMLAttribute();
-    XMLAttribute(const XMLAttribute& that);
-    XMLAttribute(string ns, string name, string value);
-    ~XMLAttribute();
-
-    int Compare(const XMLAttribute& that) const;
-
-    inline bool operator<(const XMLAttribute& that) const { return Compare(that) < 0; }
-    inline bool operator<=(const XMLAttribute& that) const { return Compare(that) <= 0; }
-    inline bool operator==(const XMLAttribute& that) const { return Compare(that) == 0; }
-    inline bool operator!=(const XMLAttribute& that) const { return Compare(that) != 0; }
-    inline bool operator>=(const XMLAttribute& that) const { return Compare(that) >= 0; }
-    inline bool operator>(const XMLAttribute& that) const { return Compare(that) > 0; }
-
-    static string Find(const vector<XMLAttribute>& list,
-                                const string& ns, const string& name, const string& def);
-};
-
-class XMLNamespaceMap
-{
-public:
-    XMLNamespaceMap();
-    XMLNamespaceMap(char const*const* nspaces);
-    string Get(const string& ns) const;
-    string GetPrefix(const string& ns) const;
-    void AddToAttributes(vector<XMLAttribute>* attrs) const;
-private:
-    map<string,string> m_map;
-};
-
-struct XMLNode
-{
-public:
-    enum {
-        EXACT = 0,
-        PRETTY = 1
-    };
-
-    enum {
-        ELEMENT = 0,
-        TEXT = 1
-    };
-
-    static XMLNode* NewElement(const SourcePos& pos, const string& ns, const string& name,
-                        const vector<XMLAttribute>& attrs, int pretty);
-    static XMLNode* NewText(const SourcePos& pos, const string& text, int pretty);
-
-    ~XMLNode();
-
-    // a deep copy
-    XMLNode* Clone() const;
-
-    inline int Type() const                                     { return m_type; }
-    inline int Pretty() const                                   { return m_pretty; }
-    void SetPrettyRecursive(int value);
-    string ContentsToString(const XMLNamespaceMap& nspaces) const;
-    string ToString(const XMLNamespaceMap& nspaces) const;
-    string OpenTagToString(const XMLNamespaceMap& nspaces, int pretty) const;
-
-    string CollapseTextContents() const;
-
-    inline const SourcePos& Position() const                    { return m_pos; }
-
-    // element
-    inline string Namespace() const                             { return m_ns; }
-    inline string Name() const                                  { return m_name; }
-    inline void SetName(const string& ns, const string& n)      { m_ns = ns; m_name = n; }
-    inline const vector<XMLAttribute>& Attributes() const       { return m_attrs; }
-    inline vector<XMLAttribute>& EditAttributes()               { return m_attrs; }
-    inline const vector<XMLNode*>& Children() const             { return m_children; }
-    inline vector<XMLNode*>& EditChildren()                     { return m_children; }
-    vector<XMLNode*> GetElementsByName(const string& ns, const string& name) const;
-    XMLNode* GetElementByNameAt(const string& ns, const string& name, size_t index) const;
-    size_t CountElementsByName(const string& ns, const string& name) const;
-    string GetAttribute(const string& ns, const string& name, const string& def) const;
-
-    // text
-    inline string Text() const                                  { return m_text; }
-
-private:
-    XMLNode();
-    XMLNode(const XMLNode&);
-
-    string contents_to_string(const XMLNamespaceMap& nspaces, const string& indent) const;
-    string to_string(const XMLNamespaceMap& nspaces, const string& indent) const;
-    string open_tag_to_string(const XMLNamespaceMap& nspaces, const string& indent,
-            int pretty) const;
-
-    int m_type;
-    int m_pretty;
-    SourcePos m_pos;
-
-    // element
-    string m_ns;
-    string m_name;
-    vector<XMLAttribute> m_attrs;
-    vector<XMLNode*> m_children;
-
-    // text
-    string m_text;
-};
-
-class XMLHandler
-{
-public:
-    // information about the element that started us
-    SourcePos elementPos;
-    string elementNamespace;
-    string elementName;
-    vector<XMLAttribute> elementAttributes;
-
-    XMLHandler();
-    virtual ~XMLHandler();
-
-    XMLHandler* parent;
-
-    virtual int OnStartElement(const SourcePos& pos, const string& ns, const string& name,
-                                const vector<XMLAttribute>& attrs, XMLHandler** next);
-    virtual int OnEndElement(const SourcePos& pos, const string& ns, const string& name);
-    virtual int OnText(const SourcePos& pos, const string& text);
-    virtual int OnComment(const SourcePos& pos, const string& text);
-    virtual int OnDone(const SourcePos& pos);
-
-    static bool ParseFile(const string& filename, XMLHandler* handler);
-    static bool ParseString(const string& filename, const string& text, XMLHandler* handler);
-};
-
-class TopElementHandler : public XMLHandler
-{
-public:
-    TopElementHandler(const string& ns, const string& name, XMLHandler* next);
-
-    virtual int OnStartElement(const SourcePos& pos, const string& ns, const string& name,
-                                const vector<XMLAttribute>& attrs, XMLHandler** next);
-    virtual int OnEndElement(const SourcePos& pos, const string& ns, const string& name);
-    virtual int OnText(const SourcePos& pos, const string& text);
-    virtual int OnDone(const SourcePos& endPos);
-
-private:
-    string m_ns;
-    string m_name;
-    XMLHandler* m_next;
-};
-
-class NodeHandler : public XMLHandler
-{
-public:
-    // after it's done, you own everything created and added to root
-    NodeHandler(XMLNode* root, int pretty);
-    ~NodeHandler();
-
-    virtual int OnStartElement(const SourcePos& pos, const string& ns, const string& name,
-                                const vector<XMLAttribute>& attrs, XMLHandler** next);
-    virtual int OnEndElement(const SourcePos& pos, const string& ns, const string& name);
-    virtual int OnText(const SourcePos& pos, const string& text);
-    virtual int OnComment(const SourcePos& pos, const string& text);
-    virtual int OnDone(const SourcePos& endPos);
-
-    inline XMLNode* Root() const                { return m_root; }
-
-    static XMLNode* ParseFile(const string& filename, int pretty);
-    static XMLNode* ParseString(const string& filename, const string& text, int pretty);
-
-private:
-    XMLNode* m_root;
-    int m_pretty;
-    vector<XMLNode*> m_nodes;
-};
-
-template <class T>
-static void delete_object(T* obj)
-{
-    delete obj;
-}
-
-#endif // XML_H
diff --git a/tools/localize/XMLHandler_test.cpp b/tools/localize/XMLHandler_test.cpp
deleted file mode 100644
index 1c81c0c..0000000
--- a/tools/localize/XMLHandler_test.cpp
+++ /dev/null
@@ -1,133 +0,0 @@
-#include "XMLHandler.h"
-#include <stdio.h>
-#include <unistd.h>
-#include <fcntl.h>
-
-const char *const NS_MAP[] = {
-    "xml", XMLNS_XMLNS,
-    NULL, NULL
-};
-
-const XMLNamespaceMap NO_NAMESPACES(NS_MAP);
-
-char const*const EXPECTED_EXACT = 
-       "<ASDF>\n"
-        "    <a id=\"system\" old-cl=\"1\" new-cl=\"43019\">\n"
-        "        <app dir=\"apps/common\" />\n"
-        "    </a>\n"
-        "    <a id=\"samples\" old-cl=\"1\" new-cl=\"43019\">asdf\n"
-        "        <app dir=\"samples/NotePad\" />\n"
-        "        <app dir=\"samples/LunarLander\" />\n"
-        "        <something>a<b>,</b>b </something>\n"
-        "        <exact xml:space=\"preserve\">a<b>,</b>b </exact>\n"
-        "    </a>\n"
-        "</ASDF>\n";
-
-char const*const EXPECTED_PRETTY =
-        "<ASDF>\n"
-        "  <a id=\"system\"\n"
-        "      old-cl=\"1\"\n"
-        "      new-cl=\"43019\">\n"
-        "    <app dir=\"apps/common\" />\n"
-        "  </a>\n"
-        "  <a id=\"samples\"\n"
-        "      old-cl=\"1\"\n"
-        "      new-cl=\"43019\">asdf\n"
-        "    <app dir=\"samples/NotePad\" />\n"
-        "    <app dir=\"samples/LunarLander\" />\n"
-        "    <something>a\n"
-        "      <b>,\n"
-        "      </b>b \n"
-        "    </something>\n"
-        "    <exact xml:space=\"preserve\">a<b>,</b>b </exact>\n"
-        "  </a>\n"
-        "</ASDF>\n";
-
-static string
-read_file(const string& filename)
-{
-    char buf[1024];
-    int fd = open(filename.c_str(), O_RDONLY);
-    if (fd < 0) {
-        return "";
-    }
-    string result;
-    while (true) {
-        ssize_t len = read(fd, buf, sizeof(buf)-1);
-        buf[len] = '\0';
-        if (len <= 0) {
-            break;
-        }
-        result.append(buf, len);
-    }
-    close(fd);
-    return result;
-}
-
-static int
-ParseFile_EXACT_test()
-{
-    XMLNode* root = NodeHandler::ParseFile("testdata/xml.xml", XMLNode::EXACT);
-    if (root == NULL) {
-        return 1;
-    }
-    string result = root->ToString(NO_NAMESPACES);
-    delete root;
-    //printf("[[%s]]\n", result.c_str());
-    return result == EXPECTED_EXACT;
-}
-
-static int
-ParseFile_PRETTY_test()
-{
-    XMLNode* root = NodeHandler::ParseFile("testdata/xml.xml", XMLNode::PRETTY);
-    if (root == NULL) {
-        return 1;
-    }
-    string result = root->ToString(NO_NAMESPACES);
-    delete root;
-    //printf("[[%s]]\n", result.c_str());
-    return result == EXPECTED_PRETTY;
-}
-
-static int
-ParseString_EXACT_test()
-{
-    string text = read_file("testdata/xml.xml");
-    XMLNode* root = NodeHandler::ParseString("testdata/xml.xml", text, XMLNode::EXACT);
-    if (root == NULL) {
-        return 1;
-    }
-    string result = root->ToString(NO_NAMESPACES);
-    delete root;
-    //printf("[[%s]]\n", result.c_str());
-    return result == EXPECTED_EXACT;
-}
-
-static int
-ParseString_PRETTY_test()
-{
-    string text = read_file("testdata/xml.xml");
-    XMLNode* root = NodeHandler::ParseString("testdata/xml.xml", text, XMLNode::PRETTY);
-    if (root == NULL) {
-        return 1;
-    }
-    string result = root->ToString(NO_NAMESPACES);
-    delete root;
-    //printf("[[%s]]\n", result.c_str());
-    return result == EXPECTED_PRETTY;
-}
-
-int
-XMLHandler_test()
-{
-    int err = 0;
-    bool all = true;
-
-    if (all) err |= ParseFile_EXACT_test();
-    if (all) err |= ParseFile_PRETTY_test();
-    if (all) err |= ParseString_EXACT_test();
-    if (all) err |= ParseString_PRETTY_test();
-
-    return err;
-}
diff --git a/tools/localize/XMLNode.h b/tools/localize/XMLNode.h
deleted file mode 100644
index bfb9f55..0000000
--- a/tools/localize/XMLNode.h
+++ /dev/null
@@ -1,19 +0,0 @@
-#ifndef XMLNODE_H
-#define XMLNODE_H
-
-#include <string>
-
-using namespace std;
-
-struct XMLAttribute
-{
-    string ns;
-    string name;
-    string value;
-
-    static string Find(const vector<XMLAttribute>& list,
-                                const string& ns, const string& name, const string& def);
-};
-
-
-#endif // XMLNODE_H
diff --git a/tools/localize/file_utils.cpp b/tools/localize/file_utils.cpp
deleted file mode 100644
index 775ce2f..0000000
--- a/tools/localize/file_utils.cpp
+++ /dev/null
@@ -1,181 +0,0 @@
-#include <string.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include "file_utils.h"
-#include "Perforce.h"
-#include <utils/String8.h>
-#include <sys/fcntl.h>
-#include <sys/stat.h>
-#include <errno.h>
-#include <string.h>
-#include <stdlib.h>
-#include <cstdio>
-#include "log.h"
-
-using namespace android;
-using namespace std;
-
-static string
-parent_dir(const string& path)
-{
-    return string(String8(path.c_str()).getPathDir().string());
-}
-
-static int
-mkdirs(const char* last)
-{
-    String8 dest;
-    const char* s = last-1;
-    int err;
-    do {
-        s++;
-        if (s > last && (*s == '.' || *s == 0)) {
-            String8 part(last, s-last);
-            dest.appendPath(part);
-#ifdef HAVE_MS_C_RUNTIME
-            err = _mkdir(dest.string());
-#else                    
-            err = mkdir(dest.string(), S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP);
-#endif                    
-            if (err != 0) {
-                return err;
-            }
-            last = s+1;
-        }
-    } while (*s);
-    return 0;
-}
-
-string
-translated_file_name(const string& file, const string& locale)
-{
-    const char* str = file.c_str();
-    const char* p = str + file.length();
-    const char* rest = NULL;
-    const char* values = p;
-
-    while (p > str) {
-        p--;
-        if (*p == '/') {
-            rest = values;
-            values = p;
-            if (0 == strncmp("values", values+1, rest-values-1)) {
-                break;
-            }
-        }
-    }
-    values++;
-
-    string result(str, values-str);
-    result.append(values, rest-values);
-
-    string language, region;
-    if (locale == "") {
-        language = "";
-        region = "";
-    }
-    else if (!split_locale(locale, &language, &region)) {
-        return "";
-    }
-
-    if (language != "") {
-        result += '-';
-        result += language;
-    }
-    if (region != "") {
-        result += "-r";
-        result += region;
-    }
-
-    result += rest;
-
-    return result;
-}
-
-ValuesFile*
-get_values_file(const string& filename, const Configuration& configuration,
-                int version, const string& versionString, bool printOnFailure)
-{
-    int err;
-    string text;
-
-    log_printf("get_values_file filename=%s\n", filename.c_str());
-    err = Perforce::GetFile(filename, versionString, &text, printOnFailure);
-    if (err != 0 || text == "") {
-        return NULL;
-    }
-
-    ValuesFile* result = ValuesFile::ParseString(filename, text, configuration, version,
-                                                    versionString);
-    if (result == NULL) {
-        fprintf(stderr, "unable to parse file: %s\n", filename.c_str());
-        exit(1);
-    }
-    return result;
-}
-
-ValuesFile*
-get_local_values_file(const string& filename, const Configuration& configuration,
-                int version, const string& versionString, bool printOnFailure)
-{
-    int err;
-    string text;
-    char buf[2049];
-    int fd;
-    ssize_t amt;
-    
-    fd = open(filename.c_str(), O_RDONLY);
-    if (fd == -1) {
-        fprintf(stderr, "unable to open file: %s\n", filename.c_str());
-        return NULL;
-    }
-
-    while ((amt = read(fd, buf, sizeof(buf)-1)) > 0) {
-        text.append(buf, amt);
-    }
-
-    close(fd);
-    
-    if (text == "") {
-        return NULL;
-    }
-        
-    ValuesFile* result = ValuesFile::ParseString(filename, text, configuration, version,
-                                                    versionString);
-    if (result == NULL) {
-        fprintf(stderr, "unable to parse file: %s\n", filename.c_str());
-        exit(1);
-    }
-    return result;
-}
-
-void
-print_file_status(size_t j, size_t J, const string& message)
-{
-    printf("\r%s file %zd of %zd...", message.c_str(), j, J);
-    fflush(stdout);
-}
-
-int
-write_to_file(const string& filename, const string& text)
-{
-    mkdirs(parent_dir(filename).c_str());
-    int fd = open(filename.c_str(), O_RDWR | O_CREAT | O_TRUNC, 0666);
-    if (fd < 0) {
-        fprintf(stderr, "unable to open file for write (%s): %s\n", strerror(errno),
-                filename.c_str());
-        return -1;
-    }
-
-    ssize_t amt = write(fd, text.c_str(), text.length());
-
-    close(fd);
-
-    if (amt < 0) {
-        return amt;
-    }
-    return amt == (ssize_t)text.length() ? 0 : -1;
-}
-
-
diff --git a/tools/localize/file_utils.h b/tools/localize/file_utils.h
deleted file mode 100644
index 7706587..0000000
--- a/tools/localize/file_utils.h
+++ /dev/null
@@ -1,22 +0,0 @@
-#ifndef FILE_UTILS_H
-#define FILE_UTILS_H
-
-#include "ValuesFile.h"
-#include "Configuration.h"
-#include <string>
-#include <cstdio>
-
-using namespace std;
-
-string translated_file_name(const string& file, const string& locale);
-
-ValuesFile* get_values_file(const string& filename, const Configuration& configuration,
-                int version, const string& versionString, bool printOnFailure);
-ValuesFile* get_local_values_file(const string& filename, const Configuration& configuration,
-                int version, const string& versionString, bool printOnFailure);
-
-void print_file_status(size_t j, size_t J, const string& message = "Reading");
-int write_to_file(const string& filename, const string& text);
-
-
-#endif // FILE_UTILS_H
diff --git a/tools/localize/localize.cpp b/tools/localize/localize.cpp
deleted file mode 100644
index 68c03b6..0000000
--- a/tools/localize/localize.cpp
+++ /dev/null
@@ -1,768 +0,0 @@
-#include "SourcePos.h"
-#include "ValuesFile.h"
-#include "XLIFFFile.h"
-#include "Perforce.h"
-#include "merge_res_and_xliff.h"
-#include "localize.h"
-#include "file_utils.h"
-#include "res_check.h"
-#include "xmb.h"
-
-#include <host/pseudolocalize.h>
-
-#include <stdlib.h>
-#include <stdarg.h>
-#include <sstream>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-
-using namespace std;
-
-FILE* g_logFile = NULL;
-
-int test();
-
-int
-read_settings(const string& filename, map<string,Settings>* result, const string& rootDir)
-{
-    XMLNode* root = NodeHandler::ParseFile(filename, XMLNode::PRETTY);
-    if (root == NULL) {
-        SourcePos(filename, -1).Error("Error reading file.");
-        return 1;
-    }
-
-    // <configuration>
-    vector<XMLNode*> configNodes = root->GetElementsByName("", "configuration");
-    const size_t I = configNodes.size();
-    for (size_t i=0; i<I; i++) {
-        const XMLNode* configNode = configNodes[i];
-
-        Settings settings;
-        settings.id = configNode->GetAttribute("", "id", "");
-        if (settings.id == "") {
-            configNode->Position().Error("<configuration> needs an id attribute.");
-            delete root;
-            return 1;
-        }
-
-        settings.oldVersion = configNode->GetAttribute("", "old-cl", "");
-
-        settings.currentVersion = configNode->GetAttribute("", "new-cl", "");
-        if (settings.currentVersion == "") {
-            configNode->Position().Error("<configuration> needs a new-cl attribute.");
-            delete root;
-            return 1;
-        }
-
-        // <app>
-        vector<XMLNode*> appNodes = configNode->GetElementsByName("", "app");
-
-        const size_t J = appNodes.size();
-        for (size_t j=0; j<J; j++) {
-            const XMLNode* appNode = appNodes[j];
-
-            string dir = appNode->GetAttribute("", "dir", "");
-            if (dir == "") {
-                appNode->Position().Error("<app> needs a dir attribute.");
-                delete root;
-                return 1;
-            }
-
-            settings.apps.push_back(dir);
-        }
-
-        // <reject>
-        vector<XMLNode*> rejectNodes = configNode->GetElementsByName("", "reject");
-
-        const size_t K = rejectNodes.size();
-        for (size_t k=0; k<K; k++) {
-            const XMLNode* rejectNode = rejectNodes[k];
-
-            Reject reject;
-
-            reject.file = rejectNode->GetAttribute("", "file", "");
-            if (reject.file == "") {
-                rejectNode->Position().Error("<reject> needs a file attribute.");
-                delete root;
-                return 1;
-            }
-            string f =  reject.file;
-            reject.file = rootDir;
-            reject.file += '/';
-            reject.file += f;
-            
-            reject.name = rejectNode->GetAttribute("", "name", "");
-            if (reject.name == "") {
-                rejectNode->Position().Error("<reject> needs a name attribute.");
-                delete root;
-                return 1;
-            }
-
-            reject.comment = trim_string(rejectNode->CollapseTextContents());
-
-            settings.reject.push_back(reject);
-        }
-
-        (*result)[settings.id] = settings;
-    }
-
-    delete root;
-    return 0;
-}
-
-
-static void
-ValuesFile_to_XLIFFFile(const ValuesFile* values, XLIFFFile* xliff, const string& englishFilename)
-{
-    const set<StringResource>& strings = values->GetStrings();
-    for (set<StringResource>::const_iterator it=strings.begin(); it!=strings.end(); it++) {
-        StringResource res = *it;
-        res.file = englishFilename;
-        xliff->AddStringResource(res);
-    }
-}
-
-static bool
-contains_reject(const Settings& settings, const string& file, const TransUnit& tu)
-{
-    const string name = tu.id;
-    const vector<Reject>& reject = settings.reject;
-    const size_t I = reject.size();
-    for (size_t i=0; i<I; i++) {
-        const Reject& r = reject[i];
-        if (r.file == file && r.name == name) {
-            return true;
-        }
-    }
-    return false;
-}
-
-/**
- * If it's been rejected, then we keep whatever info we have.
- *
- * Implements this truth table:
- *
- *    S   AT   AS     Keep
- *   -----------------------
- *    0    0    0      0    (this case can't happen)
- *    0    0    1      0    (it was there, never translated, and removed)
- *    0    1    0      0    (somehow it got translated, but it was removed)
- *    0    1    1      0    (it was removed after having been translated)
- *
- *    1    0    0      1    (it was just added)
- *    1    0    1      1    (it was added, has been changed, but it never got translated)
- *    1    1    0      1    (somehow it got translated, but we don't know based on what)
- *    1    1    1     0/1   (it's in both.  0 if S=AS b/c there's no need to retranslate if they're
- *                           the same.  1 if S!=AS because S changed, so it should be retranslated)
- *
- * The first four are cases where, whatever happened in the past, the string isn't there
- * now, so it shouldn't be in the XLIFF file.
- *
- * For cases 4 and 5, the string has never been translated, so get it translated.
- *
- * For case 6, it's unclear where the translated version came from, so we're conservative
- * and send it back for them to have another shot at.
- *
- * For case 7, we have some data.  We have two choices.  We could rely on the translator's
- * translation memory or tools to notice that the strings haven't changed, and populate the
- * <target> field themselves.  Or if the string hasn't changed since last time, we can just
- * not even tell them about it.  As the project nears the end, it will be convenient to see
- * the xliff files reducing in size, so we pick the latter.  Obviously, if the string has
- * changed, then we need to get it retranslated.
- */
-bool
-keep_this_trans_unit(const string& file, const TransUnit& unit, void* cookie)
-{
-    const Settings* settings = reinterpret_cast<const Settings*>(cookie);
-
-    if (contains_reject(*settings, file, unit)) {
-        return true;
-    }
-
-    if (unit.source.id == "") {
-        return false;
-    }
-    if (unit.altTarget.id == "" || unit.altSource.id == "") {
-        return true;
-    }
-    return unit.source.value->ContentsToString(XLIFF_NAMESPACES)
-            != unit.altSource.value->ContentsToString(XLIFF_NAMESPACES);
-}
-
-int
-validate_config(const string& settingsFile, const map<string,Settings>& settings,
-        const string& config)
-{
-    if (settings.find(config) == settings.end()) {
-        SourcePos(settingsFile, -1).Error("settings file does not contain setting: %s\n",
-                config.c_str());
-        return 1;
-    }
-    return 0;
-}
-
-int
-validate_configs(const string& settingsFile, const map<string,Settings>& settings,
-        const vector<string>& configs)
-{
-    int err = 0;
-    for (size_t i=0; i<configs.size(); i++) {
-        string config = configs[i];
-        err |= validate_config(settingsFile, settings, config);
-    }
-    return err;
-}
-
-int
-select_files(vector<string> *resFiles, const string& config,
-        const map<string,Settings>& settings, const string& rootDir)
-{
-    int err;
-    vector<vector<string> > allResFiles;
-    vector<string> configs;
-    configs.push_back(config);
-    err = select_files(&allResFiles, configs, settings, rootDir);
-    if (err == 0) {
-        *resFiles = allResFiles[0];
-    }
-    return err;
-}
-
-int
-select_files(vector<vector<string> > *allResFiles, const vector<string>& configs,
-        const map<string,Settings>& settings, const string& rootDir)
-{
-    int err;
-    printf("Selecting files...");
-    fflush(stdout);
-
-    for (size_t i=0; i<configs.size(); i++) {
-        const string& config = configs[i];
-        const Settings& setting = settings.find(config)->second;
-
-        vector<string> resFiles;
-        err = Perforce::GetResourceFileNames(setting.currentVersion, rootDir,
-                                                setting.apps, &resFiles, true);
-        if (err != 0) {
-            fprintf(stderr, "error with perforce.  bailing\n");
-            return err;
-        }
-
-        allResFiles->push_back(resFiles);
-    }
-    return 0;
-}
-
-static int
-do_export(const string& settingsFile, const string& rootDir, const string& outDir,
-            const string& targetLocale, const vector<string>& configs)
-{
-    bool success = true;
-    int err;
-
-    if (false) {
-        printf("settingsFile=%s\n", settingsFile.c_str());
-        printf("rootDir=%s\n", rootDir.c_str());
-        printf("outDir=%s\n", outDir.c_str());
-        for (size_t i=0; i<configs.size(); i++) {
-            printf("config[%zd]=%s\n", i, configs[i].c_str());
-        }
-    }
-
-    map<string,Settings> settings;
-    err = read_settings(settingsFile, &settings, rootDir);
-    if (err != 0) {
-        return err;
-    }
-
-    err = validate_configs(settingsFile, settings, configs);
-    if (err != 0) {
-        return err;
-    }
-
-    vector<vector<string> > allResFiles;
-    err = select_files(&allResFiles, configs, settings, rootDir);
-    if (err != 0) {
-        return err;
-    }
-
-    size_t totalFileCount = 0;
-    for (size_t i=0; i<allResFiles.size(); i++) {
-        totalFileCount += allResFiles[i].size();
-    }
-    totalFileCount *= 3; // we try all 3 versions of the file
-
-    size_t fileProgress = 0;
-    vector<Stats> stats;
-    vector<pair<string,XLIFFFile*> > xliffs;
-
-    for (size_t i=0; i<configs.size(); i++) {
-        const string& config = configs[i];
-        const Settings& setting = settings[config];
-
-        if (false) {
-            fprintf(stderr, "Configuration: %s (%zd of %zd)\n", config.c_str(), i+1,
-                    configs.size());
-            fprintf(stderr, "  Old CL:     %s\n", setting.oldVersion.c_str());
-            fprintf(stderr, "  Current CL: %s\n", setting.currentVersion.c_str());
-        }
-
-        Configuration english;
-            english.locale = "en_US";
-        Configuration translated;
-            translated.locale = targetLocale;
-        XLIFFFile* xliff = XLIFFFile::Create(english, translated, setting.currentVersion);
-
-        const vector<string>& resFiles = allResFiles[i];
-        const size_t J = resFiles.size();
-        for (size_t j=0; j<J; j++) {
-            string resFile = resFiles[j];
-
-            // parse the files into a ValuesFile
-            // pull out the strings and add them to the XLIFFFile
-            
-            // current file
-            print_file_status(++fileProgress, totalFileCount);
-            ValuesFile* currentFile = get_values_file(resFile, english, CURRENT_VERSION,
-                                                        setting.currentVersion, true);
-            if (currentFile != NULL) {
-                ValuesFile_to_XLIFFFile(currentFile, xliff, resFile);
-                //printf("currentFile=[%s]\n", currentFile->ToString().c_str());
-            } else {
-                fprintf(stderr, "error reading file %s@%s\n", resFile.c_str(),
-                            setting.currentVersion.c_str());
-                success = false;
-            }
-
-            // old file
-            print_file_status(++fileProgress, totalFileCount);
-            ValuesFile* oldFile = get_values_file(resFile, english, OLD_VERSION,
-                                                        setting.oldVersion, false);
-            if (oldFile != NULL) {
-                ValuesFile_to_XLIFFFile(oldFile, xliff, resFile);
-                //printf("oldFile=[%s]\n", oldFile->ToString().c_str());
-            }
-
-            // translated version
-            // (get the head of the tree for the most recent translation, but it's considered
-            // the old one because the "current" one hasn't been made yet, and this goes into
-            // the <alt-trans> tag if necessary
-            print_file_status(++fileProgress, totalFileCount);
-            string transFilename = translated_file_name(resFile, targetLocale);
-            ValuesFile* transFile = get_values_file(transFilename, translated, OLD_VERSION,
-                                                        setting.currentVersion, false);
-            if (transFile != NULL) {
-                ValuesFile_to_XLIFFFile(transFile, xliff, resFile);
-            }
-
-            delete currentFile;
-            delete oldFile;
-            delete transFile;
-        }
-
-        Stats beforeFilterStats = xliff->GetStats(config);
-
-        // run through the XLIFFFile and strip out TransUnits that have identical
-        // old and current source values and are not in the reject list, or just
-        // old values and no source values
-        xliff->Filter(keep_this_trans_unit, (void*)&setting);
-
-        Stats afterFilterStats = xliff->GetStats(config);
-        afterFilterStats.totalStrings = beforeFilterStats.totalStrings;
-
-        // add the reject comments
-        for (vector<Reject>::const_iterator reject = setting.reject.begin();
-                reject != setting.reject.end(); reject++) {
-            TransUnit* tu = xliff->EditTransUnit(reject->file, reject->name);
-            tu->rejectComment = reject->comment;
-        }
-
-        // config-locale-current_cl.xliff
-        stringstream filename;
-        if (outDir != "") {
-            filename << outDir << '/';
-        }
-        filename << config << '-' << targetLocale << '-' << setting.currentVersion << ".xliff";
-        xliffs.push_back(pair<string,XLIFFFile*>(filename.str(), xliff));
-
-        stats.push_back(afterFilterStats);
-    }
-
-    // today is a good day to die
-    if (!success || SourcePos::HasErrors()) {
-        return 1;
-    }
-
-    // write the XLIFF files
-    printf("\nWriting %zd file%s...\n", xliffs.size(), xliffs.size() == 1 ? "" : "s");
-    for (vector<pair<string,XLIFFFile*> >::iterator it = xliffs.begin(); it != xliffs.end(); it++) {
-        const string& filename = it->first;
-        XLIFFFile* xliff = it->second;
-        string text = xliff->ToString();
-        write_to_file(filename, text);
-    }
-
-    // the stats
-    printf("\n"
-           "                                  to          without     total\n"
-           " config               files       translate   comments    strings\n"
-           "-----------------------------------------------------------------------\n");
-    Stats totals;
-        totals.config = "total";
-        totals.files = 0;
-        totals.toBeTranslated = 0;
-        totals.noComments = 0;
-        totals.totalStrings = 0;
-    for (vector<Stats>::iterator it=stats.begin(); it!=stats.end(); it++) {
-        string cfg = it->config;
-        if (cfg.length() > 20) {
-            cfg.resize(20);
-        }
-        printf(" %-20s  %-9zd   %-9zd   %-9zd   %-19zd\n", cfg.c_str(), it->files,
-                it->toBeTranslated, it->noComments, it->totalStrings);
-        totals.files += it->files;
-        totals.toBeTranslated += it->toBeTranslated;
-        totals.noComments += it->noComments;
-        totals.totalStrings += it->totalStrings;
-    }
-    if (stats.size() > 1) {
-        printf("-----------------------------------------------------------------------\n"
-               " %-20s  %-9zd   %-9zd   %-9zd   %-19zd\n", totals.config.c_str(), totals.files,
-                    totals.toBeTranslated, totals.noComments, totals.totalStrings);
-    }
-    printf("\n");
-    return 0;
-}
-
-struct PseudolocalizeSettings {
-    XLIFFFile* xliff;
-    bool expand;
-};
-
-
-string
-pseudolocalize_string(const string& source, const PseudolocalizeSettings* settings)
-{
-    return pseudolocalize_string(source);
-}
-
-static XMLNode*
-pseudolocalize_xml_node(const XMLNode* source, const PseudolocalizeSettings* settings)
-{
-    if (source->Type() == XMLNode::TEXT) {
-        return XMLNode::NewText(source->Position(), pseudolocalize_string(source->Text(), settings),
-                                source->Pretty());
-    } else {
-        XMLNode* target;
-        if (source->Namespace() == XLIFF_XMLNS && source->Name() == "g") {
-            // XXX don't translate these
-            target = XMLNode::NewElement(source->Position(), source->Namespace(),
-                                    source->Name(), source->Attributes(), source->Pretty());
-        } else {
-            target = XMLNode::NewElement(source->Position(), source->Namespace(),
-                                    source->Name(), source->Attributes(), source->Pretty());
-        }
-
-        const vector<XMLNode*>& children = source->Children();
-        const size_t I = children.size();
-        for (size_t i=0; i<I; i++) {
-            target->EditChildren().push_back(pseudolocalize_xml_node(children[i], settings));
-        }
-
-        return target;
-    }
-}
-
-void
-pseudolocalize_trans_unit(const string&file, TransUnit* unit, void* cookie)
-{
-    const PseudolocalizeSettings* settings = (PseudolocalizeSettings*)cookie;
-
-    const StringResource& source = unit->source;
-    StringResource* target = &unit->target;
-    *target = source;
-
-    target->config = settings->xliff->TargetConfig();
-
-    delete target->value;
-    target->value = pseudolocalize_xml_node(source.value, settings);
-}
-
-int
-pseudolocalize_xliff(XLIFFFile* xliff, bool expand)
-{
-    PseudolocalizeSettings settings;
-
-    settings.xliff = xliff;
-    settings.expand = expand;
-    xliff->Map(pseudolocalize_trans_unit, &settings);
-    return 0;
-}
-
-static int
-do_pseudo(const string& infile, const string& outfile, bool expand)
-{
-    int err;
-
-    XLIFFFile* xliff = XLIFFFile::Parse(infile);
-    if (xliff == NULL) {
-        return 1;
-    }
-
-    pseudolocalize_xliff(xliff, expand);
-
-    err = write_to_file(outfile, xliff->ToString());
-
-    delete xliff;
-
-    return err;
-}
-
-void
-log_printf(const char *fmt, ...)
-{
-    int ret;
-    va_list ap;
-
-    if (g_logFile != NULL) {
-        va_start(ap, fmt);
-        ret = vfprintf(g_logFile, fmt, ap);
-        va_end(ap);
-        fflush(g_logFile);
-    }
-}
-
-void
-close_log_file()
-{
-    if (g_logFile != NULL) {
-        fclose(g_logFile);
-    }
-}
-
-void
-open_log_file(const char* file)
-{
-    g_logFile = fopen(file, "w");
-    printf("log file: %s -- %p\n", file, g_logFile);
-    atexit(close_log_file);
-}
-
-static int
-usage()
-{
-    fprintf(stderr,
-            "usage: localize export OPTIONS CONFIGS...\n"
-            "   REQUIRED OPTIONS\n"
-            "     --settings SETTINGS   The settings file to use.  See CONFIGS below.\n"
-            "     --root TREE_ROOT      The location in Perforce of the files.  e.g. //device\n"
-            "     --target LOCALE       The target locale.  See LOCALES below.\n"
-            "\n"
-            "   OPTIONAL OPTIONS\n"
-            "      --out DIR            Directory to put the output files.  Defaults to the\n"
-            "                           current directory if not supplied.  Files are\n"
-            "                           named as follows:\n"
-            "                               CONFIG-LOCALE-CURRENT_CL.xliff\n"
-            "\n"
-            "\n"
-            "usage: localize import XLIFF_FILE...\n"
-            "\n"
-            "Import a translated XLIFF file back into the tree.\n"
-            "\n"
-            "\n"
-            "usage: localize xlb XMB_FILE VALUES_FILES...\n"
-            "\n"
-            "Read resource files from the tree file and write the corresponding XLB file\n"
-            "\n"
-            "Supply all of the android resource files (values files) to export after that.\n"
-            "\n"
-            "\n"
-            "\n"
-            "CONFIGS\n"
-            "\n"
-            "LOCALES\n"
-            "Locales are specified in the form en_US  They will be processed correctly\n"
-            "to locate the resouce files in the tree.\n"
-            "\n"
-            "\n"
-            "usage: localize pseudo OPTIONS INFILE [OUTFILE]\n"
-            "   OPTIONAL OPTIONS\n"
-            "     --big                 Pad strings so they get longer.\n"
-            "\n"
-            "Read INFILE, an XLIFF file, and output a pseudotranslated version of that file.  If\n"
-            "OUTFILE is specified, the results are written there; otherwise, the results are\n"
-            "written back to INFILE.\n"
-            "\n"
-            "\n"
-            "usage: localize rescheck FILES...\n"
-            "\n"
-            "Reads the base strings and prints warnings about bad resources from the given files.\n"
-            "\n");
-    return 1;
-}
-
-int
-main(int argc, const char** argv)
-{
-    //open_log_file("log.txt");
-    //g_logFile = stdout;
-
-    if (argc == 2 && 0 == strcmp(argv[1], "--test")) {
-        return test();
-    }
-
-    if (argc < 2) {
-        return usage();
-    }
-
-    int index = 1;
-    
-    if (0 == strcmp("export", argv[index])) {
-        string settingsFile;
-        string rootDir;
-        string outDir;
-        string baseLocale = "en";
-        string targetLocale;
-        string language, region;
-        vector<string> configs;
-
-        index++;
-        while (index < argc) {
-            if (0 == strcmp("--settings", argv[index])) {
-                settingsFile = argv[index+1];
-                index += 2;
-            }
-            else if (0 == strcmp("--root", argv[index])) {
-                rootDir = argv[index+1];
-                index += 2;
-            }
-            else if (0 == strcmp("--out", argv[index])) {
-                outDir = argv[index+1];
-                index += 2;
-            }
-            else if (0 == strcmp("--target", argv[index])) {
-                targetLocale = argv[index+1];
-                index += 2;
-            }
-            else if (argv[index][0] == '-') {
-                fprintf(stderr, "unknown argument %s\n", argv[index]);
-                return usage();
-            }
-            else {
-                break;
-            }
-        }
-        for (; index<argc; index++) {
-            configs.push_back(argv[index]);
-        }
-
-        if (settingsFile == "" || rootDir == "" || configs.size() == 0 || targetLocale == "") {
-            return usage();
-        }
-        if (!split_locale(targetLocale, &language, &region)) {
-            fprintf(stderr, "illegal --target locale: '%s'\n", targetLocale.c_str());
-            return usage();
-        }
-
-
-        return do_export(settingsFile, rootDir, outDir, targetLocale, configs);
-    }
-    else if (0 == strcmp("import", argv[index])) {
-        vector<string> xliffFilenames;
-
-        index++;
-        for (; index<argc; index++) {
-            xliffFilenames.push_back(argv[index]);
-        }
-
-        return do_merge(xliffFilenames);
-    }
-    else if (0 == strcmp("xlb", argv[index])) {
-        string outfile;
-        vector<string> resFiles;
-
-        index++;
-        if (argc < index+1) {
-            return usage();
-        }
-
-        outfile = argv[index];
-
-        index++;
-        for (; index<argc; index++) {
-            resFiles.push_back(argv[index]);
-        }
-
-        return do_xlb_export(outfile, resFiles);
-    }
-    else if (0 == strcmp("pseudo", argv[index])) {
-        string infile;
-        string outfile;
-        bool big = false;
-
-        index++;
-        while (index < argc) {
-            if (0 == strcmp("--big", argv[index])) {
-                big = true;
-                index += 1;
-            }
-            else if (argv[index][0] == '-') {
-                fprintf(stderr, "unknown argument %s\n", argv[index]);
-                return usage();
-            }
-            else {
-                break;
-            }
-        }
-
-        if (index == argc-1) {
-            infile = argv[index];
-            outfile = argv[index];
-        }
-        else if (index == argc-2) {
-            infile = argv[index];
-            outfile = argv[index+1];
-        }
-        else {
-            fprintf(stderr, "unknown argument %s\n", argv[index]);
-            return usage();
-        }
-
-        return do_pseudo(infile, outfile, big);
-    }
-    else if (0 == strcmp("rescheck", argv[index])) {
-        vector<string> files;
-
-        index++;
-        while (index < argc) {
-            if (argv[index][0] == '-') {
-                fprintf(stderr, "unknown argument %s\n", argv[index]);
-                return usage();
-            }
-            else {
-                break;
-            }
-        }
-        for (; index<argc; index++) {
-            files.push_back(argv[index]);
-        }
-
-        if (files.size() == 0) {
-            return usage();
-        }
-
-        return do_rescheck(files);
-    }
-    else {
-        return usage();
-    }
-
-    if (SourcePos::HasErrors()) {
-        SourcePos::PrintErrors(stderr);
-        return 1;
-    }
-
-    return 0;
-}
-
diff --git a/tools/localize/localize.h b/tools/localize/localize.h
deleted file mode 100644
index 615d14e..0000000
--- a/tools/localize/localize.h
+++ /dev/null
@@ -1,40 +0,0 @@
-#ifndef LOCALIZE_H
-#define LOCALIZE_H
-
-#include "XLIFFFile.h"
-
-#include <map>
-#include <string>
-
-using namespace std;
-
-struct Reject
-{
-    string file;
-    string name;
-    string comment;
-};
-
-struct Settings
-{
-    string id;
-    string oldVersion;
-    string currentVersion;
-    vector<string> apps;
-    vector<Reject> reject;
-};
-
-int read_settings(const string& filename, map<string,Settings>* result, const string& rootDir);
-string translated_file_name(const string& file, const string& locale);
-bool keep_this_trans_unit(const string& file, const TransUnit& unit, void* cookie);
-int validate_config(const string& settingsFile, const map<string,Settings>& settings,
-        const string& configs);
-int validate_configs(const string& settingsFile, const map<string,Settings>& settings,
-        const vector<string>& configs);
-int select_files(vector<string> *resFiles, const string& config,
-        const map<string,Settings>& settings, const string& rootDir);
-int select_files(vector<vector<string> > *allResFiles, const vector<string>& configs,
-        const map<string,Settings>& settings, const string& rootDir);
-
-
-#endif // LOCALIZE_H
diff --git a/tools/localize/localize_test.cpp b/tools/localize/localize_test.cpp
deleted file mode 100644
index 1d0ac9a..0000000
--- a/tools/localize/localize_test.cpp
+++ /dev/null
@@ -1,221 +0,0 @@
-#include <cstdio>
-#include "XLIFFFile.h"
-#include "ValuesFile.h"
-#include "localize.h"
-#include <stdio.h>
-
-int pseudolocalize_xliff(XLIFFFile* xliff, bool expand);
-
-static int
-test_filename(const string& file, const string& locale, const string& expected)
-{
-    string result = translated_file_name(file, locale);
-    if (result != expected) {
-        fprintf(stderr, "translated_file_name test failed\n");
-        fprintf(stderr, "  locale='%s'\n", locale.c_str());
-        fprintf(stderr, "  expected='%s'\n", expected.c_str());
-        fprintf(stderr, "    result='%s'\n", result.c_str());
-        return 1;
-    } else {
-        if (false) {
-            fprintf(stderr, "translated_file_name test passed\n");
-            fprintf(stderr, "  locale='%s'\n", locale.c_str());
-            fprintf(stderr, "  expected='%s'\n", expected.c_str());
-            fprintf(stderr, "    result='%s'\n", result.c_str());
-        }
-        return 0;
-    }
-}
-
-static int
-translated_file_name_test()
-{
-    bool all = true;
-    int err = 0;
-
-    if (all) err |= test_filename("//device/samples/NotePad/res/values/strings.xml", "zz_ZZ",
-                                  "//device/samples/NotePad/res/values-zz-rZZ/strings.xml");
-
-    if (all) err |= test_filename("//device/samples/NotePad/res/values/strings.xml", "zz",
-                                  "//device/samples/NotePad/res/values-zz/strings.xml");
-
-    if (all) err |= test_filename("//device/samples/NotePad/res/values/strings.xml", "",
-                                  "//device/samples/NotePad/res/values/strings.xml");
-
-    return err;
-}
-
-bool
-return_false(const string&, const TransUnit& unit, void* cookie)
-{
-    return false;
-}
-
-static int
-delete_trans_units()
-{
-    XLIFFFile* xliff = XLIFFFile::Parse("testdata/strip_xliff.xliff");
-    if (xliff == NULL) {
-        printf("couldn't read file\n");
-        return 1;
-    }
-    if (false) {
-        printf("XLIFF was [[%s]]\n", xliff->ToString().c_str());
-    }
-
-    xliff->Filter(return_false, NULL);
-
-    if (false) {
-        printf("XLIFF is [[%s]]\n", xliff->ToString().c_str());
-
-        set<StringResource> const& strings = xliff->GetStringResources();
-        printf("strings.size=%zd\n", strings.size());
-        for (set<StringResource>::iterator it=strings.begin(); it!=strings.end(); it++) {
-            const StringResource& str = *it;
-            printf("STRING!!! id=%s value='%s' pos=%s file=%s version=%d(%s)\n", str.id.c_str(),
-                    str.value->ContentsToString(ANDROID_NAMESPACES).c_str(),
-                    str.pos.ToString().c_str(), str.file.c_str(), str.version,
-                    str.versionString.c_str());
-        }
-    }
- 
-    return 0;
-}
-
-static int
-filter_trans_units()
-{
-    XLIFFFile* xliff = XLIFFFile::Parse("testdata/strip_xliff.xliff");
-    if (xliff == NULL) {
-        printf("couldn't read file\n");
-        return 1;
-    }
-
-    if (false) {
-        printf("XLIFF was [[%s]]\n", xliff->ToString().c_str());
-    }
-
-    Settings setting;
-    xliff->Filter(keep_this_trans_unit, &setting);
-
-    if (false) {
-        printf("XLIFF is [[%s]]\n", xliff->ToString().c_str());
-
-        set<StringResource> const& strings = xliff->GetStringResources();
-        printf("strings.size=%zd\n", strings.size());
-        for (set<StringResource>::iterator it=strings.begin(); it!=strings.end(); it++) {
-            const StringResource& str = *it;
-            printf("STRING!!! id=%s value='%s' pos=%s file=%s version=%d(%s)\n", str.id.c_str(),
-                    str.value->ContentsToString(ANDROID_NAMESPACES).c_str(),
-                    str.pos.ToString().c_str(), str.file.c_str(), str.version,
-                    str.versionString.c_str());
-        }
-    }
- 
-    return 0;
-}
-
-static int
-settings_test()
-{
-    int err;
-    map<string,Settings> settings;
-    map<string,Settings>::iterator it;
-
-    err = read_settings("testdata/config.xml", &settings, "//asdf");
-    if (err != 0) {
-        return err;
-    }
-
-    if (false) {
-        for (it=settings.begin(); it!=settings.end(); it++) {
-            const Settings& setting = it->second;
-            printf("CONFIG:\n");
-            printf("              id='%s'\n", setting.id.c_str());
-            printf("      oldVersion='%s'\n", setting.oldVersion.c_str());
-            printf("  currentVersion='%s'\n", setting.currentVersion.c_str());
-            int i=0;
-            for (vector<string>::const_iterator app=setting.apps.begin();
-                    app!=setting.apps.end(); app++) {
-                printf("        apps[%02d]='%s'\n", i, app->c_str());
-                i++;
-            }
-            i=0;
-            for (vector<Reject>::const_iterator reject=setting.reject.begin();
-                    reject!=setting.reject.end(); reject++) {
-                i++;
-                printf("      reject[%02d]=('%s','%s','%s')\n", i, reject->file.c_str(),
-                        reject->name.c_str(), reject->comment.c_str());
-            }
-        }
-    }
-
-    for (it=settings.begin(); it!=settings.end(); it++) {
-        const Settings& setting = it->second;
-        if (it->first != setting.id) {
-            fprintf(stderr, "it->first='%s' setting.id='%s'\n", it->first.c_str(),
-                    setting.id.c_str());
-            err |= 1;
-        }
-    }
-
-
-    return err;
-}
-
-static int
-test_one_pseudo(bool big, const char* expected)
-{
-    XLIFFFile* xliff = XLIFFFile::Parse("testdata/pseudo.xliff");
-    if (xliff == NULL) {
-        printf("couldn't read file\n");
-        return 1;
-    }
-    if (false) {
-        printf("XLIFF was [[%s]]\n", xliff->ToString().c_str());
-    }
-
-    pseudolocalize_xliff(xliff, big);
-    string newString = xliff->ToString();
-    delete xliff;
-
-    if (false) {
-        printf("XLIFF is [[%s]]\n", newString.c_str());
-    }
-
-    if (false && newString != expected) {
-        fprintf(stderr, "xliff didn't translate as expected\n");
-        fprintf(stderr, "newString=[[%s]]\n", newString.c_str());
-        fprintf(stderr, "expected=[[%s]]\n", expected);
-        return 1;
-    }
-
-    return 0;
-}
-
-static int
-pseudolocalize_test()
-{
-    int err = 0;
-    
-    err |= test_one_pseudo(false, "");
-    //err |= test_one_pseudo(true, "");
-
-    return err;
-}
-
-int
-localize_test()
-{
-    bool all = true;
-    int err = 0;
-
-    if (all) err |= translated_file_name_test();
-    if (all) err |= delete_trans_units();
-    if (all) err |= filter_trans_units();
-    if (all) err |= settings_test();
-    if (all) err |= pseudolocalize_test();
-
-    return err;
-}
-
diff --git a/tools/localize/log.h b/tools/localize/log.h
deleted file mode 100644
index 4a5fa7f..0000000
--- a/tools/localize/log.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#ifndef LOG_H
-#define LOG_H
-
-void log_printf(const char* fmt, ...);
-
-#endif // LOG_H
-
diff --git a/tools/localize/merge_res_and_xliff.cpp b/tools/localize/merge_res_and_xliff.cpp
deleted file mode 100644
index 1fdaa0e..0000000
--- a/tools/localize/merge_res_and_xliff.cpp
+++ /dev/null
@@ -1,392 +0,0 @@
-#include "merge_res_and_xliff.h"
-
-#include "file_utils.h"
-#include "Perforce.h"
-#include "log.h"
-#include <stdio.h>
-
-static set<StringResource>::const_iterator
-find_id(const set<StringResource>& s, const string& id, int index)
-{
-    for (set<StringResource>::const_iterator it = s.begin(); it != s.end(); it++) {
-        if (it->id == id && it->index == index) {
-            return it;
-        }
-    }
-    return s.end();
-}
-
-static set<StringResource>::const_iterator
-find_in_xliff(const set<StringResource>& s, const string& filename, const string& id, int index,
-                int version, const Configuration& config)
-{
-    for (set<StringResource>::const_iterator it = s.begin(); it != s.end(); it++) {
-        if (it->file == filename && it->id == id && it->index == index && it->version == version
-                && it->config == config) {
-            return it;
-        }
-    }
-    return s.end();
-}
-
-
-static void
-printit(const set<StringResource>& s, const set<StringResource>::const_iterator& it)
-{
-    if (it == s.end()) {
-        printf("(none)\n");
-    } else {
-        printf("id=%s index=%d config=%s file=%s value='%s'\n", it->id.c_str(), it->index,
-                it->config.ToString().c_str(), it->file.c_str(),
-                it->value->ToString(ANDROID_NAMESPACES).c_str());
-    }
-}
-
-StringResource
-convert_resource(const StringResource& s, const string& file, const Configuration& config,
-                    int version, const string& versionString)
-{
-    return StringResource(s.pos, file, config, s.id, s.index, s.value ? s.value->Clone() : NULL,
-            version, versionString, s.comment);
-}
-
-static bool
-resource_has_contents(const StringResource& res)
-{
-    XMLNode* value = res.value;
-    if (value == NULL) {
-        return false;
-    }
-    string contents = value->ContentsToString(ANDROID_NAMESPACES);
-    return contents != "";
-}
-
-ValuesFile*
-merge_res_and_xliff(const ValuesFile* en_currentFile,
-        const ValuesFile* xx_currentFile, const ValuesFile* xx_oldFile,
-        const string& filename, const XLIFFFile* xliffFile)
-{
-    bool success = true;
-
-    Configuration en_config = xliffFile->SourceConfig();
-    Configuration xx_config = xliffFile->TargetConfig();
-    string currentVersion = xliffFile->CurrentVersion();
-
-    ValuesFile* result = new ValuesFile(xx_config);
-
-    set<StringResource> en_cur = en_currentFile->GetStrings();
-    set<StringResource> xx_cur = xx_currentFile->GetStrings();
-    set<StringResource> xx_old = xx_oldFile->GetStrings();
-    set<StringResource> xliff = xliffFile->GetStringResources();
-
-    // for each string in en_current
-    for (set<StringResource>::const_iterator en_c = en_cur.begin();
-            en_c != en_cur.end(); en_c++) {
-        set<StringResource>::const_iterator xx_c = find_id(xx_cur, en_c->id, en_c->index);
-        set<StringResource>::const_iterator xx_o = find_id(xx_old, en_c->id, en_c->index);
-        set<StringResource>::const_iterator xlf = find_in_xliff(xliff, en_c->file, en_c->id,
-                                                        en_c->index, CURRENT_VERSION, xx_config);
-
-        if (false) {
-            printf("\nen_c: "); printit(en_cur, en_c);
-            printf("xx_c: "); printit(xx_cur, xx_c);
-            printf("xx_o: "); printit(xx_old, xx_o);
-            printf("xlf:  "); printit(xliff, xlf);
-        }
-
-        // if it changed between xx_old and xx_current, use xx_current
-        // (someone changed it by hand)
-        if (xx_o != xx_old.end() && xx_c != xx_cur.end()) {
-            string xx_o_value = xx_o->value->ToString(ANDROID_NAMESPACES);
-            string xx_c_value = xx_c->value->ToString(ANDROID_NAMESPACES);
-            if (xx_o_value != xx_c_value && xx_c_value != "") {
-                StringResource r(convert_resource(*xx_c, filename, xx_config,
-                                                    CURRENT_VERSION, currentVersion));
-                if (resource_has_contents(r)) {
-                    result->AddString(r);
-                }
-                continue;
-            }
-        }
-
-        // if it is present in xliff, use that
-        // (it just got translated)
-        if (xlf != xliff.end() && xlf->value->ToString(ANDROID_NAMESPACES) != "") {
-            StringResource r(convert_resource(*xlf, filename, xx_config,
-                                                CURRENT_VERSION, currentVersion));
-            if (resource_has_contents(r)) {
-                result->AddString(r);
-            }
-        }
-
-        // if it is present in xx_current, use that
-        // (it was already translated, and not retranslated)
-        // don't filter out empty strings if they were added by hand, the above code just
-        // guarantees that this tool never adds an empty one.
-        if (xx_c != xx_cur.end()) {
-            StringResource r(convert_resource(*xx_c, filename, xx_config,
-                                                CURRENT_VERSION, currentVersion));
-            result->AddString(r);
-        }
-
-        // othwerwise, leave it out.  The resource fall-through code will use the English
-        // one at runtime, and the xliff export code will pick it up for translation next time.
-    }
-
-    if (success) {
-        return result;
-    } else {
-        delete result;
-        return NULL;
-    }
-}
-
-
-struct MergedFile {
-    XLIFFFile* xliff;
-    string xliffFilename;
-    string original;
-    string translated;
-    ValuesFile* en_current;
-    ValuesFile* xx_current;
-    ValuesFile* xx_old;
-    ValuesFile* xx_new;
-    string xx_new_text;
-    string xx_new_filename;
-    bool new_file;
-    bool deleted_file;
-
-    MergedFile();
-    MergedFile(const MergedFile&);
-};
-
-struct compare_filenames {
-    bool operator()(const MergedFile& lhs, const MergedFile& rhs) const
-    {
-        return lhs.original < rhs.original;
-    }
-};
-
-MergedFile::MergedFile()
-    :xliff(NULL),
-     xliffFilename(),
-     original(),
-     translated(),
-     en_current(NULL),
-     xx_current(NULL),
-     xx_old(NULL),
-     xx_new(NULL),
-     xx_new_text(),
-     xx_new_filename(),
-     new_file(false),
-     deleted_file(false)
-{
-}
-
-MergedFile::MergedFile(const MergedFile& that)
-    :xliff(that.xliff),
-     xliffFilename(that.xliffFilename),
-     original(that.original),
-     translated(that.translated),
-     en_current(that.en_current),
-     xx_current(that.xx_current),
-     xx_old(that.xx_old),
-     xx_new(that.xx_new),
-     xx_new_text(that.xx_new_text),
-     xx_new_filename(that.xx_new_filename),
-     new_file(that.new_file),
-     deleted_file(that.deleted_file)
-{
-}
-
-
-typedef set<MergedFile, compare_filenames> MergedFileSet;
-
-int
-do_merge(const vector<string>& xliffFilenames)
-{
-    int err = 0;
-    MergedFileSet files;
-
-    printf("\rPreparing..."); fflush(stdout);
-    string currentChange = Perforce::GetCurrentChange(true);
-
-    // for each xliff, make a MergedFile record and do a little error checking
-    for (vector<string>::const_iterator xliffFilename=xliffFilenames.begin();
-            xliffFilename!=xliffFilenames.end(); xliffFilename++) {
-        XLIFFFile* xliff = XLIFFFile::Parse(*xliffFilename);
-        if (xliff == NULL) {
-            fprintf(stderr, "localize import: unable to read file %s\n", xliffFilename->c_str());
-            err = 1;
-            continue;
-        }
-
-        set<string> xf = xliff->Files();
-        for (set<string>::const_iterator f=xf.begin(); f!=xf.end(); f++) {
-            MergedFile mf;
-            mf.xliff = xliff;
-            mf.xliffFilename = *xliffFilename;
-            mf.original = *f;
-            mf.translated = translated_file_name(mf.original, xliff->TargetConfig().locale);
-            log_printf("mf.translated=%s mf.original=%s locale=%s\n", mf.translated.c_str(),
-                    mf.original.c_str(), xliff->TargetConfig().locale.c_str());
-
-            if (files.find(mf) != files.end()) {
-                fprintf(stderr, "%s: duplicate string resources for file %s\n",
-                        xliffFilename->c_str(), f->c_str());
-                fprintf(stderr, "%s: previously defined here.\n",
-                        files.find(mf)->xliffFilename.c_str());
-                err = 1;
-                continue;
-            }
-            files.insert(mf);
-        }
-    }
-
-    size_t deletedFileCount = 0;
-    size_t J = files.size() * 3;
-    size_t j = 1;
-    // Read all of the files from perforce.
-    for (MergedFileSet::iterator mf = files.begin(); mf != files.end(); mf++) {
-        MergedFile* file = const_cast<MergedFile*>(&(*mf));
-        // file->en_current
-        print_file_status(j++, J);
-        file->en_current = get_values_file(file->original, file->xliff->SourceConfig(),
-                                            CURRENT_VERSION, currentChange, true);
-        if (file->en_current == NULL) {
-            // deleted file
-            file->deleted_file = true;
-            deletedFileCount++;
-            continue;
-        }
-
-        // file->xx_current;
-        print_file_status(j++, J);
-        file->xx_current = get_values_file(file->translated, file->xliff->TargetConfig(),
-                                            CURRENT_VERSION, currentChange, false);
-        if (file->xx_current == NULL) {
-            file->xx_current = new ValuesFile(file->xliff->TargetConfig());
-            file->new_file = true;
-        }
-
-        // file->xx_old (note that the xliff's current version is our old version, because that
-        // was the current version when it was exported)
-        print_file_status(j++, J);
-        file->xx_old = get_values_file(file->translated, file->xliff->TargetConfig(),
-                                            OLD_VERSION, file->xliff->CurrentVersion(), false);
-        if (file->xx_old == NULL) {
-            file->xx_old = new ValuesFile(file->xliff->TargetConfig());
-            file->new_file = true;
-        }
-    }
-
-    // merge them
-    for (MergedFileSet::iterator mf = files.begin(); mf != files.end(); mf++) {
-        MergedFile* file = const_cast<MergedFile*>(&(*mf));
-        if (file->deleted_file) {
-            continue;
-        }
-        file->xx_new = merge_res_and_xliff(file->en_current, file->xx_current, file->xx_old,
-                                            file->original, file->xliff);
-    }
-
-    // now is a good time to stop if there was an error
-    if (err != 0) {
-        return err;
-    }
-
-    // locate the files
-    j = 1;
-    for (MergedFileSet::iterator mf = files.begin(); mf != files.end(); mf++) {
-        MergedFile* file = const_cast<MergedFile*>(&(*mf));
-        print_file_status(j++, J, "Locating");
-
-        file->xx_new_filename = Perforce::Where(file->translated, true);
-        if (file->xx_new_filename == "") {
-            fprintf(stderr, "\nWas not able to determine the location of depot file %s\n",
-                    file->translated.c_str());
-            err = 1;
-        }
-    }
-
-    if (err != 0) {
-        return err;
-    }
-
-    // p4 edit the files
-    // only do this if it changed - no need to submit files that haven't changed meaningfully
-    vector<string> filesToEdit;
-    vector<string> filesToAdd;
-    vector<string> filesToDelete;
-    for (MergedFileSet::iterator mf = files.begin(); mf != files.end(); mf++) {
-        MergedFile* file = const_cast<MergedFile*>(&(*mf));
-        if (file->deleted_file) {
-            filesToDelete.push_back(file->xx_new_filename);
-            continue;
-        }
-        string xx_current_text = file->xx_current->ToString();
-        string xx_new_text = file->xx_new->ToString();
-        if (xx_current_text != xx_new_text) {
-            if (file->xx_new->GetStrings().size() == 0) {
-                file->deleted_file = true;
-                filesToDelete.push_back(file->xx_new_filename);
-            } else {
-                file->xx_new_text = xx_new_text;
-                if (file->new_file) {
-                    filesToAdd.push_back(file->xx_new_filename);
-                } else {
-                    filesToEdit.push_back(file->xx_new_filename);
-                }
-            }
-        }
-    }
-    if (filesToAdd.size() == 0 && filesToEdit.size() == 0 && deletedFileCount == 0) {
-        printf("\nAll of the files are the same.  Nothing to change.\n");
-        return 0;
-    }
-    if (filesToEdit.size() > 0) {
-        printf("\np4 editing files...\n");
-        if (0 != Perforce::EditFiles(filesToEdit, true)) {
-            return 1;
-        }
-    }
-
-
-    printf("\n");
-
-    for (MergedFileSet::iterator mf = files.begin(); mf != files.end(); mf++) {
-        MergedFile* file = const_cast<MergedFile*>(&(*mf));
-        if (file->deleted_file) {
-            continue;
-        }
-        if (file->xx_new_text != "" && file->xx_new_filename != "") {
-            if (0 != write_to_file(file->xx_new_filename, file->xx_new_text)) {
-                err = 1;
-            }
-        }
-    }
-
-    if (err != 0) {
-        return err;
-    }
-
-    if (filesToAdd.size() > 0) {
-        printf("p4 adding %zd new files...\n", filesToAdd.size());
-        err = Perforce::AddFiles(filesToAdd, true);
-    }
-
-    if (filesToDelete.size() > 0) {
-        printf("p4 deleting %zd removed files...\n", filesToDelete.size());
-        err = Perforce::DeleteFiles(filesToDelete, true);
-    }
-
-    if (err != 0) {
-        return err;
-    }
-
-    printf("\n"
-           "Theoretically, this merge was successfull.  Next you should\n"
-           "review the diffs, get a code review, and submit it.  Enjoy.\n\n");
-    return 0;
-}
-
diff --git a/tools/localize/merge_res_and_xliff.h b/tools/localize/merge_res_and_xliff.h
deleted file mode 100644
index acf2fff..0000000
--- a/tools/localize/merge_res_and_xliff.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#ifndef MERGE_RES_AND_XLIFF_H
-#define MERGE_RES_AND_XLIFF_H
-
-#include "ValuesFile.h"
-#include "XLIFFFile.h"
-
-ValuesFile* merge_res_and_xliff(const ValuesFile* en_current,
-                                const ValuesFile* xx_current, const ValuesFile* xx_old,
-                                const string& filename, const XLIFFFile* xliff);
-
-int do_merge(const vector<string>& xliffFilenames);
-
-#endif // MERGE_RES_AND_XLIFF_H
diff --git a/tools/localize/merge_res_and_xliff_test.cpp b/tools/localize/merge_res_and_xliff_test.cpp
deleted file mode 100644
index 6fe2629..0000000
--- a/tools/localize/merge_res_and_xliff_test.cpp
+++ /dev/null
@@ -1,48 +0,0 @@
-#include <cstdio>
-#include "merge_res_and_xliff.h"
-#include <stdio.h>
-
-int
-merge_test()
-{
-    Configuration english;
-        english.locale = "en_US";
-    Configuration translated;
-        translated.locale = "zz_ZZ";
-
-    ValuesFile* en_current = ValuesFile::ParseFile("testdata/merge_en_current.xml", english,
-                                                    CURRENT_VERSION, "3");
-    if (en_current == NULL) {
-        fprintf(stderr, "merge_test: unable to read testdata/merge_en_current.xml\n");
-        return 1;
-    }
-
-    ValuesFile* xx_current = ValuesFile::ParseFile("testdata/merge_xx_current.xml", translated,
-                                                    CURRENT_VERSION, "3");
-    if (xx_current == NULL) {
-        fprintf(stderr, "merge_test: unable to read testdata/merge_xx_current.xml\n");
-        return 1;
-    }
-    ValuesFile* xx_old = ValuesFile::ParseFile("testdata/merge_xx_old.xml", translated,
-                                                    OLD_VERSION, "2");
-    if (xx_old == NULL) {
-        fprintf(stderr, "merge_test: unable to read testdata/merge_xx_old.xml\n");
-        return 1;
-    }
-
-    XLIFFFile* xliff = XLIFFFile::Parse("testdata/merge.xliff");
-
-    ValuesFile* result = merge_res_and_xliff(en_current, xx_current, xx_old,
-                                "//device/tools/localize/testdata/res/values/strings.xml", xliff);
-
-    if (result == NULL) {
-        fprintf(stderr, "merge_test: result is NULL\n");
-        return 1;
-    }
-
-    printf("======= RESULT =======\n%s===============\n", result->ToString().c_str());
-
-    return 0;
-}
-
-
diff --git a/tools/localize/res_check.cpp b/tools/localize/res_check.cpp
deleted file mode 100644
index 0fab98a..0000000
--- a/tools/localize/res_check.cpp
+++ /dev/null
@@ -1,106 +0,0 @@
-#include "res_check.h"
-#include "localize.h"
-#include "file_utils.h"
-#include "ValuesFile.h"
-
-#include <stdio.h>
-
-static int check_file(const ValuesFile* file);
-static int check_value(const SourcePos& pos, const XMLNode* value);
-static int scan_for_unguarded_format(const SourcePos& pos, const XMLNode* value, int depth = 0);
-
-int
-do_rescheck(const vector<string>& files)
-{
-    int err;
-
-    Configuration english;
-        english.locale = "en_US";
-
-    for (size_t i=0; i<files.size(); i++) {
-        const string filename = files[i];
-        ValuesFile* valuesFile = get_local_values_file(filename, english, CURRENT_VERSION,
-                "0", true);
-        if (valuesFile != NULL) {
-            err |= check_file(valuesFile);
-            delete valuesFile;
-        } else {
-            err |= 1;
-        }
-    }
-
-    return err;
-}
-
-static int
-check_file(const ValuesFile* file)
-{
-    int err = 0;
-    set<StringResource> strings = file->GetStrings();
-    for (set<StringResource>::iterator it=strings.begin(); it!=strings.end(); it++) {
-        XMLNode* value = it->value;
-        if (value != NULL) {
-            err |= check_value(it->pos, value);
-        }
-    }
-    return err;
-}
-
-static bool
-contains_percent(const string& str)
-{
-    const size_t len = str.length();
-    for (size_t i=0; i<len; i++) {
-        char c = str[i];
-        if (c == '%') {
-            return true;
-        }
-    }
-    return false;
-}
-
-static int
-check_value(const SourcePos& pos, const XMLNode* value)
-{
-    int err = 0;
-    err |= scan_for_unguarded_format(pos, value);
-    return err;
-}
-
-static bool
-is_xliff_block(const string& ns, const string& name)
-{
-    if (ns == XLIFF_XMLNS) {
-        return name == "g";
-    } else {
-        return false;
-    }
-}
-
-static int
-scan_for_unguarded_format(const SourcePos& pos, const string& string)
-{
-    bool containsPercent = contains_percent(string);
-    if (containsPercent) {
-        pos.Error("unguarded percent: '%s'\n", string.c_str());
-    }
-    return 0;
-}
-
-static int
-scan_for_unguarded_format(const SourcePos& pos, const XMLNode* value, int depth)
-{
-    if (value->Type() == XMLNode::ELEMENT) {
-        int err = 0;
-        if (depth == 0 || !is_xliff_block(value->Namespace(), value->Name())) {
-            const vector<XMLNode*>& children = value->Children();
-            for (size_t i=0; i<children.size(); i++) {
-                err |= scan_for_unguarded_format(pos, children[i], depth+1);
-            }
-        }
-        return err;
-    } else {
-        return scan_for_unguarded_format(pos, value->Text());
-    }
-}
-
diff --git a/tools/localize/res_check.h b/tools/localize/res_check.h
deleted file mode 100644
index 86e7ce6..0000000
--- a/tools/localize/res_check.h
+++ /dev/null
@@ -1,12 +0,0 @@
-#ifndef RESCHECK_H
-#define RESCHECK_H
-
-#include <map>
-#include <string>
-#include <vector>
-
-using namespace std;
-
-int do_rescheck(const vector<string>& files);
-
-#endif // RESCHECK_H
diff --git a/tools/localize/test.cpp b/tools/localize/test.cpp
deleted file mode 100644
index 5fa2c17..0000000
--- a/tools/localize/test.cpp
+++ /dev/null
@@ -1,31 +0,0 @@
-#include "SourcePos.h"
-#include <stdio.h>
-
-int ValuesFile_test();
-int XLIFFFile_test();
-int XMLHandler_test();
-int Perforce_test();
-int localize_test();
-int merge_test();
-
-int
-test()
-{
-    bool all = true;
-    int err = 0;
-
-    if (all) err |= XMLHandler_test();
-    if (all) err |= ValuesFile_test();
-    if (all) err |= XLIFFFile_test();
-    if (all) err |= Perforce_test();
-    if (all) err |= localize_test();
-    if (all) err |= merge_test();
-
-    if (err != 0) {
-        fprintf(stderr, "some tests failed\n");
-    } else {
-        fprintf(stderr, "all tests passed\n");
-    }
-
-    return err;
-}
diff --git a/tools/localize/testdata/config.xml b/tools/localize/testdata/config.xml
deleted file mode 100644
index affa140f..0000000
--- a/tools/localize/testdata/config.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<localize-config>
-    <configuration id="system"
-            old-cl="1"
-            new-cl="43019">
-        <app dir="apps/common" />
-    </configuration>
-    <configuration id="samples"
-            old-cl="24801"
-            new-cl="43019">
-        <app dir="samples/NotePad" />
-        <reject file="samples/NotePad/res/values/strings.xml" name="string:menu_delete">
-            QA says this sounds <b>rude</b>.
-        </reject>
-    </configuration>
-</localize-config>
diff --git a/tools/localize/testdata/import.xliff b/tools/localize/testdata/import.xliff
deleted file mode 100644
index b99b739..0000000
--- a/tools/localize/testdata/import.xliff
+++ /dev/null
@@ -1,72 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2"
-        version="1.2"
-        >
-    <file datatype="x-android-res"
-            original="//device/tools/localize/testdata/res/values/strings.xml"
-            product-version="1.0"
-            date="08:10:54 12/07/07 PST"
-            source-language="en_US"
-            product-name="kila"
-            target-language="zz_ZZ"
-            build-num="44391"
-            >
-        <body>
-            <trans-unit id="string:changed_in_xx">
-                <source>aaa</source>
-                <target>AAA</target>
-            </trans-unit>
-            <trans-unit id="string:first_translation">
-                <source>bbb</source>
-                <target>BBB</target>
-            </trans-unit>
-            <trans-unit id="string:deleted_string">
-                <source>ddd</source>
-                <target>DDDD</target>
-            </trans-unit>
-            <trans-unit id="array:0:growing_array">
-                <source>1-One</source>
-                <target>1-oNE</target>
-            </trans-unit>
-            <trans-unit id="array:1:growing_array">
-                <source>1-Two</source>
-                <target>1-tWO</target>
-            </trans-unit>
-            <trans-unit id="array:2:growing_array">
-                <source>1-Three</source>
-                <target>1-tHREE</target>
-            </trans-unit>
-            <trans-unit id="array:0:shrinking_array">
-                <source>2-One</source>
-                <target>2-oNE</target>
-            </trans-unit>
-            <trans-unit id="array:1:shrinking_array">
-                <source>2-Two</source>
-                <target>2-tWO</target>
-            </trans-unit>
-            <trans-unit id="array:2:shrinking_array">
-                <source>2-Three</source>
-                <target>2-tHREE</target>
-            </trans-unit>
-            <trans-unit id="array:3:shrinking_array">
-                <source>2-Four</source>
-                <target>2-fOUR</target>
-            </trans-unit>
-            <trans-unit id="array:0:deleted_array">
-                <source>4-One</source>
-                <target>4-oNE</target>
-            </trans-unit>
-            <trans-unit id="array:1:deleted_array">
-                <source>4-Two</source>
-                <target>4-tWO</target>
-            </trans-unit>
-            <trans-unit id="array:2:deleted_array">
-                <source>4-Three</source>
-                <target>4-tHREE</target>
-            </trans-unit>
-
-        </body>
-    </file>
-</xliff>
-
-
diff --git a/tools/localize/testdata/merge.xliff b/tools/localize/testdata/merge.xliff
deleted file mode 100644
index 2b78c45..0000000
--- a/tools/localize/testdata/merge.xliff
+++ /dev/null
@@ -1,72 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2"
-        version="1.2"
-        >
-    <file datatype="x-android-res"
-            original="testdata/merge_en_current.xml"
-            product-version="1.0"
-            date="08:10:54 12/07/07 PST"
-            source-language="en-US"
-            product-name="kila"
-            target-language="zz-ZZ"
-            build-num="44391"
-            >
-        <body>
-            <trans-unit id="string:changed_in_xx">
-                <source>aaa</source>
-                <target>AAA</target>
-            </trans-unit>
-            <trans-unit id="string:first_translation">
-                <source>bbb</source>
-                <target>BBB</target>
-            </trans-unit>
-            <trans-unit id="string:deleted_string">
-                <source>ddd</source>
-                <target>DDDD</target>
-            </trans-unit>
-            <trans-unit id="array:0:growing_array">
-                <source>1-One</source>
-                <target>1-oNE</target>
-            </trans-unit>
-            <trans-unit id="array:1:growing_array">
-                <source>1-Two</source>
-                <target>1-tWO</target>
-            </trans-unit>
-            <trans-unit id="array:2:growing_array">
-                <source>1-Three</source>
-                <target>1-tHREE</target>
-            </trans-unit>
-            <trans-unit id="array:0:shrinking_array">
-                <source>2-One</source>
-                <target>2-oNE</target>
-            </trans-unit>
-            <trans-unit id="array:1:shrinking_array">
-                <source>2-Two</source>
-                <target>2-tWO</target>
-            </trans-unit>
-            <trans-unit id="array:2:shrinking_array">
-                <source>2-Three</source>
-                <target>2-tHREE</target>
-            </trans-unit>
-            <trans-unit id="array:3:shrinking_array">
-                <source>2-Four</source>
-                <target>2-fOUR</target>
-            </trans-unit>
-            <trans-unit id="array:0:deleted_array">
-                <source>4-One</source>
-                <target>4-oNE</target>
-            </trans-unit>
-            <trans-unit id="array:1:deleted_array">
-                <source>4-Two</source>
-                <target>4-tWO</target>
-            </trans-unit>
-            <trans-unit id="array:2:deleted_array">
-                <source>4-Three</source>
-                <target>4-tHREE</target>
-            </trans-unit>
-
-        </body>
-    </file>
-</xliff>
-
-
diff --git a/tools/localize/testdata/merge_en_current.xml b/tools/localize/testdata/merge_en_current.xml
deleted file mode 100644
index 6a11e68..0000000
--- a/tools/localize/testdata/merge_en_current.xml
+++ /dev/null
@@ -1,44 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2007 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-  
-          http://www.apache.org/licenses/LICENSE-2.0
-  
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="changed_in_xx">aaa</string>
-    <string name="first_translation">bbb</string>
-    <string name="previously_translated">ccc</string>
-    <string name="new_string">ccc</string>
-
-    <string name="formatted_string"><b>bold</b><i>italic<u>italic_underline</u></i><u>underline</u></string>
-
-    <array name="growing_array">
-        <!-- somebody wrote a comment! -->
-        <item>1-One</item>
-        <item>1-Two</item>
-        <item>1-Three</item>
-        <item>1-Four</item>
-    </array>
-    <array name="shrinking_array">
-        <!-- somebody wrote a comment! -->
-        <item>2-One</item>
-        <item>2-Two</item>
-        <item>2-Three</item>
-    </array>
-    <array name="new_array">
-        <!-- somebody wrote a comment! -->
-        <item>3-One</item>
-        <item>3-Two</item>
-        <item>3-Three</item>
-    </array>
-</resources>
diff --git a/tools/localize/testdata/merge_en_old.xml b/tools/localize/testdata/merge_en_old.xml
deleted file mode 100644
index 933f98e..0000000
--- a/tools/localize/testdata/merge_en_old.xml
+++ /dev/null
@@ -1,45 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2007 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-  
-          http://www.apache.org/licenses/LICENSE-2.0
-  
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="changed_in_xx">aaa</string>
-    <string name="first_translation">bbb</string>
-    <string name="previously_translated">ccc</string>
-    <string name="deleted_string">ddd</string>
-
-    <string name="formatted_string"><b>bold</b><i>italic<u>italic_underline</u></i><u>underline</u></string>
-
-    <array name="growing_array">
-        <!-- somebody wrote a comment! -->
-        <item>1-One</item>
-        <item>1-Two</item>
-        <item>1-Three</item>
-    </array>
-    <array name="shrinking_array">
-        <!-- somebody wrote a comment! -->
-        <item>2-One</item>
-        <item>2-Two</item>
-        <item>2-Three</item>
-        <item>2-Four</item>
-    </array>
-    <array name="deleted_array">
-        <!-- somebody wrote a comment! -->
-        <item>4-One</item>
-        <item>4-Two</item>
-        <item>4-Three</item>
-    </array>
-</resources>
-
diff --git a/tools/localize/testdata/merge_xx_current.xml b/tools/localize/testdata/merge_xx_current.xml
deleted file mode 100644
index c2a783d..0000000
--- a/tools/localize/testdata/merge_xx_current.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2007 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-  
-          http://www.apache.org/licenses/LICENSE-2.0
-  
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="changed_in_xx">AAAA</string>
-    <string name="previously_translated">CCC</string>
-</resources>
-
-
diff --git a/tools/localize/testdata/pseudo.xliff b/tools/localize/testdata/pseudo.xliff
deleted file mode 100644
index 5b44f86..0000000
--- a/tools/localize/testdata/pseudo.xliff
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2"
-        version="1.2"
-        >
-    <file datatype="x-android-res"
-            original="//device/tools/localization/tests/res/values/strings.xml"
-            product-version="1.0"
-            date="08:10:54 12/07/07 PST"
-            source-language="en-US"
-            product-name="kila"
-            target-language="zz-ZZ"
-            build-num="32138"
-            >
-        <body>
-            <trans-unit id="string:complex">
-                <source>First <g id="string:complex:0" ctype="underline">underline</g>, <g id="string:complex:1" ctype="italic">italic<g id="string:complex:2" ctype="bold">italicbold</g></g> End </source>
-            </trans-unit>
-            <trans-unit id="string:complex-quoted">
-                <source xml:space="preserve">First <g id="string:complex-quoted:0" ctype="underline">underline</g>, <g id="string:complex-quoted:1" ctype="italic">italic<g id="string:complex-quoted:2" ctype="bold">italicbold</g></g> End</source>
-            </trans-unit>
-            <trans-unit id="string:simple">
-                <source>Simple</source>
-            </trans-unit>
-            <trans-unit id="array:0:simple">
-                <source>Simple</source>
-            </trans-unit>
-            <trans-unit id="array:1:simple">
-                <source>Simple</source>
-            </trans-unit>
-            <trans-unit id="string:simple-quoted">
-                <source xml:space="preserve"> Quote</source>
-                <alt-trans>
-                    <source xml:lang="en" xml:space="preserve"> OLD Quote</source>
-                    <target xml:lang="xx"> OLD Ờũỡŧę</target>
-                </alt-trans>
-            </trans-unit>
-        </body>
-    </file>
-</xliff>
-
diff --git a/tools/localize/testdata/res/values/strings.xml b/tools/localize/testdata/res/values/strings.xml
deleted file mode 100644
index 6a11e68..0000000
--- a/tools/localize/testdata/res/values/strings.xml
+++ /dev/null
@@ -1,44 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2007 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-  
-          http://www.apache.org/licenses/LICENSE-2.0
-  
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="changed_in_xx">aaa</string>
-    <string name="first_translation">bbb</string>
-    <string name="previously_translated">ccc</string>
-    <string name="new_string">ccc</string>
-
-    <string name="formatted_string"><b>bold</b><i>italic<u>italic_underline</u></i><u>underline</u></string>
-
-    <array name="growing_array">
-        <!-- somebody wrote a comment! -->
-        <item>1-One</item>
-        <item>1-Two</item>
-        <item>1-Three</item>
-        <item>1-Four</item>
-    </array>
-    <array name="shrinking_array">
-        <!-- somebody wrote a comment! -->
-        <item>2-One</item>
-        <item>2-Two</item>
-        <item>2-Three</item>
-    </array>
-    <array name="new_array">
-        <!-- somebody wrote a comment! -->
-        <item>3-One</item>
-        <item>3-Two</item>
-        <item>3-Three</item>
-    </array>
-</resources>
diff --git a/tools/localize/testdata/strip_xliff.xliff b/tools/localize/testdata/strip_xliff.xliff
deleted file mode 100644
index 9254cf2..0000000
--- a/tools/localize/testdata/strip_xliff.xliff
+++ /dev/null
@@ -1,70 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2"
-        version="1.2"
-        >
-    <file datatype="x-android-res"
-            original="//device/tools/localization/tests/res/values/strings.xml"
-            product-version="1.0"
-            date="08:10:54 12/07/07 PST"
-            source-language="en-US"
-            product-name="kila"
-            target-language="zz-ZZ"
-            build-num="32138"
-            >
-        <body>
-
-            <trans-unit id="string:string-000-0">
-            </trans-unit>
-            <trans-unit id="string:string-001-0">
-                <alt-trans>
-                    <source xml:lang="en" xml:space="preserve">source</source>
-                </alt-trans>
-            </trans-unit>
-            <trans-unit id="string:string-010-0">
-                <alt-trans>
-                    <target xml:lang="zz" xml:space="preserve">target</target>
-                </alt-trans>
-            </trans-unit>
-            <trans-unit id="string:string-011-0">
-                <alt-trans>
-                    <source xml:lang="en" xml:space="preserve">source</source>
-                    <target xml:lang="zz" xml:space="preserve">target</target>
-                </alt-trans>
-            </trans-unit>
-
-            <trans-unit id="string:string-100-1">
-                <source xml:space="preserve">source</source>
-            </trans-unit>
-            <trans-unit id="string:string-101-1">
-                <source xml:space="preserve">source</source>
-                <alt-trans>
-                    <source xml:lang="en" xml:space="preserve">source</source>
-                </alt-trans>
-            </trans-unit>
-            <trans-unit id="string:string-110-1">
-                <source xml:space="preserve">source</source>
-                <alt-trans>
-                    <target xml:lang="zz" xml:space="preserve">target</target>
-                </alt-trans>
-            </trans-unit>
-
-            <trans-unit id="string:string-111-0">
-                <source xml:space="preserve">source</source>
-                <alt-trans>
-                    <source xml:lang="en" xml:space="preserve">source</source>
-                    <target xml:lang="zz" xml:space="preserve">target</target>
-                </alt-trans>
-            </trans-unit>
-            <trans-unit id="string:string-111-1">
-                <source xml:space="preserve">source</source>
-                <alt-trans>
-                    <source xml:lang="en" xml:space="preserve">alt-source</source>
-                    <target xml:lang="zz" xml:space="preserve">target</target>
-                </alt-trans>
-            </trans-unit>
-
-        </body>
-    </file>
-</xliff>
-
-
diff --git a/tools/localize/testdata/values/strings.xml b/tools/localize/testdata/values/strings.xml
deleted file mode 100644
index 5e8d43d..0000000
--- a/tools/localize/testdata/values/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2007 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-  
-          http://www.apache.org/licenses/LICENSE-2.0
-  
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<resources
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="test1">Discard</string>
-    <!-- comment -->
-    <string name="test2">a<b>b<i>c</i></b>d</string>
-    <string name="test3">a<xliff:g  a="b" xliff:a="asdf">bBb</xliff:g>C</string>
-
-    <!-- Email address types from android.provider.Contacts -->
-    <array name="emailAddressTypes">
-        <!-- somebody wrote a comment! -->
-        <item>Email</item>
-        <item>Home</item>
-        <item>Work</item>
-        <item>Other\u2026</item>
-    </array>
-</resources>
diff --git a/tools/localize/testdata/xliff1.xliff b/tools/localize/testdata/xliff1.xliff
deleted file mode 100644
index 55a8d8e..0000000
--- a/tools/localize/testdata/xliff1.xliff
+++ /dev/null
@@ -1,46 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2"
-        version="1.2"
-        >
-    <file datatype="x-android-res"
-            original="//device/tools/localization/tests/res/values/strings.xml"
-            product-version="1.0"
-            date="08:10:54 12/07/07 PST"
-            source-language="en-US"
-            product-name="kila"
-            target-language="zz-ZZ"
-            build-num="32138"
-            >
-        <body>
-            <trans-unit id="string:complex">
-                <source>First <g id="string:complex:0" ctype="underline">underline</g>, <g id="string:complex:1" ctype="italic">italic<g id="string:complex:2" ctype="bold">italicbold</g></g> End </source>
-                <target>Ḟịṙṩŧ ,  Ḛŋḋ </target>
-            </trans-unit>
-            <trans-unit id="string:complex-quoted">
-                <source xml:space="preserve">First <g id="string:complex-quoted:0" ctype="underline">underline</g>, <g id="string:complex-quoted:1" ctype="italic">italic<g id="string:complex-quoted:2" ctype="bold">italicbold</g></g> End</source>
-                <target>Ḟịṙṩŧ ,  Ḛŋḋ</target>
-            </trans-unit>
-            <trans-unit id="string:simple">
-                <source>Simple</source>
-                <target>Ṩịṃṕļę</target>
-            </trans-unit>
-            <trans-unit id="array:0:simple">
-                <source>Simple</source>
-                <target>Ṩịṃṕļę</target>
-            </trans-unit>
-            <trans-unit id="array:1:simple">
-                <source>Simple</source>
-                <target>Ṩịṃṕļę</target>
-            </trans-unit>
-            <trans-unit id="string:simple-quoted">
-                <source xml:space="preserve"> Quote</source>
-                <target> Ờũỡŧę</target>
-                <alt-trans>
-                    <source xml:lang="en" xml:space="preserve"> OLD Quote</source>
-                    <target xml:lang="xx"> OLD Ờũỡŧę</target>
-                </alt-trans>
-            </trans-unit>
-        </body>
-    </file>
-</xliff>
-
diff --git a/tools/localize/testdata/xml.xml b/tools/localize/testdata/xml.xml
deleted file mode 100644
index ef930d0..0000000
--- a/tools/localize/testdata/xml.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<ASDF>
-    <a id="system"
-            old-cl="1"
-            new-cl="43019">
-        <app dir="apps/common" />
-    </a>
-    <a id="samples"
-            old-cl="1"
-            new-cl="43019">asdf
-        <app dir="samples/NotePad" />
-        <app dir="samples/LunarLander" />
-        <something>a<b>,</b>b </something>
-        <exact xml:space="preserve">a<b>,</b>b </exact>
-    </a>
-</ASDF>
-
diff --git a/tools/localize/xmb.cpp b/tools/localize/xmb.cpp
deleted file mode 100644
index d8f6ff0..0000000
--- a/tools/localize/xmb.cpp
+++ /dev/null
@@ -1,182 +0,0 @@
-#include "xmb.h"
-
-#include "file_utils.h"
-#include "localize.h"
-#include "ValuesFile.h"
-#include "XMLHandler.h"
-#include "XLIFFFile.h"
-
-#include <map>
-#include <cstdio>
-
-using namespace std;
-
-const char *const NS_MAP[] = {
-    "xml", XMLNS_XMLNS,
-    NULL, NULL
-};
-
-set<string> g_tags;
-
-static string
-strip_newlines(const string& str)
-{
-    string res;
-    const size_t N = str.length();
-    for (size_t i=0; i<N; i++) {
-        char c = str[i];
-        if (c != '\n' && c != '\r') {
-            res += c;
-        } else {
-            res += ' ';
-        }
-    }
-    return res;
-}
-
-static int
-rename_id_attribute(XMLNode* node)
-{
-    vector<XMLAttribute>& attrs = node->EditAttributes();
-    const size_t I = attrs.size();
-    for (size_t i=0; i<I; i++) {
-        XMLAttribute attr = attrs[i];
-        if (attr.name == "id") {
-            attr.name = "name";
-            attrs.erase(attrs.begin()+i);
-            attrs.push_back(attr);
-            return 0;
-        }
-    }
-    return 1;
-}
-
-static int
-convert_xliff_to_ph(XMLNode* node, int* phID)
-{
-    int err = 0;
-    if (node->Type() == XMLNode::ELEMENT) {
-        if (node->Namespace() == XLIFF_XMLNS) {
-            g_tags.insert(node->Name());
-            node->SetName("", "ph");
-
-            err = rename_id_attribute(node);
-            if (err != 0) {
-                char name[30];
-                (*phID)++;
-                sprintf(name, "id-%d", *phID);
-                node->EditAttributes().push_back(XMLAttribute("", "name", name));
-                err = 0;
-            }
-        }
-        vector<XMLNode*>& children = node->EditChildren();
-        const size_t I = children.size();
-        for (size_t i=0; i<I; i++) {
-            err |= convert_xliff_to_ph(children[i], phID);
-        }
-    }
-    return err;
-}
-
-XMLNode*
-resource_to_xmb_msg(const StringResource& res)
-{
-    // the msg element
-    vector<XMLAttribute> attrs;
-    string name = res.pos.file;
-    name += ":";
-    name += res.TypedID();
-    attrs.push_back(XMLAttribute("", "name", name));
-    attrs.push_back(XMLAttribute("", "desc", strip_newlines(res.comment)));
-    attrs.push_back(XMLAttribute(XMLNS_XMLNS, "space", "preserve"));
-    XMLNode* msg = XMLNode::NewElement(res.pos, "", "msg", attrs, XMLNode::EXACT);
-
-    // the contents are in xliff/html, convert it to xliff
-    int err = 0;
-    XMLNode* value = res.value;
-    string tag = value->Name();
-    int phID = 0;
-    for (vector<XMLNode*>::const_iterator it=value->Children().begin();
-            it!=value->Children().end(); it++) {
-        err |= convert_html_to_xliff(*it, tag, msg, &phID);
-    }
-
-    if (err != 0) {
-        return NULL;
-    }
-
-    // and then convert that to xmb
-    for (vector<XMLNode*>::iterator it=msg->EditChildren().begin();
-            it!=msg->EditChildren().end(); it++) {
-        err |= convert_xliff_to_ph(*it, &phID);
-    }
-
-    if (err == 0) {
-        return msg;
-    } else {
-        return NULL;
-    }
-}
-
-int
-do_xlb_export(const string& outfile, const vector<string>& resFiles)
-{
-    int err = 0;
-
-    size_t totalFileCount = resFiles.size();
-
-    Configuration english;
-        english.locale = "en_US";
-
-    set<StringResource> allResources;
-
-    const size_t J = resFiles.size();
-    for (size_t j=0; j<J; j++) {
-        string resFile = resFiles[j];
-
-        ValuesFile* valuesFile = get_local_values_file(resFile, english, CURRENT_VERSION, "", true);
-        if (valuesFile != NULL) {
-            set<StringResource> resources = valuesFile->GetStrings();
-            allResources.insert(resources.begin(), resources.end());
-        } else {
-            fprintf(stderr, "error reading file %s\n", resFile.c_str());
-        }
-
-        delete valuesFile;
-    }
-
-    // Construct the XLB xml
-    vector<XMLAttribute> attrs;
-    attrs.push_back(XMLAttribute("", "locale", "en"));
-    XMLNode* localizationbundle = XMLNode::NewElement(GENERATED_POS, "", "localizationbundle",
-            attrs, XMLNode::PRETTY);
-
-    for (set<StringResource>::iterator it=allResources.begin(); it!=allResources.end(); it++) {
-        XMLNode* msg = resource_to_xmb_msg(*it);
-        if (msg) {
-            localizationbundle->EditChildren().push_back(msg);
-        } else {
-            err = 1;
-        }
-    }
-
-#if 0
-    for (set<string>::iterator it=g_tags.begin(); it!=g_tags.end(); it++) {
-        printf("tag: %s\n", it->c_str());
-    }
-    printf("err=%d\n", err);
-#endif
-    if (err == 0) {
-        FILE* f = fopen(outfile.c_str(), "wb");
-        if (f == NULL) {
-            fprintf(stderr, "can't open outputfile: %s\n", outfile.c_str());
-            return 1;
-        }
-        fprintf(f, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
-        fprintf(f, "%s\n", localizationbundle->ToString(NS_MAP).c_str());
-        fclose(f);
-    }
-
-    return err;
-}
-
diff --git a/tools/localize/xmb.h b/tools/localize/xmb.h
deleted file mode 100644
index 96492b1..0000000
--- a/tools/localize/xmb.h
+++ /dev/null
@@ -1,11 +0,0 @@
-#ifndef XMB_H
-#define XMB_H
-
-#include <string>
-#include <vector>
-
-using namespace std;
-
-int do_xlb_export(const string& outFile, const vector<string>& resFiles);
-
-#endif // XMB_H
diff --git a/tools/orientationplot/README.txt b/tools/orientationplot/README.txt
index 0143510..d53f65e 100644
--- a/tools/orientationplot/README.txt
+++ b/tools/orientationplot/README.txt
@@ -16,15 +16,15 @@
 The tool works by scaping the debug log output from WindowOrientationListener
 for interesting data and then plotting it.
 
-1. Enable the Window Orientation Listener debugging data log using the
-   Development Settings in the Dev Tools application (Development.apk).
-
-2. Plug in the device.  Ensure that it is the only device plugged in
+1. Plug in the device.  Ensure that it is the only device plugged in
    since this script is of very little brain and will get confused otherwise.
 
-3. Run "orientationplot.py".
+2. Enable the Window Orientation Listener debugging data log.
+   adb shell setprop debug.orientation.log true
+   adb shell stop
+   adb shell start
 
-4. When finished, remember to disable the debug log output since it is quite verbose!
+3. Run "orientationplot.py".
 
 
 WHAT IT ALL MEANS
diff --git a/tools/orientationplot/orientationplot.py b/tools/orientationplot/orientationplot.py
index f4e6b45..6fc3922 100755
--- a/tools/orientationplot/orientationplot.py
+++ b/tools/orientationplot/orientationplot.py
@@ -152,6 +152,7 @@
     self.time_until_settled = self._make_timeseries()
     self.time_until_flat_delay_expired = self._make_timeseries()
     self.time_until_swing_delay_expired = self._make_timeseries()
+    self.time_until_acceleration_delay_expired = self._make_timeseries()
     self.stability_axes = self._add_timeseries_axes(
         6, 'Proposal Stability', 'ms', [-10, 600],
         sharex=shared_axis,
@@ -162,6 +163,8 @@
         self.stability_axes, 'time until flat delay expired', 'green')
     self.time_until_swing_delay_expired_line = self._add_timeseries_line(
         self.stability_axes, 'time until swing delay expired', 'blue')
+    self.time_until_acceleration_delay_expired_line = self._add_timeseries_line(
+        self.stability_axes, 'time until acceleration delay expired', 'red')
     self._add_timeseries_legend(self.stability_axes)
 
     self.sample_latency = self._make_timeseries()
@@ -253,6 +256,7 @@
     self.parse_time_until_settled = None
     self.parse_time_until_flat_delay_expired = None
     self.parse_time_until_swing_delay_expired = None
+    self.parse_time_until_acceleration_delay_expired = None
     self.parse_sample_latency = None
 
   # Update samples.
@@ -303,6 +307,7 @@
         self.parse_time_until_settled = self._get_following_number(line, 'timeUntilSettledMS=')
         self.parse_time_until_flat_delay_expired = self._get_following_number(line, 'timeUntilFlatDelayExpiredMS=')
         self.parse_time_until_swing_delay_expired = self._get_following_number(line, 'timeUntilSwingDelayExpiredMS=')
+        self.parse_time_until_acceleration_delay_expired = self._get_following_number(line, 'timeUntilAccelerationDelayExpiredMS=')
 
         self._append(self.raw_acceleration_x, timeindex, self.parse_raw_acceleration_x)
         self._append(self.raw_acceleration_y, timeindex, self.parse_raw_acceleration_y)
@@ -326,6 +331,7 @@
         self._append(self.time_until_settled, timeindex, self.parse_time_until_settled)
         self._append(self.time_until_flat_delay_expired, timeindex, self.parse_time_until_flat_delay_expired)
         self._append(self.time_until_swing_delay_expired, timeindex, self.parse_time_until_swing_delay_expired)
+        self._append(self.time_until_acceleration_delay_expired, timeindex, self.parse_time_until_acceleration_delay_expired)
         self._append(self.sample_latency, timeindex, self.parse_sample_latency)
         self._reset_parse_state()
 
@@ -349,6 +355,7 @@
       self._scroll(self.time_until_settled, bottom)
       self._scroll(self.time_until_flat_delay_expired, bottom)
       self._scroll(self.time_until_swing_delay_expired, bottom)
+      self._scroll(self.time_until_acceleration_delay_expired, bottom)
       self._scroll(self.sample_latency, bottom)
 
     # Redraw the plots.
@@ -368,6 +375,7 @@
     self.time_until_settled_line.set_data(self.time_until_settled)
     self.time_until_flat_delay_expired_line.set_data(self.time_until_flat_delay_expired)
     self.time_until_swing_delay_expired_line.set_data(self.time_until_swing_delay_expired)
+    self.time_until_acceleration_delay_expired_line.set_data(self.time_until_acceleration_delay_expired)
     self.sample_latency_line.set_data(self.sample_latency)
 
     self.fig.canvas.draw_idle()