Merge "minor cleanup."
diff --git a/Android.mk b/Android.mk
index 4ecf5bd..a48ef45 100644
--- a/Android.mk
+++ b/Android.mk
@@ -116,13 +116,11 @@
 	core/java/android/hardware/ISensorService.aidl \
 	core/java/android/net/IConnectivityManager.aidl \
 	core/java/android/net/INetworkManagementEventObserver.aidl \
-	core/java/android/os/ICheckinService.aidl \
 	core/java/android/os/IMessenger.aidl \
 	core/java/android/os/storage/IMountService.aidl \
 	core/java/android/os/storage/IMountServiceListener.aidl \
 	core/java/android/os/INetworkManagementService.aidl \
 	core/java/android/os/INetStatService.aidl \
-	core/java/android/os/IParentalControlCallback.aidl \
 	core/java/android/os/IPermissionController.aidl \
 	core/java/android/os/IPowerManager.aidl \
     core/java/android/os/IRemoteCallback.aidl \
@@ -409,7 +407,9 @@
 		-samplecode $(sample_dir)/Wiktionary \
 		            resources/samples/Wiktionary "Wiktionary" \
 		-samplecode $(sample_dir)/WiktionarySimple \
-		            resources/samples/WiktionarySimple "Wiktionary (Simplified)"
+		            resources/samples/WiktionarySimple "Wiktionary (Simplified)" \
+		-samplecode $(sample_dir)/VoiceRecognitionService \
+		            resources/samples/VoiceRecognitionService "Voice Recognition Service"
 
 ## SDK version identifiers used in the published docs
   # major[.minor] version for current SDK. (full releases only)
diff --git a/api/current.xml b/api/current.xml
index 08de474..56e8cb6 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -1537,6 +1537,17 @@
  visibility="public"
 >
 </field>
+<field name="cycle_interpolator"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="17432588"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="decelerate_interpolator"
  type="int"
  transient="false"
@@ -85749,6 +85760,461 @@
 >
 </field>
 </class>
+<class name="Downloads"
+ extends="java.lang.Object"
+ abstract="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<method name="isStatusError"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="status" type="int">
+</parameter>
+</method>
+<method name="isStatusSuccess"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="status" type="int">
+</parameter>
+</method>
+<field name="ACTION_DOWNLOAD_COMPLETED"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;android.intent.action.DOWNLOAD_COMPLETED&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="COLUMN_NOTIFICATION_EXTRAS"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;notificationextras&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="DOWNLOAD_DESTINATION_CACHE"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="2"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="DOWNLOAD_DESTINATION_CACHE_PURGEABLE"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="3"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="DOWNLOAD_DESTINATION_EXTERNAL"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="1"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="DOWNLOAD_ID_INVALID"
+ type="long"
+ transient="false"
+ volatile="false"
+ value="-1L"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="STATUS_DEVICE_NOT_FOUND_ERROR"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="499"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="STATUS_INSUFFICIENT_SPACE_ERROR"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="498"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="STATUS_NOT_ACCEPTABLE"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="406"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="STATUS_PENDING"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="190"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="STATUS_RUNNING"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="192"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="STATUS_SUCCESS"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="200"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="STATUS_UNHANDLED_REDIRECT"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="493"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="STATUS_UNKNOWN_ERROR"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="491"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+</class>
+<class name="Downloads.ById"
+ extends="android.net.Downloads.DownloadBase"
+ abstract="false"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<method name="deleteDownload"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="context" type="android.content.Context">
+</parameter>
+<parameter name="downloadId" type="long">
+</parameter>
+</method>
+<method name="getMimeTypeForId"
+ return="java.lang.String"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="context" type="android.content.Context">
+</parameter>
+<parameter name="downloadId" type="long">
+</parameter>
+</method>
+<method name="getStatus"
+ return="android.net.Downloads.StatusInfo"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="context" type="android.content.Context">
+</parameter>
+<parameter name="downloadId" type="long">
+</parameter>
+</method>
+<method name="openDownload"
+ return="android.os.ParcelFileDescriptor"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="context" type="android.content.Context">
+</parameter>
+<parameter name="downloadId" type="long">
+</parameter>
+<parameter name="mode" type="java.lang.String">
+</parameter>
+<exception name="FileNotFoundException" type="java.io.FileNotFoundException">
+</exception>
+</method>
+<method name="openDownloadStream"
+ return="java.io.InputStream"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="context" type="android.content.Context">
+</parameter>
+<parameter name="downloadId" type="long">
+</parameter>
+<exception name="FileNotFoundException" type="java.io.FileNotFoundException">
+</exception>
+<exception name="IOException" type="java.io.IOException">
+</exception>
+</method>
+</class>
+<class name="Downloads.ByUri"
+ extends="android.net.Downloads.DownloadBase"
+ abstract="false"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<method name="getStatus"
+ return="android.net.Downloads.StatusInfo"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="context" type="android.content.Context">
+</parameter>
+<parameter name="url" type="java.lang.String">
+</parameter>
+<parameter name="redownload_threshold" type="long">
+</parameter>
+</method>
+<method name="removeAllDownloadsByPackage"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="context" type="android.content.Context">
+</parameter>
+<parameter name="notification_package" type="java.lang.String">
+</parameter>
+<parameter name="notification_class" type="java.lang.String">
+</parameter>
+</method>
+</class>
+<class name="Downloads.DownloadBase"
+ extends="java.lang.Object"
+ abstract="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="private"
+>
+<method name="startDownloadByUri"
+ return="long"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="context" type="android.content.Context">
+</parameter>
+<parameter name="url" type="java.lang.String">
+</parameter>
+<parameter name="cookieData" type="java.lang.String">
+</parameter>
+<parameter name="showDownload" type="boolean">
+</parameter>
+<parameter name="downloadDestination" type="int">
+</parameter>
+<parameter name="allowRoaming" type="boolean">
+</parameter>
+<parameter name="skipIntegrityCheck" type="boolean">
+</parameter>
+<parameter name="title" type="java.lang.String">
+</parameter>
+<parameter name="notification_package" type="java.lang.String">
+</parameter>
+<parameter name="notification_class" type="java.lang.String">
+</parameter>
+<parameter name="notification_extras" type="java.lang.String">
+</parameter>
+</method>
+</class>
+<class name="Downloads.StatusInfo"
+ extends="java.lang.Object"
+ abstract="false"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<constructor name="Downloads.StatusInfo"
+ type="android.net.Downloads.StatusInfo"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</constructor>
+<method name="isComplete"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="isSuccessful"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<field name="bytesSoFar"
+ type="long"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="completed"
+ type="boolean"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="filename"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="id"
+ type="long"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="statusCode"
+ type="int"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+</class>
 <class name="LocalServerSocket"
  extends="java.lang.Object"
  abstract="false"
@@ -139884,7 +140350,7 @@
  deprecated="not deprecated"
  visibility="public"
 >
-<parameter name="bundleWithValues" type="android.os.Bundle">
+<parameter name="bundle" type="android.os.Bundle">
 </parameter>
 </constructor>
 <method name="fillInNotifierBundle"
@@ -163514,6 +163980,243 @@
 </method>
 </class>
 </package>
+<package name="android.util.base64"
+>
+<class name="Base64"
+ extends="java.lang.Object"
+ abstract="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<method name="decode"
+ return="byte[]"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="str" type="java.lang.String">
+</parameter>
+<parameter name="flags" type="int">
+</parameter>
+</method>
+<method name="decode"
+ return="byte[]"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="input" type="byte[]">
+</parameter>
+<parameter name="flags" type="int">
+</parameter>
+</method>
+<method name="decode"
+ return="byte[]"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="input" type="byte[]">
+</parameter>
+<parameter name="offset" type="int">
+</parameter>
+<parameter name="len" type="int">
+</parameter>
+<parameter name="flags" type="int">
+</parameter>
+</method>
+<method name="encode"
+ return="byte[]"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="input" type="byte[]">
+</parameter>
+<parameter name="flags" type="int">
+</parameter>
+</method>
+<method name="encode"
+ return="byte[]"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="input" type="byte[]">
+</parameter>
+<parameter name="offset" type="int">
+</parameter>
+<parameter name="len" type="int">
+</parameter>
+<parameter name="flags" type="int">
+</parameter>
+</method>
+<method name="encodeToString"
+ return="java.lang.String"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="input" type="byte[]">
+</parameter>
+<parameter name="flags" type="int">
+</parameter>
+</method>
+<method name="encodeToString"
+ return="java.lang.String"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="input" type="byte[]">
+</parameter>
+<parameter name="offset" type="int">
+</parameter>
+<parameter name="len" type="int">
+</parameter>
+<parameter name="flags" type="int">
+</parameter>
+</method>
+<field name="CRLF"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="4"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="DEFAULT"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="0"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="NO_CLOSE"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="NO_PADDING"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="1"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="NO_WRAP"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="2"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="URL_SAFE"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="8"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+</class>
+<class name="Base64InputStream"
+ extends="java.io.FilterInputStream"
+ abstract="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<constructor name="Base64InputStream"
+ type="android.util.base64.Base64InputStream"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="in" type="java.io.InputStream">
+</parameter>
+<parameter name="flags" type="int">
+</parameter>
+</constructor>
+</class>
+<class name="Base64OutputStream"
+ extends="java.io.FilterOutputStream"
+ abstract="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<constructor name="Base64OutputStream"
+ type="android.util.base64.Base64OutputStream"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="out" type="java.io.OutputStream">
+</parameter>
+<parameter name="flags" type="int">
+</parameter>
+</constructor>
+</class>
+</package>
 <package name="android.view"
 >
 <class name="AbsSavedState"
@@ -164725,6 +165428,17 @@
  visibility="public"
 >
 </field>
+<field name="KEYBOARD_TAP"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="3"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="LONG_PRESS"
  type="int"
  transient="false"
@@ -168389,6 +169103,28 @@
  visibility="public"
 >
 </method>
+<method name="getActionIndex"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getActionMasked"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
 <method name="getDeviceId"
  return="int"
  abstract="false"
@@ -169009,7 +169745,7 @@
  value="5"
  static="true"
  final="true"
- deprecated="not deprecated"
+ deprecated="deprecated"
  visibility="public"
 >
 </field>
@@ -169020,7 +169756,7 @@
  value="6"
  static="true"
  final="true"
- deprecated="not deprecated"
+ deprecated="deprecated"
  visibility="public"
 >
 </field>
@@ -169031,7 +169767,7 @@
  value="261"
  static="true"
  final="true"
- deprecated="not deprecated"
+ deprecated="deprecated"
  visibility="public"
 >
 </field>
@@ -169042,7 +169778,7 @@
  value="262"
  static="true"
  final="true"
- deprecated="not deprecated"
+ deprecated="deprecated"
  visibility="public"
 >
 </field>
@@ -169053,7 +169789,7 @@
  value="517"
  static="true"
  final="true"
- deprecated="not deprecated"
+ deprecated="deprecated"
  visibility="public"
 >
 </field>
@@ -169064,7 +169800,7 @@
  value="518"
  static="true"
  final="true"
- deprecated="not deprecated"
+ deprecated="deprecated"
  visibility="public"
 >
 </field>
@@ -169086,7 +169822,7 @@
  value="65280"
  static="true"
  final="true"
- deprecated="not deprecated"
+ deprecated="deprecated"
  visibility="public"
 >
 </field>
@@ -169097,6 +169833,28 @@
  value="8"
  static="true"
  final="true"
+ deprecated="deprecated"
+ visibility="public"
+>
+</field>
+<field name="ACTION_POINTER_INDEX_MASK"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="65280"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="ACTION_POINTER_INDEX_SHIFT"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="8"
+ static="true"
+ final="true"
  deprecated="not deprecated"
  visibility="public"
 >
diff --git a/cmds/installd/commands.c b/cmds/installd/commands.c
index cd0302c..a447f53 100644
--- a/cmds/installd/commands.c
+++ b/cmds/installd/commands.c
@@ -690,6 +690,83 @@
     }
 }
 
+int movefileordir(char* srcpath, char* dstpath, int dstuid, int dstgid,
+        struct stat* statbuf)
+{
+    DIR *d;
+    struct dirent *de;
+    int res;
+
+    int srcend = strlen(srcpath);
+    int dstend = strlen(dstpath);
+    
+    if (lstat(srcpath, statbuf) < 0) {
+        LOGW("Unable to stat %s: %s\n", srcpath, strerror(errno));
+        return 1;
+    }
+    
+    if ((statbuf->st_mode&S_IFDIR) == 0) {
+        LOGI("Renaming %s to %s (uid %d)\n", srcpath, dstpath, dstuid);
+        mkinnerdirs(dstpath, dstend-1, S_IRWXU|S_IRWXG|S_IXOTH, dstuid, dstgid);
+        if (rename(srcpath, dstpath) >= 0) {
+            if (chown(dstpath, dstuid, dstgid) < 0) {
+                LOGE("cannot chown %s: %s\n", dstpath, strerror(errno));
+                unlink(dstpath);
+                return 1;
+            }
+        } else {
+            LOGW("Unable to rename %s to %s: %s\n",
+                srcpath, dstpath, strerror(errno));
+            return 1;
+        }
+        return 0;
+    }
+
+    d = opendir(srcpath);
+    if (d == NULL) {
+        LOGW("Unable to opendir %s: %s\n", srcpath, strerror(errno));
+        return 1;
+    }
+
+    res = 0;
+    
+    while ((de = readdir(d))) {
+        const char *name = de->d_name;
+            /* always skip "." and ".." */
+        if (name[0] == '.') {
+            if (name[1] == 0) continue;
+            if ((name[1] == '.') && (name[2] == 0)) continue;
+        }
+        
+        if ((srcend+strlen(name)) >= (PKG_PATH_MAX-2)) {
+            LOGW("Source path too long; skipping: %s/%s\n", srcpath, name);
+            continue;
+        }
+        
+        if ((dstend+strlen(name)) >= (PKG_PATH_MAX-2)) {
+            LOGW("Destination path too long; skipping: %s/%s\n", dstpath, name);
+            continue;
+        }
+        
+        srcpath[srcend] = dstpath[dstend] = '/';
+        strcpy(srcpath+srcend+1, name);
+        strcpy(dstpath+dstend+1, name);
+        
+        if (movefileordir(srcpath, dstpath, dstuid, dstgid, statbuf) != 0) {
+            res = 1;
+        }
+        
+        // Note: we will be leaving empty directories behind in srcpath,
+        // but that is okay, the package manager will be erasing all of the
+        // data associated with .apks that disappear.
+        
+        srcpath[srcend] = dstpath[dstend] = 0;
+    }
+    
+    closedir(d);
+    return res;
+}
+
 int movefiles()
 {
     DIR *d;
@@ -703,7 +780,7 @@
     char dstpkg[PKG_NAME_MAX];
     char srcpath[PKG_PATH_MAX];
     char dstpath[PKG_PATH_MAX];
-    int dstuid, dstgid;
+    int dstuid=-1, dstgid=-1;
     int hasspace;
 
     d = opendir(UPDATE_COMMANDS_DIR_PREFIX);
@@ -757,18 +834,7 @@
                             LOGV("Move file: %s (from %s to %s)\n", buf+bufp, srcpkg, dstpkg);
                             if (!create_move_path(srcpath, PKG_DIR_PREFIX, srcpkg, buf+bufp) &&
                                     !create_move_path(dstpath, PKG_DIR_PREFIX, dstpkg, buf+bufp)) {
-                                LOGI("Renaming %s to %s (uid %d)\n", srcpath, dstpath, dstuid);
-                                mkinnerdirs(dstpath, strlen(dstpath)-(bufi-bufp),
-                                    S_IRWXU|S_IRWXG|S_IXOTH, dstuid, dstgid);
-                                if (rename(srcpath, dstpath) >= 0) {
-                                    if (chown(dstpath, dstuid, dstgid) < 0) {
-                                        LOGE("cannot chown %s: %s\n", dstpath, strerror(errno));
-                                        unlink(dstpath);
-                                    }
-                                } else {
-                                    LOGW("Unable to rename %s to %s: %s\n",
-                                        srcpath, dstpath, strerror(errno));
-                                }
+                                movefileordir(srcpath, dstpath, dstuid, dstgid, &s);
                             }
                         }
                     } else {
@@ -812,10 +878,11 @@
                                             dstuid = s.st_uid;
                                             dstgid = s.st_gid;
                                         } else {
+                                            // Destination package doesn't
+                                            // exist...  due to original-package,
+                                            // this is normal, so don't be
+                                            // noisy about it.
                                             srcpkg[0] = 0;
-                                            LOGW("Can't stat path %s in %s%s: %s\n",
-                                                    dstpath, UPDATE_COMMANDS_DIR_PREFIX,
-                                                    name, strerror(errno));
                                         }
                                     } else {
                                         srcpkg[0] = 0;
diff --git a/cmds/pm/src/com/android/commands/pm/Pm.java b/cmds/pm/src/com/android/commands/pm/Pm.java
index 68373cb..ff16c6e 100644
--- a/cmds/pm/src/com/android/commands/pm/Pm.java
+++ b/cmds/pm/src/com/android/commands/pm/Pm.java
@@ -600,7 +600,7 @@
             } else if (opt.equals("-t")) {
                 installFlags |= PackageManager.INSTALL_ALLOW_TEST;
             } else if (opt.equals("-s")) {
-                installFlags |= PackageManager.INSTALL_ON_SDCARD;
+                installFlags |= PackageManager.INSTALL_EXTERNAL;
             } else {
                 System.err.println("Error: Unknown option: " + opt);
                 showUsage();
diff --git a/common/java/com/android/common/Base64.java b/common/java/com/android/common/Base64.java
deleted file mode 100644
index d65e24e..0000000
--- a/common/java/com/android/common/Base64.java
+++ /dev/null
@@ -1,705 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.common;
-
-/**
- * Utilities for encoding and decoding the Base64 encoding.  See RFCs
- * 2045 and 3548.
- */
-public class Base64 {
-    /**
-     * Default values for encoder/decoder flags.
-     */
-    public static final int DEFAULT = 0;
-
-    /**
-     * Encoder flag bit to indicate you want the padding '='
-     * characters at the end (if any) to be omitted.
-     */
-    public static final int NO_PADDING = 1;
-
-    /**
-     * Encoder flag bit to indicate you want all line terminators to
-     * be omitted (ie, the output will be on one long line).
-     */
-    public static final int NO_WRAP = 2;
-
-    /**
-     * Encoder flag bit to indicate you want lines to be ended with
-     * CRLF instead of just LF.
-     */
-    public static final int CRLF = 4;
-
-    /**
-     * Encoder/decoder flag bit to indicate using the "web safe"
-     * variant of Base64 (see RFC 3548 section 4) where '-' and '_'
-     * are used in place of '+' and '/'.
-     */
-    public static final int WEB_SAFE = 8;
-
-    /**
-     * Flag to pass to Base64OutputStream to indicate that it should
-     * not close the output stream it is wrapping when it itself is
-     * closed.
-     */
-    public static final int NO_CLOSE = 16;
-
-    //  --------------------------------------------------------
-    //  decoding
-    //  --------------------------------------------------------
-
-    /**
-     * Lookup table for turning bytes into their position in the
-     * Base64 alphabet.
-     */
-    private static final int DECODE[] = {
-        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
-        52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -2, -1, -1,
-        -1,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,
-        15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
-        -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
-        41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1,
-        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-    };
-
-    /**
-     * Decode lookup table for the "web safe" variant (RFC 3548
-     * sec. 4) where - and _ replace + and /.
-     */
-    private static final int DECODE_WEBSAFE[] = {
-        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1,
-        52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -2, -1, -1,
-        -1,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,
-        15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, 63,
-        -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
-        41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1,
-        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-    };
-
-    /** Non-data values in the DECODE arrays. */
-    private static final int SKIP = -1;
-    private static final int EQUALS = -2;
-
-    /**
-     * Decode the Base64-encoded data in input and return the data in
-     * a new byte array.
-     *
-     * The padding '=' characters at the end are considered optional, but
-     * if any are present, there must be the correct number of them.
-     *
-     * @param input the input String to decode, which is converted to
-     *               bytes using the default charset
-     * @param flags  controls certain features of the decoded output.
-     *               Pass {@code DEFAULT} to decode standard Base64.
-     *
-     * @throws IllegalArgumentException if the input contains
-     * incorrect padding
-     */
-    public static byte[] decode(String str, int flags) {
-        return decode(str.getBytes(), flags);
-    }
-
-    /**
-     * Decode the Base64-encoded data in input and return the data in
-     * a new byte array.
-     *
-     * The padding '=' characters at the end are considered optional, but
-     * if any are present, there must be the correct number of them.
-     *
-     * @param input the input array to decode
-     * @param flags  controls certain features of the decoded output.
-     *               Pass {@code DEFAULT} to decode standard Base64.
-     *
-     * @throws IllegalArgumentException if the input contains
-     * incorrect padding
-     */
-    public static byte[] decode(byte[] input, int flags) {
-        return decode(input, 0, input.length, flags);
-    }
-
-    /**
-     * Decode the Base64-encoded data in input and return the data in
-     * a new byte array.
-     *
-     * The padding '=' characters at the end are considered optional, but
-     * if any are present, there must be the correct number of them.
-     *
-     * @param input  the data to decode
-     * @param offset the position within the input array at which to start
-     * @param len    the number of bytes of input to decode
-     * @param flags  controls certain features of the decoded output.
-     *               Pass {@code DEFAULT} to decode standard Base64.
-     *
-     * @throws IllegalArgumentException if the input contains
-     * incorrect padding
-     */
-    public static byte[] decode(byte[] input, int offset, int len, int flags) {
-        // Allocate space for the most data the input could represent.
-        // (It could contain less if it contains whitespace, etc.)
-        DecoderState state = new DecoderState(flags, new byte[len*3/4]);
-
-        if (!decodeInternal(input, offset, len, state, true)) {
-            throw new IllegalArgumentException("bad base-64");
-        }
-
-        // Maybe we got lucky and allocated exactly enough output space.
-        if (state.op == state.output.length) {
-            return state.output;
-        }
-
-        // Need to shorten the array, so allocate a new one of the
-        // right size and copy.
-        byte[] temp = new byte[state.op];
-        System.arraycopy(state.output, 0, temp, 0, state.op);
-        return temp;
-    }
-
-    /* package */ static class DecoderState {
-        public byte[] output;
-        public int op;
-
-        public int state;   // state number (0 to 6)
-        public int value;
-
-        final public int[] alphabet;
-
-        public DecoderState(int flags, byte[] output) {
-            this.output = output;
-
-            alphabet = ((flags & WEB_SAFE) == 0) ? DECODE : DECODE_WEBSAFE;
-            state = 0;
-            value = 0;
-        }
-    }
-
-    /**
-     * Decode another block of input data.
-     *
-     * @param dstate a DecoderState object whose (caller-provided)
-     *        output array is big enough to hold all the decoded data.
-     *        On return, dstate.op will be set to the length of the
-     *        decoded data.
-     * @param finish true if this is the final call to decodeInternal
-     *        with the given DecoderState object.  Will finalize the
-     *        decoder state and include any final bytes in the output.
-     *
-     * @return true if the state machine is still healthy.  false if
-     *         bad base-64 data has been detected in the input stream.
-     */
-
-    /* package */ static boolean decodeInternal(
-        byte[] input, int offset, int len, final DecoderState dstate, boolean finish) {
-        if (dstate.state == 6) return false;
-
-        int state = dstate.state;
-        int value = dstate.value;
-        final int[] decode = dstate.alphabet;
-        final byte[] output = dstate.output;
-        int op = 0;
-
-        int p = offset;
-        len += offset;
-
-        while (p < len) {
-
-            // Try the fast path:  we're starting a new tuple and the
-            // next four bytes of the input stream are all data
-            // bytes.  This corresponds to going through states
-            // 0-1-2-3-0.  We expect to use this method for most of
-            // the data.
-            //
-            // If any of the next four bytes of input are non-data
-            // (whitespace, etc.), value will end up negative.  (All
-            // the non-data values in decode are small negative
-            // numbers, so shifting any of them up and or'ing them
-            // together will result in a value with its top bit set.)
-            //
-            // You can remove this whole block and the output should
-            // be the same, just slower.
-            if (state == 0 && p+4 <= len &&
-                (value = ((decode[input[p] & 0xff] << 18) |
-                          (decode[input[p+1] & 0xff] << 12) |
-                          (decode[input[p+2] & 0xff] << 6) |
-                          (decode[input[p+3] & 0xff]))) >= 0) {
-                output[op+2] = (byte) value;
-                output[op+1] = (byte) (value >> 8);
-                output[op] = (byte) (value >> 16);
-                op += 3;
-                p += 4;
-                continue;
-            }
-
-            // The fast path isn't available -- either we've read a
-            // partial tuple, or the next four input bytes aren't all
-            // data, or whatever.  Fall back to the slower state
-            // machine implementation.
-            //
-            // States 0-3 are reading through the next input tuple.
-            // State 4 is having read one '=' and expecting exactly
-            // one more.
-            // State 5 is expecting no more data or padding characters
-            // in the input.
-            // State 6 is the error state; an error has been detected
-            // in the input and no future input can "fix" it.
-
-            int d = decode[input[p++] & 0xff];
-
-            switch (state) {
-                case 0:
-                    if (d >= 0) {
-                        value = d;
-                        ++state;
-                    } else if (d != SKIP) {
-                        dstate.state = 6;
-                        return false;
-                    }
-                    break;
-
-                case 1:
-                    if (d >= 0) {
-                        value = (value << 6) | d;
-                        ++state;
-                    } else if (d != SKIP) {
-                        dstate.state = 6;
-                        return false;
-                    }
-                    break;
-
-                case 2:
-                    if (d >= 0) {
-                        value = (value << 6) | d;
-                        ++state;
-                    } else if (d == EQUALS) {
-                        // Emit the last (partial) output tuple;
-                        // expect exactly one more padding character.
-                        output[op++] = (byte) (value >> 4);
-                        state = 4;
-                    } else if (d != SKIP) {
-                        dstate.state = 6;
-                        return false;
-                    }
-                    break;
-
-                case 3:
-                    if (d >= 0) {
-                        // Emit the output triple and return to state 0.
-                        value = (value << 6) | d;
-                        output[op+2] = (byte) value;
-                        output[op+1] = (byte) (value >> 8);
-                        output[op] = (byte) (value >> 16);
-                        op += 3;
-                        state = 0;
-                    } else if (d == EQUALS) {
-                        // Emit the last (partial) output tuple;
-                        // expect no further data or padding characters.
-                        output[op+1] = (byte) (value >> 2);
-                        output[op] = (byte) (value >> 10);
-                        op += 2;
-                        state = 5;
-                    } else if (d != SKIP) {
-                        dstate.state = 6;
-                        return false;
-                    }
-                    break;
-
-                case 4:
-                    if (d == EQUALS) {
-                        ++state;
-                    } else if (d != SKIP) {
-                        dstate.state = 6;
-                        return false;
-                    }
-                    break;
-
-                case 5:
-                    if (d != SKIP) {
-                        dstate.state = 6;
-                        return false;
-                    }
-                    break;
-            }
-        }
-
-        if (!finish) {
-            // We're out of input, but a future call could provide
-            // more.  Return the output we've produced on this call
-            // and save the current state of the state machine.
-            dstate.state = state;
-            dstate.value = value;
-            dstate.op = op;
-            return true;
-        }
-
-        // Done reading input.  Now figure out where we are left in
-        // the state machine and finish up.
-
-        switch (state) {
-            case 0:
-                // Output length is a multiple of three.  Fine.
-                break;
-            case 1:
-                // Read one extra input byte, which isn't enough to
-                // make another output byte.  Illegal.
-                dstate.state = 6;
-                return false;
-            case 2:
-                // Read two extra input bytes, enough to emit 1 more
-                // output byte.  Fine.
-                output[op++] = (byte) (value >> 4);
-                break;
-            case 3:
-                // Read three extra input bytes, enough to emit 2 more
-                // output bytes.  Fine.
-                output[op+1] = (byte) (value >> 2);
-                output[op] = (byte) (value >> 10);
-                op += 2;
-                break;
-            case 4:
-                // Read one padding '=' when we expected 2.  Illegal.
-                dstate.state = 6;
-                return false;
-            case 5:
-                // Read all the padding '='s we expected and no more.
-                // Fine.
-                break;
-        }
-
-        dstate.op = op;
-        return true;
-    }
-
-    //  --------------------------------------------------------
-    //  encoding
-    //  --------------------------------------------------------
-
-    /**
-     * Emit a new line every this many output tuples.  Corresponds to
-     * a 76-character line length (the maximum allowable according to
-     * RFC 2045).
-     */
-    private static final int LINE_GROUPS = 19;
-
-    /**
-     * Lookup table for turning Base64 alphabet positions (6 bits)
-     * into output bytes.
-     */
-    private static final byte ENCODE[] = {
-        'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
-        'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
-        'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
-        'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
-        'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
-        'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
-        'w', 'x', 'y', 'z', '0', '1', '2', '3',
-        '4', '5', '6', '7', '8', '9', '+', '/',
-    };
-
-    /**
-     * Lookup table for turning Base64 alphabet positions (6 bits)
-     * into output bytes.
-     */
-    private static final byte ENCODE_WEBSAFE[] = {
-        'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
-        'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
-        'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
-        'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
-        'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
-        'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
-        'w', 'x', 'y', 'z', '0', '1', '2', '3',
-        '4', '5', '6', '7', '8', '9', '-', '_',
-    };
-
-    /**
-     * Base64-encode the given data and return a newly allocated
-     * String with the result.
-     *
-     * @param input  the data to encode
-     * @param flags  controls certain features of the encoded output.
-     *               Passing {@code DEFAULT} results in output that
-     *               adheres to RFC 2045.
-     */
-    public static String encodeToString(byte[] input, int flags) {
-        return new String(encode(input, flags));
-    }
-
-    /**
-     * Base64-encode the given data and return a newly allocated
-     * String with the result.
-     *
-     * @param input  the data to encode
-     * @param offset the position within the input array at which to
-     *               start
-     * @param len    the number of bytes of input to encode
-     * @param flags  controls certain features of the encoded output.
-     *               Passing {@code DEFAULT} results in output that
-     *               adheres to RFC 2045.
-     */
-    public static String encodeToString(byte[] input, int offset, int len, int flags) {
-        return new String(encode(input, offset, len, flags));
-    }
-
-    /**
-     * Base64-encode the given data and return a newly allocated
-     * byte[] with the result.
-     *
-     * @param input  the data to encode
-     * @param flags  controls certain features of the encoded output.
-     *               Passing {@code DEFAULT} results in output that
-     *               adheres to RFC 2045.
-     */
-    public static byte[] encode(byte[] input, int flags) {
-        return encode(input, 0, input.length, flags);
-    }
-
-    /**
-     * Base64-encode the given data and return a newly allocated
-     * byte[] with the result.
-     *
-     * @param input  the data to encode
-     * @param offset the position within the input array at which to
-     *               start
-     * @param len    the number of bytes of input to encode
-     * @param flags  controls certain features of the encoded output.
-     *               Passing {@code DEFAULT} results in output that
-     *               adheres to RFC 2045.
-     */
-    public static byte[] encode(byte[] input, int offset, int len, int flags) {
-        EncoderState state = new EncoderState(flags, null);
-
-        // Compute the exact length of the array we will produce.
-        int output_len = len / 3 * 4;
-
-        // Account for the tail of the data and the padding bytes, if any.
-        if (state.do_padding) {
-            if (len % 3 > 0) {
-                output_len += 4;
-            }
-        } else {
-            switch (len % 3) {
-                case 0: break;
-                case 1: output_len += 2; break;
-                case 2: output_len += 3; break;
-            }
-        }
-
-        // Account for the newlines, if any.
-        if (state.do_newline && len > 0) {
-            output_len += (((len-1) / (3 * LINE_GROUPS)) + 1) * (state.do_cr ? 2 : 1);
-        }
-
-        state.output = new byte[output_len];
-        encodeInternal(input, offset, len, state, true);
-
-        assert state.op == output_len;
-
-        return state.output;
-    }
-
-    /* package */ static class EncoderState {
-        public byte[] output;
-        public int op;
-
-        final public byte[] tail;
-        public int tailLen;
-        public int count;
-
-        final public boolean do_padding;
-        final public boolean do_newline;
-        final public boolean do_cr;
-        final public byte[] alphabet;
-
-        public EncoderState(int flags, byte[] output) {
-            this.output = output;
-
-            do_padding = (flags & NO_PADDING) == 0;
-            do_newline = (flags & NO_WRAP) == 0;
-            do_cr = (flags & CRLF) != 0;
-            alphabet = ((flags & WEB_SAFE) == 0) ? ENCODE : ENCODE_WEBSAFE;
-
-            tail = new byte[2];
-            tailLen = 0;
-
-            count = do_newline ? LINE_GROUPS : -1;
-        }
-    }
-
-    /**
-     * Encode another block of input data.
-     *
-     * @param estate an EncoderState object whose (caller-provided)
-     *        output array is big enough to hold all the encoded data.
-     *        On return, estate.op will be set to the length of the
-     *        encoded data.
-     * @param finish true if this is the final call to encodeInternal
-     *        with the given EncoderState object.  Will finalize the
-     *        encoder state and include any final bytes in the output.
-     */
-    static void encodeInternal(byte[] input, int offset, int len,
-                               final EncoderState estate, boolean finish) {
-        final boolean do_cr = estate.do_cr;
-        final boolean do_newline = estate.do_newline;
-        final boolean do_padding = estate.do_padding;
-        final byte[] output = estate.output;
-
-        int op = 0;
-
-        int p = offset;
-        len += offset;
-        int v = -1;
-        int count = estate.count;
-
-        // First we need to concatenate the tail of the previous call
-        // with any input bytes available now and see if we can empty
-        // the tail.
-
-        switch (estate.tailLen) {
-            case 0:
-                // There was no tail.
-                break;
-
-            case 1:
-                if (p+2 <= len) {
-                    // A 1-byte tail with at least 2 bytes of
-                    // input available now.
-                    v = ((estate.tail[0] & 0xff) << 16) |
-                        ((input[p++] & 0xff) << 8) |
-                        (input[p++] & 0xff);
-                    estate.tailLen = 0;
-                };
-                break;
-
-            case 2:
-                if (p+1 <= len) {
-                    // A 2-byte tail with at least 1 byte of input.
-                    v = ((estate.tail[0] & 0xff) << 16) |
-                        ((estate.tail[1] & 0xff) << 8) |
-                        (input[p++] & 0xff);
-                    estate.tailLen = 0;
-                }
-                break;
-        }
-
-        if (v != -1) {
-            output[op++] = estate.alphabet[(v >> 18) & 0x3f];
-            output[op++] = estate.alphabet[(v >> 12) & 0x3f];
-            output[op++] = estate.alphabet[(v >> 6) & 0x3f];
-            output[op++] = estate.alphabet[v & 0x3f];
-            if (--count == 0) {
-                if (do_cr) output[op++] = '\r';
-                output[op++] = '\n';
-                count = LINE_GROUPS;
-            }
-        }
-
-        // At this point either there is no tail, or there are fewer
-        // than 3 bytes of input available.
-
-        // The main loop, turning 3 input bytes into 4 output bytes on
-        // each iteration.
-        while (p+3 <= len) {
-            v = ((input[p++] & 0xff) << 16) |
-                ((input[p++] & 0xff) << 8) |
-                (input[p++] & 0xff);
-            output[op++] = estate.alphabet[(v >> 18) & 0x3f];
-            output[op++] = estate.alphabet[(v >> 12) & 0x3f];
-            output[op++] = estate.alphabet[(v >> 6) & 0x3f];
-            output[op++] = estate.alphabet[v & 0x3f];
-            if (--count == 0) {
-                if (do_cr) output[op++] = '\r';
-                output[op++] = '\n';
-                count = LINE_GROUPS;
-            }
-        }
-
-        if (finish) {
-            // Finish up the tail of the input.  Note that we need to
-            // consume any bytes in estate.tail before any bytes
-            // remaining in input; there should be at most two bytes
-            // total.
-
-            if (p-estate.tailLen == len-1) {
-                int t = 0;
-                v = ((estate.tailLen > 0 ? estate.tail[t++] : input[p++]) & 0xff) << 4;
-                estate.tailLen -= t;
-                output[op++] = estate.alphabet[(v >> 6) & 0x3f];
-                output[op++] = estate.alphabet[v & 0x3f];
-                if (do_padding) {
-                    output[op++] = '=';
-                    output[op++] = '=';
-                }
-                if (do_newline) {
-                    if (do_cr) output[op++] = '\r';
-                    output[op++] = '\n';
-                }
-            } else if (p-estate.tailLen == len-2) {
-                int t = 0;
-                v = (((estate.tailLen > 1 ? estate.tail[t++] : input[p++]) & 0xff) << 10) |
-                    (((estate.tailLen > 0 ? estate.tail[t++] : input[p++]) & 0xff) << 2);
-                estate.tailLen -= t;
-                output[op++] = estate.alphabet[(v >> 12) & 0x3f];
-                output[op++] = estate.alphabet[(v >> 6) & 0x3f];
-                output[op++] = estate.alphabet[v & 0x3f];
-                if (do_padding) {
-                    output[op++] = '=';
-                }
-                if (do_newline) {
-                    if (do_cr) output[op++] = '\r';
-                    output[op++] = '\n';
-                }
-            } else if (do_newline && op > 0 && count != LINE_GROUPS) {
-                if (do_cr) output[op++] = '\r';
-                output[op++] = '\n';
-            }
-
-            assert estate.tailLen == 0;
-            assert p == len;
-        } else {
-            // Save the leftovers in tail to be consumed on the next
-            // call to encodeInternal.
-
-            if (p == len-1) {
-                estate.tail[estate.tailLen++] = input[p];
-            } else if (p == len-2) {
-                estate.tail[estate.tailLen++] = input[p];
-                estate.tail[estate.tailLen++] = input[p+1];
-            }
-        }
-
-        estate.op = op;
-        estate.count = count;
-    }
-
-    private Base64() { }   // don't instantiate
-}
diff --git a/common/java/com/android/common/Patterns.java b/common/java/com/android/common/Patterns.java
index 71c3a5e..3b3b038 100644
--- a/common/java/com/android/common/Patterns.java
+++ b/common/java/com/android/common/Patterns.java
@@ -24,12 +24,12 @@
  */
 public class Patterns {
     /**
-     *  Regular expression pattern to match all IANA top-level domains.
+     *  Regular expression to match all IANA top-level domains.
      *  List accurate as of 2010/02/05.  List taken from:
      *  http://data.iana.org/TLD/tlds-alpha-by-domain.txt
-     *  This pattern is auto-generated by development/tools/make-iana-tld-pattern.py
+     *  This pattern is auto-generated by frameworks/base/common/tools/make-iana-tld-pattern.py
      */
-    public static final Pattern TOP_LEVEL_DOMAIN = Pattern.compile(
+    public static final String TOP_LEVEL_DOMAIN_STR =
         "((aero|arpa|asia|a[cdefgilmnoqrstuwxz])"
         + "|(biz|b[abdefghijmnorstvwyz])"
         + "|(cat|com|coop|c[acdfghiklmnoruvxyz])"
@@ -55,20 +55,22 @@
         + "|w[fs]"
         + "|(xn\\-\\-0zwm56d|xn\\-\\-11b5bs3a9aj6g|xn\\-\\-80akhbyknj4f|xn\\-\\-9t4b11yi5a|xn\\-\\-deba0ad|xn\\-\\-g6w251d|xn\\-\\-hgbk6aj7f53bba|xn\\-\\-hlcj6aya9esc7a|xn\\-\\-jxalpdlp|xn\\-\\-kgbechtv|xn\\-\\-zckzah)"
         + "|y[etu]"
-        + "|z[amw])");
+        + "|z[amw])";
 
     /**
-     *  Regular expression pattern to match RFC 1738 URLs
+     *  Regular expression pattern to match all IANA top-level domains.
+     */
+    public static final Pattern TOP_LEVEL_DOMAIN =
+        Pattern.compile(TOP_LEVEL_DOMAIN_STR);
+
+    /**
+     *  Regular expression to match all IANA top-level domains for WEB_URL.
      *  List accurate as of 2010/02/05.  List taken from:
      *  http://data.iana.org/TLD/tlds-alpha-by-domain.txt
-     *  This pattern is auto-generated by development/tools/make-iana-tld-pattern.py
+     *  This pattern is auto-generated by frameworks/base/common/tools/make-iana-tld-pattern.py
      */
-    public static final Pattern WEB_URL = Pattern.compile(
-        "((?:(http|https|Http|Https|rtsp|Rtsp):\\/\\/(?:(?:[a-zA-Z0-9\\$\\-\\_\\.\\+\\!\\*\\'\\(\\)"
-        + "\\,\\;\\?\\&\\=]|(?:\\%[a-fA-F0-9]{2})){1,64}(?:\\:(?:[a-zA-Z0-9\\$\\-\\_"
-        + "\\.\\+\\!\\*\\'\\(\\)\\,\\;\\?\\&\\=]|(?:\\%[a-fA-F0-9]{2})){1,25})?\\@)?)?"
-        + "((?:(?:[a-zA-Z0-9][a-zA-Z0-9\\-]{0,64}\\.)+"   // named host
-        + "(?:"   // plus top level domain
+    public static final String TOP_LEVEL_DOMAIN_STR_FOR_WEB_URL =
+        "(?:"
         + "(?:aero|arpa|asia|a[cdefgilmnoqrstuwxz])"
         + "|(?:biz|b[abdefghijmnorstvwyz])"
         + "|(?:cat|com|coop|c[acdfghiklmnoruvxyz])"
@@ -94,7 +96,28 @@
         + "|w[fs]"
         + "|(?:xn\\-\\-0zwm56d|xn\\-\\-11b5bs3a9aj6g|xn\\-\\-80akhbyknj4f|xn\\-\\-9t4b11yi5a|xn\\-\\-deba0ad|xn\\-\\-g6w251d|xn\\-\\-hgbk6aj7f53bba|xn\\-\\-hlcj6aya9esc7a|xn\\-\\-jxalpdlp|xn\\-\\-kgbechtv|xn\\-\\-zckzah)"
         + "|y[etu]"
-        + "|z[amw]))"
+        + "|z[amw]))";
+
+    /**
+     * Good characters for Internationalized Resource Identifiers (IRI).
+     * This comprises most common used Unicode characters allowed in IRI
+     * as detailed in RFC 3987.
+     * Specifically, those two byte Unicode characters are not included.
+     */
+    public static final String GOOD_IRI_CHAR =
+        "a-zA-Z0-9\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF";
+
+    /**
+     *  Regular expression pattern to match most part of RFC 3987
+     *  Internationalized URLs, aka IRIs.  Commonly used Unicode characters are
+     *  added.
+     */
+    public static final Pattern WEB_URL = Pattern.compile(
+        "((?:(http|https|Http|Https|rtsp|Rtsp):\\/\\/(?:(?:[a-zA-Z0-9\\$\\-\\_\\.\\+\\!\\*\\'\\(\\)"
+        + "\\,\\;\\?\\&\\=]|(?:\\%[a-fA-F0-9]{2})){1,64}(?:\\:(?:[a-zA-Z0-9\\$\\-\\_"
+        + "\\.\\+\\!\\*\\'\\(\\)\\,\\;\\?\\&\\=]|(?:\\%[a-fA-F0-9]{2})){1,25})?\\@)?)?"
+        + "((?:(?:[" + GOOD_IRI_CHAR + "][" + GOOD_IRI_CHAR + "\\-]{0,64}\\.)+"   // named host
+        + TOP_LEVEL_DOMAIN_STR_FOR_WEB_URL
         + "|(?:(?:25[0-5]|2[0-4]" // or ip address
         + "[0-9]|[0-1][0-9]{2}|[1-9][0-9]|[1-9])\\.(?:25[0-5]|2[0-4][0-9]"
         + "|[0-1][0-9]{2}|[1-9][0-9]|[1-9]|0)\\.(?:25[0-5]|2[0-4][0-9]|[0-1]"
@@ -116,7 +139,7 @@
 
     public static final Pattern DOMAIN_NAME
         = Pattern.compile(
-            "(((([a-zA-Z0-9][a-zA-Z0-9\\-]*)*[a-zA-Z0-9]\\.)+"
+            "(((([" + GOOD_IRI_CHAR + "][" + GOOD_IRI_CHAR + "\\-]*)*[" + GOOD_IRI_CHAR + "]\\.)+"
             + TOP_LEVEL_DOMAIN + ")|"
             + IP_ADDRESS + ")");
 
diff --git a/common/java/com/android/common/ui/PointerLocationView.java b/common/java/com/android/common/ui/PointerLocationView.java
index e83c5ae..7bdb0bc 100644
--- a/common/java/com/android/common/ui/PointerLocationView.java
+++ b/common/java/com/android/common/ui/PointerLocationView.java
@@ -234,8 +234,9 @@
             }
             
             if ((action&MotionEvent.ACTION_MASK) == MotionEvent.ACTION_POINTER_DOWN) {
-                final int id = (action&MotionEvent.ACTION_POINTER_ID_MASK)
-                        >> MotionEvent.ACTION_POINTER_ID_SHIFT;
+                final int index = (action&MotionEvent.ACTION_POINTER_INDEX_MASK)
+                        >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
+                final int id = event.getPointerId(index);
                 while (NP <= id) {
                     PointerState ps = new PointerState();
                     ps.mVelocity = VelocityTracker.obtain();
@@ -260,13 +261,14 @@
             }
             
             for (int i=0; i<NI; i++) {
-                final PointerState ps = mPointers.get(event.getPointerId(i));
+                final int id = event.getPointerId(i);
+                final PointerState ps = mPointers.get(id);
                 ps.mVelocity.addMovement(event);
                 ps.mVelocity.computeCurrentVelocity(1);
                 final int N = event.getHistorySize();
                 for (int j=0; j<N; j++) {
                     if (mPrintCoords) {
-                        Log.i("Pointer", "Pointer " + (i+1) + ": ("
+                        Log.i("Pointer", "Pointer " + (id+1) + ": ("
                                 + event.getHistoricalX(i, j)
                                 + ", " + event.getHistoricalY(i, j) + ")"
                                 + " Prs=" + event.getHistoricalPressure(i, j)
@@ -276,7 +278,7 @@
                     ps.mYs.add(event.getHistoricalY(i, j));
                 }
                 if (mPrintCoords) {
-                    Log.i("Pointer", "Pointer " + (i+1) + ": ("
+                    Log.i("Pointer", "Pointer " + (id+1) + ": ("
                             + event.getX(i) + ", " + event.getY(i) + ")"
                             + " Prs=" + event.getPressure(i)
                             + " Size=" + event.getSize(i));
@@ -293,8 +295,9 @@
             }
             
             if ((action&MotionEvent.ACTION_MASK) == MotionEvent.ACTION_POINTER_UP) {
-                final int id = (action&MotionEvent.ACTION_POINTER_ID_MASK)
-                        >> MotionEvent.ACTION_POINTER_ID_SHIFT;
+                final int index = (action&MotionEvent.ACTION_POINTER_INDEX_MASK)
+                        >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
+                final int id = event.getPointerId(index);
                 final PointerState ps = mPointers.get(id);
                 ps.mXs.add(Float.NaN);
                 ps.mYs.add(Float.NaN);
@@ -306,11 +309,12 @@
             
             if (action == MotionEvent.ACTION_UP) {
                 for (int i=0; i<NI; i++) {
-                    final PointerState ps = mPointers.get(event.getPointerId(i));
+                    final int id = event.getPointerId(i);
+                    final PointerState ps = mPointers.get(id);
                     if (ps.mCurDown) {
                         ps.mCurDown = false;
                         if (mPrintCoords) {
-                            Log.i("Pointer", "Pointer " + (i+1) + ": UP");
+                            Log.i("Pointer", "Pointer " + (id+1) + ": UP");
                         }
                     }
                 }
diff --git a/common/tests/src/com/android/common/PatternsTest.java b/common/tests/src/com/android/common/PatternsTest.java
index 635601e..9e2ad58 100644
--- a/common/tests/src/com/android/common/PatternsTest.java
+++ b/common/tests/src/com/android/common/PatternsTest.java
@@ -68,6 +68,12 @@
         t = Patterns.WEB_URL.matcher("xn--fsqu00a.xn--0zwm56d").matches();
         assertTrue("Valid URL", t);
 
+        // Internationalized URL.
+        t = Patterns.WEB_URL.matcher("http://\uD604\uAE08\uC601\uC218\uC99D.kr").matches();
+        assertTrue("Valid URL", t);
+        t = Patterns.WEB_URL.matcher("\uD604\uAE08\uC601\uC218\uC99D.kr").matches();
+        assertTrue("Valid URL", t);
+
         t = Patterns.WEB_URL.matcher("ftp://www.example.com").matches();
         assertFalse("Matched invalid protocol", t);
 
@@ -99,6 +105,13 @@
         t = Patterns.DOMAIN_NAME.matcher("mail.example.com").matches();
         assertTrue("Valid domain", t);
 
+        t = Patterns.WEB_URL.matcher("google.me").matches();
+        assertTrue("Valid domain", t);
+
+        // Internationalized domains.
+        t = Patterns.DOMAIN_NAME.matcher("\uD604\uAE08\uC601\uC218\uC99D.kr").matches();
+        assertTrue("Valid domain", t);
+
         t = Patterns.DOMAIN_NAME.matcher("__+&42.xer").matches();
         assertFalse("Invalid domain", t);
     }
diff --git a/common/tools/make-iana-tld-pattern.py b/common/tools/make-iana-tld-pattern.py
index ece4dcf..de81c58 100755
--- a/common/tools/make-iana-tld-pattern.py
+++ b/common/tools/make-iana-tld-pattern.py
@@ -4,43 +4,27 @@
 
 TLD_PREFIX = r"""
     /**
-     *  Regular expression pattern to match all IANA top-level domains.
+     *  Regular expression to match all IANA top-level domains.
      *  List accurate as of 2010/02/05.  List taken from:
      *  http://data.iana.org/TLD/tlds-alpha-by-domain.txt
      *  This pattern is auto-generated by frameworks/base/common/tools/make-iana-tld-pattern.py
      */
-    public static final Pattern TOP_LEVEL_DOMAIN = Pattern.compile(
+    public static final String TOP_LEVEL_DOMAIN_STR =
 """
-TLD_SUFFIX = '");'
+TLD_SUFFIX = '";'
 
 URL_PREFIX = r"""
     /**
-     *  Regular expression pattern to match RFC 1738 URLs
+     *  Regular expression to match all IANA top-level domains for WEB_URL.
      *  List accurate as of 2010/02/05.  List taken from:
      *  http://data.iana.org/TLD/tlds-alpha-by-domain.txt
-     *  This pattern is auto-generated by frameworkds/base/common/tools/make-iana-tld-pattern.py
+     *  This pattern is auto-generated by frameworks/base/common/tools/make-iana-tld-pattern.py
      */
-    public static final Pattern WEB_URL = Pattern.compile(
-        "((?:(http|https|Http|Https|rtsp|Rtsp):\\/\\/(?:(?:[a-zA-Z0-9\\$\\-\\_\\.\\+\\!\\*\\'\\(\\)"
-        + "\\,\\;\\?\\&\\=]|(?:\\%[a-fA-F0-9]{2})){1,64}(?:\\:(?:[a-zA-Z0-9\\$\\-\\_"
-        + "\\.\\+\\!\\*\\'\\(\\)\\,\\;\\?\\&\\=]|(?:\\%[a-fA-F0-9]{2})){1,25})?\\@)?)?"
-        + "((?:(?:[a-zA-Z0-9][a-zA-Z0-9\\-]{0,64}\\.)+"   // named host
-        + "(?:"   // plus top level domain
+    public static final String TOP_LEVEL_DOMAIN_STR_FOR_WEB_URL =
+        "(?:"
 """
 
-URL_SUFFIX = r"""
-        + "|(?:(?:25[0-5]|2[0-4]" // or ip address
-        + "[0-9]|[0-1][0-9]{2}|[1-9][0-9]|[1-9])\\.(?:25[0-5]|2[0-4][0-9]"
-        + "|[0-1][0-9]{2}|[1-9][0-9]|[1-9]|0)\\.(?:25[0-5]|2[0-4][0-9]|[0-1]"
-        + "[0-9]{2}|[1-9][0-9]|[1-9]|0)\\.(?:25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}"
-        + "|[1-9][0-9]|[0-9])))"
-        + "(?:\\:\\d{1,5})?)" // plus option port number
-        + "(\\/(?:(?:[a-zA-Z0-9\\;\\/\\?\\:\\@\\&\\=\\#\\~"  // plus option query params
-        + "\\-\\.\\+\\!\\*\\'\\(\\)\\,\\_])|(?:\\%[a-fA-F0-9]{2}))*)?"
-        + "(?:\\b|$)"); // and finally, a word boundary or end of
-                        // input.  This is to stop foo.sure from
-                        // matching as foo.su
-"""
+URL_SUFFIX = ';'
 
 class Bucket:
     def __init__(self, baseLetter):
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index b4fe698..db6a4bf 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -2659,102 +2659,6 @@
             return PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
         }
 
-        // Constants related to app heuristics
-        // No-installation limit for internal flash: 10% or less space available
-        private static final double LOW_NAND_FLASH_TRESHOLD = 0.1;
-
-        // SD-to-internal app size threshold: currently set to 1 MB
-        private static final long INSTALL_ON_SD_THRESHOLD = (1024 * 1024);
-
-        public int recommendAppInstallLocation(Package pkg) {
-            // Initial implementation:
-            // Package size = code size + cache size + data size
-            // If code size > 1 MB, install on SD card.
-            // Else install on internal NAND flash, unless space on NAND is less than 10%
-
-            if (pkg == null) {
-                return INSTALL_PARSE_FAILED_NOT_APK;
-            }
-
-            StatFs internalFlashStats = new StatFs(Environment.getDataDirectory().getPath());
-            StatFs sdcardStats = new StatFs(Environment.getExternalStorageDirectory().getPath());
-
-            long totalInternalFlashSize = (long)internalFlashStats.getBlockCount() *
-                    (long)internalFlashStats.getBlockSize();
-            long availInternalFlashSize = (long)internalFlashStats.getAvailableBlocks() *
-                    (long)internalFlashStats.getBlockSize();
-            long availSDSize = (long)sdcardStats.getAvailableBlocks() *
-                    (long)sdcardStats.getBlockSize();
-
-            double pctNandFree = (double)availInternalFlashSize / (double)totalInternalFlashSize;
-
-            final String archiveFilePath = pkg.mScanPath;
-            File apkFile = new File(archiveFilePath);
-            long pkgLen = apkFile.length();
-
-            boolean auto = true;
-            // To make final copy
-            long reqInstallSize = pkgLen;
-            // For dex files
-            long reqInternalSize = 1 * pkgLen;
-            boolean intThresholdOk = (pctNandFree >= LOW_NAND_FLASH_TRESHOLD);
-            boolean intAvailOk = ((reqInstallSize + reqInternalSize) < availInternalFlashSize);
-            boolean fitsOnSd = (reqInstallSize < availSDSize) && intThresholdOk &&
-                    (reqInternalSize < availInternalFlashSize);
-            boolean fitsOnInt = intThresholdOk && intAvailOk;
-
-            // Consider application flags preferences as well...
-            boolean installOnlyOnSd = (pkg.installLocation ==
-                    PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
-            boolean installOnlyInternal = (pkg.installLocation ==
-                    PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
-            if (installOnlyInternal) {
-                // If set explicitly in manifest,
-                // let that override everything else
-                auto = false;
-            } else if (installOnlyOnSd){
-                // Check if this can be accommodated on the sdcard
-                if (fitsOnSd) {
-                    auto = false;
-                }
-            } else {
-                // Check if user option is enabled
-                boolean setInstallLoc = Settings.System.getInt(mContext.getContentResolver(),
-                        Settings.System.SET_INSTALL_LOCATION, 0) != 0;
-                if (setInstallLoc) {
-                    // Pick user preference
-                    int installPreference = Settings.System.getInt(mContext.getContentResolver(),
-                            Settings.System.DEFAULT_INSTALL_LOCATION,
-                            PackageInfo.INSTALL_LOCATION_AUTO);
-                    if (installPreference == 1) {
-                        installOnlyInternal = true;
-                        auto = false;
-                    } else if (installPreference == 2) {
-                        installOnlyOnSd = true;
-                        auto = false;
-                    }
-                }
-            }
-            if (!auto) {
-                if (installOnlyOnSd) {
-                    return fitsOnSd ? INSTALL_ON_SDCARD : INSTALL_FAILED_INSUFFICIENT_STORAGE;
-                } else if (installOnlyInternal){
-                    // Check on internal flash
-                    return fitsOnInt ? INSTALL_ON_INTERNAL_FLASH : INSTALL_FAILED_INSUFFICIENT_STORAGE;
-                }
-            }
-            // Try to install internally
-            if (fitsOnInt) {
-                return INSTALL_ON_INTERNAL_FLASH;
-            }
-            // Try the sdcard now.
-            if (fitsOnSd) {
-                return INSTALL_ON_SDCARD;
-            }
-            // Return error code
-            return INSTALL_FAILED_INSUFFICIENT_STORAGE;
-        }
-
         private final ContextImpl mContext;
         private final IPackageManager mPM;
 
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 17bee48..ff2ed3d 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -258,14 +258,7 @@
      * package has to be installed on the sdcard.
      * @hide
      */
-    public static final int INSTALL_ON_SDCARD = 0x00000008;
-
-    /**
-     * Convenience flag parameter to indicate that this package has to be installed
-     * on internal flash.
-     * @hide
-     */
-    public static final int INSTALL_ON_INTERNAL_FLASH = 0x00000000;
+    public static final int INSTALL_EXTERNAL = 0x00000008;
 
     /**
      * Flag parameter for
@@ -529,6 +522,14 @@
     public static final int INSTALL_PARSE_FAILED_MANIFEST_EMPTY = -109;
 
     /**
+     * Installation failed return code: this is passed to the {@link IPackageInstallObserver} by
+     * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)}
+     * if the system failed to install the package because of system issues.
+     * @hide
+     */
+    public static final int INSTALL_FAILED_INTERNAL_ERROR = -110;
+
+    /**
      * Indicates the state of installation. Used by PackageManager to
      * figure out incomplete installations. Say a package is being installed
      * (the state is set to PKG_INSTALL_INCOMPLETE) and remains so till
@@ -627,23 +628,6 @@
      */
     public static final String ACTION_CLEAN_EXTERNAL_STORAGE
             = "android.content.pm.CLEAN_EXTERNAL_STORAGE";
-    
-    /**
-     * Determines best place to install an application: either SD or internal FLASH.
-     * If applications explicitly set installLocation in their manifest, that
-     * preference takes precedence. If not a recommended location is returned
-     * based on current available storage on internal flash or sdcard.
-     * @param pkgInfo PackageParser.Package of the package that is to be installed.
-     * Call utility method to obtain.
-     * @return {@link INSTALL_ON_INTERNAL_FLASH} if it is best to install package on internal
-     * storage, {@link INSTALL_ON_SDCARD} if it is best to install package on SD card,
-     * and {@link INSTALL_FAILED_INSUFFICIENT_STORAGE} if insufficient space to safely install
-     * the application. {@link INSTALL_PARSE_FAILED_NOT_APK} Is returned if any input
-     * parameter is <code>null</code>.
-     * This recommendation does take into account the package's own flags.
-     * @hide
-     */
-    public abstract int recommendAppInstallLocation(PackageParser.Package pkg);
 
     /**
      * Retrieve overall information about an application package that is
diff --git a/core/java/android/database/sqlite/SQLiteDatabase.java b/core/java/android/database/sqlite/SQLiteDatabase.java
index a7e6ca0..9ac8a4d 100644
--- a/core/java/android/database/sqlite/SQLiteDatabase.java
+++ b/core/java/android/database/sqlite/SQLiteDatabase.java
@@ -201,10 +201,17 @@
 
     private long mLastLockMessageTime = 0L;
 
-    // always log queries which take 100ms+; shorter queries are sampled accordingly
+    // Things related to query logging/sampling for debugging
+    // slow/frequent queries during development.  Always log queries
+    // which take 100ms+; shorter queries are sampled accordingly.
+    // Commit statements, which are typically slow, are logged
+    // together with the most recently executed SQL statement, for
+    // disambiguation.
     private static final int QUERY_LOG_TIME_IN_MILLIS = 100;
     private static final int QUERY_LOG_SQL_LENGTH = 64;
+    private static final String COMMIT_SQL = "COMMIT;";
     private final Random mRandom = new Random();
+    private String mLastSqlStatement = null;
 
     /** Used by native code, do not rename */
     /* package */ int mNativeHandle = 0;
@@ -540,7 +547,7 @@
                 }
             }
             if (mTransactionIsSuccessful) {
-                execSQL("COMMIT;");
+                execSQL(COMMIT_SQL);
             } else {
                 try {
                     execSQL("ROLLBACK;");
@@ -1660,7 +1667,15 @@
         } finally {
             unlock();
         }
-        logTimeStat(sql, timeStart);
+
+        // Log commit statements along with the most recently executed
+        // SQL statement for disambiguation.  Note that instance
+        // equality to COMMIT_SQL is safe here.
+        if (sql == COMMIT_SQL) {
+            logTimeStat(sql + mLastSqlStatement, timeStart);
+        } else {
+            logTimeStat(sql, timeStart);
+        }
     }
 
     /**
@@ -1786,6 +1801,11 @@
 
 
     /* package */ void logTimeStat(String sql, long beginMillis) {
+        // Keep track of the last statement executed here, as this is
+        // the common funnel through which all methods of hitting
+        // libsqlite eventually flow.
+        mLastSqlStatement = sql;
+
         // Sample fast queries in proportion to the time taken.
         // Quantize the % first, so the logged sampling probability
         // exactly equals the actual sampling rate for this query.
diff --git a/core/java/android/net/Downloads.java b/core/java/android/net/Downloads.java
index b86a0e2..a794af2 100644
--- a/core/java/android/net/Downloads.java
+++ b/core/java/android/net/Downloads.java
@@ -22,165 +22,197 @@
 import android.content.Context;
 import android.database.Cursor;
 import android.net.Uri;
+import android.os.ParcelFileDescriptor;
 import android.os.SystemClock;
 import android.provider.BaseColumns;
 import android.util.Log;
 
 import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.File;
+import java.io.InputStream;
 
 /**
  * The Download Manager
  *
- * @pending
+ *
  */
 public final class Downloads {
 
-    public static final class ByUri {
 
+    /**
+     * Download status codes
+     */
+
+    /**
+     * This download hasn't started yet
+     */
+    public static final int STATUS_PENDING = 190;
+
+    /**
+     * This download has started
+     */
+    public static final int STATUS_RUNNING = 192;
+
+    /**
+     * This download has successfully completed.
+     * Warning: there might be other status values that indicate success
+     * in the future.
+     * Use isSucccess() to capture the entire category.
+     */
+    public static final int STATUS_SUCCESS = 200;
+
+    /**
+     * This download can't be performed because the content type cannot be
+     * handled.
+     */
+    public static final int STATUS_NOT_ACCEPTABLE = 406;
+
+    /**
+     * This download has completed with an error.
+     * Warning: there will be other status values that indicate errors in
+     * the future. Use isStatusError() to capture the entire category.
+     */
+    public static final int STATUS_UNKNOWN_ERROR = 491;
+
+    /**
+     * This download couldn't be completed because of an HTTP
+     * redirect response that the download manager couldn't
+     * handle.
+     */
+    public static final int STATUS_UNHANDLED_REDIRECT = 493;
+
+    /**
+     * This download couldn't be completed due to insufficient storage
+     * space.  Typically, this is because the SD card is full.
+     */
+    public static final int STATUS_INSUFFICIENT_SPACE_ERROR = 498;
+
+    /**
+     * This download couldn't be completed because no external storage
+     * device was found.  Typically, this is because the SD card is not
+     * mounted.
+     */
+    public static final int STATUS_DEVICE_NOT_FOUND_ERROR = 499;
+
+    /**
+     * Returns whether the status is a success (i.e. 2xx).
+     */
+    public static boolean isStatusSuccess(int status) {
+        return (status >= 200 && status < 300);
+    }
+
+    /**
+     * Returns whether the status is an error (i.e. 4xx or 5xx).
+     */
+    public static boolean isStatusError(int status) {
+        return (status >= 400 && status < 600);
+    }
+
+    /**
+     * Download destinations
+     */
+
+    /**
+     * This download will be saved to the external storage. This is the
+     * default behavior, and should be used for any file that the user
+     * can freely access, copy, delete. Even with that destination,
+     * unencrypted DRM files are saved in secure internal storage.
+     * Downloads to the external destination only write files for which
+     * there is a registered handler. The resulting files are accessible
+     * by filename to all applications.
+     */
+    public static final int DOWNLOAD_DESTINATION_EXTERNAL = 1;
+
+    /**
+     * This download will be saved to the download manager's private
+     * partition. This is the behavior used by applications that want to
+     * download private files that are used and deleted soon after they
+     * get downloaded. All file types are allowed, and only the initiating
+     * application can access the file (indirectly through a content
+     * provider). This requires the
+     * android.permission.ACCESS_DOWNLOAD_MANAGER_ADVANCED permission.
+     */
+    public static final int DOWNLOAD_DESTINATION_CACHE = 2;
+
+    /**
+     * This download will be saved to the download manager's private
+     * partition and will be purged as necessary to make space. This is
+     * for private files (similar to CACHE_PARTITION) that aren't deleted
+     * immediately after they are used, and are kept around by the download
+     * manager as long as space is available.
+     */
+    public static final int DOWNLOAD_DESTINATION_CACHE_PURGEABLE = 3;
+
+
+    /**
+     * An invalid download id
+     */
+    public static final long DOWNLOAD_ID_INVALID = -1;
+
+
+    /**
+     * Broadcast Action: this is sent by the download manager to the app
+     * that had initiated a download when that download completes. The
+     * download's content: uri is specified in the intent's data.
+     */
+    public static final String ACTION_DOWNLOAD_COMPLETED =
+            "android.intent.action.DOWNLOAD_COMPLETED";
+
+    /**
+     * If extras are specified when requesting a download they will be provided in the intent that
+     * is sent to the specified class and package when a download has finished.
+     * <P>Type: TEXT</P>
+     * <P>Owner can Init</P>
+     */
+    public static final String COLUMN_NOTIFICATION_EXTRAS = "notificationextras";
+
+
+    /**
+     * Status class for a download
+     */
+    public static final class StatusInfo {
+        public boolean completed = false;
+        /** The filename of the active download. */
+        public String filename = null;
+        /** An opaque id for the download */
+        public long id = DOWNLOAD_ID_INVALID;
+        /** An opaque status code for the download */
+        public int statusCode = -1;
+        /** Approximate number of bytes downloaded so far, for debugging purposes. */
+        public long bytesSoFar = -1;
+
+        /**
+         * Returns whether the download is completed
+         * @return a boolean whether the download is complete.
+         */
+        public boolean isComplete() {
+            return android.provider.Downloads.Impl.isStatusCompleted(statusCode);
+        }
+
+        /**
+         * Returns whether the download is successful
+         * @return a boolean whether the download is successful.
+         */
+        public boolean isSuccessful() {
+            return android.provider.Downloads.Impl.isStatusCompleted(statusCode);
+        }
+    }
+
+    /**
+     * Class to access initiate and query download by server uri
+     */
+    public static final class ByUri extends DownloadBase {
         /** @hide */
         private ByUri() {}
 
         /**
-          * Initiate a download where the download will be tracked by its URI.
-          * @pending
-          */
-        public static boolean startDownloadByUri(
-                Context context,
-                String url,
-                boolean showDownload,
-                boolean allowRoaming,
-                String title,
-                String notification_package,
-                String notification_class) {
-            ContentResolver cr = context.getContentResolver();
-
-            // Tell download manager to start downloading update.
-            ContentValues values = new ContentValues();
-            values.put(android.provider.Downloads.Impl.COLUMN_URI, url);
-            values.put(android.provider.Downloads.Impl.COLUMN_VISIBILITY,
-                       showDownload ? android.provider.Downloads.Impl.VISIBILITY_VISIBLE
-                       : android.provider.Downloads.Impl.VISIBILITY_HIDDEN);
-            if (title != null) {
-                values.put(android.provider.Downloads.Impl.COLUMN_TITLE, title);
-            }
-            values.put(android.provider.Downloads.Impl.COLUMN_APP_DATA, url);
-            values.put(android.provider.Downloads.Impl.COLUMN_DESTINATION,
-                       allowRoaming ? android.provider.Downloads.Impl.DESTINATION_CACHE_PARTITION :
-                       android.provider.Downloads.Impl.DESTINATION_CACHE_PARTITION_NOROAMING);
-            values.put(android.provider.Downloads.Impl.COLUMN_NO_INTEGRITY, true);  // Don't check ETag
-            if (notification_package != null && notification_class != null) {
-                values.put(android.provider.Downloads.Impl.COLUMN_NOTIFICATION_PACKAGE, notification_package);
-                values.put(android.provider.Downloads.Impl.COLUMN_NOTIFICATION_CLASS, notification_class);
-            }
-
-            if (cr.insert(android.provider.Downloads.Impl.CONTENT_URI, values) == null) {
-                return false;
-            }
-            return true;
-        }
-
-        public static final class StatusInfo {
-            public boolean completed = false;
-            /** The filename of the active download. */
-            public String filename = null;
-            /** An opaque id for the download */
-            public long id = -1;
-            /** An opaque status code for the download */
-            public int statusCode = -1;
-            /** Approximate number of bytes downloaded so far, for debugging purposes. */
-            public long bytesSoFar = -1;
-        }
-
-        /** @hide */
-        private static final int STATUS_INVALID = 0;
-        /** @hide */
-        private static final int STATUS_DOWNLOADING_UPDATE = 3;
-        /** @hide */
-        private static final int STATUS_DOWNLOADED_UPDATE = 4;
-
-        /**
-         * Column projection for the query to the download manager. This must match
-         * with the constants DOWNLOADS_COLUMN_*.
-          * @hide
-         */
-        private static final String[] DOWNLOADS_PROJECTION = {
-            BaseColumns._ID,
-            android.provider.Downloads.Impl.COLUMN_APP_DATA,
-            android.provider.Downloads.Impl.COLUMN_STATUS,
-            android.provider.Downloads.Impl._DATA,
-            android.provider.Downloads.Impl.COLUMN_LAST_MODIFICATION,
-            android.provider.Downloads.Impl.COLUMN_CURRENT_BYTES,
-        };
-
-        /**
-          * The column index for the ID.
-          * @hide
-          */
-        private static final int DOWNLOADS_COLUMN_ID = 0;
-        /**
-          * The column index for the URI.
-          * @hide
-          */
-        private static final int DOWNLOADS_COLUMN_URI = 1;
-        /**
-          * The column index for the status code.
-          * @hide
-          */
-        private static final int DOWNLOADS_COLUMN_STATUS = 2;
-        /**
-          * The column index for the filename.
-          * @hide
-          */
-        private static final int DOWNLOADS_COLUMN_FILENAME = 3;
-        /**
-          * The column index for the last modification time.
-          * @hide
-          */
-        private static final int DOWNLOADS_COLUMN_LAST_MODIFICATION = 4;
-        /**
-          * The column index for the number of bytes downloaded so far.
-          * @hide
-          */
-        private static final int DOWNLOADS_COLUMN_CURRENT_BYTES = 5;
-
-        /**
-         * Gets the status of a download.
-         *
-         * @param c A Cursor pointing to a download.  The URL column is assumed to be valid.
-         * @return The status of the download.
+         * Query where clause by app data.
          * @hide
          */
-        private static final int getStatusOfDownload(
-                Cursor c,
-                long redownload_threshold) {
-            int status = c.getInt(DOWNLOADS_COLUMN_STATUS);
-            long realtime = SystemClock.elapsedRealtime();
-
-            // TODO(dougz): special handling of 503, 404?  (eg, special
-            // explanatory messages to user)
-
-            if (!android.provider.Downloads.Impl.isStatusCompleted(status)) {
-                // Check if it's stuck
-                long modified = c.getLong(DOWNLOADS_COLUMN_LAST_MODIFICATION);
-                long now = System.currentTimeMillis();
-                if (now < modified || now - modified > redownload_threshold) {
-                    return STATUS_INVALID;
-                }
-
-                return STATUS_DOWNLOADING_UPDATE;
-            }
-
-            if (android.provider.Downloads.Impl.isStatusError(status)) {
-                return STATUS_INVALID;
-            }
-
-            String filename = c.getString(DOWNLOADS_COLUMN_FILENAME);
-            if (filename == null) {
-                return STATUS_INVALID;
-            }
-
-            return STATUS_DOWNLOADED_UPDATE;
-        }
+        private static final String QUERY_WHERE_APP_DATA_CLAUSE =
+                android.provider.Downloads.Impl.COLUMN_APP_DATA + "=?";
 
         /**
          * Gets a Cursor pointing to the download(s) of the current system update.
@@ -190,15 +222,14 @@
             return context.getContentResolver().query(
                     android.provider.Downloads.Impl.CONTENT_URI,
                     DOWNLOADS_PROJECTION,
-                    android.provider.Downloads.Impl.COLUMN_APP_DATA + "='" + url.replace("'", "''") + "'",
-                    null,
+                    QUERY_WHERE_APP_DATA_CLAUSE,
+                    new String[] {url},
                     null);
         }
 
         /**
          * Returns a StatusInfo with the result of trying to download the
          * given URL.  Returns null if no attempts have been made.
-         * @pending
          */
         public static final StatusInfo getStatus(
                 Context context,
@@ -237,14 +268,15 @@
                     result.bytesSoFar = c.getLong(DOWNLOADS_COLUMN_CURRENT_BYTES);
                 }
             } finally {
-                c.close();
+                if (c != null) {
+                    c.close();
+                }
             }
             return result;
         }
 
         /**
          * Query where clause for general querying.
-         * @hide
          */
         private static final String QUERY_WHERE_CLAUSE =
                 android.provider.Downloads.Impl.COLUMN_NOTIFICATION_PACKAGE + "=? AND " +
@@ -252,7 +284,6 @@
 
         /**
          * Delete all the downloads for a package/class pair.
-         * @pending
          */
         public static final void removeAllDownloadsByPackage(
                 Context context,
@@ -287,19 +318,324 @@
 
         /** @hide */
         private static final String[] PROJECTION = {
-            BaseColumns._ID, android.provider.Downloads.Impl.COLUMN_CURRENT_BYTES, android.provider.Downloads.Impl.COLUMN_TOTAL_BYTES
+            BaseColumns._ID,
+            android.provider.Downloads.Impl.COLUMN_CURRENT_BYTES,
+            android.provider.Downloads.Impl.COLUMN_TOTAL_BYTES
         };
 
         /**
          * @pending
          */
         public static final Cursor getProgressCursor(Context context, long id) {
-            Uri downloadUri = Uri.withAppendedPath(android.provider.Downloads.Impl.CONTENT_URI, String.valueOf(id));
+            Uri downloadUri = Uri.withAppendedPath(android.provider.Downloads.Impl.CONTENT_URI,
+                    String.valueOf(id));
             return context.getContentResolver().query(downloadUri, PROJECTION, null, null, null);
         }
     }
 
     /**
+     * Class to access downloads by opaque download id
+     */
+    public static final class ById extends DownloadBase {
+        /** @hide */
+        private ById() {}
+
+        /**
+         * Get the mime tupe of the download specified by the download id
+         */
+        public static String getMimeTypeForId(Context context, long downloadId) {
+            ContentResolver cr = context.getContentResolver();
+
+            String mimeType = null;
+            Cursor downloadCursor = null;
+
+            try {
+                Uri downloadUri = getDownloadUri(downloadId);
+
+                downloadCursor = cr.query(
+                        downloadUri, new String[]{android.provider.Downloads.Impl.COLUMN_MIME_TYPE},
+                        null, null, null);
+                if (downloadCursor.moveToNext()) {
+                    mimeType = downloadCursor.getString(0);
+                }
+            } finally {
+                if (downloadCursor != null) downloadCursor.close();
+            }
+            return mimeType;
+        }
+
+        /**
+         * Delete a download by Id
+         */
+        public static void deleteDownload(Context context, long downloadId) {
+            ContentResolver cr = context.getContentResolver();
+
+            String mimeType = null;
+
+            Uri downloadUri = getDownloadUri(downloadId);
+
+            cr.delete(downloadUri, null, null);
+        }
+
+        /**
+         * Open a filedescriptor to a particular download
+         */
+        public static ParcelFileDescriptor openDownload(
+                Context context, long downloadId, String mode)
+            throws FileNotFoundException
+        {
+            ContentResolver cr = context.getContentResolver();
+
+            String mimeType = null;
+
+            Uri downloadUri = getDownloadUri(downloadId);
+
+            return cr.openFileDescriptor(downloadUri, mode);
+        }
+
+        /**
+         * Open a stream to a particular download
+         */
+        public static InputStream openDownloadStream(Context context, long downloadId)
+                throws FileNotFoundException, IOException
+        {
+            ContentResolver cr = context.getContentResolver();
+
+            String mimeType = null;
+
+            Uri downloadUri = getDownloadUri(downloadId);
+
+            return cr.openInputStream(downloadUri);
+        }
+
+        private static Uri getDownloadUri(long downloadId) {
+            return Uri.parse(android.provider.Downloads.Impl.CONTENT_URI + "/" + downloadId);
+        }
+
+        /**
+         * Returns a StatusInfo with the result of trying to download the
+         * given URL.  Returns null if no attempts have been made.
+         */
+        public static final StatusInfo getStatus(
+                Context context,
+                long downloadId) {
+            StatusInfo result = null;
+            boolean hasFailedDownload = false;
+            long failedDownloadModificationTime = 0;
+
+            Uri downloadUri = getDownloadUri(downloadId);
+
+            ContentResolver cr = context.getContentResolver();
+
+            Cursor c = cr.query(
+                    downloadUri, DOWNLOADS_PROJECTION, null /* selection */, null /* selection args */,
+                    null /* sort order */);
+            try {
+                if (!c.moveToNext()) {
+                    return result;
+                }
+
+                if (result == null) {
+                    result = new StatusInfo();
+                }
+                int status = getStatusOfDownload(c,0);
+                if (status == STATUS_DOWNLOADING_UPDATE ||
+                        status == STATUS_DOWNLOADED_UPDATE) {
+                    result.completed = (status == STATUS_DOWNLOADED_UPDATE);
+                    result.filename = c.getString(DOWNLOADS_COLUMN_FILENAME);
+                    result.id = c.getLong(DOWNLOADS_COLUMN_ID);
+                    result.statusCode = c.getInt(DOWNLOADS_COLUMN_STATUS);
+                    result.bytesSoFar = c.getLong(DOWNLOADS_COLUMN_CURRENT_BYTES);
+                    return result;
+                }
+
+                long modTime = c.getLong(DOWNLOADS_COLUMN_LAST_MODIFICATION);
+
+                result.statusCode = c.getInt(DOWNLOADS_COLUMN_STATUS);
+                result.bytesSoFar = c.getLong(DOWNLOADS_COLUMN_CURRENT_BYTES);
+            } finally {
+                if (c != null) {
+                    c.close();
+                }
+            }
+            return result;
+        }
+    }
+
+
+    /**
+     * Base class with common functionality for the various download classes
+     */
+    private static class DownloadBase {
+        /** @hide */
+        DownloadBase() {}
+
+        /**
+          * Initiate a download where the download will be tracked by its URI.
+          */
+        public static long startDownloadByUri(
+                Context context,
+                String url,
+                String cookieData,
+                boolean showDownload,
+                int downloadDestination,
+                boolean allowRoaming,
+                boolean skipIntegrityCheck,
+                String title,
+                String notification_package,
+                String notification_class,
+                String notification_extras) {
+            ContentResolver cr = context.getContentResolver();
+
+            // Tell download manager to start downloading update.
+            ContentValues values = new ContentValues();
+            values.put(android.provider.Downloads.Impl.COLUMN_URI, url);
+            values.put(android.provider.Downloads.Impl.COLUMN_COOKIE_DATA, cookieData);
+            values.put(android.provider.Downloads.Impl.COLUMN_VISIBILITY,
+                       showDownload ? android.provider.Downloads.Impl.VISIBILITY_VISIBLE
+                       : android.provider.Downloads.Impl.VISIBILITY_HIDDEN);
+            if (title != null) {
+                values.put(android.provider.Downloads.Impl.COLUMN_TITLE, title);
+            }
+            values.put(android.provider.Downloads.Impl.COLUMN_APP_DATA, url);
+
+
+            // NOTE:  destination should be seperated from whether the download
+            // can happen when roaming
+            int destination = android.provider.Downloads.Impl.DESTINATION_EXTERNAL;
+            switch (downloadDestination) {
+                case DOWNLOAD_DESTINATION_EXTERNAL:
+                    destination = android.provider.Downloads.Impl.DESTINATION_EXTERNAL;
+                    break;
+                case DOWNLOAD_DESTINATION_CACHE:
+                    if (allowRoaming) {
+                        destination = android.provider.Downloads.Impl.DESTINATION_CACHE_PARTITION;
+                    } else {
+                        destination =
+                                android.provider.Downloads.Impl.DESTINATION_CACHE_PARTITION_NOROAMING;
+                    }
+                    break;
+                case DOWNLOAD_DESTINATION_CACHE_PURGEABLE:
+                    destination =
+                            android.provider.Downloads.Impl.DESTINATION_CACHE_PARTITION_PURGEABLE;
+                    break;
+            }
+            values.put(android.provider.Downloads.Impl.COLUMN_DESTINATION, destination);
+            values.put(android.provider.Downloads.Impl.COLUMN_NO_INTEGRITY,
+                    skipIntegrityCheck);  // Don't check ETag
+            if (notification_package != null && notification_class != null) {
+                values.put(android.provider.Downloads.Impl.COLUMN_NOTIFICATION_PACKAGE,
+                        notification_package);
+                values.put(android.provider.Downloads.Impl.COLUMN_NOTIFICATION_CLASS,
+                        notification_class);
+
+                if (notification_extras != null) {
+                    values.put(android.provider.Downloads.Impl.COLUMN_NOTIFICATION_EXTRAS,
+                            notification_extras);
+                }
+            }
+
+            Uri downloadUri = cr.insert(android.provider.Downloads.Impl.CONTENT_URI, values);
+
+            long downloadId = DOWNLOAD_ID_INVALID;
+            if (downloadUri != null) {
+                downloadId = Long.parseLong(downloadUri.getLastPathSegment());
+            }
+            return downloadId;
+        }
+    }
+
+    /** @hide */
+    private static final int STATUS_INVALID = 0;
+    /** @hide */
+    private static final int STATUS_DOWNLOADING_UPDATE = 3;
+    /** @hide */
+    private static final int STATUS_DOWNLOADED_UPDATE = 4;
+
+    /**
+     * Column projection for the query to the download manager. This must match
+     * with the constants DOWNLOADS_COLUMN_*.
+     * @hide
+     */
+    private static final String[] DOWNLOADS_PROJECTION = {
+            BaseColumns._ID,
+            android.provider.Downloads.Impl.COLUMN_APP_DATA,
+            android.provider.Downloads.Impl.COLUMN_STATUS,
+            android.provider.Downloads.Impl._DATA,
+            android.provider.Downloads.Impl.COLUMN_LAST_MODIFICATION,
+            android.provider.Downloads.Impl.COLUMN_CURRENT_BYTES,
+    };
+
+    /**
+     * The column index for the ID.
+     * @hide
+     */
+    private static final int DOWNLOADS_COLUMN_ID = 0;
+    /**
+     * The column index for the URI.
+     * @hide
+     */
+    private static final int DOWNLOADS_COLUMN_URI = 1;
+    /**
+     * The column index for the status code.
+     * @hide
+     */
+    private static final int DOWNLOADS_COLUMN_STATUS = 2;
+    /**
+     * The column index for the filename.
+     * @hide
+     */
+    private static final int DOWNLOADS_COLUMN_FILENAME = 3;
+    /**
+     * The column index for the last modification time.
+     * @hide
+     */
+    private static final int DOWNLOADS_COLUMN_LAST_MODIFICATION = 4;
+    /**
+     * The column index for the number of bytes downloaded so far.
+     * @hide
+     */
+    private static final int DOWNLOADS_COLUMN_CURRENT_BYTES = 5;
+
+    /**
+     * Gets the status of a download.
+     *
+     * @param c A Cursor pointing to a download.  The URL column is assumed to be valid.
+     * @return The status of the download.
+     * @hide
+     */
+    private static final int getStatusOfDownload( Cursor c, long redownload_threshold) {
+        int status = c.getInt(DOWNLOADS_COLUMN_STATUS);
+        long realtime = SystemClock.elapsedRealtime();
+
+        // TODO(dougz): special handling of 503, 404?  (eg, special
+        // explanatory messages to user)
+
+        if (!android.provider.Downloads.Impl.isStatusCompleted(status)) {
+            // Check if it's stuck
+            long modified = c.getLong(DOWNLOADS_COLUMN_LAST_MODIFICATION);
+            long now = System.currentTimeMillis();
+            if (now < modified || now - modified > redownload_threshold) {
+                return STATUS_INVALID;
+            }
+
+            return STATUS_DOWNLOADING_UPDATE;
+        }
+
+        if (android.provider.Downloads.Impl.isStatusError(status)) {
+            return STATUS_INVALID;
+        }
+
+        String filename = c.getString(DOWNLOADS_COLUMN_FILENAME);
+        if (filename == null) {
+            return STATUS_INVALID;
+        }
+
+        return STATUS_DOWNLOADED_UPDATE;
+    }
+
+
+    /**
      * @hide
      */
     private Downloads() {}
diff --git a/core/java/android/net/WebAddress.java b/core/java/android/net/WebAddress.java
index f4ae66a..2d078c1 100644
--- a/core/java/android/net/WebAddress.java
+++ b/core/java/android/net/WebAddress.java
@@ -16,6 +16,8 @@
 
 package android.net;
 
+import static com.android.common.Patterns.GOOD_IRI_CHAR;
+
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
@@ -54,7 +56,7 @@
     static Pattern sAddressPattern = Pattern.compile(
             /* scheme    */ "(?:(http|HTTP|https|HTTPS|file|FILE)\\:\\/\\/)?" +
             /* authority */ "(?:([-A-Za-z0-9$_.+!*'(),;?&=]+(?:\\:[-A-Za-z0-9$_.+!*'(),;?&=]+)?)@)?" +
-            /* host      */ "([-A-Za-z0-9%_]+(?:\\.[-A-Za-z0-9%_]+)*|\\[[0-9a-fA-F:\\.]+\\])?" +
+            /* host      */ "([-" + GOOD_IRI_CHAR + "%_]+(?:\\.[-" + GOOD_IRI_CHAR + "%_]+)*|\\[[0-9a-fA-F:\\.]+\\])?" +
             /* port      */ "(?:\\:([0-9]+))?" +
             /* path      */ "(\\/?.*)?");
 
diff --git a/core/java/android/os/ICheckinService.aidl b/core/java/android/os/ICheckinService.aidl
deleted file mode 100644
index 37af496..0000000
--- a/core/java/android/os/ICheckinService.aidl
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * 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.
- */
-
-package android.os;
-
-import android.os.IParentalControlCallback;
-
-/**
- * System private API for direct access to the checkin service.
- * Users should use the content provider instead.
- *
- * @see android.provider.Checkin
- * {@hide}
- */
-interface ICheckinService {
-    /**
-     * Determine if the device is under parental control. Return null if
-     * we are unable to check the parental control status.
-     */
-    void getParentalControlState(IParentalControlCallback p,
-                                 String requestingApp);
-}
diff --git a/core/java/android/os/IParentalControlCallback.aidl b/core/java/android/os/IParentalControlCallback.aidl
deleted file mode 100644
index 2f1a563..0000000
--- a/core/java/android/os/IParentalControlCallback.aidl
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (c) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.os;
-
-import com.google.android.net.ParentalControlState;
-
-/**
- * This callback interface is used to deliver the parental control state to the calling application.
- * {@hide}
- */
-oneway interface IParentalControlCallback {
-	void onResult(in ParentalControlState state);
-}
diff --git a/core/java/android/pim/vcard/VCardComposer.java b/core/java/android/pim/vcard/VCardComposer.java
index 389c9f4..5e978f6 100644
--- a/core/java/android/pim/vcard/VCardComposer.java
+++ b/core/java/android/pim/vcard/VCardComposer.java
@@ -25,6 +25,7 @@
 import android.database.sqlite.SQLiteException;
 import android.net.Uri;
 import android.os.RemoteException;
+import android.pim.vcard.exception.VCardException;
 import android.provider.CallLog;
 import android.provider.CallLog.Calls;
 import android.provider.ContactsContract.Contacts;
@@ -54,6 +55,7 @@
 import java.io.OutputStreamWriter;
 import java.io.UnsupportedEncodingException;
 import java.io.Writer;
+import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.nio.charset.UnsupportedCharsetException;
 import java.util.ArrayList;
@@ -199,6 +201,10 @@
                 try {
                     // Create one empty entry.
                     mWriter.write(createOneEntryInternal("-1", null));
+                } catch (VCardException e) {
+                    Log.e(LOG_TAG, "VCardException has been thrown during on Init(): " +
+                            e.getMessage());
+                    return false;
                 } catch (IOException e) {
                     Log.e(LOG_TAG,
                             "IOException occurred during exportOneContactData: "
@@ -455,6 +461,9 @@
                     return true;
                 }
             }
+        } catch (VCardException e) {
+            Log.e(LOG_TAG, "VCardException has been thrown: " + e.getMessage());
+            return false;
         } catch (OutOfMemoryError error) {
             // Maybe some data (e.g. photo) is too big to have in memory. But it
             // should be rare.
@@ -486,27 +495,37 @@
     }
 
     private String createOneEntryInternal(final String contactId,
-            Method getEntityIteratorMethod) {
+            Method getEntityIteratorMethod) throws VCardException {
         final Map<String, List<ContentValues>> contentValuesListMap =
                 new HashMap<String, List<ContentValues>>();
         // The resolver may return the entity iterator with no data. It is possiible.
         // e.g. If all the data in the contact of the given contact id are not exportable ones,
         //      they are hidden from the view of this method, though contact id itself exists.
-        boolean dataExists = false;
         EntityIterator entityIterator = null;
         try {
-
             if (getEntityIteratorMethod != null) {
+                final Uri uri = RawContacts.CONTENT_URI.buildUpon()
+                        .appendQueryParameter(Data.FOR_EXPORT_ONLY, "1")
+                        .build();
+                final String selection = Data.CONTACT_ID + "=?";
+                final String[] selectionArgs = new String[] {contactId};
                 try {
-                    final Uri uri = RawContacts.CONTENT_URI.buildUpon()
-                            .appendQueryParameter(Data.FOR_EXPORT_ONLY, "1")
-                            .build();
-                    final String selection = Data.CONTACT_ID + "=?";
-                    final String[] selectionArgs = new String[] {contactId};
                     entityIterator = (EntityIterator)getEntityIteratorMethod.invoke(null,
                             mContentResolver, uri, selection, selectionArgs, null);
-                } catch (Exception e) {
-                    e.printStackTrace();
+                } catch (IllegalArgumentException e) {
+                    Log.e(LOG_TAG, "IllegalArgumentException has been thrown: " +
+                            e.getMessage());
+                } catch (IllegalAccessException e) {
+                    Log.e(LOG_TAG, "IllegalAccessException has been thrown: " +
+                            e.getMessage());
+                } catch (InvocationTargetException e) {
+                    Log.e(LOG_TAG, "InvocationTargetException has been thrown: ");
+                    StackTraceElement[] stackTraceElements = e.getCause().getStackTrace();
+                    for (StackTraceElement element : stackTraceElements) {
+                        Log.e(LOG_TAG, "    at " + element.toString());
+                    }
+                    throw new VCardException("InvocationTargetException has been thrown: " +
+                            e.getCause().getMessage());
                 }
             } else {
                 final Uri uri = RawContacts.CONTENT_URI.buildUpon()
@@ -523,7 +542,11 @@
                 return "";
             }
 
-            dataExists = entityIterator.hasNext();
+            if (!entityIterator.hasNext()) {
+                Log.w(LOG_TAG, "Data does not exist. contactId: " + contactId);
+                return "";
+            }
+
             while (entityIterator.hasNext()) {
                 Entity entity = entityIterator.next();
                 for (NamedContentValues namedContentValues : entity.getSubValues()) {
@@ -550,10 +573,6 @@
             }
         }
 
-        if (!dataExists) {
-            return "";
-        }
-
         final VCardBuilder builder = new VCardBuilder(mVCardType);
         builder.appendNameProperties(contentValuesListMap.get(StructuredName.CONTENT_ITEM_TYPE))
                 .appendNickNames(contentValuesListMap.get(Nickname.CONTENT_ITEM_TYPE))
diff --git a/core/java/android/pim/vcard/VCardEntry.java b/core/java/android/pim/vcard/VCardEntry.java
index 20eee84..1cf3144 100644
--- a/core/java/android/pim/vcard/VCardEntry.java
+++ b/core/java/android/pim/vcard/VCardEntry.java
@@ -281,6 +281,29 @@
                     isPrimary == organization.isPrimary);
         }
 
+        public String getFormattedString() {
+            final StringBuilder builder = new StringBuilder();
+            if (!TextUtils.isEmpty(companyName)) {
+                builder.append(companyName);
+            }
+
+            if (!TextUtils.isEmpty(departmentName)) {
+                if (builder.length() > 0) {
+                    builder.append(", ");
+                }
+                builder.append(departmentName);
+            }
+
+            if (!TextUtils.isEmpty(titleName)) {
+                if (builder.length() > 0) {
+                    builder.append(", ");
+                }
+                builder.append(titleName);
+            }
+
+            return builder.toString();
+        }
+
         @Override
         public String toString() {
             return String.format(
@@ -1008,6 +1031,8 @@
             mDisplayName = mPhoneList.get(0).data;
         } else if (mPostalList != null && mPostalList.size() > 0) {
             mDisplayName = mPostalList.get(0).getFormattedAddress(mVCardType);
+        } else if (mOrganizationList != null && mOrganizationList.size() > 0) {
+            mDisplayName = mOrganizationList.get(0).getFormattedString();
         }
 
         if (mDisplayName == null) {
diff --git a/core/java/android/provider/Checkin.java b/core/java/android/provider/Checkin.java
deleted file mode 100644
index 75936a1..0000000
--- a/core/java/android/provider/Checkin.java
+++ /dev/null
@@ -1,269 +0,0 @@
-/*
- * Copyright (C) 2006 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.provider;
-
-import org.apache.commons.codec.binary.Base64;
-
-import android.content.ContentResolver;
-import android.content.ContentValues;
-import android.database.SQLException;
-import android.net.Uri;
-import android.os.SystemClock;
-import android.util.Log;
-
-import java.io.ByteArrayOutputStream;
-import java.io.DataOutputStream;
-
-/**
- * Contract class for the checkin provider, used to store events and
- * statistics that will be uploaded to a checkin server eventually.
- * Describes the exposed database schema, and offers methods to add
- * events and statistics to be uploaded.
- *
- * TODO: Move this to vendor/google when we have a home for it.
- *
- * @hide
- */
-public final class Checkin {
-    public static final String AUTHORITY = "android.server.checkin";
-
-    /**
-     * The events table is a log of important timestamped occurrences.
-     * Each event has a type tag and an optional string value.
-     * If too many events are added before they can be reported, the
-     * content provider will erase older events to limit the table size.
-     */
-    public interface Events extends BaseColumns {
-        public static final String TABLE_NAME = "events";
-        public static final Uri CONTENT_URI =
-            Uri.parse("content://" + AUTHORITY + "/" + TABLE_NAME);
-
-        public static final String TAG = "tag";     // TEXT
-        public static final String VALUE = "value"; // TEXT
-        public static final String DATE = "date";   // INTEGER
-
-        /** Valid tag values.  Extend as necessary for your needs. */
-        public enum Tag {
-            APANIC_CONSOLE,
-            APANIC_THREADS,
-            AUTOTEST_FAILURE,
-            AUTOTEST_SEQUENCE_BEGIN,
-            AUTOTEST_SUITE_BEGIN,
-            AUTOTEST_TCPDUMP_BEGIN,
-            AUTOTEST_TCPDUMP_DATA,
-            AUTOTEST_TCPDUMP_END,
-            AUTOTEST_TEST_BEGIN,
-            AUTOTEST_TEST_FAILURE,
-            AUTOTEST_TEST_SUCCESS,
-            BROWSER_BUG_REPORT,
-            CARRIER_BUG_REPORT,
-            CHECKIN_FAILURE,
-            CHECKIN_SUCCESS,
-            FOTA_BEGIN,
-            FOTA_FAILURE,
-            FOTA_INSTALL,
-            FOTA_PROMPT,
-            FOTA_PROMPT_ACCEPT,
-            FOTA_PROMPT_REJECT,
-            FOTA_PROMPT_SKIPPED,
-            GSERVICES_ERROR,
-            GSERVICES_UPDATE,
-            LOGIN_SERVICE_ACCOUNT_TRIED,
-            LOGIN_SERVICE_ACCOUNT_SAVED,
-            LOGIN_SERVICE_AUTHENTICATE,
-            LOGIN_SERVICE_CAPTCHA_ANSWERED,
-            LOGIN_SERVICE_CAPTCHA_SHOWN,
-            LOGIN_SERVICE_PASSWORD_ENTERED,
-            LOGIN_SERVICE_SWITCH_GOOGLE_MAIL,
-            NETWORK_DOWN,
-            NETWORK_UP,
-            PHONE_UI,
-            RADIO_BUG_REPORT,
-            SETUP_COMPLETED,
-            SETUP_INITIATED,
-            SETUP_IO_ERROR,
-            SETUP_NETWORK_ERROR,
-            SETUP_REQUIRED_CAPTCHA,
-            SETUP_RETRIES_EXHAUSTED,
-            SETUP_SERVER_ERROR,
-            SETUP_SERVER_TIMEOUT,
-            SETUP_NO_DATA_NETWORK,
-            SYSTEM_BOOT,
-            SYSTEM_LAST_KMSG,
-            SYSTEM_RECOVERY_LOG,
-            SYSTEM_RESTART,
-            SYSTEM_SERVICE_LOOPING,
-            SYSTEM_TOMBSTONE,
-            TEST, 
-            BATTERY_DISCHARGE_INFO,
-            MARKET_DOWNLOAD,
-            MARKET_INSTALL,
-            MARKET_REMOVE,
-            MARKET_REFUND,
-            MARKET_UNINSTALL,
-        }
-    }
-
-    /**
-     * The stats table is a list of counter values indexed by a tag name.
-     * Each statistic has a count and sum fields, so it can track averages.
-     * When multiple statistics are inserted with the same tag, the count
-     * and sum fields are added together into a single entry in the database.
-     */
-    public interface Stats extends BaseColumns {
-        public static final String TABLE_NAME = "stats";
-        public static final Uri CONTENT_URI =
-            Uri.parse("content://" + AUTHORITY + "/" + TABLE_NAME);
-
-        public static final String TAG = "tag";      // TEXT UNIQUE
-        public static final String COUNT = "count";  // INTEGER
-        public static final String SUM = "sum";      // REAL
-
-        /** Valid tag values.  Extend as necessary for your needs. */
-        public enum Tag {
-            BROWSER_SNAP_CENTER,
-            BROWSER_TEXT_SIZE_CHANGE,
-            BROWSER_ZOOM_OVERVIEW,
-
-            CRASHES_REPORTED,
-            CRASHES_TRUNCATED,
-            ELAPSED_REALTIME_SEC,
-            ELAPSED_UPTIME_SEC,
-            HTTP_REQUEST,
-            HTTP_REUSED,
-            HTTP_STATUS,
-            PHONE_GSM_REGISTERED,
-            PHONE_GPRS_ATTEMPTED,
-            PHONE_GPRS_CONNECTED,
-            PHONE_RADIO_RESETS,
-            TEST,
-            NETWORK_RX_MOBILE,
-            NETWORK_TX_MOBILE,
-            PHONE_CDMA_REGISTERED,
-            PHONE_CDMA_DATA_ATTEMPTED,
-            PHONE_CDMA_DATA_CONNECTED,
-        }
-    }
-
-    /**
-     * The properties table is a set of tagged values sent with every checkin.
-     * Unlike statistics or events, they are not cleared after being uploaded.
-     * Multiple properties inserted with the same tag overwrite each other.
-     */
-    public interface Properties extends BaseColumns {
-        public static final String TABLE_NAME = "properties";
-        public static final Uri CONTENT_URI =
-            Uri.parse("content://" + AUTHORITY + "/" + TABLE_NAME);
-
-        public static final String TAG = "tag";      // TEXT UNIQUE
-        public static final String VALUE = "value";  // TEXT
-
-        /** Valid tag values, to be extended as necessary. */
-        public enum Tag {
-            DESIRED_BUILD,
-            MARKET_CHECKIN,
-        }
-    }
-
-    /**
-     * The crashes table is a log of crash reports, kept separate from the
-     * general event log because crashes are large, important, and bursty.
-     * Like the events table, the crashes table is pruned on insert.
-     */
-    public interface Crashes extends BaseColumns {
-        public static final String TABLE_NAME = "crashes";
-        public static final Uri CONTENT_URI =
-            Uri.parse("content://" + AUTHORITY + "/" + TABLE_NAME);
-
-        // TODO: one or both of these should be a file attachment, not a column
-        public static final String DATA = "data";    // TEXT
-        public static final String LOGS = "logs";    // TEXT
-    }
-
-    /**
-     * Intents with this action cause a checkin attempt.  Normally triggered by
-     * a periodic alarm, these may be sent directly to force immediate checkin.
-     */
-    public interface TriggerIntent {
-        public static final String ACTION = "android.server.checkin.CHECKIN";
-
-        // The category is used for GTalk service messages
-        public static final String CATEGORY = "android.server.checkin.CHECKIN";
-        
-        // If true indicates that the checkin should only transfer market related data
-        public static final String EXTRA_MARKET_ONLY = "market_only";
-    }
-
-    private static final String TAG = "Checkin";
-
-    /**
-     * Helper function to log an event to the database.
-     *
-     * @param resolver from {@link android.content.Context#getContentResolver}
-     * @param tag identifying the type of event being recorded
-     * @param value associated with event, if any
-     * @return URI of the event that was added
-     */
-    static public Uri logEvent(ContentResolver resolver,
-            Events.Tag tag, String value) {
-        try {
-            // Don't specify the date column; the content provider will add that.
-            ContentValues values = new ContentValues();
-            values.put(Events.TAG, tag.toString());
-            if (value != null) values.put(Events.VALUE, value);
-            return resolver.insert(Events.CONTENT_URI, values);
-        } catch (IllegalArgumentException e) {  // thrown when provider is unavailable.
-            Log.w(TAG, "Can't log event " + tag + ": " + e);
-            return null;
-        } catch (SQLException e) {
-            Log.e(TAG, "Can't log event " + tag, e);  // Database errors are not fatal.
-            return null;
-        }
-    }
-
-    /**
-     * Helper function to update statistics in the database.
-     * Note that multiple updates to the same tag will be combined.
-     *
-     * @param tag identifying what is being observed
-     * @param count of occurrences
-     * @param sum of some value over these occurrences
-     * @return URI of the statistic that was returned
-     */
-    static public Uri updateStats(ContentResolver resolver,
-            Stats.Tag tag, int count, double sum) {
-        try {
-            ContentValues values = new ContentValues();
-            values.put(Stats.TAG, tag.toString());
-            if (count != 0) values.put(Stats.COUNT, count);
-            if (sum != 0.0) values.put(Stats.SUM, sum);
-            return resolver.insert(Stats.CONTENT_URI, values);
-        } catch (IllegalArgumentException e) {  // thrown when provider is unavailable.
-            Log.w(TAG, "Can't update stat " + tag + ": " + e);
-            return null;
-        } catch (SQLException e) {
-            Log.e(TAG, "Can't update stat " + tag, e);  // Database errors are not fatal.
-            return null;
-        }
-    }
-
-    /** Minimum time to wait after a crash failure before trying again. */
-    static private final long MIN_CRASH_FAILURE_RETRY = 10000;  // 10 seconds
-
-    /** {@link SystemClock#elapsedRealtime} of the last time a crash report failed. */
-    static private volatile long sLastCrashFailureRealtime = -MIN_CRASH_FAILURE_RETRY;
-}
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index bfab30a..7b52f7f 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -1497,6 +1497,66 @@
         public static final String POINTER_LOCATION = "pointer_location";
 
         /**
+         * Whether to play a sound for low-battery alerts.
+         * @hide
+         */
+        public static final String POWER_SOUNDS_ENABLED = "power_sounds_enabled";
+
+        /**
+         * Whether to play a sound for dock events.
+         * @hide
+         */
+        public static final String DOCK_SOUNDS_ENABLED = "dock_sounds_enabled";
+
+        /**
+         * Whether to play sounds when the keyguard is shown and dismissed.
+         * @hide
+         */
+        public static final String LOCKSCREEN_SOUNDS_ENABLED = "lockscreen_sounds_enabled";
+
+        /**
+         * URI for the low battery sound file.
+         * @hide
+         */
+        public static final String LOW_BATTERY_SOUND = "low_battery_sound";
+
+        /**
+         * URI for the desk dock "in" event sound.
+         * @hide
+         */
+        public static final String DESK_DOCK_SOUND = "desk_dock_sound";
+
+        /**
+         * URI for the desk dock "out" event sound.
+         * @hide
+         */
+        public static final String DESK_UNDOCK_SOUND = "desk_undock_sound";
+
+        /**
+         * URI for the car dock "in" event sound.
+         * @hide
+         */
+        public static final String CAR_DOCK_SOUND = "car_dock_sound";
+
+        /**
+         * URI for the car dock "out" event sound.
+         * @hide
+         */
+        public static final String CAR_UNDOCK_SOUND = "car_undock_sound";
+
+        /**
+         * URI for the "device locked" (keyguard shown) sound.
+         * @hide
+         */
+        public static final String LOCK_SOUND = "lock_sound";
+
+        /**
+         * URI for the "device unlocked" (keyguard dismissed) sound.
+         * @hide
+         */
+        public static final String UNLOCK_SOUND = "unlock_sound";
+
+        /**
          * Settings to backup. This is here so that it's in the same place as the settings
          * keys and easy to update.
          * @hide
@@ -2150,14 +2210,17 @@
         public static final String NETWORK_PREFERENCE = "network_preference";
 
         /**
+         * No longer supported.
          */
         public static final String PARENTAL_CONTROL_ENABLED = "parental_control_enabled";
 
         /**
+         * No longer supported.
          */
         public static final String PARENTAL_CONTROL_LAST_UPDATE = "parental_control_last_update";
 
         /**
+         * No longer supported.
          */
         public static final String PARENTAL_CONTROL_REDIRECT_URL = "parental_control_redirect_url";
 
diff --git a/core/java/android/util/base64/Base64.java b/core/java/android/util/base64/Base64.java
new file mode 100644
index 0000000..f6d3905
--- /dev/null
+++ b/core/java/android/util/base64/Base64.java
@@ -0,0 +1,741 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.util.base64;
+
+import java.io.UnsupportedEncodingException;
+
+/**
+ * Utilities for encoding and decoding the Base64 representation of
+ * binary data.  See RFCs <a
+ * href="http://www.ietf.org/rfc/rfc2045.txt">2045</a> and <a
+ * href="http://www.ietf.org/rfc/rfc3548.txt">3548</a>.
+ */
+public class Base64 {
+    /**
+     * Default values for encoder/decoder flags.
+     */
+    public static final int DEFAULT = 0;
+
+    /**
+     * Encoder flag bit to omit the padding '=' characters at the end
+     * of the output (if any).
+     */
+    public static final int NO_PADDING = 1;
+
+    /**
+     * Encoder flag bit to omit all line terminators (i.e., the output
+     * will be on one long line).
+     */
+    public static final int NO_WRAP = 2;
+
+    /**
+     * Encoder flag bit to indicate lines should be terminated with a
+     * CRLF pair instead of just an LF.  Has no effect if {@code
+     * NO_WRAP} is specified as well.
+     */
+    public static final int CRLF = 4;
+
+    /**
+     * Encoder/decoder flag bit to indicate using the "URL and
+     * filename safe" variant of Base64 (see RFC 3548 section 4) where
+     * {@code -} and {@code _} are used in place of {@code +} and
+     * {@code /}.
+     */
+    public static final int URL_SAFE = 8;
+
+    /**
+     * Flag to pass to {@link Base64OutputStream} to indicate that it
+     * should not close the output stream it is wrapping when it
+     * itself is closed.
+     */
+    public static final int NO_CLOSE = 16;
+
+    //  --------------------------------------------------------
+    //  shared code
+    //  --------------------------------------------------------
+
+    /* package */ static abstract class Coder {
+        public byte[] output;
+        public int op;
+
+        /**
+         * Encode/decode another block of input data.  this.output is
+         * provided by the caller, and must be big enough to hold all
+         * the coded data.  On exit, this.opwill be set to the length
+         * of the coded data.
+         *
+         * @param finish true if this is the final call to process for
+         *        this object.  Will finalize the coder state and
+         *        include any final bytes in the output.
+         *
+         * @return true if the input so far is good; false if some
+         *         error has been detected in the input stream..
+         */
+        public abstract boolean process(byte[] input, int offset, int len, boolean finish);
+
+        /**
+         * @return the maximum number of bytes a call to process()
+         * could produce for the given number of input bytes.  This may
+         * be an overestimate.
+         */
+        public abstract int maxOutputSize(int len);
+    }
+
+    //  --------------------------------------------------------
+    //  decoding
+    //  --------------------------------------------------------
+
+    /**
+     * Decode the Base64-encoded data in input and return the data in
+     * a new byte array.
+     *
+     * <p>The padding '=' characters at the end are considered optional, but
+     * if any are present, there must be the correct number of them.
+     *
+     * @param str    the input String to decode, which is converted to
+     *               bytes using the default charset
+     * @param flags  controls certain features of the decoded output.
+     *               Pass {@code DEFAULT} to decode standard Base64.
+     *
+     * @throws IllegalArgumentException if the input contains
+     * incorrect padding
+     */
+    public static byte[] decode(String str, int flags) {
+        return decode(str.getBytes(), flags);
+    }
+
+    /**
+     * Decode the Base64-encoded data in input and return the data in
+     * a new byte array.
+     *
+     * <p>The padding '=' characters at the end are considered optional, but
+     * if any are present, there must be the correct number of them.
+     *
+     * @param input the input array to decode
+     * @param flags  controls certain features of the decoded output.
+     *               Pass {@code DEFAULT} to decode standard Base64.
+     *
+     * @throws IllegalArgumentException if the input contains
+     * incorrect padding
+     */
+    public static byte[] decode(byte[] input, int flags) {
+        return decode(input, 0, input.length, flags);
+    }
+
+    /**
+     * Decode the Base64-encoded data in input and return the data in
+     * a new byte array.
+     *
+     * <p>The padding '=' characters at the end are considered optional, but
+     * if any are present, there must be the correct number of them.
+     *
+     * @param input  the data to decode
+     * @param offset the position within the input array at which to start
+     * @param len    the number of bytes of input to decode
+     * @param flags  controls certain features of the decoded output.
+     *               Pass {@code DEFAULT} to decode standard Base64.
+     *
+     * @throws IllegalArgumentException if the input contains
+     * incorrect padding
+     */
+    public static byte[] decode(byte[] input, int offset, int len, int flags) {
+        // Allocate space for the most data the input could represent.
+        // (It could contain less if it contains whitespace, etc.)
+        Decoder decoder = new Decoder(flags, new byte[len*3/4]);
+
+        if (!decoder.process(input, offset, len, true)) {
+            throw new IllegalArgumentException("bad base-64");
+        }
+
+        // Maybe we got lucky and allocated exactly enough output space.
+        if (decoder.op == decoder.output.length) {
+            return decoder.output;
+        }
+
+        // Need to shorten the array, so allocate a new one of the
+        // right size and copy.
+        byte[] temp = new byte[decoder.op];
+        System.arraycopy(decoder.output, 0, temp, 0, decoder.op);
+        return temp;
+    }
+
+    /* package */ static class Decoder extends Coder {
+        /**
+         * Lookup table for turning bytes into their position in the
+         * Base64 alphabet.
+         */
+        private static final int DECODE[] = {
+            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
+            52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -2, -1, -1,
+            -1,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,
+            15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
+            -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
+            41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1,
+            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+        };
+
+        /**
+         * Decode lookup table for the "web safe" variant (RFC 3548
+         * sec. 4) where - and _ replace + and /.
+         */
+        private static final int DECODE_WEBSAFE[] = {
+            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1,
+            52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -2, -1, -1,
+            -1,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,
+            15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, 63,
+            -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
+            41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1,
+            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+        };
+
+        /** Non-data values in the DECODE arrays. */
+        private static final int SKIP = -1;
+        private static final int EQUALS = -2;
+
+        /**
+         * States 0-3 are reading through the next input tuple.
+         * State 4 is having read one '=' and expecting exactly
+         * one more.
+         * State 5 is expecting no more data or padding characters
+         * in the input.
+         * State 6 is the error state; an error has been detected
+         * in the input and no future input can "fix" it.
+         */
+        private int state;   // state number (0 to 6)
+        private int value;
+
+        final private int[] alphabet;
+
+        public Decoder(int flags, byte[] output) {
+            this.output = output;
+
+            alphabet = ((flags & URL_SAFE) == 0) ? DECODE : DECODE_WEBSAFE;
+            state = 0;
+            value = 0;
+        }
+
+        /**
+         * @return an overestimate for the number of bytes {@code
+         * len} bytes could decode to.
+         */
+        public int maxOutputSize(int len) {
+            return len * 3/4 + 10;
+        }
+
+        /**
+         * Decode another block of input data.
+         *
+         * @return true if the state machine is still healthy.  false if
+         *         bad base-64 data has been detected in the input stream.
+         */
+        public boolean process(byte[] input, int offset, int len, boolean finish) {
+            if (this.state == 6) return false;
+
+            int p = offset;
+            len += offset;
+
+            // Using local variables makes the decoder about 12%
+            // faster than if we manipulate the member variables in
+            // the loop.  (Even alphabet makes a measurable
+            // difference, which is somewhat surprising to me since
+            // the member variable is final.)
+            int state = this.state;
+            int value = this.value;
+            int op = 0;
+            final byte[] output = this.output;
+            final int[] alphabet = this.alphabet;
+
+            while (p < len) {
+                // Try the fast path:  we're starting a new tuple and the
+                // next four bytes of the input stream are all data
+                // bytes.  This corresponds to going through states
+                // 0-1-2-3-0.  We expect to use this method for most of
+                // the data.
+                //
+                // If any of the next four bytes of input are non-data
+                // (whitespace, etc.), value will end up negative.  (All
+                // the non-data values in decode are small negative
+                // numbers, so shifting any of them up and or'ing them
+                // together will result in a value with its top bit set.)
+                //
+                // You can remove this whole block and the output should
+                // be the same, just slower.
+                if (state == 0) {
+                    while (p+4 <= len &&
+                           (value = ((alphabet[input[p] & 0xff] << 18) |
+                                     (alphabet[input[p+1] & 0xff] << 12) |
+                                     (alphabet[input[p+2] & 0xff] << 6) |
+                                     (alphabet[input[p+3] & 0xff]))) >= 0) {
+                        output[op+2] = (byte) value;
+                        output[op+1] = (byte) (value >> 8);
+                        output[op] = (byte) (value >> 16);
+                        op += 3;
+                        p += 4;
+                    }
+                    if (p >= len) break;
+                }
+
+                // The fast path isn't available -- either we've read a
+                // partial tuple, or the next four input bytes aren't all
+                // data, or whatever.  Fall back to the slower state
+                // machine implementation.
+
+                int d = alphabet[input[p++] & 0xff];
+
+                switch (state) {
+                case 0:
+                    if (d >= 0) {
+                        value = d;
+                        ++state;
+                    } else if (d != SKIP) {
+                        this.state = 6;
+                        return false;
+                    }
+                    break;
+
+                case 1:
+                    if (d >= 0) {
+                        value = (value << 6) | d;
+                        ++state;
+                    } else if (d != SKIP) {
+                        this.state = 6;
+                        return false;
+                    }
+                    break;
+
+                case 2:
+                    if (d >= 0) {
+                        value = (value << 6) | d;
+                        ++state;
+                    } else if (d == EQUALS) {
+                        // Emit the last (partial) output tuple;
+                        // expect exactly one more padding character.
+                        output[op++] = (byte) (value >> 4);
+                        state = 4;
+                    } else if (d != SKIP) {
+                        this.state = 6;
+                        return false;
+                    }
+                    break;
+
+                case 3:
+                    if (d >= 0) {
+                        // Emit the output triple and return to state 0.
+                        value = (value << 6) | d;
+                        output[op+2] = (byte) value;
+                        output[op+1] = (byte) (value >> 8);
+                        output[op] = (byte) (value >> 16);
+                        op += 3;
+                        state = 0;
+                    } else if (d == EQUALS) {
+                        // Emit the last (partial) output tuple;
+                        // expect no further data or padding characters.
+                        output[op+1] = (byte) (value >> 2);
+                        output[op] = (byte) (value >> 10);
+                        op += 2;
+                        state = 5;
+                    } else if (d != SKIP) {
+                        this.state = 6;
+                        return false;
+                    }
+                    break;
+
+                case 4:
+                    if (d == EQUALS) {
+                        ++state;
+                    } else if (d != SKIP) {
+                        this.state = 6;
+                        return false;
+                    }
+                    break;
+
+                case 5:
+                    if (d != SKIP) {
+                        this.state = 6;
+                        return false;
+                    }
+                    break;
+                }
+            }
+
+            if (!finish) {
+                // We're out of input, but a future call could provide
+                // more.
+                this.state = state;
+                this.value = value;
+                this.op = op;
+                return true;
+            }
+
+            // Done reading input.  Now figure out where we are left in
+            // the state machine and finish up.
+
+            switch (state) {
+            case 0:
+                // Output length is a multiple of three.  Fine.
+                break;
+            case 1:
+                // Read one extra input byte, which isn't enough to
+                // make another output byte.  Illegal.
+                this.state = 6;
+                return false;
+            case 2:
+                // Read two extra input bytes, enough to emit 1 more
+                // output byte.  Fine.
+                output[op++] = (byte) (value >> 4);
+                break;
+            case 3:
+                // Read three extra input bytes, enough to emit 2 more
+                // output bytes.  Fine.
+                output[op++] = (byte) (value >> 10);
+                output[op++] = (byte) (value >> 2);
+                break;
+            case 4:
+                // Read one padding '=' when we expected 2.  Illegal.
+                this.state = 6;
+                return false;
+            case 5:
+                // Read all the padding '='s we expected and no more.
+                // Fine.
+                break;
+            }
+
+            this.state = state;
+            this.op = op;
+            return true;
+        }
+    }
+
+    //  --------------------------------------------------------
+    //  encoding
+    //  --------------------------------------------------------
+
+    /**
+     * Base64-encode the given data and return a newly allocated
+     * String with the result.
+     *
+     * @param input  the data to encode
+     * @param flags  controls certain features of the encoded output.
+     *               Passing {@code DEFAULT} results in output that
+     *               adheres to RFC 2045.
+     */
+    public static String encodeToString(byte[] input, int flags) {
+        try {
+            return new String(encode(input, flags), "US-ASCII");
+        } catch (UnsupportedEncodingException e) {
+            // US-ASCII is guaranteed to be available.
+            throw new AssertionError(e);
+        }
+    }
+
+    /**
+     * Base64-encode the given data and return a newly allocated
+     * String with the result.
+     *
+     * @param input  the data to encode
+     * @param offset the position within the input array at which to
+     *               start
+     * @param len    the number of bytes of input to encode
+     * @param flags  controls certain features of the encoded output.
+     *               Passing {@code DEFAULT} results in output that
+     *               adheres to RFC 2045.
+     */
+    public static String encodeToString(byte[] input, int offset, int len, int flags) {
+        try {
+            return new String(encode(input, offset, len, flags), "US-ASCII");
+        } catch (UnsupportedEncodingException e) {
+            // US-ASCII is guaranteed to be available.
+            throw new AssertionError(e);
+        }
+    }
+
+    /**
+     * Base64-encode the given data and return a newly allocated
+     * byte[] with the result.
+     *
+     * @param input  the data to encode
+     * @param flags  controls certain features of the encoded output.
+     *               Passing {@code DEFAULT} results in output that
+     *               adheres to RFC 2045.
+     */
+    public static byte[] encode(byte[] input, int flags) {
+        return encode(input, 0, input.length, flags);
+    }
+
+    /**
+     * Base64-encode the given data and return a newly allocated
+     * byte[] with the result.
+     *
+     * @param input  the data to encode
+     * @param offset the position within the input array at which to
+     *               start
+     * @param len    the number of bytes of input to encode
+     * @param flags  controls certain features of the encoded output.
+     *               Passing {@code DEFAULT} results in output that
+     *               adheres to RFC 2045.
+     */
+    public static byte[] encode(byte[] input, int offset, int len, int flags) {
+        Encoder encoder = new Encoder(flags, null);
+
+        // Compute the exact length of the array we will produce.
+        int output_len = len / 3 * 4;
+
+        // Account for the tail of the data and the padding bytes, if any.
+        if (encoder.do_padding) {
+            if (len % 3 > 0) {
+                output_len += 4;
+            }
+        } else {
+            switch (len % 3) {
+                case 0: break;
+                case 1: output_len += 2; break;
+                case 2: output_len += 3; break;
+            }
+        }
+
+        // Account for the newlines, if any.
+        if (encoder.do_newline && len > 0) {
+            output_len += (((len-1) / (3 * Encoder.LINE_GROUPS)) + 1) *
+                (encoder.do_cr ? 2 : 1);
+        }
+
+        encoder.output = new byte[output_len];
+        encoder.process(input, offset, len, true);
+
+        assert encoder.op == output_len;
+
+        return encoder.output;
+    }
+
+    /* package */ static class Encoder extends Coder {
+        /**
+         * Emit a new line every this many output tuples.  Corresponds to
+         * a 76-character line length (the maximum allowable according to
+         * <a href="http://www.ietf.org/rfc/rfc2045.txt">RFC 2045</a>).
+         */
+        public static final int LINE_GROUPS = 19;
+
+        /**
+         * Lookup table for turning Base64 alphabet positions (6 bits)
+         * into output bytes.
+         */
+        private static final byte ENCODE[] = {
+            'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
+            'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
+            'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
+            'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/',
+        };
+
+        /**
+         * Lookup table for turning Base64 alphabet positions (6 bits)
+         * into output bytes.
+         */
+        private static final byte ENCODE_WEBSAFE[] = {
+            'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
+            'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
+            'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
+            'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-', '_',
+        };
+
+        final private byte[] tail;
+        /* package */ int tailLen;
+        private int count;
+
+        final public boolean do_padding;
+        final public boolean do_newline;
+        final public boolean do_cr;
+        final private byte[] alphabet;
+
+        public Encoder(int flags, byte[] output) {
+            this.output = output;
+
+            do_padding = (flags & NO_PADDING) == 0;
+            do_newline = (flags & NO_WRAP) == 0;
+            do_cr = (flags & CRLF) != 0;
+            alphabet = ((flags & URL_SAFE) == 0) ? ENCODE : ENCODE_WEBSAFE;
+
+            tail = new byte[2];
+            tailLen = 0;
+
+            count = do_newline ? LINE_GROUPS : -1;
+        }
+
+        /**
+         * @return an overestimate for the number of bytes {@code
+         * len} bytes could encode to.
+         */
+        public int maxOutputSize(int len) {
+            return len * 8/5 + 10;
+        }
+
+        public boolean process(byte[] input, int offset, int len, boolean finish) {
+            // Using local variables makes the encoder about 9% faster.
+            final byte[] alphabet = this.alphabet;
+            final byte[] output = this.output;
+            int op = 0;
+            int count = this.count;
+
+            int p = offset;
+            len += offset;
+            int v = -1;
+
+            // First we need to concatenate the tail of the previous call
+            // with any input bytes available now and see if we can empty
+            // the tail.
+
+            switch (tailLen) {
+                case 0:
+                    // There was no tail.
+                    break;
+
+                case 1:
+                    if (p+2 <= len) {
+                        // A 1-byte tail with at least 2 bytes of
+                        // input available now.
+                        v = ((tail[0] & 0xff) << 16) |
+                            ((input[p++] & 0xff) << 8) |
+                            (input[p++] & 0xff);
+                        tailLen = 0;
+                    };
+                    break;
+
+                case 2:
+                    if (p+1 <= len) {
+                        // A 2-byte tail with at least 1 byte of input.
+                        v = ((tail[0] & 0xff) << 16) |
+                            ((tail[1] & 0xff) << 8) |
+                            (input[p++] & 0xff);
+                        tailLen = 0;
+                    }
+                    break;
+            }
+
+            if (v != -1) {
+                output[op++] = alphabet[(v >> 18) & 0x3f];
+                output[op++] = alphabet[(v >> 12) & 0x3f];
+                output[op++] = alphabet[(v >> 6) & 0x3f];
+                output[op++] = alphabet[v & 0x3f];
+                if (--count == 0) {
+                    if (do_cr) output[op++] = '\r';
+                    output[op++] = '\n';
+                    count = LINE_GROUPS;
+                }
+            }
+
+            // At this point either there is no tail, or there are fewer
+            // than 3 bytes of input available.
+
+            // The main loop, turning 3 input bytes into 4 output bytes on
+            // each iteration.
+            while (p+3 <= len) {
+                v = ((input[p] & 0xff) << 16) |
+                    ((input[p+1] & 0xff) << 8) |
+                    (input[p+2] & 0xff);
+                output[op] = alphabet[(v >> 18) & 0x3f];
+                output[op+1] = alphabet[(v >> 12) & 0x3f];
+                output[op+2] = alphabet[(v >> 6) & 0x3f];
+                output[op+3] = alphabet[v & 0x3f];
+                p += 3;
+                op += 4;
+                if (--count == 0) {
+                    if (do_cr) output[op++] = '\r';
+                    output[op++] = '\n';
+                    count = LINE_GROUPS;
+                }
+            }
+
+            if (finish) {
+                // Finish up the tail of the input.  Note that we need to
+                // consume any bytes in tail before any bytes
+                // remaining in input; there should be at most two bytes
+                // total.
+
+                if (p-tailLen == len-1) {
+                    int t = 0;
+                    v = ((tailLen > 0 ? tail[t++] : input[p++]) & 0xff) << 4;
+                    tailLen -= t;
+                    output[op++] = alphabet[(v >> 6) & 0x3f];
+                    output[op++] = alphabet[v & 0x3f];
+                    if (do_padding) {
+                        output[op++] = '=';
+                        output[op++] = '=';
+                    }
+                    if (do_newline) {
+                        if (do_cr) output[op++] = '\r';
+                        output[op++] = '\n';
+                    }
+                } else if (p-tailLen == len-2) {
+                    int t = 0;
+                    v = (((tailLen > 1 ? tail[t++] : input[p++]) & 0xff) << 10) |
+                        (((tailLen > 0 ? tail[t++] : input[p++]) & 0xff) << 2);
+                    tailLen -= t;
+                    output[op++] = alphabet[(v >> 12) & 0x3f];
+                    output[op++] = alphabet[(v >> 6) & 0x3f];
+                    output[op++] = alphabet[v & 0x3f];
+                    if (do_padding) {
+                        output[op++] = '=';
+                    }
+                    if (do_newline) {
+                        if (do_cr) output[op++] = '\r';
+                        output[op++] = '\n';
+                    }
+                } else if (do_newline && op > 0 && count != LINE_GROUPS) {
+                    if (do_cr) output[op++] = '\r';
+                    output[op++] = '\n';
+                }
+
+                assert tailLen == 0;
+                assert p == len;
+            } else {
+                // Save the leftovers in tail to be consumed on the next
+                // call to encodeInternal.
+
+                if (p == len-1) {
+                    tail[tailLen++] = input[p];
+                } else if (p == len-2) {
+                    tail[tailLen++] = input[p];
+                    tail[tailLen++] = input[p+1];
+                }
+            }
+
+            this.op = op;
+            this.count = count;
+
+            return true;
+        }
+    }
+
+    private Base64() { }   // don't instantiate
+}
diff --git a/common/java/com/android/common/Base64InputStream.java b/core/java/android/util/base64/Base64InputStream.java
similarity index 64%
rename from common/java/com/android/common/Base64InputStream.java
rename to core/java/android/util/base64/Base64InputStream.java
index 1969bc4..935939e 100644
--- a/common/java/com/android/common/Base64InputStream.java
+++ b/core/java/android/util/base64/Base64InputStream.java
@@ -14,28 +14,24 @@
  * limitations under the License.
  */
 
-package com.android.common;
+package android.util.base64;
 
 import java.io.FilterInputStream;
 import java.io.IOException;
 import java.io.InputStream;
 
 /**
- * An OutputStream that does either Base64 encoding or decoding on the
- * data written to it, writing the resulting data to another
- * OutputStream.
+ * An InputStream that does Base64 decoding on the data read through
+ * it.
  */
 public class Base64InputStream extends FilterInputStream {
-    private final boolean encode;
-    private final Base64.EncoderState estate;
-    private final Base64.DecoderState dstate;
+    private final Base64.Coder coder;
 
     private static byte[] EMPTY = new byte[0];
 
     private static final int BUFFER_SIZE = 2048;
     private boolean eof;
     private byte[] inputBuffer;
-    private byte[] outputBuffer;
     private int outputStart;
     private int outputEnd;
 
@@ -47,8 +43,8 @@
      * @param flags bit flags for controlling the decoder; see the
      *        constants in {@link Base64}
      */
-    public Base64InputStream(InputStream out, int flags) {
-        this(out, flags, false);
+    public Base64InputStream(InputStream in, int flags) {
+        this(in, flags, false);
     }
 
     /**
@@ -59,25 +55,19 @@
      * @param flags bit flags for controlling the decoder; see the
      *        constants in {@link Base64}
      * @param encode true to encode, false to decode
+     *
+     * @hide
      */
-    public Base64InputStream(InputStream out, int flags, boolean encode) {
-        super(out);
-        this.encode = encode;
+    public Base64InputStream(InputStream in, int flags, boolean encode) {
+        super(in);
         eof = false;
         inputBuffer = new byte[BUFFER_SIZE];
         if (encode) {
-            // len*8/5+10 is an overestimate of the most bytes the
-            // encoder can produce for len bytes of input.
-            outputBuffer = new byte[BUFFER_SIZE * 8/5 + 10];
-            estate = new Base64.EncoderState(flags, outputBuffer);
-            dstate = null;
+            coder = new Base64.Encoder(flags, null);
         } else {
-            // len*3/4+10 is an overestimate of the most bytes the
-            // decoder can produce for len bytes of input.
-            outputBuffer = new byte[BUFFER_SIZE * 3/4 + 10];
-            estate = null;
-            dstate = new Base64.DecoderState(flags, outputBuffer);
+            coder = new Base64.Decoder(flags, null);
         }
+        coder.output = new byte[coder.maxOutputSize(BUFFER_SIZE)];
         outputStart = 0;
         outputEnd = 0;
     }
@@ -122,7 +112,7 @@
         if (outputStart >= outputEnd) {
             return -1;
         } else {
-            return outputBuffer[outputStart++];
+            return coder.output[outputStart++];
         }
     }
 
@@ -134,36 +124,30 @@
             return -1;
         }
         int bytes = Math.min(len, outputEnd-outputStart);
-        System.arraycopy(outputBuffer, outputStart, b, off, bytes);
+        System.arraycopy(coder.output, outputStart, b, off, bytes);
         outputStart += bytes;
         return bytes;
     }
 
     /**
      * Read data from the input stream into inputBuffer, then
-     * decode/encode it into the empty outputBuffer, and reset the
+     * decode/encode it into the empty coder.output, and reset the
      * outputStart and outputEnd pointers.
      */
     private void refill() throws IOException {
         if (eof) return;
         int bytesRead = in.read(inputBuffer);
-        if (encode) {
-            if (bytesRead == -1) {
-                eof = true;
-                Base64.encodeInternal(EMPTY, 0, 0, estate, true);
-            } else {
-                Base64.encodeInternal(inputBuffer, 0, bytesRead, estate, false);
-            }
-            outputEnd = estate.op;
+        boolean success;
+        if (bytesRead == -1) {
+            eof = true;
+            success = coder.process(EMPTY, 0, 0, true);
         } else {
-            if (bytesRead == -1) {
-                eof = true;
-                Base64.decodeInternal(EMPTY, 0, 0, dstate, true);
-            } else {
-                Base64.decodeInternal(inputBuffer, 0, bytesRead, dstate, false);
-            }
-            outputEnd = dstate.op;
+            success = coder.process(inputBuffer, 0, bytesRead, false);
         }
+        if (!success) {
+            throw new IOException("bad base-64");
+        }
+        outputEnd = coder.op;
         outputStart = 0;
     }
 }
diff --git a/common/java/com/android/common/Base64OutputStream.java b/core/java/android/util/base64/Base64OutputStream.java
similarity index 72%
rename from common/java/com/android/common/Base64OutputStream.java
rename to core/java/android/util/base64/Base64OutputStream.java
index 76e1b6a..35e9a2b 100644
--- a/common/java/com/android/common/Base64OutputStream.java
+++ b/core/java/android/util/base64/Base64OutputStream.java
@@ -14,21 +14,18 @@
  * limitations under the License.
  */
 
-package com.android.common;
+package android.util.base64;
 
 import java.io.FilterOutputStream;
 import java.io.IOException;
 import java.io.OutputStream;
 
 /**
- * An OutputStream that does either Base64 encoding or decoding on the
- * data written to it, writing the resulting data to another
- * OutputStream.
+ * An OutputStream that does Base64 encoding on the data written to
+ * it, writing the resulting data to another OutputStream.
  */
 public class Base64OutputStream extends FilterOutputStream {
-    private final boolean encode;
-    private final Base64.EncoderState estate;
-    private final Base64.DecoderState dstate;
+    private final Base64.Coder coder;
     private final int flags;
 
     private byte[] buffer = null;
@@ -57,17 +54,16 @@
      * @param flags bit flags for controlling the encoder; see the
      *        constants in {@link Base64}
      * @param encode true to encode, false to decode
+     *
+     * @hide
      */
     public Base64OutputStream(OutputStream out, int flags, boolean encode) {
         super(out);
         this.flags = flags;
-        this.encode = encode;
         if (encode) {
-            estate = new Base64.EncoderState(flags, null);
-            dstate = null;
+            coder = new Base64.Encoder(flags, null);
         } else {
-            estate = null;
-            dstate = new Base64.DecoderState(flags, null);
+            coder = new Base64.Decoder(flags, null);
         }
     }
 
@@ -106,12 +102,28 @@
     }
 
     public void close() throws IOException {
-        flushBuffer();
-        internalWrite(EMPTY, 0, 0, true);
-        if ((flags & Base64.NO_CLOSE) == 0) {
-            out.close();
-        } else {
-            out.flush();
+        IOException thrown = null;
+        try {
+            flushBuffer();
+            internalWrite(EMPTY, 0, 0, true);
+        } catch (IOException e) {
+            thrown = e;
+        }
+
+        try {
+            if ((flags & Base64.NO_CLOSE) == 0) {
+                out.close();
+            } else {
+                out.flush();
+            }
+        } catch (IOException e) {
+            if (thrown != null) {
+                thrown = e;
+            }
+        }
+
+        if (thrown != null) {
+            throw thrown;
         }
     }
 
@@ -122,21 +134,11 @@
      *        encoder/decoder state to be finalized.
      */
     private void internalWrite(byte[] b, int off, int len, boolean finish) throws IOException {
-        if (encode) {
-            // len*8/5+10 is an overestimate of the most bytes the
-            // encoder can produce for len bytes of input.
-            estate.output = embiggen(estate.output, len*8/5+10);
-            Base64.encodeInternal(b, off, len, estate, finish);
-            out.write(estate.output, 0, estate.op);
-        } else {
-            // len*3/4+10 is an overestimate of the most bytes the
-            // decoder can produce for len bytes of input.
-            dstate.output = embiggen(dstate.output, len*3/4+10);
-            if (!Base64.decodeInternal(b, off, len, dstate, finish)) {
-                throw new IOException("bad base-64");
-            }
-            out.write(dstate.output, 0, dstate.op);
+        coder.output = embiggen(coder.output, coder.maxOutputSize(len));
+        if (!coder.process(b, off, len, finish)) {
+            throw new IOException("bad base-64");
         }
+        out.write(coder.output, 0, coder.op);
     }
 
     /**
diff --git a/core/java/android/view/GestureDetector.java b/core/java/android/view/GestureDetector.java
index 3c79200..58f998e 100644
--- a/core/java/android/view/GestureDetector.java
+++ b/core/java/android/view/GestureDetector.java
@@ -465,10 +465,10 @@
         case MotionEvent.ACTION_POINTER_UP:
             // Ending a multitouch gesture and going back to 1 finger
             if (mIgnoreMultitouch && ev.getPointerCount() == 2) {
-                int id = (((action & MotionEvent.ACTION_POINTER_ID_MASK)
-                        >> MotionEvent.ACTION_POINTER_ID_SHIFT) == 0) ? 1 : 0;
-                mLastMotionX = ev.getX(id);
-                mLastMotionY = ev.getY(id);
+                int index = (((action & MotionEvent.ACTION_POINTER_INDEX_MASK)
+                        >> MotionEvent.ACTION_POINTER_INDEX_SHIFT) == 0) ? 1 : 0;
+                mLastMotionX = ev.getX(index);
+                mLastMotionY = ev.getY(index);
                 mVelocityTracker.recycle();
                 mVelocityTracker = VelocityTracker.obtain();
             }
diff --git a/core/java/android/view/HapticFeedbackConstants.java b/core/java/android/view/HapticFeedbackConstants.java
index ccbd8d4..d31c8dc 100644
--- a/core/java/android/view/HapticFeedbackConstants.java
+++ b/core/java/android/view/HapticFeedbackConstants.java
@@ -34,13 +34,18 @@
      * The user has pressed on a virtual on-screen key.
      */
     public static final int VIRTUAL_KEY = 1;
-    
+
     /**
      * The user has hit the barrier point while scrolling a view.
      */
     public static final int SCROLL_BARRIER = 2;
     
     /**
+     * The user has pressed a soft keyboard key.
+     */
+    public static final int KEYBOARD_TAP = 3;
+
+    /**
      * This is a private constant.  Feel free to renumber as desired.
      * @hide
      */
diff --git a/core/java/android/view/MotionEvent.java b/core/java/android/view/MotionEvent.java
index ca907af..d648e96 100644
--- a/core/java/android/view/MotionEvent.java
+++ b/core/java/android/view/MotionEvent.java
@@ -76,61 +76,81 @@
     public static final int ACTION_POINTER_DOWN     = 5;
     
     /**
-     * Synonym for {@link #ACTION_POINTER_DOWN} with
-     * {@link #ACTION_POINTER_ID_MASK} of 0: the primary pointer has gone done.
-     */
-    public static final int ACTION_POINTER_1_DOWN   = ACTION_POINTER_DOWN | 0x0000;
-    
-    /**
-     * Synonym for {@link #ACTION_POINTER_DOWN} with
-     * {@link #ACTION_POINTER_ID_MASK} of 1: the secondary pointer has gone done.
-     */
-    public static final int ACTION_POINTER_2_DOWN   = ACTION_POINTER_DOWN | 0x0100;
-    
-    /**
-     * Synonym for {@link #ACTION_POINTER_DOWN} with
-     * {@link #ACTION_POINTER_ID_MASK} of 2: the tertiary pointer has gone done.
-     */
-    public static final int ACTION_POINTER_3_DOWN   = ACTION_POINTER_DOWN | 0x0200;
-    
-    /**
      * A non-primary pointer has gone up.  The bits in
      * {@link #ACTION_POINTER_ID_MASK} indicate which pointer changed.
      */
     public static final int ACTION_POINTER_UP       = 6;
     
     /**
-     * Synonym for {@link #ACTION_POINTER_UP} with
-     * {@link #ACTION_POINTER_ID_MASK} of 0: the primary pointer has gone up.
+     * Bits in the action code that represent a pointer index, used with
+     * {@link #ACTION_POINTER_DOWN} and {@link #ACTION_POINTER_UP}.  Shifting
+     * down by {@link #ACTION_POINTER_INDEX_SHIFT} provides the actual pointer
+     * index where the data for the pointer going up or down can be found; you can
+     * get its identifier with {@link #getPointerId(int)} and the actual
+     * data with {@link #getX(int)} etc.
      */
+    public static final int ACTION_POINTER_INDEX_MASK  = 0xff00;
+    
+    /**
+     * Bit shift for the action bits holding the pointer index as
+     * defined by {@link #ACTION_POINTER_INDEX_MASK}.
+     */
+    public static final int ACTION_POINTER_INDEX_SHIFT = 8;
+    
+    /**
+     * @deprecated Use {@link #ACTION_POINTER_INDEX_MASK} to retrieve the
+     * data index associated with {@link #ACTION_POINTER_DOWN}.
+     */
+    @Deprecated
+    public static final int ACTION_POINTER_1_DOWN   = ACTION_POINTER_DOWN | 0x0000;
+    
+    /**
+     * @deprecated Use {@link #ACTION_POINTER_INDEX_MASK} to retrieve the
+     * data index associated with {@link #ACTION_POINTER_DOWN}.
+     */
+    @Deprecated
+    public static final int ACTION_POINTER_2_DOWN   = ACTION_POINTER_DOWN | 0x0100;
+    
+    /**
+     * @deprecated Use {@link #ACTION_POINTER_INDEX_MASK} to retrieve the
+     * data index associated with {@link #ACTION_POINTER_DOWN}.
+     */
+    @Deprecated
+    public static final int ACTION_POINTER_3_DOWN   = ACTION_POINTER_DOWN | 0x0200;
+    
+    /**
+     * @deprecated Use {@link #ACTION_POINTER_INDEX_MASK} to retrieve the
+     * data index associated with {@link #ACTION_POINTER_UP}.
+     */
+    @Deprecated
     public static final int ACTION_POINTER_1_UP     = ACTION_POINTER_UP | 0x0000;
     
     /**
-     * Synonym for {@link #ACTION_POINTER_UP} with
-     * {@link #ACTION_POINTER_ID_MASK} of 1: the secondary pointer has gone up.
+     * @deprecated Use {@link #ACTION_POINTER_INDEX_MASK} to retrieve the
+     * data index associated with {@link #ACTION_POINTER_UP}.
      */
+    @Deprecated
     public static final int ACTION_POINTER_2_UP     = ACTION_POINTER_UP | 0x0100;
     
     /**
-     * Synonym for {@link #ACTION_POINTER_UP} with
-     * {@link #ACTION_POINTER_ID_MASK} of 2: the tertiary pointer has gone up.
+     * @deprecated Use {@link #ACTION_POINTER_INDEX_MASK} to retrieve the
+     * data index associated with {@link #ACTION_POINTER_UP}.
      */
+    @Deprecated
     public static final int ACTION_POINTER_3_UP     = ACTION_POINTER_UP | 0x0200;
     
     /**
-     * Bits in the action code that represent a pointer ID, used with
-     * {@link #ACTION_POINTER_DOWN} and {@link #ACTION_POINTER_UP}.  Pointer IDs
-     * start at 0, with 0 being the primary (first) pointer in the motion.  Note
-     * that this not <em>not</em> an index into the array of pointer values,
-     * which is compacted to only contain pointers that are down; the pointer
-     * ID for a particular index can be found with {@link #findPointerIndex}.
+     * @deprecated Renamed to {@link #ACTION_POINTER_INDEX_MASK} to match
+     * the actual data contained in these bits.
      */
+    @Deprecated
     public static final int ACTION_POINTER_ID_MASK  = 0xff00;
     
     /**
-     * Bit shift for the action bits holding the pointer identifier as
-     * defined by {@link #ACTION_POINTER_ID_MASK}.
+     * @deprecated Renamed to {@link #ACTION_POINTER_INDEX_SHIFT} to match
+     * the actual data contained in these bits.
      */
+    @Deprecated
     public static final int ACTION_POINTER_ID_SHIFT = 8;
     
     private static final boolean TRACK_RECYCLED_LOCATION = false;
@@ -618,13 +638,39 @@
     /**
      * Return the kind of action being performed -- one of either
      * {@link #ACTION_DOWN}, {@link #ACTION_MOVE}, {@link #ACTION_UP}, or
-     * {@link #ACTION_CANCEL}.
+     * {@link #ACTION_CANCEL}.  Consider using {@link #getActionMasked}
+     * and {@link #getActionIndex} to retrieve the separate masked action
+     * and pointer index.
      */
     public final int getAction() {
         return mAction;
     }
 
     /**
+     * Return the masked action being performed, without pointer index
+     * information.  May be any of the actions: {@link #ACTION_DOWN},
+     * {@link #ACTION_MOVE}, {@link #ACTION_UP}, {@link #ACTION_CANCEL},
+     * {@link #ACTION_POINTER_DOWN}, or {@link #ACTION_POINTER_UP}.
+     * Use {@link #getActionIndex} to return the index associated with
+     * pointer actions.
+     */
+    public final int getActionMasked() {
+        return mAction & ACTION_MASK;
+    }
+
+    /**
+     * For {@link #ACTION_POINTER_DOWN} or {@link #ACTION_POINTER_UP}
+     * as returned by {@link #getActionMasked}, this returns the associated
+     * pointer index.  The index may be used with {@link #getPointerId(int)},
+     * {@link #getX(int)}, {@link #getY(int)}, {@link #getPressure(int)},
+     * and {@link #getSize(int)} to get information about the pointer that has
+     * gone down or up.
+     */
+    public final int getActionIndex() {
+        return (mAction & ACTION_POINTER_INDEX_MASK) >> ACTION_POINTER_INDEX_SHIFT;
+    }
+
+    /**
      * Returns the time (in ms) when the user originally pressed down to start
      * a stream of position events.
      */
diff --git a/core/java/android/view/VelocityTracker.java b/core/java/android/view/VelocityTracker.java
index 9a8ee02..91fd6f1 100644
--- a/core/java/android/view/VelocityTracker.java
+++ b/core/java/android/view/VelocityTracker.java
@@ -124,24 +124,37 @@
      * @param ev The MotionEvent you received and would like to track.
      */
     public void addMovement(MotionEvent ev) {
-        long time = ev.getEventTime();
         final int N = ev.getHistorySize();
         final int pointerCount = ev.getPointerCount();
-        for (int p = 0; p < pointerCount; p++) {
-            for (int i=0; i<N; i++) {
-                addPoint(p, ev.getHistoricalX(p, i), ev.getHistoricalY(p, i),
-                        ev.getHistoricalEventTime(i));
+        int touchIndex = (mLastTouch + 1) % NUM_PAST;
+        for (int i=0; i<N; i++) {
+            for (int id = 0; id < MotionEvent.BASE_AVAIL_POINTERS; id++) {
+                mPastTime[id][touchIndex] = 0;
             }
-            addPoint(p, ev.getX(p), ev.getY(p), time);
-        }
-    }
+            for (int p = 0; p < pointerCount; p++) {
+                int id = ev.getPointerId(p);
+                mPastX[id][touchIndex] = ev.getHistoricalX(p, i);
+                mPastY[id][touchIndex] = ev.getHistoricalY(p, i);
+                mPastTime[id][touchIndex] = ev.getHistoricalEventTime(i);
+            }
 
-    private void addPoint(int pos, float x, float y, long time) {
-        final int lastTouch = (mLastTouch + 1) % NUM_PAST;
-        mPastX[pos][lastTouch] = x;
-        mPastY[pos][lastTouch] = y;
-        mPastTime[pos][lastTouch] = time;
-        mLastTouch = lastTouch;
+            touchIndex = (touchIndex + 1) % NUM_PAST;
+        }
+
+        // During calculation any pointer values with a time of 0 are treated
+        // as a break in input. Initialize all to 0 for each new touch index.
+        for (int id = 0; id < MotionEvent.BASE_AVAIL_POINTERS; id++) {
+            mPastTime[id][touchIndex] = 0;
+        }
+        final long time = ev.getEventTime();
+        for (int p = 0; p < pointerCount; p++) {
+            int id = ev.getPointerId(p);
+            mPastX[id][touchIndex] = ev.getX(p);
+            mPastY[id][touchIndex] = ev.getY(p);
+            mPastTime[id][touchIndex] = time;
+        }
+
+        mLastTouch = touchIndex;
     }
 
     /**
@@ -177,10 +190,12 @@
             // find oldest acceptable time
             int oldestTouch = lastTouch;
             if (pastTime[lastTouch] > 0) { // cleared ?
-                oldestTouch = (lastTouch + 1) % NUM_PAST;
                 final float acceptableTime = pastTime[lastTouch] - LONGEST_PAST_TIME;
-                while (pastTime[oldestTouch] < acceptableTime) {
-                    oldestTouch = (oldestTouch + 1) % NUM_PAST;
+                int nextOldestTouch = (NUM_PAST + oldestTouch - 1) % NUM_PAST;
+                while (pastTime[nextOldestTouch] >= acceptableTime &&
+                        nextOldestTouch != lastTouch) {
+                    oldestTouch = nextOldestTouch;
+                    nextOldestTouch = (NUM_PAST + oldestTouch - 1) % NUM_PAST;
                 }
             }
         
@@ -241,25 +256,25 @@
      * Retrieve the last computed X velocity.  You must first call
      * {@link #computeCurrentVelocity(int)} before calling this function.
      * 
-     * @param pos Which pointer's velocity to return.
+     * @param id Which pointer's velocity to return.
      * @return The previously computed X velocity.
      * 
      * @hide Pending API approval
      */
-    public float getXVelocity(int pos) {
-        return mXVelocity[pos];
+    public float getXVelocity(int id) {
+        return mXVelocity[id];
     }
     
     /**
      * Retrieve the last computed Y velocity.  You must first call
      * {@link #computeCurrentVelocity(int)} before calling this function.
      * 
-     * @param pos Which pointer's velocity to return.
+     * @param id Which pointer's velocity to return.
      * @return The previously computed Y velocity.
      * 
      * @hide Pending API approval
      */
-    public float getYVelocity(int pos) {
-        return mYVelocity[pos];
+    public float getYVelocity(int id) {
+        return mYVelocity[id];
     }
 }
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index cdf9eb0..2ed623d 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -3398,7 +3398,7 @@
 
         /**
          * Special value for the height or width requested by a View.
-         * MATCH_PARENT means that the view wants to be as bigas its parent,
+         * MATCH_PARENT means that the view wants to be as big as its parent,
          * minus the parent's padding, if any.
          */
         public static final int MATCH_PARENT = -1;
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 9148a18..ae6c666 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -5893,6 +5893,10 @@
                     }
                     break;
                 case UPDATE_TEXT_SELECTION_MSG_ID:
+                    // If no textfield was in focus, and the user touched one,
+                    // causing it to send this message, then WebTextView has not
+                    // been set up yet.  Rebuild it so it can set its selection.
+                    rebuildWebTextView();
                     if (inEditingMode()
                             && mWebTextView.isSameTextField(msg.arg1)
                             && msg.arg2 == mTextGeneration) {
diff --git a/core/java/android/widget/EditText.java b/core/java/android/widget/EditText.java
index 57aca24..1532db1 100644
--- a/core/java/android/widget/EditText.java
+++ b/core/java/android/widget/EditText.java
@@ -16,9 +16,13 @@
 
 package android.widget;
 
-import android.text.*;
-import android.text.method.*;
 import android.content.Context;
+import android.text.Editable;
+import android.text.Selection;
+import android.text.Spannable;
+import android.text.TextUtils;
+import android.text.method.ArrowKeyMovementMethod;
+import android.text.method.MovementMethod;
 import android.util.AttributeSet;
 
 
diff --git a/core/java/android/widget/GridView.java b/core/java/android/widget/GridView.java
index 30a38df..b9acf5e 100644
--- a/core/java/android/widget/GridView.java
+++ b/core/java/android/widget/GridView.java
@@ -1856,8 +1856,11 @@
             final int top = view.getTop();
             int height = view.getHeight();
             if (height > 0) {
-                final int whichRow = mFirstPosition / mNumColumns;
-                return Math.max(whichRow * 100 - (top * 100) / height, 0);
+                final int numColumns = mNumColumns;
+                final int whichRow = mFirstPosition / numColumns;
+                final int rowCount = (mItemCount + numColumns - 1) / numColumns;
+                return Math.max(whichRow * 100 - (top * 100) / height +
+                        (int) ((float) mScrollY / getHeight() * rowCount * 100), 0);
             }
         }
         return 0;
@@ -1868,7 +1871,12 @@
         // TODO: Account for vertical spacing too
         final int numColumns = mNumColumns;
         final int rowCount = (mItemCount + numColumns - 1) / numColumns;
-        return Math.max(rowCount * 100, 0);
+        int result = Math.max(rowCount * 100, 0);
+        if (mScrollY != 0) {
+            // Compensate for overscroll
+            result += Math.abs((int) ((float) mScrollY / getHeight() * rowCount * 100));
+        }
+        return result;
     }
 }
 
diff --git a/core/java/android/widget/HorizontalScrollView.java b/core/java/android/widget/HorizontalScrollView.java
index c62724c..a7b819a 100644
--- a/core/java/android/widget/HorizontalScrollView.java
+++ b/core/java/android/widget/HorizontalScrollView.java
@@ -890,14 +890,15 @@
      */
     @Override
     protected int computeHorizontalScrollRange() {
-        int count = getChildCount();
+        final int count = getChildCount();
+        final int contentWidth = getWidth() - mPaddingLeft - mPaddingRight;
         if (count == 0) {
-            return getWidth();
+            return contentWidth;
         }
         
         int scrollRange = getChildAt(0).getRight();
-        int scrollX = mScrollX;
-        int overscrollRight = scrollRange - getWidth() - mPaddingLeft - mPaddingRight;
+        final int scrollX = mScrollX;
+        final int overscrollRight = Math.max(0, scrollRange - contentWidth);
         if (scrollX < 0) {
             scrollRange -= scrollX;
         } else if (scrollX > overscrollRight) {
diff --git a/core/java/android/widget/LinearLayout.java b/core/java/android/widget/LinearLayout.java
index ea5841a..9fcb829 100644
--- a/core/java/android/widget/LinearLayout.java
+++ b/core/java/android/widget/LinearLayout.java
@@ -16,6 +16,8 @@
 
 package android.widget;
 
+import com.android.internal.R;
+
 import android.content.Context;
 import android.content.res.TypedArray;
 import android.util.AttributeSet;
@@ -25,8 +27,6 @@
 import android.view.ViewGroup;
 import android.widget.RemoteViews.RemoteView;
 
-import com.android.internal.R;
-
 
 /**
  * A Layout that arranges its children in a single column or a single row. The direction of 
@@ -366,14 +366,15 @@
                 int oldHeight = Integer.MIN_VALUE;
 
                 if (lp.height == 0 && lp.weight > 0) {
-                   // heightMode is either UNSPECIFIED OR AT_MOST, and this child
-                   // wanted to stretch to fill available space. Translate that to
-                   // WRAP_CONTENT so that it does not end up with a height of 0
-                   oldHeight = 0;
-                   lp.height = LayoutParams.WRAP_CONTENT;
+                    // heightMode is either UNSPECIFIED or AT_MOST, and this
+                    // child wanted to stretch to fill available space.
+                    // Translate that to WRAP_CONTENT so that it does not end up
+                    // with a height of 0
+                    oldHeight = 0;
+                    lp.height = LayoutParams.WRAP_CONTENT;
                 }
 
-                // Determine how big this child would like to.  If this or
+                // Determine how big this child would like to be. If this or
                 // previous children have given a weight, then we allow it to
                 // use all available space (and we will shrink things later
                 // if needed).
@@ -673,7 +674,8 @@
                 int oldWidth = Integer.MIN_VALUE;
 
                 if (lp.width == 0 && lp.weight > 0) {
-                    // widthMode is either UNSPECIFIED OR AT_MOST, and this child
+                    // widthMode is either UNSPECIFIED or AT_MOST, and this
+                    // child
                     // wanted to stretch to fill available space. Translate that to
                     // WRAP_CONTENT so that it does not end up with a width of 0
                     oldWidth = 0;
diff --git a/core/java/android/widget/ScrollView.java b/core/java/android/widget/ScrollView.java
index 2ee7ad5..52ed11d 100644
--- a/core/java/android/widget/ScrollView.java
+++ b/core/java/android/widget/ScrollView.java
@@ -892,14 +892,15 @@
      */
     @Override
     protected int computeVerticalScrollRange() {
-        int count = getChildCount();
+        final int count = getChildCount();
+        final int contentHeight = getHeight() - mPaddingBottom - mPaddingTop;
         if (count == 0) {
-            return getHeight();
+            return contentHeight;
         }
         
         int scrollRange = getChildAt(0).getBottom();
-        int scrollY = mScrollY;
-        int overscrollBottom = scrollRange - getHeight() - mPaddingBottom - mPaddingTop;
+        final int scrollY = mScrollY;
+        final int overscrollBottom = Math.max(0, scrollRange - contentHeight);
         if (scrollY < 0) {
             scrollRange -= scrollY;
         } else if (scrollY > overscrollBottom) {
diff --git a/core/java/android/widget/TabHost.java b/core/java/android/widget/TabHost.java
index 78e2fee..d4d9063 100644
--- a/core/java/android/widget/TabHost.java
+++ b/core/java/android/widget/TabHost.java
@@ -16,6 +16,8 @@
 
 package android.widget;
 
+import com.android.internal.R;
+
 import android.app.LocalActivityManager;
 import android.content.Context;
 import android.content.Intent;
@@ -33,8 +35,6 @@
 import java.util.ArrayList;
 import java.util.List;
 
-import com.android.internal.R;
-
 /**
  * Container for a tabbed window view. This object holds two children: a set of tab labels that the
  * user clicks to select a specific tab, and a FrameLayout object that displays the contents of that
@@ -624,7 +624,7 @@
         }
 
         public void tabClosed() {
-            mTabContent.setVisibility(View.INVISIBLE);
+            mTabContent.setVisibility(View.GONE);
         }
     }
 
diff --git a/core/java/android/widget/TableLayout.java b/core/java/android/widget/TableLayout.java
index 66500a3..73760ac 100644
--- a/core/java/android/widget/TableLayout.java
+++ b/core/java/android/widget/TableLayout.java
@@ -575,6 +575,16 @@
         final int totalExtraSpace = size - totalWidth;
         int extraSpace = totalExtraSpace / count;
 
+        // Column's widths are changed: force child table rows to re-measure.
+        // (done by super.measureVertical after shrinkAndStretchColumns.)
+        final int nbChildren = getChildCount();
+        for (int i = 0; i < nbChildren; i++) {
+            View child = getChildAt(i);
+            if (child instanceof TableRow) {
+                child.forceLayout();
+            }
+        }
+
         if (!allColumns) {
             for (int i = 0; i < count; i++) {
                 int column = columns.keyAt(i);
diff --git a/core/java/android/widget/TableRow.java b/core/java/android/widget/TableRow.java
index abf08bf..48d12df 100644
--- a/core/java/android/widget/TableRow.java
+++ b/core/java/android/widget/TableRow.java
@@ -22,8 +22,8 @@
 import android.util.SparseIntArray;
 import android.view.Gravity;
 import android.view.View;
-import android.view.ViewGroup;
 import android.view.ViewDebug;
+import android.view.ViewGroup;
 
 
 /**
diff --git a/core/java/com/android/internal/app/IMediaContainerService.aidl b/core/java/com/android/internal/app/IMediaContainerService.aidl
index 726e28f..c0e9587 100755
--- a/core/java/com/android/internal/app/IMediaContainerService.aidl
+++ b/core/java/com/android/internal/app/IMediaContainerService.aidl
@@ -25,4 +25,5 @@
                 String key, String resFileName);
     boolean copyResource(in Uri packageURI,
                 in ParcelFileDescriptor outStream);
+    int getRecommendedInstallLocation(in Uri fileUri);
 }
\ No newline at end of file
diff --git a/core/java/com/android/internal/content/PackageHelper.java b/core/java/com/android/internal/content/PackageHelper.java
new file mode 100644
index 0000000..4d7d2d1
--- /dev/null
+++ b/core/java/com/android/internal/content/PackageHelper.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.content;
+
+/**
+ * Constants used internally between the PackageManager
+ * and media container service transports.
+ */
+public class PackageHelper {
+    public static final int RECOMMEND_INSTALL_INTERNAL = 1;
+    public static final int RECOMMEND_INSTALL_EXTERNAL = 2;
+    public static final int RECOMMEND_FAILED_INSUFFICIENT_STORAGE = -1;
+    public static final int RECOMMEND_FAILED_INVALID_APK = -2;
+}
diff --git a/core/java/com/android/internal/os/RuntimeInit.java b/core/java/com/android/internal/os/RuntimeInit.java
index 57a28e6..c134d88 100644
--- a/core/java/com/android/internal/os/RuntimeInit.java
+++ b/core/java/com/android/internal/os/RuntimeInit.java
@@ -22,7 +22,6 @@
 import android.os.Build;
 import android.os.Debug;
 import android.os.IBinder;
-import android.os.ICheckinService;
 import android.os.Process;
 import android.os.RemoteException;
 import android.os.ServiceManager;
diff --git a/core/java/com/google/android/net/ParentalControl.java b/core/java/com/google/android/net/ParentalControl.java
deleted file mode 100644
index 71a3958..0000000
--- a/core/java/com/google/android/net/ParentalControl.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.android.net;
-
-import android.os.ICheckinService;
-import android.os.IParentalControlCallback;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.util.Log;
-
-public class ParentalControl {
-    /**
-     * Strings to identify your app. To enable parental control checking for
-     * new apps, please add it here, and configure GServices accordingly.
-     */
-    public static final String VENDING = "vending";
-    public static final String YOUTUBE = "youtube";
-
-    /**
-     * This interface is supplied to getParentalControlState and is callback upon with
-     * the state of parental control.
-     */
-    public interface Callback {
-        /**
-         * This method will be called when the state of parental control is known. If state is
-         * null, then the state of parental control is unknown.
-         * @param state The state of parental control.
-         */
-        void onResult(ParentalControlState state);
-    }
-
-    private static class RemoteCallback extends IParentalControlCallback.Stub {
-        private Callback mCallback;
-
-        public RemoteCallback(Callback callback) {
-            mCallback = callback;
-        }
-
-        public void onResult(ParentalControlState state) {
-            if (mCallback != null) {
-                mCallback.onResult(state);
-            }
-        }
-    };
-
-    public static void getParentalControlState(Callback callback,
-                                               String requestingApp) {
-        ICheckinService service =
-          ICheckinService.Stub.asInterface(ServiceManager.getService("checkin"));
-
-        RemoteCallback remoteCallback = new RemoteCallback(callback);
-        try {
-            service.getParentalControlState(remoteCallback, requestingApp);
-        } catch (RemoteException e) {
-            // This should never happen.
-            Log.e("ParentalControl", "Failed to talk to the checkin service.");
-        }
-    }
-}
diff --git a/core/java/com/google/android/net/ParentalControlState.aidl b/core/java/com/google/android/net/ParentalControlState.aidl
deleted file mode 100644
index ed1326a..0000000
--- a/core/java/com/google/android/net/ParentalControlState.aidl
+++ /dev/null
@@ -1,18 +0,0 @@
-/**
- * Copyright (c) 2008, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.android.net;
-parcelable ParentalControlState;
diff --git a/core/java/com/google/android/net/ParentalControlState.java b/core/java/com/google/android/net/ParentalControlState.java
deleted file mode 100644
index 162a1f6..0000000
--- a/core/java/com/google/android/net/ParentalControlState.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.android.net;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-public class ParentalControlState implements Parcelable {
-    public boolean isEnabled;
-    public String redirectUrl;
-
-    /**
-     * Used to read a ParentalControlStatus from a Parcel.
-     */
-    public static final Parcelable.Creator<ParentalControlState> CREATOR =
-        new Parcelable.Creator<ParentalControlState>() {
-              public ParentalControlState createFromParcel(Parcel source) {
-                    ParentalControlState status = new ParentalControlState();
-                    status.isEnabled = (source.readInt() == 1);
-                    status.redirectUrl = source.readString();
-                    return status;
-              }
-
-              public ParentalControlState[] newArray(int size) {
-                  return new ParentalControlState[size];
-              }
-        };
-
-    public int describeContents() {
-        return 0;
-    }
-
-    public void writeToParcel(Parcel dest, int flags) {
-      dest.writeInt(isEnabled ? 1 : 0);
-      dest.writeString(redirectUrl);
-    }
-
-    @Override
-    public String toString() {
-        return isEnabled + ", " + redirectUrl;
-    }
-};
diff --git a/core/jni/android_text_AndroidCharacter.cpp b/core/jni/android_text_AndroidCharacter.cpp
index 450cee2..05d7b73 100644
--- a/core/jni/android_text_AndroidCharacter.cpp
+++ b/core/jni/android_text_AndroidCharacter.cpp
@@ -20,8 +20,32 @@
 #include <jni.h>
 #include <android_runtime/AndroidRuntime.h>
 #include "utils/misc.h"
-#include "utils/AndroidUnicode.h"
 #include "utils/Log.h"
+#include "unicode/uchar.h"
+
+#define DIRECTIONALITY_UNDEFINED (-1)
+// ICU => JDK mapping
+static int directionality_map[U_CHAR_DIRECTION_COUNT] = {
+    0, // U_LEFT_TO_RIGHT (0) => DIRECTIONALITY_LEFT_TO_RIGHT (0)
+    1, // U_RIGHT_TO_LEFT (1) => DIRECTIONALITY_RIGHT_TO_LEFT (1)
+    3, // U_EUROPEAN_NUMBER (2) => DIRECTIONALITY_EUROPEAN_NUMBER (3)
+    4, // U_EUROPEAN_NUMBER_SEPARATOR (3) => DIRECTIONALITY_EUROPEAN_NUMBER_SEPARATOR (4)
+    5, // U_EUROPEAN_NUMBER_TERMINATOR (4) => DIRECTIONALITY_EUROPEAN_NUMBER_TERMINATOR (5)
+    6, // U_ARABIC_NUMBER (5) => DIRECTIONALITY_ARABIC_NUMBER (6)
+    7, // U_COMMON_NUMBER_SEPARATOR (6) => DIRECTIONALITY_COMMON_NUMBER_SEPARATOR (7)
+    10, // U_BLOCK_SEPARATOR (7) => DIRECTIONALITY_PARAGRAPH_SEPARATOR (10)
+    11, // U_SEGMENT_SEPARATOR (8) => DIRECTIONALITY_SEGMENT_SEPARATOR (11)
+    12, // U_WHITE_SPACE_NEUTRAL (9) => DIRECTIONALITY_WHITESPACE (12)
+    13, // U_OTHER_NEUTRAL (10) => DIRECTIONALITY_OTHER_NEUTRALS (13)
+    14, // U_LEFT_TO_RIGHT_EMBEDDING (11) => DIRECTIONALITY_LEFT_TO_RIGHT_EMBEDDING (14)
+    15, // U_LEFT_TO_RIGHT_OVERRIDE (12) => DIRECTIONALITY_LEFT_TO_RIGHT_OVERRIDE (15)
+    2, // U_RIGHT_TO_LEFT_ARABIC (13) => DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC (2)
+    16, // U_RIGHT_TO_LEFT_EMBEDDING (14) => DIRECTIONALITY_RIGHT_TO_LEFT_EMBEDDING (16)
+    17, // U_RIGHT_TO_LEFT_OVERRIDE (15) => DIRECTIONALITY_RIGHT_TO_LEFT_OVERRIDE (17)
+    18, // U_POP_DIRECTIONAL_FORMAT (16) => DIRECTIONALITY_POP_DIRECTIONAL_FORMAT (18)
+    8, // U_DIR_NON_SPACING_MARK (17) => DIRECTIONALITY_NONSPACING_MARK (8)
+    9, // U_BOUNDARY_NEUTRAL (18) => DIRECTIONALITY_BOUNDARY_NEUTRAL (9)
+};
 
 namespace android {
     
@@ -53,15 +77,21 @@
             src[i + 1] >= 0xDC00 && src[i + 1] <= 0xDFFF) {
             int c = 0x00010000 + ((src[i] - 0xD800) << 10) +
                                  (src[i + 1] & 0x3FF);
-            int dir = android::Unicode::getDirectionality(c);
+            int dir = u_charDirection(c);
+            if (dir < 0 || dir >= U_CHAR_DIRECTION_COUNT)
+                dir = DIRECTIONALITY_UNDEFINED;
+            else
+                dir = directionality_map[dir];
 
             dest[i++] = dir;
             dest[i] = dir;
         } else {
             int c = src[i];
-            int dir = android::Unicode::getDirectionality(c);
-
-            dest[i] = dir;
+            int dir = u_charDirection(c);
+            if (dir < 0 || dir >= U_CHAR_DIRECTION_COUNT)
+                dest[i] = DIRECTIONALITY_UNDEFINED;
+            else
+                dest[i] = directionality_map[dir];
         }
     }
     
@@ -89,7 +119,7 @@
         // XXX this thinks it knows that surrogates are never mirrored
 
         int c1 = data[i];
-        int c2 = android::Unicode::toMirror(c1);
+        int c2 = u_charMirror(c1);
 
         if (c1 != c2) {
             data[i] = c2;
@@ -104,7 +134,7 @@
 
 static jchar getMirror(JNIEnv* env, jobject obj, jchar c)
 {   
-    return android::Unicode::toMirror(c);
+    return u_charMirror(c);
 }
 
 static JNINativeMethod gMethods[] = {
diff --git a/core/jni/android_text_format_Time.cpp b/core/jni/android_text_format_Time.cpp
index d89a7e6..c152aa8 100644
--- a/core/jni/android_text_format_Time.cpp
+++ b/core/jni/android_text_format_Time.cpp
@@ -584,9 +584,9 @@
             inUtc = true;
 
 	    if (offset != 0) {
-	        if (len < tz_index + 5) {
+	        if (len < tz_index + 6) {
 	            char msg[100];
-	            sprintf(msg, "Unexpected length; should be %d characters", tz_index + 5);
+	            sprintf(msg, "Unexpected length; should be %d characters", tz_index + 6);
 	            jniThrowException(env, "android/util/TimeFormatException", msg);
 	            return false;
 	        }
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index f5f5a27..8273dbf 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1161,13 +1161,6 @@
         android:description="@string/permdesc_backup"
         android:protectionLevel="signatureOrSystem" />
 
-    <!-- Allows an application to participate in the backup and restore process
-         @hide -->
-    <permission android:name="android.permission.BACKUP_DATA"
-        android:label="@string/permlab_backup_data"
-        android:description="@string/permdesc_backup_data"
-        android:protectionLevel="signatureOrSystem" />
-
     <!-- Allows an application to tell the AppWidget service which application
          can access AppWidget's data.  The normal user flow is that a user
          picks an AppWidget to go into a particular host, thereby giving that
diff --git a/core/res/res/anim/cycle_interpolator.xml b/core/res/res/anim/cycle_interpolator.xml
new file mode 100644
index 0000000..70ebcb1
--- /dev/null
+++ b/core/res/res/anim/cycle_interpolator.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2010, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License"); 
+** you may not use this file except in compliance with the License. 
+** You may obtain a copy of the License at 
+**
+**     http://www.apache.org/licenses/LICENSE-2.0 
+**
+** Unless required by applicable law or agreed to in writing, software 
+** distributed under the License is distributed on an "AS IS" BASIS, 
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+** See the License for the specific language governing permissions and 
+** limitations under the License.
+*/
+-->
+
+<cycleInterpolator />
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 7bd07a5..40c78f7 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -138,6 +138,11 @@
         <item>30</item>
     </integer-array>
 
+    <!-- Vibrator pattern for a very short but reliable vibration for soft keyboard tap -->
+    <integer-array name="config_keyboardTapVibePattern">
+        <item>40</item>
+    </integer-array>
+
     <!-- Vibrator pattern for feedback about booting with safe mode disabled -->
     <integer-array name="config_safeModeDisabledVibePattern">
         <item>0</item>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 7706f30..3c6338e 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -1230,5 +1230,7 @@
   <public type="attr" name="neverEncrypt" id="0x010102b7" />
   <public type="attr" name="installLocation" id="0x010102b8" />
   <public type="attr" name="safeMode" id="0x010102b9" />
+
+  <public type="anim" name="cycle_interpolator" id="0x010a000c" />
     
 </resources>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 9e596ef..6f34b4f 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -565,11 +565,6 @@
     <string name="permdesc_backup">Allows the application to control the system\'s backup and restore mechanism.  Not for use by normal applications.</string>
 
     <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
-    <string name="permlab_backup_data">back up and restore the application\'s data</string>
-    <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
-    <string name="permdesc_backup_data">Allows the application to participate in the system\'s backup and restore mechanism.</string>
-
-    <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permlab_internalSystemWindow">display unauthorized windows</string>
     <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permdesc_internalSystemWindow">Allows the creation of
diff --git a/core/tests/coretests/src/android/app/SearchManagerTest.java b/core/tests/coretests/src/android/app/SearchManagerTest.java
index 21ed4c5..fc7e787 100644
--- a/core/tests/coretests/src/android/app/SearchManagerTest.java
+++ b/core/tests/coretests/src/android/app/SearchManagerTest.java
@@ -141,7 +141,6 @@
      * Tests that startSearch() can be called multiple times without stopSearch()
      * in between.
      */
-    @MediumTest
     public void testStartSearchIdempotent() throws Exception {
          SearchManager searchManager = (SearchManager)
                  mContext.getSystemService(Context.SEARCH_SERVICE);
@@ -156,7 +155,6 @@
      * Tests that stopSearch() can be called when the search UI is not visible and can be
      * called multiple times without startSearch() in between.
      */
-    @MediumTest
     public void testStopSearchIdempotent() throws Exception {
          SearchManager searchManager = (SearchManager)
                  mContext.getSystemService(Context.SEARCH_SERVICE);
@@ -172,7 +170,6 @@
      * The goal of this test is to confirm that we can start and then
      * stop a simple search.
      */
-    @MediumTest
     public void testSearchManagerInvocations() throws Exception {
         SearchManager searchManager = (SearchManager)
                 mContext.getSystemService(Context.SEARCH_SERVICE);
diff --git a/common/tests/src/com/android/common/Base64Test.java b/core/tests/coretests/src/android/util/base64/Base64Test.java
similarity index 89%
rename from common/tests/src/com/android/common/Base64Test.java
rename to core/tests/coretests/src/android/util/base64/Base64Test.java
index 1064625f2..48192bb 100644
--- a/common/tests/src/com/android/common/Base64Test.java
+++ b/core/tests/coretests/src/android/util/base64/Base64Test.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.common;
+package android.util.base64;
 
 import junit.framework.TestCase;
 
@@ -23,7 +23,7 @@
 import java.util.Random;
 
 public class Base64Test extends TestCase {
-    private static final String TAG = "B64Test";
+    private static final String TAG = "Base64Test";
 
     /** Decodes a string, returning a string. */
     private String decodeString(String in) throws Exception {
@@ -134,25 +134,25 @@
     }
 
     public void testWebSafe() throws Exception {
-        assertEquals(BYTES, 0, Base64.decode("", Base64.WEB_SAFE));
-        assertEquals(BYTES, 1, Base64.decode("_w==", Base64.WEB_SAFE));
-        assertEquals(BYTES, 2, Base64.decode("_-4=", Base64.WEB_SAFE));
-        assertEquals(BYTES, 3, Base64.decode("_-7d", Base64.WEB_SAFE));
-        assertEquals(BYTES, 4, Base64.decode("_-7dzA==", Base64.WEB_SAFE));
-        assertEquals(BYTES, 5, Base64.decode("_-7dzLs=", Base64.WEB_SAFE));
-        assertEquals(BYTES, 6, Base64.decode("_-7dzLuq", Base64.WEB_SAFE));
-        assertEquals(BYTES, 7, Base64.decode("_-7dzLuqmQ==", Base64.WEB_SAFE));
-        assertEquals(BYTES, 8, Base64.decode("_-7dzLuqmYg=", Base64.WEB_SAFE));
+        assertEquals(BYTES, 0, Base64.decode("", Base64.URL_SAFE));
+        assertEquals(BYTES, 1, Base64.decode("_w==", Base64.URL_SAFE));
+        assertEquals(BYTES, 2, Base64.decode("_-4=", Base64.URL_SAFE));
+        assertEquals(BYTES, 3, Base64.decode("_-7d", Base64.URL_SAFE));
+        assertEquals(BYTES, 4, Base64.decode("_-7dzA==", Base64.URL_SAFE));
+        assertEquals(BYTES, 5, Base64.decode("_-7dzLs=", Base64.URL_SAFE));
+        assertEquals(BYTES, 6, Base64.decode("_-7dzLuq", Base64.URL_SAFE));
+        assertEquals(BYTES, 7, Base64.decode("_-7dzLuqmQ==", Base64.URL_SAFE));
+        assertEquals(BYTES, 8, Base64.decode("_-7dzLuqmYg=", Base64.URL_SAFE));
 
-        assertEquals("", Base64.encodeToString(BYTES, 0, 0, Base64.WEB_SAFE));
-        assertEquals("_w==\n", Base64.encodeToString(BYTES, 0, 1, Base64.WEB_SAFE));
-        assertEquals("_-4=\n", Base64.encodeToString(BYTES, 0, 2, Base64.WEB_SAFE));
-        assertEquals("_-7d\n", Base64.encodeToString(BYTES, 0, 3, Base64.WEB_SAFE));
-        assertEquals("_-7dzA==\n", Base64.encodeToString(BYTES, 0, 4, Base64.WEB_SAFE));
-        assertEquals("_-7dzLs=\n", Base64.encodeToString(BYTES, 0, 5, Base64.WEB_SAFE));
-        assertEquals("_-7dzLuq\n", Base64.encodeToString(BYTES, 0, 6, Base64.WEB_SAFE));
-        assertEquals("_-7dzLuqmQ==\n", Base64.encodeToString(BYTES, 0, 7, Base64.WEB_SAFE));
-        assertEquals("_-7dzLuqmYg=\n", Base64.encodeToString(BYTES, 0, 8, Base64.WEB_SAFE));
+        assertEquals("", Base64.encodeToString(BYTES, 0, 0, Base64.URL_SAFE));
+        assertEquals("_w==\n", Base64.encodeToString(BYTES, 0, 1, Base64.URL_SAFE));
+        assertEquals("_-4=\n", Base64.encodeToString(BYTES, 0, 2, Base64.URL_SAFE));
+        assertEquals("_-7d\n", Base64.encodeToString(BYTES, 0, 3, Base64.URL_SAFE));
+        assertEquals("_-7dzA==\n", Base64.encodeToString(BYTES, 0, 4, Base64.URL_SAFE));
+        assertEquals("_-7dzLs=\n", Base64.encodeToString(BYTES, 0, 5, Base64.URL_SAFE));
+        assertEquals("_-7dzLuq\n", Base64.encodeToString(BYTES, 0, 6, Base64.URL_SAFE));
+        assertEquals("_-7dzLuqmQ==\n", Base64.encodeToString(BYTES, 0, 7, Base64.URL_SAFE));
+        assertEquals("_-7dzLuqmYg=\n", Base64.encodeToString(BYTES, 0, 8, Base64.URL_SAFE));
     }
 
     public void testFlags() throws Exception {
@@ -227,55 +227,55 @@
     }
 
     /**
-     * Tests that Base64.encodeInternal does correct handling of the
+     * Tests that Base64.Encoder.encode() does correct handling of the
      * tail for each call.
      *
      * This test is disabled because while it passes if you can get it
      * to run, android's test infrastructure currently doesn't allow
-     * us to get at package-private members (Base64.EncoderState in
+     * us to get at package-private members (Base64.Encoder in
      * this case).
      */
     public void XXXtestEncodeInternal() throws Exception {
         byte[] input = { (byte) 0x61, (byte) 0x62, (byte) 0x63 };
         byte[] output = new byte[100];
 
-        Base64.EncoderState state = new Base64.EncoderState(Base64.NO_PADDING | Base64.NO_WRAP,
-                                                            output);
+        Base64.Encoder encoder = new Base64.Encoder(Base64.NO_PADDING | Base64.NO_WRAP,
+                                                    output);
 
-        Base64.encodeInternal(input, 0, 3, state, false);
-        assertEquals("YWJj".getBytes(), 4, state.output, state.op);
-        assertEquals(0, state.tailLen);
+        encoder.process(input, 0, 3, false);
+        assertEquals("YWJj".getBytes(), 4, encoder.output, encoder.op);
+        assertEquals(0, encoder.tailLen);
 
-        Base64.encodeInternal(input, 0, 3, state, false);
-        assertEquals("YWJj".getBytes(), 4, state.output, state.op);
-        assertEquals(0, state.tailLen);
+        encoder.process(input, 0, 3, false);
+        assertEquals("YWJj".getBytes(), 4, encoder.output, encoder.op);
+        assertEquals(0, encoder.tailLen);
 
-        Base64.encodeInternal(input, 0, 1, state, false);
-        assertEquals(0, state.op);
-        assertEquals(1, state.tailLen);
+        encoder.process(input, 0, 1, false);
+        assertEquals(0, encoder.op);
+        assertEquals(1, encoder.tailLen);
 
-        Base64.encodeInternal(input, 0, 1, state, false);
-        assertEquals(0, state.op);
-        assertEquals(2, state.tailLen);
+        encoder.process(input, 0, 1, false);
+        assertEquals(0, encoder.op);
+        assertEquals(2, encoder.tailLen);
 
-        Base64.encodeInternal(input, 0, 1, state, false);
-        assertEquals("YWFh".getBytes(), 4, state.output, state.op);
-        assertEquals(0, state.tailLen);
+        encoder.process(input, 0, 1, false);
+        assertEquals("YWFh".getBytes(), 4, encoder.output, encoder.op);
+        assertEquals(0, encoder.tailLen);
 
-        Base64.encodeInternal(input, 0, 2, state, false);
-        assertEquals(0, state.op);
-        assertEquals(2, state.tailLen);
+        encoder.process(input, 0, 2, false);
+        assertEquals(0, encoder.op);
+        assertEquals(2, encoder.tailLen);
 
-        Base64.encodeInternal(input, 0, 2, state, false);
-        assertEquals("YWJh".getBytes(), 4, state.output, state.op);
-        assertEquals(1, state.tailLen);
+        encoder.process(input, 0, 2, false);
+        assertEquals("YWJh".getBytes(), 4, encoder.output, encoder.op);
+        assertEquals(1, encoder.tailLen);
 
-        Base64.encodeInternal(input, 0, 2, state, false);
-        assertEquals("YmFi".getBytes(), 4, state.output, state.op);
-        assertEquals(0, state.tailLen);
+        encoder.process(input, 0, 2, false);
+        assertEquals("YmFi".getBytes(), 4, encoder.output, encoder.op);
+        assertEquals(0, encoder.tailLen);
 
-        Base64.encodeInternal(input, 0, 1, state, true);
-        assertEquals("YQ".getBytes(), 2, state.output, state.op);
+        encoder.process(input, 0, 1, true);
+        assertEquals("YQ".getBytes(), 2, encoder.output, encoder.op);
     }
 
     private static final String lipsum =
@@ -307,7 +307,7 @@
                           Base64.NO_WRAP,
                           Base64.NO_PADDING | Base64.NO_WRAP,
                           Base64.CRLF,
-                          Base64.WEB_SAFE };
+                          Base64.URL_SAFE };
         int[] writeLengths = { -10, -5, -1, 0, 1, 1, 2, 2, 3, 10, 100 };
         Random rng = new Random(32176L);
 
@@ -414,7 +414,7 @@
                           Base64.NO_WRAP,
                           Base64.NO_PADDING | Base64.NO_WRAP,
                           Base64.CRLF,
-                          Base64.WEB_SAFE };
+                          Base64.URL_SAFE };
         int[] writeLengths = { -10, -5, -1, 0, 1, 1, 2, 2, 3, 10, 100 };
         Random rng = new Random(32176L);
 
diff --git a/core/tests/coretests/src/com/google/android/net/ParentalControlTest.java b/core/tests/coretests/src/com/google/android/net/ParentalControlTest.java
deleted file mode 100644
index d8ffeab..0000000
--- a/core/tests/coretests/src/com/google/android/net/ParentalControlTest.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.android.net;
-
-import com.google.android.net.ParentalControl;
-import com.google.android.net.ParentalControlState;
-
-import android.os.SystemClock;
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.SmallTest;
-import android.util.Log;
-
-import junit.framework.Assert;
-
-public class ParentalControlTest extends AndroidTestCase {
-
-    private boolean mOnResultCalled = false;
-
-    public class Callback implements ParentalControl.Callback {
-        public void onResult(ParentalControlState state) {
-            synchronized (ParentalControlTest.class) {
-                mOnResultCalled = true;
-                ParentalControlTest.class.notifyAll();
-            }
-        }
-    }
-
-    @SmallTest
-    public void testParentalControlCallback() {
-        synchronized (ParentalControlTest.class) {
-            ParentalControl.getParentalControlState(new Callback(), null);
-            try {
-                long start = SystemClock.uptimeMillis();
-                ParentalControlTest.class.wait(20 * 1000);
-                long end = SystemClock.uptimeMillis();
-                Log.d("AndroidTests", "ParentalControlTest callback took " + (end-start) + " ms.");
-            } catch (InterruptedException ex) {
-            }
-        }
-
-        Assert.assertTrue(mOnResultCalled);
-    }
-}
diff --git a/data/sounds/AudioPackage2.mk b/data/sounds/AudioPackage2.mk
index 5dacc70..d7f7c7e 100644
--- a/data/sounds/AudioPackage2.mk
+++ b/data/sounds/AudioPackage2.mk
@@ -67,6 +67,11 @@
 	$(LOCAL_PATH)/effects/KeypressReturn.ogg:system/media/audio/ui/KeypressReturn.ogg \
 	$(LOCAL_PATH)/effects/VideoRecord.ogg:system/media/audio/ui/VideoRecord.ogg \
 	$(LOCAL_PATH)/effects/camera_click.ogg:system/media/audio/ui/camera_click.ogg \
+	$(LOCAL_PATH)/effects/LowBattery.ogg:system/media/audio/ui/LowBattery.ogg \
+	$(LOCAL_PATH)/effects/Dock.ogg:system/media/audio/ui/Dock.ogg \
+	$(LOCAL_PATH)/effects/Undock.ogg:system/media/audio/ui/Undock.ogg \
+	$(LOCAL_PATH)/effects/Lock.ogg:system/media/audio/ui/Lock.ogg \
+	$(LOCAL_PATH)/effects/Unlock.ogg:system/media/audio/ui/Unlock.ogg \
 	$(LOCAL_PATH)/newwavelabs/CrazyDream.ogg:system/media/audio/ringtones/CrazyDream.ogg \
 	$(LOCAL_PATH)/newwavelabs/DreamTheme.ogg:system/media/audio/ringtones/DreamTheme.ogg \
 	$(LOCAL_PATH)/newwavelabs/Big_Easy.ogg:system/media/audio/ringtones/Big_Easy.ogg \
diff --git a/data/sounds/AudioPackage3.mk b/data/sounds/AudioPackage3.mk
index f2f6212..64d6717 100644
--- a/data/sounds/AudioPackage3.mk
+++ b/data/sounds/AudioPackage3.mk
@@ -59,6 +59,11 @@
 	$(LOCAL_PATH)/effects/KeypressReturn.ogg:system/media/audio/ui/KeypressReturn.ogg \
 	$(LOCAL_PATH)/effects/VideoRecord.ogg:system/media/audio/ui/VideoRecord.ogg \
 	$(LOCAL_PATH)/effects/camera_click.ogg:system/media/audio/ui/camera_click.ogg \
+	$(LOCAL_PATH)/effects/LowBattery.ogg:system/media/audio/ui/LowBattery.ogg \
+	$(LOCAL_PATH)/effects/Dock.ogg:system/media/audio/ui/Dock.ogg \
+	$(LOCAL_PATH)/effects/Undock.ogg:system/media/audio/ui/Undock.ogg \
+	$(LOCAL_PATH)/effects/Lock.ogg:system/media/audio/ui/Lock.ogg \
+	$(LOCAL_PATH)/effects/Unlock.ogg:system/media/audio/ui/Unlock.ogg \
 	$(LOCAL_PATH)/newwavelabs/Big_Easy.ogg:system/media/audio/ringtones/Big_Easy.ogg \
 	$(LOCAL_PATH)/newwavelabs/Bollywood.ogg:system/media/audio/ringtones/Bollywood.ogg \
 	$(LOCAL_PATH)/newwavelabs/Cairo.ogg:system/media/audio/ringtones/Cairo.ogg \
@@ -89,4 +94,3 @@
 	$(LOCAL_PATH)/notifications/pixiedust.ogg:system/media/audio/notifications/pixiedust.ogg \
 	$(LOCAL_PATH)/notifications/pizzicato.ogg:system/media/audio/notifications/pizzicato.ogg \
 	$(LOCAL_PATH)/notifications/tweeters.ogg:system/media/audio/notifications/tweeters.ogg
-
diff --git a/data/sounds/AudioPackage4.mk b/data/sounds/AudioPackage4.mk
index 6c36bad..b011b78 100644
--- a/data/sounds/AudioPackage4.mk
+++ b/data/sounds/AudioPackage4.mk
@@ -46,6 +46,11 @@
 	$(LOCAL_PATH)/effects/KeypressReturn.ogg:system/media/audio/ui/KeypressReturn.ogg \
 	$(LOCAL_PATH)/effects/VideoRecord.ogg:system/media/audio/ui/VideoRecord.ogg \
 	$(LOCAL_PATH)/effects/camera_click.ogg:system/media/audio/ui/camera_click.ogg \
+	$(LOCAL_PATH)/effects/LowBattery.ogg:system/media/audio/ui/LowBattery.ogg \
+	$(LOCAL_PATH)/effects/Dock.ogg:system/media/audio/ui/Dock.ogg \
+	$(LOCAL_PATH)/effects/Undock.ogg:system/media/audio/ui/Undock.ogg \
+	$(LOCAL_PATH)/effects/Lock.ogg:system/media/audio/ui/Lock.ogg \
+	$(LOCAL_PATH)/effects/Unlock.ogg:system/media/audio/ui/Unlock.ogg \
 	$(LOCAL_PATH)/Ring_Classic_02.ogg:system/media/audio/ringtones/Ring_Classic_02.ogg \
 	$(LOCAL_PATH)/Ring_Digital_02.ogg:system/media/audio/ringtones/Ring_Digital_02.ogg \
 	$(LOCAL_PATH)/Ring_Synth_04.ogg:system/media/audio/ringtones/Ring_Synth_04.ogg \
diff --git a/data/sounds/effects/Dock.aif b/data/sounds/effects/Dock.aif
new file mode 100644
index 0000000..9f408cc
--- /dev/null
+++ b/data/sounds/effects/Dock.aif
Binary files differ
diff --git a/data/sounds/effects/Dock.ogg b/data/sounds/effects/Dock.ogg
new file mode 100644
index 0000000..1462813d
--- /dev/null
+++ b/data/sounds/effects/Dock.ogg
Binary files differ
diff --git a/data/sounds/effects/Lock.aiff b/data/sounds/effects/Lock.aiff
new file mode 100644
index 0000000..90870f2
--- /dev/null
+++ b/data/sounds/effects/Lock.aiff
Binary files differ
diff --git a/data/sounds/effects/Lock.ogg b/data/sounds/effects/Lock.ogg
new file mode 100644
index 0000000..841ee2e
--- /dev/null
+++ b/data/sounds/effects/Lock.ogg
Binary files differ
diff --git a/data/sounds/effects/LowBattery.aif b/data/sounds/effects/LowBattery.aif
new file mode 100644
index 0000000..9216583
--- /dev/null
+++ b/data/sounds/effects/LowBattery.aif
Binary files differ
diff --git a/data/sounds/effects/LowBattery.ogg b/data/sounds/effects/LowBattery.ogg
new file mode 100644
index 0000000..68eb2c3
--- /dev/null
+++ b/data/sounds/effects/LowBattery.ogg
Binary files differ
diff --git a/data/sounds/effects/Undock.aif b/data/sounds/effects/Undock.aif
new file mode 100644
index 0000000..fe9d0b05
--- /dev/null
+++ b/data/sounds/effects/Undock.aif
Binary files differ
diff --git a/data/sounds/effects/Undock.ogg b/data/sounds/effects/Undock.ogg
new file mode 100644
index 0000000..0053066
--- /dev/null
+++ b/data/sounds/effects/Undock.ogg
Binary files differ
diff --git a/data/sounds/effects/Unlock.aiff b/data/sounds/effects/Unlock.aiff
new file mode 100644
index 0000000..546ea39
--- /dev/null
+++ b/data/sounds/effects/Unlock.aiff
Binary files differ
diff --git a/data/sounds/effects/Unlock.ogg b/data/sounds/effects/Unlock.ogg
new file mode 100644
index 0000000..26d5ea6
--- /dev/null
+++ b/data/sounds/effects/Unlock.ogg
Binary files differ
diff --git a/docs/html/sitemap.txt b/docs/html/sitemap.txt
index f82b2fe..5039dfc 100644
--- a/docs/html/sitemap.txt
+++ b/docs/html/sitemap.txt
@@ -2864,11 +2864,6 @@
 http://developer.android.com/reference/org/apache/http/cookie/params/package-descr.html
 http://developer.android.com/reference/java/util/concurrent/locks/package-descr.html
 http://developer.android.com/reference/org/apache/http/conn/routing/package-descr.html
-http://developer.android.com/guide/samples/index.html
-http://developer.android.com/guide/tutorials/notepad/notepad-ex1.html
-http://developer.android.com/guide/tutorials/notepad/notepad-ex2.html
-http://developer.android.com/guide/tutorials/notepad/notepad-ex3.html
-http://developer.android.com/guide/tutorials/notepad/notepad-extra-credit.html
 http://developer.android.com/guide/appendix/faq/commontasks.html
 http://developer.android.com/reference/javax/security/cert/package-descr.html
 http://developer.android.com/reference/org/xml/sax/ext/package-descr.html
@@ -3029,7 +3024,6 @@
 http://developer.android.com/sdk/api_diff/6/changes/android.view.WindowManager.LayoutParams.html
 http://developer.android.com/reference/android/net/package-descr.html
 http://developer.android.com/reference/org/apache/http/client/package-descr.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/app/RemoteService.html
 http://developer.android.com/sdk/download.html?v=archives/android-sdk-windows-1.6_r1.zip
 http://developer.android.com/sdk/download.html?v=archives/android-sdk-mac_x86-1.6_r1.zip
 http://developer.android.com/sdk/download.html?v=archives/android-sdk-linux_x86-1.6_r1.tgz
@@ -3299,7 +3293,6 @@
 http://developer.android.com/resources/samples/BluetoothChat/res/layout/message.html
 http://developer.android.com/resources/samples/NotePad/res/drawable-ldpi-v6/app_notes.html
 http://developer.android.com/resources/samples/NotePad/res/drawable-ldpi-v6/live_folder_notes.html
-http://developer.android.com/guide/tutorials/views/index.html
 http://developer.android.com/sdk/api_diff/4/changes/pkg_android.html
 http://developer.android.com/sdk/api_diff/4/changes/pkg_android.app.html
 http://developer.android.com/sdk/api_diff/4/changes/pkg_android.content.res.html
@@ -3523,21 +3516,6 @@
 http://developer.android.com/resources/samples/ApiDemos/tests/src/com/example/android/apis/index.html
 http://developer.android.com/reference/org/apache/http/conn/ssl/package-descr.html
 http://developer.android.com/resources/samples/ContactManager/res/drawable-hdpi/icon.html
-http://developer.android.com/guide/tutorials/views/hello-linearlayout.html
-http://developer.android.com/guide/tutorials/views/hello-relativelayout.html
-http://developer.android.com/guide/tutorials/views/hello-tablelayout.html
-http://developer.android.com/guide/tutorials/views/hello-datepicker.html
-http://developer.android.com/guide/tutorials/views/hello-timepicker.html
-http://developer.android.com/guide/tutorials/views/hello-formstuff.html
-http://developer.android.com/guide/tutorials/views/hello-spinner.html
-http://developer.android.com/guide/tutorials/views/hello-autocomplete.html
-http://developer.android.com/guide/tutorials/views/hello-listview.html
-http://developer.android.com/guide/tutorials/views/hello-gridview.html
-http://developer.android.com/guide/tutorials/views/hello-gallery.html
-http://developer.android.com/guide/tutorials/views/hello-tabwidget.html
-http://developer.android.com/guide/tutorials/views/hello-mapview.html
-http://developer.android.com/guide/tutorials/views/hello-webview.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/index.html
 http://developer.android.com/sdk/api_diff/5/changes/packages_index_all.html
 http://developer.android.com/sdk/api_diff/5/changes/classes_index_all.html
 http://developer.android.com/sdk/api_diff/5/changes/constructors_index_all.html
@@ -3858,112 +3836,6 @@
 http://developer.android.com/reference/org/w3c/dom/package-descr.html
 http://developer.android.com/reference/org/apache/http/package-descr.html
 http://developer.android.com/resources/samples/MultiResolution/src/com/example/index.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/RelativeLayout1.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/RelativeLayout2.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/LinearLayout1.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/LinearLayout2.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/LinearLayout3.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/LinearLayout4.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/LinearLayout5.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/LinearLayout6.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/LinearLayout7.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/LinearLayout8.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/LinearLayout9.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/ScrollView1.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/ScrollView2.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/TableLayout1.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/TableLayout2.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/TableLayout3.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/TableLayout4.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/TableLayout5.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/TableLayout6.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/TableLayout7.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/TableLayout8.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/TableLayout9.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/TableLayout10.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/TableLayout11.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/TableLayout12.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/Baseline1.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/Baseline2.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/Baseline3.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/Baseline4.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/Baseline6.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/Baseline7.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/BaselineNested1.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/BaselineNested2.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/BaselineNested3.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/RadioGroup1.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/ScrollBar1.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/ScrollBar2.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/Visibility1.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/List1.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/List2.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/List3.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/List4.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/List5.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/List6.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/List7.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/List8.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/CustomView1.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/ImageButton1.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/DateWidgets1.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/DateWidgets2.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/Gallery1.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/Gallery2.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/Spinner1.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/Grid1.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/Grid2.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/ImageSwitcher1.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/TextSwitcher1.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/Animation1.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/Animation2.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/Controls1.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/Controls2.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/AutoComplete1.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/AutoComplete2.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/AutoComplete3.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/AutoComplete4.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/AutoComplete5.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/ProgressBar1.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/ProgressBar2.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/ProgressBar3.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/ProgressBar4.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/Focus1.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/Focus2.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/Focus3.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/Animation3.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/AutoComplete6.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/Buttons1.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/ChronometerDemo.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/ExpandableList1.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/ExpandableList2.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/ExpandableList3.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/ImageView1.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/InternalSelectionFocus.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/InternalSelectionScroll.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/InternalSelectionView.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/LabelView.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/LayoutAnimation1.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/LayoutAnimation2.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/LayoutAnimation3.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/LayoutAnimation4.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/LayoutAnimation5.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/LayoutAnimation6.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/LayoutAnimation7.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/LinearLayout10.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/List10.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/List11.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/List12.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/List13.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/List14.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/List9.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/RatingBar1.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/ScrollBar3.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/SeekBar1.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/Tabs1.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/Tabs2.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/Tabs3.html
-http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/view/WebView1.html
 http://developer.android.com/resources/samples/Home/res/drawable/all_applications.html
 http://developer.android.com/resources/samples/Home/res/drawable/all_applications_background.html
 http://developer.android.com/resources/samples/Home/res/drawable/all_applications_button_background.html
diff --git a/include/utils/AndroidUnicode.h b/include/utils/AndroidUnicode.h
deleted file mode 100644
index 2b185d3..0000000
--- a/include/utils/AndroidUnicode.h
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * Copyright (C) 2006 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.
- */
-
-//
-
-#ifndef ANDROID_UNICODE_H
-#define ANDROID_UNICODE_H
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#define REPLACEMENT_CHAR (0xFFFD)
-
-// this part of code is copied from umachine.h under ICU
-/**
- * Define UChar32 as a type for single Unicode code points.
- * UChar32 is a signed 32-bit integer (same as int32_t).
- *
- * The Unicode code point range is 0..0x10ffff.
- * All other values (negative or >=0x110000) are illegal as Unicode code points.
- * They may be used as sentinel values to indicate "done", "error"
- * or similar non-code point conditions.
- *
- * @stable ICU 2.4
- */
-typedef int32_t UChar32;
-
-namespace android {
-
-    class Encoding;
-    /**
-     * \class Unicode
-     *
-     * Helper class for getting properties of Unicode characters. Characters
-     * can have one of the types listed in CharType and each character can have the
-     * directionality of Direction.
-     */
-    class Unicode
-    {
-    public:
-        /**
-         * Directions specified in the Unicode standard. These directions map directly
-         * to java.lang.Character.
-         */
-        enum Direction {
-            DIRECTIONALITY_UNDEFINED = -1,
-            DIRECTIONALITY_LEFT_TO_RIGHT,
-            DIRECTIONALITY_RIGHT_TO_LEFT,
-            DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC,
-            DIRECTIONALITY_EUROPEAN_NUMBER,
-            DIRECTIONALITY_EUROPEAN_NUMBER_SEPARATOR,
-            DIRECTIONALITY_EUROPEAN_NUMBER_TERMINATOR,
-            DIRECTIONALITY_ARABIC_NUMBER,
-            DIRECTIONALITY_COMMON_NUMBER_SEPARATOR,
-            DIRECTIONALITY_NONSPACING_MARK,
-            DIRECTIONALITY_BOUNDARY_NEUTRAL,
-            DIRECTIONALITY_PARAGRAPH_SEPARATOR,
-            DIRECTIONALITY_SEGMENT_SEPARATOR,
-            DIRECTIONALITY_WHITESPACE,
-            DIRECTIONALITY_OTHER_NEUTRALS,
-            DIRECTIONALITY_LEFT_TO_RIGHT_EMBEDDING,
-            DIRECTIONALITY_LEFT_TO_RIGHT_OVERRIDE,
-            DIRECTIONALITY_RIGHT_TO_LEFT_EMBEDDING,
-            DIRECTIONALITY_RIGHT_TO_LEFT_OVERRIDE,
-            DIRECTIONALITY_POP_DIRECTIONAL_FORMAT
-        };
-
-        /**
-         * Returns the packed data for java calls
-         * @param c The unicode character.
-         * @return The packed data for the character.
-         *
-         * Copied from java.lang.Character implementation:
-         * 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
-         * F E D C B A 9 8 7 6 5 4 3 2 1 0 F E D C B A 9 8 7 6 5 4 3 2 1 0
-         * 
-         *                              31 types                 ---------
-         *                   18 directionalities       ---------
-         *                   2 mirroreds             -
-         *                               -----------      56  toupper diffs
-         *                   -----------                  48  tolower diffs
-         *               ---                              4 totitlecase diffs
-         * -------------                                 84 numeric values
-         *     ---------                                 24 mirror char diffs
-         */
-        static uint32_t getPackedData(UChar32 c);
-        
-        /**
-         * Get the directionality of the character.
-         * @param c The unicode character.
-         * @return The direction of the character or DIRECTIONALITY_UNDEFINED.
-         */
-        static Direction getDirectionality(UChar32 c);
-            
-        /**
-         * Check if the character is a mirrored character. This means that the character
-         * has an equivalent character that is the mirror image of itself.
-         * @param c The unicode character.
-         * @return True iff c has a mirror equivalent.
-         */
-        static bool isMirrored(UChar32 c);
-         
-        /**
-         * Return the mirror of the given character.
-         * @param c The unicode character.
-         * @return The mirror equivalent of c. If c does not have a mirror equivalent,
-         *         the original character is returned.
-         * @see isMirrored
-         */
-        static UChar32 toMirror(UChar32 c);
-   };
-
-}
-
-#endif
diff --git a/libs/rs/java/ImageProcessing/res/raw/threshold.rs b/libs/rs/java/ImageProcessing/res/raw/threshold.rs
index 888b5cd..888f0cd 100644
--- a/libs/rs/java/ImageProcessing/res/raw/threshold.rs
+++ b/libs/rs/java/ImageProcessing/res/raw/threshold.rs
@@ -1,3 +1,29 @@
+/*
+// block of defines matching what RS will insert at runtime.
+struct Params_s{
+    int inHeight;
+    int inWidth;
+    int outHeight;
+    int outWidth;
+    float threshold;
+};
+struct Params_s * Params;
+struct InPixel_s{
+    char a;
+    char b;
+    char g;
+    char r;
+};
+struct InPixel_s * InPixel;
+struct OutPixel_s{
+    char a;
+    char b;
+    char g;
+    char r;
+};
+struct OutPixel_s * OutPixel;
+*/
+
 struct color_s {
     char b;
     char g;
@@ -15,8 +41,6 @@
     int i;
     float threshold = (Params->threshold * 255.f);
 
-    //testFnc(count, threshold, in, out);
-
     for (i = 0; i < count; i++) {
         float luminance = 0.2125f * in->r +
                           0.7154f * in->g +
diff --git a/libs/utils/Android.mk b/libs/utils/Android.mk
index 59409a2..d2cfd3b 100644
--- a/libs/utils/Android.mk
+++ b/libs/utils/Android.mk
@@ -75,7 +75,6 @@
 # we have the common sources, plus some device-specific stuff
 LOCAL_SRC_FILES:= \
 	$(commonSources) \
-	Unicode.cpp \
     BackupData.cpp \
 	BackupHelpers.cpp
 
diff --git a/libs/utils/CharacterData.h b/libs/utils/CharacterData.h
deleted file mode 100644
index d9b7c56..0000000
--- a/libs/utils/CharacterData.h
+++ /dev/null
@@ -1,689 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-// Automatically generated on 07-11-2006 by make-CharacterDataC
-// DO NOT EDIT DIRECTLY
-namespace CharacterData {
-
-    // Structure containing an array of ranges
-    struct Range {
-        int length;
-        const uint32_t* array;
-    };
-
-    // For Latin1 characters just index into this array to get the index and decomposition
-    static const uint16_t LATIN1_DATA[] = {
-        0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
-        0x0001, 0x0002, 0x0003, 0x0002, 0x0004, 0x0003, 0x0001, 0x0001, 
-        0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
-        0x0001, 0x0001, 0x0001, 0x0001, 0x0003, 0x0003, 0x0003, 0x0002, 
-        0x0005, 0x0006, 0x0006, 0x0007, 0x0008, 0x0007, 0x0006, 0x0006, 
-        0x0009, 0x000A, 0x0006, 0x000B, 0x000C, 0x000D, 0x000C, 0x000C, 
-        0x000E, 0x000F, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 
-        0x0016, 0x0017, 0x000C, 0x0006, 0x0018, 0x0019, 0x001A, 0x0006, 
-        0x0006, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, 0x0020, 0x0021, 
-        0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 
-        0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F, 0x0030, 0x0031, 
-        0x0032, 0x0033, 0x0034, 0x0035, 0x0006, 0x0036, 0x0037, 0x0038, 
-        0x0037, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, 
-        0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 
-        0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, 
-        0x0050, 0x0051, 0x0052, 0x0035, 0x0019, 0x0036, 0x0019, 0x0001, 
-        0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0003, 0x0001, 0x0001, 
-        0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
-        0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
-        0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 
-        0x5853, 0x0006, 0x0008, 0x0008, 0x0008, 0x0008, 0x0054, 0x0054, 
-        0x1037, 0x0054, 0x7855, 0x0056, 0x0019, 0x0057, 0x0054, 0x1037, 
-        0x0058, 0x0059, 0x785A, 0x785B, 0x1037, 0x105C, 0x0054, 0x0006, 
-        0x1037, 0x785D, 0x7855, 0x005E, 0x305F, 0x305F, 0x305F, 0x0006, 
-        0x0860, 0x0860, 0x0860, 0x0860, 0x0860, 0x0860, 0x0060, 0x0860, 
-        0x0860, 0x0860, 0x0860, 0x0860, 0x0860, 0x0860, 0x0860, 0x0860, 
-        0x0060, 0x0860, 0x0860, 0x0860, 0x0860, 0x0860, 0x0860, 0x0019, 
-        0x0060, 0x0860, 0x0860, 0x0860, 0x0860, 0x0860, 0x0060, 0x0055, 
-        0x0861, 0x0861, 0x0861, 0x0861, 0x0861, 0x0861, 0x0061, 0x0861, 
-        0x0861, 0x0861, 0x0861, 0x0861, 0x0861, 0x0861, 0x0861, 0x0861, 
-        0x0061, 0x0861, 0x0861, 0x0861, 0x0861, 0x0861, 0x0861, 0x0019, 
-        0x0061, 0x0861, 0x0861, 0x0861, 0x0861, 0x0861, 0x0061, 0x0862
-    };
-
-    // Each of these arrays is stripped into ranges. In order to build the arrays, each
-    // codepoint was bit-shifted so that even and odd characters were separated into different
-    // arrays. The identifier of each array is the top byte after bit-shifting.
-    // The numbers stored in the array are the bit-shifted codepoint, the decomposition, and an
-    // index into another array of all possible packed data values. The top 16 bits are the
-    // codepoint and the bottom 16 are the decomposition and index. The top 5 bits for the decomposition
-    // and the rest for the index.
-    static const uint32_t a0[] = {
-        0x00800863, 0x00880063, 0x00890863, 0x00930063, 0x00940863, 0x00980864, 0x00991063, 0x009A0863, 
-        0x009C0055, 0x009D0865, 0x00A01065, 0x00A10065, 0x00A20865, 0x00A50063, 0x00A60863, 0x00A90063, 
-        0x00AA0863, 0x00B30063, 0x00B40863, 0x00BC0866, 0x00BD0865, 0x00C00055, 0x00C10063, 0x00C30067, 
-        0x00C40065, 0x00C50068, 0x00C60065, 0x00C70069, 0x00C8006A, 0x00C90065, 0x00CA006B, 0x00CB006C, 
-        0x00CC0063, 0x00CD006D, 0x00CE006C, 0x00CF006E, 0x00D00863, 0x00D10063, 0x00D3006F, 0x00D40065, 
-        0x00D50055, 0x00D60063, 0x00D7006F, 0x00D80865, 0x00D90070, 0x00DA0065, 0x00DC0063, 0x00DD0055, 
-        0x00DE0063, 0x00DF0055, 0x00E00071, 0x00E21072, 0x00E31073, 0x00E41074, 0x00E51072, 0x00E61073, 
-        0x00E70865, 0x00EF0863, 0x00F20063, 0x00F30863, 0x00F80855, 0x00F91074, 0x00FA0863, 0x00FB0075, 
-        0x00FC0863, 0x010E0063, 0x010F0863, 0x01100076, 0x01110063, 0x01130863, 0x011A0055, 0x011D0077, 
-        0x011E0065, 0x011F0077, 0x01200055, 0x01210078, 0x01280055, 0x012A0079, 0x012B007A, 0x012C0055, 
-        0x0130007A, 0x01310055, 0x0134007B, 0x01350055, 0x0139007C, 0x013A0055, 0x0140007D, 0x01410055, 
-        0x0144007D, 0x0145007E, 0x01460055, 0x0149007F, 0x014A0080, 0x014B0055, 0x01587881, 0x015D0082, 
-        0x015E0081, 0x01610037, 0x01630082, 0x01680081, 0x01690037, 0x016C1037, 0x016F0037, 0x01707881, 
-        0x01730037, 0x01770081, 0x01780037, 0x01800083, 0x01A00883, 0x01A10083, 0x01A20883, 0x01A30083, 
-        0x01B80078, 0x01BA0837, 0x01BB0078, 0x01BD1081, 0x01BE0078, 0x01BF0806, 0x01C00078, 0x01C21037, 
-        0x01C30884, 0x01C40885, 0x01C60886, 0x01C70887, 0x01C80855, 0x01C90060, 0x01D10078, 0x01D20060, 
-        0x01D50860, 0x01D60888, 0x01D70889, 0x01D80855, 0x01D90061, 0x01E1008A, 0x01E20061, 0x01E50861, 
-        0x01E6088B, 0x01E7088C, 0x01E8108D, 0x01E91077, 0x01EA0877, 0x01EB108E, 0x01EC0063, 0x01F8108F, 
-        0x01F91090, 0x01FA1091, 0x01FB0019, 0x01FC0065, 0x01FD0063, 0x01FE0055, 0x01FF0077, 0x02000892, 
-        0x02010092, 0x02060892, 0x02080060, 0x02180061, 0x02280893, 0x02290093, 0x022E0893, 0x02300063, 
-        0x023B0863, 0x023C0063, 0x02410094, 0x02420083, 0x02440095, 0x02450063, 0x02600077, 0x02610865, 
-        0x02620065, 0x02680863, 0x026A0063, 0x026B0863, 0x026C0063, 0x026D0863, 0x02700063, 0x02710863, 
-        0x02740063, 0x02750863, 0x027B0063, 0x027C0863, 0x027D0078, 0x02800063, 0x02880078, 0x02990096, 
-        0x02AC0078, 0x02AD0097, 0x02B00078, 0x02B10098, 0x02C40078, 0x02C50099, 0x02C60078, 0x02C90083, 
-        0x02DD0078, 0x02DE0083, 0x02DF009A, 0x02E10083, 0x02E3009A, 0x02E40078, 0x02E8009B, 0x02F60078, 
-        0x02F8009B, 0x02FA009A, 0x02FB0078, 0x0300009C, 0x03020078, 0x0306000C, 0x03070054, 0x03080083, 
-        0x030B0078, 0x030F009D, 0x03100078, 0x0311089E, 0x0314009E, 0x031E0078, 0x0320009F, 0x0321009E, 
-        0x03260083, 0x033000A0, 0x033100A1, 0x033200A2, 0x033300A3, 0x033400A4, 0x03350007, 0x033600A5, 
-        0x0337009E, 0x03380083, 0x0339009E, 0x033B109E, 0x033D009E, 0x0360089E, 0x0362009E, 0x036A009D, 
-        0x036B0083, 0x036F0095, 0x03700083, 0x0373009F, 0x03740083, 0x0377009E, 0x0378000E, 0x03790010, 
-        0x037A0012, 0x037B0014, 0x037C0016, 0x037D009E, 0x037F00A6, 0x0380009D, 0x03870078, 0x0388009E, 
-        0x03980083, 0x03A60078, 0x03A7009E, 0x03B70078, 0x03C0009E, 0x03D30083, 0x03D90078, 0x04810083, 
-        0x04820071, 0x049A0871, 0x049B0071, 0x049D0078, 0x049E0083, 0x049F00A7, 0x04A10083, 0x04A500A7, 
-        0x04A70078, 0x04A80071, 0x04A90083, 0x04AB0078, 0x04AC0871, 0x04B00071, 0x04B10083, 0x04B20097, 
-        0x04B300A8, 0x04B400A9, 0x04B500AA, 0x04B600AB, 0x04B700AC, 0x04B80097, 0x04B90078, 0x04C100A7, 
-        0x04C20078, 0x04C30071, 0x04C70078, 0x04C80071, 0x04C90078, 0x04CA0071, 0x04DA0078, 0x04DB0071, 
-        0x04DD0078, 0x04DE0083, 0x04DF00A7, 0x04E10083, 0x04E30078, 0x04E400A7, 0x04E50078, 0x04E608A7, 
-        0x04E70071, 0x04E80078, 0x04EE0871, 0x04EF0078, 0x04F00071, 0x04F10083, 0x04F20078, 0x04F300A8, 
-        0x04F400A9, 0x04F500AA, 0x04F600AB, 0x04F700AC, 0x04F80071, 0x04F90008, 0x04FA00AD, 0x04FB00AE, 
-        0x04FC00AF, 0x04FD0094, 0x04FE0078, 0x05010083, 0x05020078, 0x05030071, 0x05060078, 0x05080071, 
-        0x05090078, 0x050A0071, 0x051A0078, 0x051B0871, 0x051C0071, 0x051D0078, 0x051E0083, 0x051F00A7, 
-        0x05210083, 0x05220078, 0x05240083, 0x05250078, 0x05260083, 0x05270078, 0x052D0871, 0x052E0071, 
-        0x052F0871, 0x05300078, 0x053300A8, 0x053400A9, 0x053500AA, 0x053600AB, 0x053700AC, 0x05380083, 
-        0x05390071, 0x053B0078, 0x05410083, 0x05420078, 0x05430071, 0x05470078, 0x05480071, 0x05490078, 
-        0x054A0071, 0x055A0078, 0x055B0071, 0x055D0078, 0x055E0083, 0x055F00A7, 0x05610083, 0x05630078, 
-        0x05640083, 0x05650078, 0x056600A7, 0x05670078, 0x05680071, 0x05690078, 0x05700071, 0x05710083, 
-        0x05720078, 0x057300A8, 0x057400A9, 0x057500AA, 0x057600AB, 0x057700AC, 0x05780078, 0x058100A7, 
-        0x05820078, 0x05830071, 0x05870078, 0x05880071, 0x05890078, 0x058A0071, 0x059A0078, 0x059B0071, 
-        0x059D0078, 0x059E0083, 0x059F00A7, 0x05A10083, 0x05A20078, 0x05A408A7, 0x05A50078, 0x05A608A7, 
-        0x05A70078, 0x05AB0083, 0x05AC0078, 0x05AE0871, 0x05AF0078, 0x05B00071, 0x05B10078, 0x05B300A8, 
-        0x05B400A9, 0x05B500AA, 0x05B600AB, 0x05B700AC, 0x05B80094, 0x05B90078, 0x05C10083, 0x05C20078, 
-        0x05C30071, 0x05C60078, 0x05C70071, 0x05CA0871, 0x05CB0078, 0x05CD0071, 0x05D00078, 0x05D20071, 
-        0x05D30078, 0x05D40071, 0x05D60078, 0x05D70071, 0x05DD0078, 0x05DF00A7, 0x05E00083, 0x05E100A7, 
-        0x05E20078, 0x05E300A7, 0x05E508A7, 0x05E70078, 0x05F300A8, 0x05F400A9, 0x05F500AA, 0x05F600AB, 
-        0x05F700AC, 0x05F800B0, 0x05F900B1, 0x05FA0054, 0x05FE0078, 0x060100A7, 0x06020078, 0x06030071, 
-        0x061A0078, 0x061B0071, 0x061D0078, 0x061F0083, 0x062100A7, 0x06230083, 0x06240883, 0x06250083, 
-        0x06270078, 0x062B0083, 0x062C0078, 0x06300071, 0x06310078, 0x063300A8, 0x063400A9, 0x063500AA, 
-        0x063600AB, 0x063700AC, 0x06380078, 0x064100A7, 0x06420078, 0x06430071, 0x065A0078, 0x065B0071, 
-        0x065D0078, 0x065E0083, 0x065F00A7, 0x066008A7, 0x066100A7, 0x066300B2, 0x066408A7, 0x06660083, 
-        0x06670078, 0x066B00A7, 0x066C0078, 0x066F0071, 0x06710078, 0x067300A8, 0x067400A9, 0x067500AA, 
-        0x067600AB, 0x067700AC, 0x06780078, 0x068100A7, 0x06820078, 0x06830071, 0x069D0078, 0x069F00A7, 
-        0x06A10083, 0x06A20078, 0x06A300A7, 0x06A508A7, 0x06A70078, 0x06B00071, 0x06B10078, 0x06B300A8, 
-        0x06B400A9, 0x06B500AA, 0x06B600AB, 0x06B700AC, 0x06B80078, 0x06C100A7, 0x06C20078, 0x06C30071, 
-        0x06CC0078, 0x06CD0071, 0x06D90078, 0x06DA0071, 0x06DE0078, 0x06E00071, 0x06E40078, 0x06E50083, 
-        0x06E60078, 0x06E800A7, 0x06E90083, 0x06EC00A7, 0x06ED08A7, 0x06F00078, 0x06F900A7, 0x06FA0097, 
-        0x06FB0078, 0x07010071, 0x071A0083, 0x071E0078, 0x07200071, 0x07230081, 0x07240083, 0x072800A8, 
-        0x072900A9, 0x072A00AA, 0x072B00AB, 0x072C00AC, 0x072D0097, 0x072E0078, 0x07410071, 0x07430078, 
-        0x07440071, 0x07460078, 0x074A0071, 0x074C0078, 0x074D0071, 0x07500078, 0x07510071, 0x07520078, 
-        0x07550071, 0x07560078, 0x07570071, 0x075A0083, 0x075D0078, 0x075E0083, 0x075F0078, 0x07600071, 
-        0x07630081, 0x07640083, 0x07670078, 0x076800A8, 0x076900A9, 0x076A00AA, 0x076B00AB, 0x076C00AC, 
-        0x076D0078, 0x076E1071, 0x076F0078, 0x07800071, 0x07810094, 0x07820097, 0x07865897, 0x07870097, 
-        0x078A0094, 0x078C0083, 0x078D0094, 0x079000A8, 0x079100A9, 0x079200AA, 0x079300AB, 0x079400AC, 
-        0x079500B3, 0x079A0094, 0x079D00B4, 0x079F00A7, 0x07A00071, 0x07A40078, 0x07A50071, 0x07A90871, 
-        0x07AA0071, 0x07AE0871, 0x07AF0071, 0x07B60078, 0x07B90083, 0x07BB0883, 0x07BD0083, 0x07C40071, 
-        0x07C60078, 0x07C80083, 0x07CC0078, 0x07CD0083, 0x07D10883, 0x07D20083, 0x07D60883, 0x07D70083, 
-        0x07DF0094, 0x07E30083, 0x07E40094, 0x07E70078, 0x07E80097, 0x07E90078, 0x08000071, 0x08110078, 
-        0x08120071, 0x08130871, 0x08140078, 0x08150071, 0x081600A7, 0x08170083, 0x081A0078, 0x081B0083, 
-        0x081C00A7, 0x081D0078, 0x082000A8, 0x082100A9, 0x082200AA, 0x082300AB, 0x082400AC, 0x08250097, 
-        0x08280071, 0x082B00A7, 0x082C0083, 0x082D0078, 0x085000B5, 0x08630078, 0x08680071, 0x087E7881, 
-        0x087F0078, 0x08800071, 0x08AD0078, 0x08B00071, 0x08D20078, 0x08D40071, 0x08FD0078, 0x09000071, 
-        0x09270078, 0x09280071, 0x092F0078, 0x09300071, 0x09470078, 0x09480071, 0x095B0078, 0x095C0071, 
-        0x09630078, 0x09640071, 0x098B0078, 0x098C0071, 0x09AE0078, 0x09B00094, 0x09B10097, 0x09B500B6, 
-        0x09B600B7, 0x09B700B8, 0x09B800B9, 0x09B900B0, 0x09BA00BA, 0x09BB00BB, 0x09BC00BC, 0x09BD00BD, 
-        0x09BE00BE, 0x09BF0078, 0x09C00071, 0x09C80054, 0x09CD0078, 0x09D00071, 0x09FB0078, 0x0A010071, 
-        0x0B370097, 0x0B380071, 0x0B3C0078, 0x0B400005, 0x0B410071, 0x0B4E00BF, 0x0B4F0078, 0x0B500071, 
-        0x0B760097, 0x0B7700C0, 0x0B7800C1, 0x0B790078, 0x0B800071, 0x0B890083, 0x0B8B0078, 0x0B900071, 
-        0x0B990083, 0x0B9B0097, 0x0B9C0078, 0x0BA00071, 0x0BA90083, 0x0BAA0078, 0x0BB00071, 0x0BB90083, 
-        0x0BBA0078, 0x0BC00071, 0x0BDA00C2, 0x0BDB00A7, 0x0BDC0083, 0x0BDF00A7, 0x0BE30083, 0x0BE400A7, 
-        0x0BE50083, 0x0BEA0097, 0x0BEE0071, 0x0BEF0078, 0x0BF000A8, 0x0BF100A9, 0x0BF200AA, 0x0BF300AB, 
-        0x0BF400AC, 0x0BF50078, 0x0BF800C3, 0x0BF900C4, 0x0BFA00C5, 0x0BFB00C6, 0x0BFC00C7, 0x0BFD0078, 
-        0x0C000006, 0x0C030099, 0x0C040006, 0x0C060083, 0x0C070005, 0x0C0800A8, 0x0C0900A9, 0x0C0A00AA, 
-        0x0C0B00AB, 0x0C0C00AC, 0x0C0D0078, 0x0C100071, 0x0C3C0078, 0x0C400071, 0x0C550078, 0x0C800071, 
-        0x0C8F0078, 0x0C900083, 0x0C9200A7, 0x0C940083, 0x0C9500C8, 0x0C960078, 0x0C9800A7, 0x0C990083, 
-        0x0C9A00A7, 0x0C9D0083, 0x0C9E0078, 0x0CA00054, 0x0CA10078, 0x0CA20006, 0x0CA300A8, 0x0CA400A9, 
-        0x0CA500AA, 0x0CA600AB, 0x0CA700AC, 0x0CA80071, 0x0CB70078, 0x0CB80071, 0x0CBB0078, 0x0CC00071, 
-        0x0CD50078, 0x0CD800A7, 0x0CE10071, 0x0CE400A7, 0x0CE50078, 0x0CE800A8, 0x0CE900A9, 0x0CEA00AA, 
-        0x0CEB00AB, 0x0CEC00AC, 0x0CED0078, 0x0CEF0006, 0x0CF00054, 0x0D000071, 0x0D0C0083, 0x0D0D00A7, 
-        0x0D0E0078, 0x0D0F0097, 0x0D100078, 0x0E800055, 0x0E967881, 0x0EA70081, 0x0EA87881, 0x0EB17055, 
-        0x0EB60055, 0x0EBC7881, 0x0EBD0055, 0x0ECE7881, 0x0EE00083, 0x0EE20078, 0x0F000863, 0x0F4B0855, 
-        0x0F4D1055, 0x0F4E0078, 0x0F500863, 0x0F7D0078, 0x0F8008C9, 0x0F8408CA, 0x0F8808C9, 0x0F8B0078, 
-        0x0F8C08CA, 0x0F8F0078, 0x0F9008C9, 0x0F9408CA, 0x0F9808C9, 0x0F9C08CA, 0x0FA008C9, 0x0FA30078, 
-        0x0FA408CA, 0x0FA70078, 0x0FA80855, 0x0FAC0078, 0x0FB008C9, 0x0FB408CA, 0x0FB808CB, 0x0FB908CC, 
-        0x0FBB08CD, 0x0FBC08CE, 0x0FBD08CF, 0x0FBE08D0, 0x0FBF0078, 0x0FC008C9, 0x0FC408D1, 0x0FC808C9, 
-        0x0FCC08D1, 0x0FD008C9, 0x0FD408D1, 0x0FD808C9, 0x0FD90855, 0x0FDC08CA, 0x0FDD08D2, 0x0FDE08D3, 
-        0x0FDF08D4, 0x0FE01037, 0x0FE10855, 0x0FE408D5, 0x0FE608D3, 0x0FE70837, 0x0FE808C9, 0x0FE90855, 
-        0x0FEA0078, 0x0FEB0855, 0x0FEC08CA, 0x0FED08D6, 0x0FEE0078, 0x0FEF0837, 0x0FF008C9, 0x0FF10855, 
-        0x0FF408CA, 0x0FF508D7, 0x0FF608D8, 0x0FF70837, 0x0FF80078, 0x0FF90855, 0x0FFC08D9, 0x0FFD08DA, 
-        0x0FFE08D3, 0x0FFF1037, 0x10000805, 0x10011005, 0x10060057, 0x100700C2, 0x10080099, 0x100B0006, 
-        0x100C00DB, 0x100D00B4, 0x100E00DB, 0x100F00B4, 0x10100006, 0x10121006, 0x101400DC, 0x101500DD, 
-        0x101600DE, 0x101700DF, 0x10180007, 0x101A1007, 0x101B1006, 0x101C0006, 0x101D00E0, 0x101E1006, 
-        0x10200038, 0x10210006, 0x102200E1, 0x1023000A, 0x10241006, 0x10250006, 0x10290019, 0x102A0038, 
-        0x102B0006, 0x10300057, 0x10320078, 0x10350057, 0x103878E2, 0x10390078, 0x103A78E3, 0x103B78E4, 
-        0x103C78E5, 0x103D780B, 0x103E7819, 0x103F780A, 0x104070E2, 0x1041705A, 0x104270E3, 0x104370E4, 
-        0x104470E5, 0x1045700B, 0x10467019, 0x1047700A, 0x10487081, 0x104B0078, 0x10500008, 0x10541008, 
-        0x10550008, 0x105B0078, 0x10680083, 0x106F0095, 0x10730083, 0x10760078, 0x10801054, 0x10812877, 
-        0x10820054, 0x10831054, 0x10840054, 0x10852855, 0x10862877, 0x10872855, 0x10882877, 0x108A0054, 
-        0x108B1054, 0x108C0054, 0x108D2877, 0x108F0054, 0x10907854, 0x10922877, 0x109308E6, 0x10942877, 
-        0x109508E7, 0x10962877, 0x10970058, 0x10982877, 0x10990054, 0x109A2855, 0x109B1071, 0x109D0054, 
-        0x109E2855, 0x109F2877, 0x10A028E8, 0x10A10019, 0x10A32855, 0x10A50054, 0x10A70078, 0x10AA305F, 
-        0x10B010E9, 0x10B110EA, 0x10B210EB, 0x10B310EC, 0x10B410ED, 0x10B510EE, 0x10B610EF, 0x10B710F0, 
-        0x10B810F1, 0x10B910F2, 0x10BA10F3, 0x10BB10F4, 0x10BC10F5, 0x10BD10F6, 0x10BE10F7, 0x10BF10F8, 
-        0x10C000F9, 0x10C100FA, 0x10C20078, 0x10C80019, 0x10CB0054, 0x10CD0819, 0x10CE0054, 0x10D00019, 
-        0x10D10054, 0x10D30019, 0x10D40054, 0x10D70819, 0x10D80054, 0x10E70819, 0x10E80054, 0x10E90019, 
-        0x10EB0054, 0x10FA0019, 0x110100E8, 0x110208E8, 0x11030019, 0x110400FB, 0x110608FC, 0x11070019, 
-        0x1109000B, 0x110A0019, 0x110B00E8, 0x110C0019, 0x110D00E8, 0x110F0019, 0x111000E8, 0x111208E8, 
-        0x11140019, 0x111610E8, 0x111700E8, 0x111810E8, 0x111900E8, 0x111A0019, 0x111E00FD, 0x111F00E8, 
-        0x112208E8, 0x112300E8, 0x11270019, 0x112900FD, 0x112B0019, 0x113008E8, 0x113200FD, 0x11360019, 
-        0x113708FD, 0x113900FD, 0x113A08FD, 0x113B00FD, 0x113C08FD, 0x113D00FD, 0x114008FD, 0x114100FD, 
-        0x114208FD, 0x114300FD, 0x114408FD, 0x114500FD, 0x114600E8, 0x11470019, 0x114800FE, 0x114A0019, 
-        0x114C00FF, 0x114D0019, 0x115100FD, 0x11520019, 0x11530100, 0x11540101, 0x115500E8, 0x115608E8, 
-        0x115800FD, 0x115C00E8, 0x115D0019, 0x115F00E8, 0x11600019, 0x116500FE, 0x11670019, 0x116800FD, 
-        0x11690019, 0x116B00FD, 0x117008FD, 0x117200FD, 0x117508FD, 0x11770019, 0x117800FD, 0x11790102, 
-        0x117B0103, 0x117C00E8, 0x117D0104, 0x117F0105, 0x11800054, 0x118400FD, 0x11860054, 0x119000E8, 
-        0x11910054, 0x1195080A, 0x11960054, 0x119B0094, 0x11BE0019, 0x11BF0054, 0x11CE0019, 0x11DA00B4, 
-        0x11DB0006, 0x11DC0054, 0x11EE0078, 0x12000054, 0x12140078, 0x12200054, 0x12260078, 0x12301906, 
-        0x12311907, 0x12321908, 0x12331909, 0x1234190A, 0x1235190B, 0x1236190C, 0x1237190D, 0x1238190E, 
-        0x1239190F, 0x123A1106, 0x123B1107, 0x123C1108, 0x123D1109, 0x123E110A, 0x123F110B, 0x1240110C, 
-        0x1241110D, 0x1242110E, 0x1243110F, 0x1244105D, 0x1245105B, 0x12461110, 0x12471111, 0x12481112, 
-        0x12491113, 0x124A1114, 0x124B1115, 0x124C1116, 0x124D1117, 0x124E1094, 0x125B1918, 0x12681919, 
-        0x127518C3, 0x1276011A, 0x1277011B, 0x1278011C, 0x1279011D, 0x127A011E, 0x127B00C4, 0x127C00C5, 
-        0x127D00C6, 0x127E00C7, 0x127F011F, 0x12800054, 0x12FC0019, 0x13000054, 0x134F0078, 0x13500054, 
-        0x13560094, 0x13570054, 0x13590078, 0x13810054, 0x13850078, 0x13860054, 0x13940078, 0x13950054, 
-        0x13A60078, 0x13A80054, 0x13AA0078, 0x13AB0054, 0x13B00078, 0x13B10054, 0x13B40009, 0x13BB0106, 
-        0x13BC0107, 0x13BD0108, 0x13BE0109, 0x13BF010A, 0x13C00106, 0x13C10107, 0x13C20108, 0x13C30109, 
-        0x13C4010A, 0x13C50106, 0x13C60107, 0x13C70108, 0x13C80109, 0x13C9010A, 0x13CA0054, 0x13CB0078, 
-        0x13CC0054, 0x13D80078, 0x13D90054, 0x13E000E8, 0x13E10019, 0x13E200FE, 0x13E3000A, 0x13E40078, 
-        0x13E80019, 0x13EA00E8, 0x13EB00FE, 0x13EC0019, 0x13EE00E8, 0x13EF00FE, 0x13F00019, 0x13F100FD, 
-        0x13F30009, 0x13F60078, 0x13F80019, 0x14000094, 0x14800019, 0x14C2000A, 0x14C70120, 0x14C80121, 
-        0x14C9000A, 0x14CD0019, 0x14CE00E8, 0x14D80019, 0x14DC0122, 0x14DD0019, 0x14E000FD, 0x14E100E8, 
-        0x14E200FD, 0x14E30019, 0x14E700E8, 0x14E800FE, 0x14EA00FD, 0x14EB0019, 0x14EC0009, 0x14EE00E8, 
-        0x14EF0019, 0x14F200E8, 0x14F30019, 0x14F400E8, 0x14F50019, 0x14FA00E8, 0x14FC00FD, 0x14FD0019, 
-        0x14FE0009, 0x14FF0019, 0x150500E8, 0x150610E8, 0x150700E8, 0x15110019, 0x151200E8, 0x15140019, 
-        0x151600FE, 0x15180019, 0x151A00FD, 0x151B0019, 0x151E00FD, 0x151F00E8, 0x15200019, 0x152C00E8, 
-        0x152D0019, 0x153200FD, 0x15330019, 0x153500E8, 0x15370019, 0x153800E8, 0x15390019, 0x153A10E8, 
-        0x153B1019, 0x153C0019, 0x153D00FE, 0x153E00E8, 0x153F00FE, 0x154300E8, 0x154600FE, 0x154700E8, 
-        0x154900FE, 0x154F00E8, 0x155100FE, 0x15520019, 0x155300FD, 0x15570019, 0x155800FE, 0x155900E8, 
-        0x155A00FE, 0x155B00E8, 0x155E00FE, 0x156400E8, 0x156700FE, 0x156C0019, 0x156E08E8, 0x156F0123, 
-        0x15700019, 0x157100E8, 0x15720124, 0x157300E8, 0x15740019, 0x157600FD, 0x157700E8, 0x15780019, 
-        0x157C00FE, 0x157E0019, 0x15800054, 0x158A0078, 0x16000096, 0x16180098, 0x16300078, 0x16400063, 
-        0x16720055, 0x16730054, 0x16760078, 0x167D0006, 0x16800125, 0x16930078, 0x16980071, 0x16B30078, 
-        0x16C00071, 0x16CC0078, 0x16D00071, 0x16F00078, 0x17000006, 0x17010126, 0x17030006, 0x170500E0, 
-        0x17060126, 0x17070006, 0x170C0078, 0x170E0126, 0x170F0078, 0x17400054, 0x174D0078, 0x174E0054, 
-        0x177A0078, 0x17801054, 0x17EB0078, 0x17F80054, 0x17FE0078, 0x18008805, 0x18010006, 0x18020054, 
-        0x18030071, 0x18040009, 0x18090054, 0x180A0009, 0x180E0099, 0x180F00BF, 0x18100054, 0x18110127, 
-        0x18120128, 0x18130129, 0x1814012A, 0x18150083, 0x18180099, 0x18190081, 0x181B1054, 0x181C112B, 
-        0x181D112C, 0x181E0071, 0x181F0054, 0x18200078, 0x18210071, 0x18260871, 0x18320071, 0x18380871, 
-        0x18390071, 0x183A0871, 0x183C0071, 0x183D0871, 0x183F0071, 0x184A0871, 0x184B0071, 0x184C0078, 
-        0x184D0083, 0x184E1037, 0x184F0881, 0x18500099, 0x18510071, 0x18560871, 0x18620071, 0x18680871, 
-        0x18690071, 0x186A0871, 0x186C0071, 0x186D0871, 0x186F0071, 0x187A0871, 0x187B0071, 0x187C0871, 
-        0x187E0081, 0x187F0881, 0x18800078, 0x18830071, 0x18970078, 0x18991071, 0x18C80094, 0x18C978AD, 
-        0x18CA78AE, 0x18CB7894, 0x18D00071, 0x18DC0078, 0x18E00054, 0x18E80078, 0x18F80071, 0x19001094, 
-        0x190F1054, 0x191010AD, 0x191110AE, 0x1912112D, 0x1913112E, 0x1914112F, 0x19151094, 0x19220078, 
-        0x19286854, 0x19291930, 0x192A1931, 0x192B1932, 0x192C1933, 0x192D1934, 0x192E1935, 0x192F1936, 
-        0x19301894, 0x193E1854, 0x194018AD, 0x194118AE, 0x1942192D, 0x1943192E, 0x1944192F, 0x19451894, 
-        0x19591937, 0x195A1938, 0x195B1939, 0x195C193A, 0x195D193B, 0x195E193C, 0x195F193D, 0x19601094, 
-        0x19666854, 0x19681894, 0x19806894, 0x19AC1094, 0x19B96894, 0x19BC6854, 0x19BE6894, 0x19EF6854, 
-        0x19F01094, 0x1A000071, 0x26DB0078, 0x26E00054, 0x27000071, 0x4FDE0078, 0x50000071, 0x52470078, 
-        0x52480054, 0x52640078, 0x53800037, 0x538C0078, 0x54000071, 0x540100C8, 0x54020071, 0x54030083, 
-        0x54040071, 0x541200A7, 0x54130083, 0x54140054, 0x54160078, 0x56000071, 0x6BD20078, 0x6C00013E, 
-        0x7000013F, 0x7C800871, 0x7D070071, 0x7D080871, 0x7D0A0071, 0x7D0B0871, 0x7D120071, 0x7D130871, 
-        0x7D140071, 0x7D150871, 0x7D170078, 0x7D180871, 0x7D360078, 0x7D380871, 0x7D6D0078, 0x7D801055, 
-        0x7D840078, 0x7D8A1055, 0x7D8C0078, 0x7D8F0083, 0x7D90289B, 0x7D95089B, 0x7DA10078, 0x7DA2089B, 
-        0x7DA8409E, 0x7DAA389E, 0x7DAB409E, 0x7DAC389E, 0x7DAD409E, 0x7DAE389E, 0x7DAF409E, 0x7DB0389E, 
-        0x7DB1409E, 0x7DB2389E, 0x7DB3409E, 0x7DB4389E, 0x7DB5409E, 0x7DB6389E, 0x7DB7409E, 0x7DB8389E, 
-        0x7DB9409E, 0x7DBA389E, 0x7DBB409E, 0x7DBC389E, 0x7DBD409E, 0x7DBE389E, 0x7DBF409E, 0x7DC0389E, 
-        0x7DC1409E, 0x7DC8389E, 0x7DC9409E, 0x7DCA389E, 0x7DCB409E, 0x7DCC389E, 0x7DCD409E, 0x7DCE389E, 
-        0x7DCF409E, 0x7DD1389E, 0x7DD2409E, 0x7DD4389E, 0x7DD5409E, 0x7DD6389E, 0x7DD7409E, 0x7DD90078, 
-        0x7DEA209E, 0x7DEB489E, 0x7DEC209E, 0x7DEF409E, 0x7DF3389E, 0x7DF5409E, 0x7DFC389E, 0x7DFD209E, 
-        0x7DFE409E, 0x7DFF389E, 0x7E00409E, 0x7E32209E, 0x7E4C389E, 0x7E70489E, 0x7E7B409E, 0x7E89209E, 
-        0x7E97389E, 0x7E9A489E, 0x7E9E209E, 0x7E9F00B4, 0x7EA00078, 0x7EA8389E, 0x7EAC209E, 0x7EAE389E, 
-        0x7EAF209E, 0x7EB0389E, 0x7EB1209E, 0x7EB4389E, 0x7EB5209E, 0x7EB8389E, 0x7EBA209E, 0x7EC3389E, 
-        0x7EC80078, 0x7EC9389E, 0x7ECB209E, 0x7ECC389E, 0x7ECD209E, 0x7EDA389E, 0x7EDB209E, 0x7EDC389E, 
-        0x7EDE209E, 0x7EE2389E, 0x7EE3209E, 0x7EE40078, 0x7EF8409E, 0x7EFE4140, 0x7EFF0078, 0x7F000083, 
-        0x7F088006, 0x7F0C80BF, 0x7F0D0078, 0x7F100083, 0x7F120078, 0x7F188006, 0x7F198099, 0x7F1A8038, 
-        0x7F1B80BF, 0x7F230006, 0x7F2480BF, 0x7F251006, 0x7F271038, 0x7F28600C, 0x7F2A6006, 0x7F2C6099, 
-        0x7F2D60BF, 0x7F306006, 0x7F31600B, 0x7F326019, 0x7F346006, 0x7F356007, 0x7F360078, 0x7F38409E, 
-        0x7F41209E, 0x7F46489E, 0x7F47209E, 0x7F49489E, 0x7F4A209E, 0x7F4C489E, 0x7F4D209E, 0x7F4E489E, 
-        0x7F4F209E, 0x7F50489E, 0x7F51209E, 0x7F52489E, 0x7F53209E, 0x7F54489E, 0x7F55209E, 0x7F5A489E, 
-        0x7F5B209E, 0x7F5C489E, 0x7F5D209E, 0x7F5E489E, 0x7F5F209E, 0x7F60489E, 0x7F61209E, 0x7F62489E, 
-        0x7F63209E, 0x7F64489E, 0x7F65209E, 0x7F66489E, 0x7F67209E, 0x7F68489E, 0x7F69209E, 0x7F6A489E, 
-        0x7F6B209E, 0x7F6C489E, 0x7F6D209E, 0x7F6E489E, 0x7F6F209E, 0x7F70489E, 0x7F71209E, 0x7F72489E, 
-        0x7F73209E, 0x7F74489E, 0x7F75209E, 0x7F76489E, 0x7F77209E, 0x7F7A489E, 0x7F7B209E, 0x7F7F0078, 
-        0x7F818806, 0x7F828808, 0x7F838806, 0x7F848809, 0x7F858806, 0x7F86880C, 0x7F88880E, 0x7F898810, 
-        0x7F8A8812, 0x7F8B8814, 0x7F8C8816, 0x7F8D880C, 0x7F8E8818, 0x7F8F881A, 0x7F908806, 0x7F918860, 
-        0x7F9E8806, 0x7F9F8837, 0x7FA18861, 0x7FAE8819, 0x7FB0880A, 0x7FB15009, 0x7FB25006, 0x7FB35071, 
-        0x7FB85081, 0x7FB95071, 0x7FCF5081, 0x7FD05071, 0x7FE00078, 0x7FE15071, 0x7FE40078, 0x7FE55071, 
-        0x7FE80078, 0x7FE95071, 0x7FEC0078, 0x7FED5071, 0x7FEF0078, 0x7FF08808, 0x7FF18819, 0x7FF28854, 
-        0x7FF38808, 0x7FF45054, 0x7FF55019, 0x7FF75054, 0x7FF80078, 0x7FFD0141, 0x7FFE0054, 0x7FFF0078, 
-        0x80000071, 0x80060078, 0x80070071, 0x801F0078, 0x80200071, 0x80270078, 0x80280071, 0x802F0078, 
-        0x80400071, 0x807E0078, 0x80800097, 0x80810094, 0x80820078, 0x808400B6, 0x808500B7, 0x808600B8, 
-        0x808700B9, 0x808800B0, 0x808900BA, 0x808A00BB, 0x808B00BC, 0x808C00BD, 0x808D0142, 0x808E0143, 
-        0x808F0144, 0x80900145, 0x809100B1, 0x80920146, 0x80930147, 0x80940148, 0x80950149, 0x8096014A, 
-        0x8097014B, 0x8098014C, 0x8099014D, 0x809A0078, 0x809C0094, 0x80A0014E, 0x80A1014F, 0x80A20150, 
-        0x80A30151, 0x80A40152, 0x80A50150, 0x80A60153, 0x80A70151, 0x80A80154, 0x80A90155, 0x80AA0156, 
-        0x80AB0157, 0x80AC014F, 0x80AE0158, 0x80B00154, 0x80B30150, 0x80B50155, 0x80B60153, 0x80B90151, 
-        0x80BA0150, 0x80BB005F, 0x80BD0054, 0x80C500C3, 0x80C60078, 0x81800071, 0x819000AD, 0x819100B0, 
-        0x81920078, 0x81980071, 0x81A50159, 0x81A60078, 0x81C00071, 0x81CF0078, 0x81D00071, 0x81E20078, 
-        0x81E40071, 0x81E80094, 0x81E90158, 0x81EA015A, 0x81EB0078, 0x8200015B, 0x8214015C, 0x82280071, 
-        0x824F0078, 0x825000A8, 0x825100A9, 0x825200AA, 0x825300AB, 0x825400AC, 0x82550078, 0x8400009B, 
-        0x84030078, 0x8404009B, 0x841B0078, 0x841C009B, 0x841D0078, 0x841E009B, 0x841F0078, 0x8500009B, 
-        0x85010083, 0x85020078, 0x85030083, 0x85040078, 0x85060083, 0x8508009B, 0x850A0078, 0x850B009B, 
-        0x850C0078, 0x850D009B, 0x851A0078, 0x851C0083, 0x851E0078, 0x8520015D, 0x8521015E, 0x8522015F, 
-        0x85230160, 0x85240078, 0x8528009A, 0x852D0078, 0xE8000094, 0xE87B0078, 0xE8800094, 0xE8940078, 
-        0xE8950094, 0xE8AF0894, 0xE8B300A7, 0xE8B40083, 0xE8B50094, 0xE8B700A7, 0xE8BA0057, 0xE8BE0083, 
-        0xE8C20094, 0xE8C30083, 0xE8C60094, 0xE8D50083, 0xE8D70094, 0xE8DE0894, 0xE8E10094, 0xE8EF0078, 
-        0xE9000054, 0xE9210083, 0xE9230078, 0xE9800054, 0xE9AC0078, 0xEA002877, 0xEA0D2855, 0xEA1A2877, 
-        0xEA272855, 0xEA342877, 0xEA412855, 0xEA4E2877, 0xEA500078, 0xEA512877, 0xEA520078, 0xEA532877, 
-        0xEA540078, 0xEA552877, 0xEA5B2855, 0xEA5D0078, 0xEA5F2855, 0xEA620078, 0xEA632855, 0xEA682877, 
-        0xEA752855, 0xEA822877, 0xEA830078, 0xEA842877, 0xEA860078, 0xEA872877, 0xEA8F2855, 0xEA9C2877, 
-        0xEA9D0078, 0xEA9E2877, 0xEAA40078, 0xEAA52877, 0xEAA92855, 0xEAB62877, 0xEAC32855, 0xEAD02877, 
-        0xEADD2855, 0xEAEA2877, 0xEAF72855, 0xEB042877, 0xEB112855, 0xEB1E2877, 0xEB2B2855, 0xEB382877, 
-        0xEB452855, 0xEB530078, 0xEB542877, 0xEB612855, 0xEB712877, 0xEB7E2855, 0xEB8E2877, 0xEB9B2855, 
-        0xEBAB2877, 0xEBB82855, 0xEBC82877, 0xEBD52855, 0xEBE50078, 0xEBE7280E, 0xEBE82810, 0xEBE92812, 
-        0xEBEA2814, 0xEBEB2816, 0xEBEC280E, 0xEBED2810, 0xEBEE2812, 0xEBEF2814, 0xEBF02816, 0xEBF1280E, 
-        0xEBF22810, 0xEBF32812, 0xEBF42814, 0xEBF52816, 0xEBF6280E, 0xEBF72810, 0xEBF82812, 0xEBF92814, 
-        0xEBFA2816, 0xEBFB280E, 0xEBFC2810, 0xEBFD2812, 0xEBFE2814, 0xEBFF2816, 0xEC000078
-    };
-
-    static const uint32_t a1[] = {
-        0x00000071, 0x536C0078, 0x7C000871, 0x7D0F0078
-    };
-
-    static const uint32_t a7[] = {
-        0x00100057, 0x00400078, 0x00800083, 0x00F80078, 0x8000013F, 0xFFFF0078
-    };
-
-    static const uint32_t a8[] = {
-        0x0000013F, 0x7FFF0078
-    };
-
-    static const uint32_t a16[] = {
-        0x00800865, 0x00880065, 0x00890865, 0x00930065, 0x00940865, 0x00980161, 0x00991065, 0x009A0865, 
-        0x009C0863, 0x009F1063, 0x00A00063, 0x00A10863, 0x00A41055, 0x00A50065, 0x00A60865, 0x00A90065, 
-        0x00AA0865, 0x00B30065, 0x00B40865, 0x00BC0863, 0x00BF1162, 0x00C00163, 0x00C10065, 0x00C30063, 
-        0x00C40068, 0x00C50063, 0x00C60055, 0x00C70164, 0x00C80063, 0x00C90068, 0x00CA0165, 0x00CB0166, 
-        0x00CC0065, 0x00CD0055, 0x00CE0167, 0x00CF0168, 0x00D00865, 0x00D10065, 0x00D30063, 0x00D4006F, 
-        0x00D50055, 0x00D60065, 0x00D70863, 0x00D80070, 0x00D90063, 0x00DB0169, 0x00DC0065, 0x00DD0071, 
-        0x00DE0065, 0x00DF016A, 0x00E00071, 0x00E21074, 0x00E31072, 0x00E41073, 0x00E51074, 0x00E60863, 
-        0x00EE016B, 0x00EF0865, 0x00F20065, 0x00F30865, 0x00F81072, 0x00F91073, 0x00FA0865, 0x00FB016C, 
-        0x00FC0865, 0x010E0065, 0x010F0865, 0x01100055, 0x01110065, 0x01130865, 0x011A0055, 0x011D0063, 
-        0x011E016D, 0x011F0055, 0x0120016E, 0x01210078, 0x01280055, 0x0129016F, 0x012A0055, 0x012B007A, 
-        0x012C0170, 0x012D0171, 0x012E0055, 0x01310172, 0x01320055, 0x01340173, 0x01350055, 0x01370173, 
-        0x01380055, 0x013A0174, 0x013B0055, 0x0141007D, 0x01420055, 0x0145007E, 0x01460055, 0x01587881, 
-        0x015C0082, 0x015D0081, 0x01610037, 0x01630082, 0x01680081, 0x01690037, 0x016C1037, 0x016F0037, 
-        0x01707881, 0x01720037, 0x01800083, 0x01A00883, 0x01A20175, 0x01A30083, 0x01B80078, 0x01BA0037, 
-        0x01BB0078, 0x01C20837, 0x01C30806, 0x01C40885, 0x01C50078, 0x01C70887, 0x01C80060, 0x01D50860, 
-        0x01D60889, 0x01D80061, 0x01E50861, 0x01E6088C, 0x01E70078, 0x01E81176, 0x01E90877, 0x01EA1177, 
-        0x01EB0055, 0x01EC0065, 0x01F81093, 0x01F90055, 0x01FA1178, 0x01FB0063, 0x01FC10D8, 0x01FD0065, 
-        0x01FE0077, 0x02000892, 0x02020092, 0x02030892, 0x02040092, 0x02060892, 0x02070092, 0x02080060, 
-        0x020C0860, 0x020D0060, 0x02180061, 0x021C0861, 0x021D0061, 0x02280893, 0x022A0093, 0x022B0893, 
-        0x022C0093, 0x022E0893, 0x022F0093, 0x02300065, 0x023B0865, 0x023C0065, 0x02410083, 0x02430078, 
-        0x02440095, 0x02450065, 0x02600863, 0x02610063, 0x02670078, 0x02680865, 0x026A0065, 0x026B0865, 
-        0x026C0065, 0x026D0865, 0x02700065, 0x02710865, 0x02740065, 0x02750865, 0x027B0065, 0x027C0865, 
-        0x027D0078, 0x02800065, 0x02880078, 0x02980096, 0x02AB0078, 0x02AC0081, 0x02AD0097, 0x02B00098, 
-        0x02C31055, 0x02C40097, 0x02C50078, 0x02C80083, 0x02E1009A, 0x02E20083, 0x02E40078, 0x02E8009B, 
-        0x02F50078, 0x02F8009B, 0x02F9009A, 0x02FA0078, 0x0300009C, 0x03020078, 0x03050140, 0x0306009D, 
-        0x03070054, 0x03080083, 0x030B0078, 0x030D009D, 0x030E0078, 0x030F009D, 0x0310009E, 0x0311089E, 
-        0x0313009E, 0x031D0078, 0x0320009E, 0x03250083, 0x032F0078, 0x03300179, 0x0331017A, 0x0332017B, 
-        0x0333017C, 0x0334017D, 0x033500A5, 0x0336009D, 0x0337009E, 0x033A109E, 0x033C009E, 0x0369089E, 
-        0x036A009E, 0x036B0083, 0x036E009C, 0x036F0083, 0x0372009F, 0x03730083, 0x03740054, 0x03750083, 
-        0x0377009E, 0x0378000F, 0x03790011, 0x037A0013, 0x037B0015, 0x037C0017, 0x037D009E, 0x037E00A6, 
-        0x037F009E, 0x0380009D, 0x03870057, 0x03880083, 0x0389009E, 0x03980083, 0x03A50078, 0x03A6009E, 
-        0x03B70078, 0x03C0009E, 0x03D30083, 0x03D8009E, 0x03D90078, 0x04800083, 0x048100A7, 0x04820071, 
-        0x04940871, 0x04950071, 0x04980871, 0x04990071, 0x049D0078, 0x049E0071, 0x049F00A7, 0x04A00083, 
-        0x04A400A7, 0x04A60083, 0x04A70078, 0x04A80083, 0x04AA0078, 0x04AC0871, 0x04B00071, 0x04B10083, 
-        0x04B20097, 0x04B3017E, 0x04B4017F, 0x04B50180, 0x04B60181, 0x04B70182, 0x04B80078, 0x04BE0071, 
-        0x04BF0078, 0x04C00083, 0x04C100A7, 0x04C20071, 0x04C60078, 0x04C70071, 0x04C80078, 0x04C90071, 
-        0x04D40078, 0x04D50071, 0x04D80078, 0x04DB0071, 0x04DD0078, 0x04DE0071, 0x04DF00A7, 0x04E00083, 
-        0x04E20078, 0x04E300A7, 0x04E40078, 0x04E508A7, 0x04E60083, 0x04E70078, 0x04EB00A7, 0x04EC0078, 
-        0x04EE0871, 0x04F00071, 0x04F10083, 0x04F20078, 0x04F3017E, 0x04F4017F, 0x04F50180, 0x04F60181, 
-        0x04F70182, 0x04F80071, 0x04F90008, 0x04FA00B6, 0x04FB00B7, 0x04FC0183, 0x04FD0078, 0x05000083, 
-        0x050100A7, 0x05020071, 0x05050078, 0x05070071, 0x05080078, 0x05090071, 0x05140078, 0x05150071, 
-        0x05180078, 0x05190871, 0x051A0071, 0x051B0078, 0x051C0071, 0x051D0078, 0x051F00A7, 0x05200083, 
-        0x05210078, 0x05230083, 0x05240078, 0x05250083, 0x05270078, 0x052C0871, 0x052E0078, 0x0533017E, 
-        0x0534017F, 0x05350180, 0x05360181, 0x05370182, 0x05380083, 0x05390071, 0x053A0078, 0x05400083, 
-        0x054100A7, 0x05420071, 0x05540078, 0x05550071, 0x05580078, 0x05590071, 0x055D0078, 0x055E0071, 
-        0x055F00A7, 0x05600083, 0x056400A7, 0x05660083, 0x05670078, 0x05700071, 0x05710083, 0x05720078, 
-        0x0573017E, 0x0574017F, 0x05750180, 0x05760181, 0x05770182, 0x05780008, 0x05790078, 0x05800083, 
-        0x058100A7, 0x05820071, 0x05860078, 0x05870071, 0x05880078, 0x05890071, 0x05940078, 0x05950071, 
-        0x05980078, 0x05990071, 0x059D0078, 0x059E0071, 0x059F0083, 0x05A20078, 0x05A300A7, 0x05A40078, 
-        0x05A508A7, 0x05A60083, 0x05A70078, 0x05AB00A7, 0x05AC0078, 0x05AE0871, 0x05AF0071, 0x05B10078, 
-        0x05B3017E, 0x05B4017F, 0x05B50180, 0x05B60181, 0x05B70182, 0x05B80071, 0x05B90078, 0x05C10071, 
-        0x05C50078, 0x05C70071, 0x05C80078, 0x05C90071, 0x05CB0078, 0x05CC0071, 0x05CD0078, 0x05CF0071, 
-        0x05D00078, 0x05D10071, 0x05D20078, 0x05D40071, 0x05D50078, 0x05D70071, 0x05DD0078, 0x05DF00A7, 
-        0x05E10078, 0x05E300A7, 0x05E40078, 0x05E508A7, 0x05E60083, 0x05E70078, 0x05EB00A7, 0x05EC0078, 
-        0x05F3017E, 0x05F4017F, 0x05F50180, 0x05F60181, 0x05F70182, 0x05F80184, 0x05F90054, 0x05FC0008, 
-        0x05FD0078, 0x060000A7, 0x06020071, 0x06060078, 0x06070071, 0x06080078, 0x06090071, 0x06140078, 
-        0x06150071, 0x061D0078, 0x061F0083, 0x062000A7, 0x06220078, 0x06230083, 0x06240078, 0x06250083, 
-        0x06270078, 0x062A0083, 0x062B0078, 0x06300071, 0x06310078, 0x0633017E, 0x0634017F, 0x06350180, 
-        0x06360181, 0x06370182, 0x06380078, 0x064100A7, 0x06420071, 0x06460078, 0x06470071, 0x06480078, 
-        0x06490071, 0x06540078, 0x06550071, 0x065D0078, 0x065E0071, 0x065F00B2, 0x066000A7, 0x06620078, 
-        0x066308A7, 0x06640078, 0x066508A7, 0x06660083, 0x06670078, 0x066A00A7, 0x066B0078, 0x06700071, 
-        0x06710078, 0x0673017E, 0x0674017F, 0x06750180, 0x06760181, 0x06770182, 0x06780078, 0x068100A7, 
-        0x06820071, 0x06860078, 0x06870071, 0x06880078, 0x06890071, 0x06940078, 0x06950071, 0x069D0078, 
-        0x069F00A7, 0x06A00083, 0x06A20078, 0x06A300A7, 0x06A40078, 0x06A508A7, 0x06A60083, 0x06A70078, 
-        0x06AB00A7, 0x06AC0078, 0x06B00071, 0x06B10078, 0x06B3017E, 0x06B4017F, 0x06B50180, 0x06B60181, 
-        0x06B70182, 0x06B80078, 0x06C100A7, 0x06C20071, 0x06CB0078, 0x06CD0071, 0x06DF0078, 0x06E00071, 
-        0x06E30078, 0x06E700A7, 0x06E90083, 0x06EA0078, 0x06EC00A7, 0x06EE08A7, 0x06EF00A7, 0x06F00078, 
-        0x06F900A7, 0x06FA0078, 0x07000071, 0x07180083, 0x07191071, 0x071A0083, 0x071D0078, 0x071F0008, 
-        0x07200071, 0x07230083, 0x07270097, 0x0728017E, 0x0729017F, 0x072A0180, 0x072B0181, 0x072C0182, 
-        0x072D0097, 0x072E0078, 0x07400071, 0x07410078, 0x07430071, 0x07440078, 0x07460071, 0x07470078, 
-        0x074A0071, 0x07540078, 0x07550071, 0x07580083, 0x07591071, 0x075A0083, 0x075E0071, 0x075F0078, 
-        0x07600071, 0x07620078, 0x07640083, 0x07670078, 0x0768017E, 0x0769017F, 0x076A0180, 0x076B0181, 
-        0x076C0182, 0x076D0078, 0x076E1071, 0x076F0078, 0x07800094, 0x07820097, 0x07890094, 0x078C0083, 
-        0x078D0094, 0x0790017E, 0x0791017F, 0x07920180, 0x07930181, 0x07940182, 0x079500B3, 0x079A0083, 
-        0x079D00BF, 0x079F00A7, 0x07A00071, 0x07A10871, 0x07A20071, 0x07A60871, 0x07A70071, 0x07AB0871, 
-        0x07AC0071, 0x07B40871, 0x07B50078, 0x07B80083, 0x07B90883, 0x07BB1083, 0x07BD0083, 0x07BF00A7, 
-        0x07C00883, 0x07C10083, 0x07C20097, 0x07C30083, 0x07C40071, 0x07C60078, 0x07C80083, 0x07C90883, 
-        0x07CA0083, 0x07CE0883, 0x07CF0083, 0x07D30883, 0x07D40083, 0x07DC0883, 0x07DD0083, 0x07DE0078, 
-        0x07DF0094, 0x07E60078, 0x07E70094, 0x07E80097, 0x07E90078, 0x08000071, 0x08150078, 0x08160083, 
-        0x081800A7, 0x08190078, 0x081B0083, 0x081D0078, 0x0820017E, 0x0821017F, 0x08220180, 0x08230181, 
-        0x08240182, 0x08250097, 0x08280071, 0x082B00A7, 0x082C0083, 0x082D0078, 0x085000B5, 0x08630078, 
-        0x08680071, 0x087D0097, 0x087E0078, 0x08800071, 0x08AD0078, 0x08AF0071, 0x08D10078, 0x08D40071, 
-        0x08FD0078, 0x09000071, 0x09240078, 0x09250071, 0x09270078, 0x09280071, 0x092B0078, 0x092D0071, 
-        0x092F0078, 0x09300071, 0x09440078, 0x09450071, 0x09470078, 0x09480071, 0x09580078, 0x09590071, 
-        0x095B0078, 0x095C0071, 0x095F0078, 0x09610071, 0x09630078, 0x09640071, 0x096B0078, 0x096C0071, 
-        0x09880078, 0x09890071, 0x098B0078, 0x098C0071, 0x09AD0078, 0x09AF0083, 0x09B00097, 0x09B400AD, 
-        0x09B500AE, 0x09B6012D, 0x09B7012E, 0x09B8012F, 0x09B90185, 0x09BA0186, 0x09BB0187, 0x09BC0188, 
-        0x09BD0184, 0x09BE0078, 0x09C00071, 0x09C80054, 0x09CD0078, 0x09D00071, 0x09FA0078, 0x0A000071, 
-        0x0B360097, 0x0B370071, 0x0B3B0078, 0x0B400071, 0x0B4D00B4, 0x0B4E0078, 0x0B500071, 0x0B750097, 
-        0x0B770189, 0x0B780078, 0x0B800071, 0x0B860078, 0x0B870071, 0x0B890083, 0x0B8A0078, 0x0B900071, 
-        0x0B990083, 0x0B9A0097, 0x0B9B0078, 0x0BA00071, 0x0BA90083, 0x0BAA0078, 0x0BB00071, 0x0BB60078, 
-        0x0BB70071, 0x0BB80078, 0x0BB90083, 0x0BBA0078, 0x0BC00071, 0x0BDA00C2, 0x0BDB0083, 0x0BDF00A7, 
-        0x0BE40083, 0x0BEA0097, 0x0BEB0081, 0x0BEC0097, 0x0BED0008, 0x0BEE0083, 0x0BEF0078, 0x0BF0017E, 
-        0x0BF1017F, 0x0BF20180, 0x0BF30181, 0x0BF40182, 0x0BF50078, 0x0BF80106, 0x0BF90107, 0x0BFA0108, 
-        0x0BFB0109, 0x0BFC010A, 0x0BFD0078, 0x0C000006, 0x0C050083, 0x0C070078, 0x0C08017E, 0x0C09017F, 
-        0x0C0A0180, 0x0C0B0181, 0x0C0C0182, 0x0C0D0078, 0x0C100071, 0x0C210081, 0x0C220071, 0x0C3C0078, 
-        0x0C400071, 0x0C540083, 0x0C550078, 0x0C800071, 0x0C8E0078, 0x0C900083, 0x0C9100A7, 0x0C930083, 
-        0x0C9400C8, 0x0C960078, 0x0C9800A7, 0x0C9C0083, 0x0C9E0078, 0x0CA20006, 0x0CA3017E, 0x0CA4017F, 
-        0x0CA50180, 0x0CA60181, 0x0CA70182, 0x0CA80071, 0x0CB70078, 0x0CB80071, 0x0CBA0078, 0x0CC00071, 
-        0x0CD50078, 0x0CD800A7, 0x0CE00071, 0x0CE400A7, 0x0CE50078, 0x0CE8017E, 0x0CE9017F, 0x0CEA0180, 
-        0x0CEB0181, 0x0CEC0182, 0x0CED0078, 0x0CEF0006, 0x0CF00054, 0x0D000071, 0x0D0B0083, 0x0D0C00A7, 
-        0x0D0E0078, 0x0D0F0097, 0x0D100078, 0x0E800055, 0x0E967881, 0x0E970081, 0x0E987881, 0x0E9D0081, 
-        0x0E9E7881, 0x0EB17055, 0x0EB50055, 0x0ECD7881, 0x0EE00083, 0x0EE20078, 0x0F000865, 0x0F4B0855, 
-        0x0F4D098A, 0x0F4E0078, 0x0F500865, 0x0F7D0078, 0x0F8008C9, 0x0F8408CA, 0x0F8808C9, 0x0F8B0078, 
-        0x0F8C08CA, 0x0F8F0078, 0x0F9008C9, 0x0F9408CA, 0x0F9808C9, 0x0F9C08CA, 0x0FA008C9, 0x0FA30078, 
-        0x0FA408CA, 0x0FA70078, 0x0FA808C9, 0x0FAC08CA, 0x0FB008C9, 0x0FB408CA, 0x0FB808CB, 0x0FB908CC, 
-        0x0FBB08CD, 0x0FBC08CE, 0x0FBD08CF, 0x0FBE08D0, 0x0FBF0078, 0x0FC008C9, 0x0FC408D1, 0x0FC808C9, 
-        0x0FCC08D1, 0x0FD008C9, 0x0FD408D1, 0x0FD808C9, 0x0FD9098B, 0x0FDA0078, 0x0FDB0855, 0x0FDC08CA, 
-        0x0FDD08D2, 0x0FDE1037, 0x0FE00837, 0x0FE1098B, 0x0FE20078, 0x0FE30855, 0x0FE408D5, 0x0FE60837, 
-        0x0FE808C9, 0x0FE90855, 0x0FEA0078, 0x0FEB0855, 0x0FEC08CA, 0x0FED08D6, 0x0FEE0837, 0x0FF008C9, 
-        0x0FF10855, 0x0FF20890, 0x0FF30855, 0x0FF408CA, 0x0FF508D7, 0x0FF60837, 0x0FF80078, 0x0FF9098B, 
-        0x0FFA0078, 0x0FFB0855, 0x0FFC08D9, 0x0FFD08DA, 0x0FFE0837, 0x0FFF0078, 0x10000805, 0x10011005, 
-        0x10035805, 0x10041005, 0x10050057, 0x1007018C, 0x10085899, 0x10090099, 0x100B1006, 0x100C018D, 
-        0x100D00DB, 0x100E018D, 0x100F00DB, 0x10100006, 0x10121006, 0x10130006, 0x1014018E, 0x1015018F, 
-        0x10160190, 0x10175853, 0x10180007, 0x10191007, 0x101A0006, 0x101B1006, 0x101C0126, 0x101D0006, 
-        0x101F0038, 0x10200006, 0x10220009, 0x10231006, 0x10250006, 0x102B1006, 0x102C0006, 0x102F1005, 
-        0x10300057, 0x10320078, 0x10350057, 0x10387855, 0x10390078, 0x103A7910, 0x103B7911, 0x103C7912, 
-        0x103D780B, 0x103E7809, 0x103F7855, 0x1040705D, 0x1041705B, 0x10427110, 0x10437111, 0x10447112, 
-        0x1045700B, 0x10467009, 0x10470078, 0x10487081, 0x104A0078, 0x10500008, 0x105B0078, 0x10680083, 
-        0x106E0095, 0x10700083, 0x10710095, 0x10720083, 0x10760078, 0x10801054, 0x10831077, 0x10841054, 
-        0x10852877, 0x10872855, 0x10882877, 0x10892855, 0x108A2877, 0x108B0054, 0x108C2877, 0x108F0054, 
-        0x10901054, 0x10910054, 0x10950991, 0x10962877, 0x10972855, 0x10982877, 0x109A1071, 0x109C2855, 
-        0x109D1054, 0x109E2855, 0x109F2877, 0x10A00019, 0x10A22877, 0x10A32855, 0x10A50019, 0x10A60078, 
-        0x10A9305F, 0x10AF3106, 0x10B01192, 0x10B11193, 0x10B21194, 0x10B31195, 0x10B41196, 0x10B51197, 
-        0x10B61198, 0x10B71199, 0x10B8119A, 0x10B9119B, 0x10BA119C, 0x10BB119D, 0x10BC119E, 0x10BD119F, 
-        0x10BE11A0, 0x10BF11A1, 0x10C001A2, 0x10C101A3, 0x10C20078, 0x10C80019, 0x10CA0054, 0x10CD0819, 
-        0x10CE0054, 0x10D10019, 0x10D20054, 0x10E60854, 0x10E70819, 0x10E80054, 0x10FA0019, 0x110000E8, 
-        0x11020019, 0x110408FB, 0x110500FC, 0x11070019, 0x110800E8, 0x11090059, 0x110A01A4, 0x110B0019, 
-        0x110D00E8, 0x11110019, 0x111500E8, 0x111610E8, 0x111800E8, 0x111A0019, 0x111C00E8, 0x111E00FE, 
-        0x111F00E8, 0x112008E8, 0x112101A5, 0x112200E8, 0x112308E8, 0x112500E8, 0x11260019, 0x112900FE, 
-        0x112B0019, 0x112F00E8, 0x11300019, 0x113200FE, 0x11360819, 0x113708FE, 0x113900FE, 0x113A08FE, 
-        0x113B00FE, 0x113C08FE, 0x113D00FE, 0x114008FE, 0x114100FE, 0x114208FE, 0x114300FE, 0x114408FE, 
-        0x114500FE, 0x11460019, 0x114700FD, 0x11490019, 0x115100FE, 0x11520019, 0x115300E8, 0x115401A6, 
-        0x115608E8, 0x115800FE, 0x115C0019, 0x115F00E8, 0x11600019, 0x116400FD, 0x116601A7, 0x11670019, 
-        0x116800FE, 0x11690019, 0x116B00FE, 0x117008FE, 0x117200FE, 0x117508FE, 0x11770019, 0x117800FE, 
-        0x11790102, 0x117A00E8, 0x117B0103, 0x117C00E8, 0x117D0104, 0x117E0105, 0x117F00E8, 0x11800054, 
-        0x118400FE, 0x11860054, 0x119000E8, 0x11910054, 0x11940809, 0x11950054, 0x119B0094, 0x11BD0054, 
-        0x11CA0094, 0x11CB0054, 0x11CD0019, 0x11DA00BF, 0x11DB0054, 0x11EE0078, 0x12000054, 0x12130078, 
-        0x12200054, 0x12250078, 0x123018C4, 0x123118C5, 0x123218C6, 0x123318C7, 0x1234191F, 0x1235191A, 
-        0x1236191B, 0x1237191C, 0x1238191D, 0x1239191E, 0x123A10C4, 0x123B10C5, 0x123C10C6, 0x123D10C7, 
-        0x123E111F, 0x123F111A, 0x1240111B, 0x1241111C, 0x1242111D, 0x1243111E, 0x1244105A, 0x124510E3, 
-        0x124610E4, 0x124710E5, 0x124811A8, 0x124911A9, 0x124A11AA, 0x124B11AB, 0x124C11AC, 0x124D11AD, 
-        0x124E1094, 0x125B1918, 0x12681919, 0x1275010B, 0x1276010C, 0x1277010D, 0x1278010E, 0x1279010F, 
-        0x127A0106, 0x127B0107, 0x127C0108, 0x127D0109, 0x127E010A, 0x127F00C3, 0x12800054, 0x12DB0019, 
-        0x12DC0054, 0x12E00019, 0x12E10054, 0x12FC0019, 0x13000054, 0x13370019, 0x13380054, 0x134E0078, 
-        0x13500054, 0x13590078, 0x13800054, 0x13820078, 0x13830054, 0x13850078, 0x13860054, 0x13A90078, 
-        0x13AC0054, 0x13AF0078, 0x13B00054, 0x13B4000A, 0x13BB00C4, 0x13BC00C5, 0x13BD00C6, 0x13BE00C7, 
-        0x13BF011F, 0x13C000C4, 0x13C100C5, 0x13C200C6, 0x13C300C7, 0x13C4011F, 0x13C500C4, 0x13C600C5, 
-        0x13C700C6, 0x13C800C7, 0x13C9011F, 0x13CA0078, 0x13CC0054, 0x13DF0078, 0x13E00019, 0x13E100FD, 
-        0x13E20009, 0x13E30078, 0x13E80019, 0x13E900E8, 0x13EA00FD, 0x13EB0019, 0x13EE00FD, 0x13EF0019, 
-        0x13F100FE, 0x13F3000A, 0x13F60078, 0x13F80019, 0x14000094, 0x14800019, 0x14C10009, 0x14C601AE, 
-        0x14C701AF, 0x14C80009, 0x14CC0019, 0x14CD00E8, 0x14D80019, 0x14E000FE, 0x14E100E8, 0x14E200FE, 
-        0x14E30019, 0x14E400E8, 0x14E50019, 0x14E700FD, 0x14E90019, 0x14EA00FE, 0x14EB0019, 0x14EC000A, 
-        0x14EE0019, 0x14F000E8, 0x14F30019, 0x14F400E8, 0x14F50019, 0x14FA01B0, 0x14FB00E8, 0x14FC00FE, 
-        0x14FD0019, 0x14FE000A, 0x14FF0019, 0x150500E8, 0x150E0019, 0x150F00E8, 0x15110019, 0x151400E8, 
-        0x151500FD, 0x15170019, 0x151A00FE, 0x151B0019, 0x151E00FE, 0x151F0019, 0x152B00E8, 0x152C0019, 
-        0x153200FE, 0x15330019, 0x153500E8, 0x15380019, 0x153900E8, 0x153A1019, 0x153B0019, 0x153C00FD, 
-        0x153D00E8, 0x153E00FD, 0x154200E8, 0x154500FD, 0x154600E8, 0x154800FD, 0x154E00E8, 0x155000FD, 
-        0x155100E8, 0x15520019, 0x155300FE, 0x155700FD, 0x155800E8, 0x155900FD, 0x155A00E8, 0x155D00FD, 
-        0x156300E8, 0x156600FD, 0x156B0019, 0x157101B1, 0x15730019, 0x157600FE, 0x15770019, 0x157900E8, 
-        0x157A0019, 0x157B00FD, 0x157D00E8, 0x157F0019, 0x15800054, 0x158A0078, 0x16000096, 0x16170078, 
-        0x16180098, 0x162F0078, 0x16400065, 0x16720054, 0x16750078, 0x167C0006, 0x167E005F, 0x167F0006, 
-        0x16800125, 0x16930078, 0x16980071, 0x16B30078, 0x16B77881, 0x16B80078, 0x16C00071, 0x16CB0078, 
-        0x16D00071, 0x16D30078, 0x16D40071, 0x16D70078, 0x16D80071, 0x16DB0078, 0x16DC0071, 0x16DF0078, 
-        0x16E00071, 0x16E30078, 0x16E40071, 0x16E70078, 0x16E80071, 0x16EB0078, 0x16EC0071, 0x16EF0078, 
-        0x17000006, 0x170100E0, 0x17030006, 0x17040126, 0x17050006, 0x170600E0, 0x17070006, 0x170B0099, 
-        0x170C0078, 0x170E00E0, 0x170F0078, 0x17400054, 0x174F1054, 0x17500054, 0x17791054, 0x177A0078, 
-        0x17801054, 0x17EB0078, 0x17F80054, 0x17FE0078, 0x18000006, 0x18020081, 0x180301B2, 0x1804000A, 
-        0x18090054, 0x180A000A, 0x180E00B4, 0x180F00BF, 0x181001B3, 0x181101B4, 0x181201B5, 0x181301B6, 
-        0x181401B7, 0x18150083, 0x18180081, 0x181B0054, 0x181C11B8, 0x181D0081, 0x181E0006, 0x181F0054, 
-        0x18200071, 0x18320871, 0x18350071, 0x18380871, 0x183A0071, 0x183B0871, 0x183D0071, 0x183E0871, 
-        0x183F0071, 0x184B0078, 0x184C0083, 0x184D1037, 0x184E0081, 0x184F8071, 0x18500071, 0x18620871, 
-        0x18650071, 0x18680871, 0x186A0071, 0x186B0871, 0x186D0071, 0x186E0871, 0x186F0071, 0x187B0871, 
-        0x187D0006, 0x187E0081, 0x187F8071, 0x18800078, 0x18820071, 0x18960078, 0x18981071, 0x18C70078, 
-        0x18C80094, 0x18C978B6, 0x18CA78B7, 0x18CB7894, 0x18D00071, 0x18DC0078, 0x18E00054, 0x18E80078, 
-        0x18F80071, 0x19001094, 0x190E1054, 0x190F0078, 0x191010B6, 0x191110B7, 0x191210B8, 0x191310B9, 
-        0x191410B0, 0x19151094, 0x19220078, 0x192819B9, 0x192919BA, 0x192A19BB, 0x192B19BC, 0x192C19BD, 
-        0x192D19BE, 0x192E19BF, 0x192F19C0, 0x19301894, 0x193E1854, 0x193F0094, 0x194018B6, 0x194118B7, 
-        0x194218B8, 0x194318B9, 0x194418B0, 0x19451894, 0x195819C1, 0x195919C2, 0x195A19C3, 0x195B19C4, 
-        0x195C19C5, 0x195D19C6, 0x195E19C7, 0x195F19C8, 0x19601094, 0x19666854, 0x19681894, 0x197F0078, 
-        0x19806894, 0x19AC1094, 0x19B86894, 0x19BB6854, 0x19BD6894, 0x19EF6854, 0x19F01094, 0x19FF6854, 
-        0x1A000071, 0x26DB0078, 0x26E00054, 0x27000071, 0x4FDE0078, 0x50000071, 0x500A0081, 0x500B0071, 
-        0x52460078, 0x52480054, 0x52630078, 0x53800037, 0x538B0078, 0x54000071, 0x54050083, 0x54060071, 
-        0x541100A7, 0x54120083, 0x541300A7, 0x54140054, 0x54160078, 0x56000071, 0x6BD20078, 0x6C00013E, 
-        0x7000013F, 0x7C800871, 0x7D070071, 0x7D0A0871, 0x7D0F0071, 0x7D120871, 0x7D130071, 0x7D150871, 
-        0x7D170078, 0x7D180871, 0x7D350078, 0x7D380871, 0x7D6D0078, 0x7D801055, 0x7D830078, 0x7D891055, 
-        0x7D8C0078, 0x7D8E089B, 0x7D90289B, 0x7D94280B, 0x7D95089B, 0x7D9B0078, 0x7D9C089B, 0x7D9E0078, 
-        0x7DA0089B, 0x7DA20078, 0x7DA3089B, 0x7DA7109B, 0x7DA8209E, 0x7DAA489E, 0x7DAB209E, 0x7DAC489E, 
-        0x7DAD209E, 0x7DAE489E, 0x7DAF209E, 0x7DB0489E, 0x7DB1209E, 0x7DB2489E, 0x7DB3209E, 0x7DB4489E, 
-        0x7DB5209E, 0x7DB6489E, 0x7DB7209E, 0x7DB8489E, 0x7DB9209E, 0x7DBA489E, 0x7DBB209E, 0x7DBC489E, 
-        0x7DBD209E, 0x7DBE489E, 0x7DBF209E, 0x7DC0489E, 0x7DC1209E, 0x7DC8489E, 0x7DC9209E, 0x7DCA489E, 
-        0x7DCB209E, 0x7DCC489E, 0x7DCD209E, 0x7DCE489E, 0x7DCF209E, 0x7DD1489E, 0x7DD2209E, 0x7DD4489E, 
-        0x7DD5209E, 0x7DD6489E, 0x7DD7209E, 0x7DD90078, 0x7DE9409E, 0x7DEA389E, 0x7DEB409E, 0x7DEF209E, 
-        0x7DF3489E, 0x7DF5209E, 0x7DFC409E, 0x7DFD389E, 0x7DFE209E, 0x7DFF489E, 0x7E00409E, 0x7E32209E, 
-        0x7E4B389E, 0x7E6F489E, 0x7E7A409E, 0x7E88209E, 0x7E96389E, 0x7E9A489E, 0x7E9E409E, 0x7E9F00BF, 
-        0x7EA00078, 0x7EA8209E, 0x7EA9389E, 0x7EAD209E, 0x7EAE389E, 0x7EAF209E, 0x7EB0389E, 0x7EB3209E, 
-        0x7EB5389E, 0x7EB7209E, 0x7EB9389E, 0x7EBA209E, 0x7EBB389E, 0x7EBC209E, 0x7EBE389E, 0x7EBF209E, 
-        0x7EC1389E, 0x7EC2209E, 0x7EC4389E, 0x7EC5209E, 0x7EC6389E, 0x7EC80078, 0x7EC9389E, 0x7ECB209E, 
-        0x7ECE389E, 0x7ECF209E, 0x7EDA389E, 0x7EDB209E, 0x7EE1389E, 0x7EE3209E, 0x7EE40078, 0x7EF8409E, 
-        0x7EFE0054, 0x7EFF0078, 0x7F000083, 0x7F088006, 0x7F0B80B4, 0x7F0C8006, 0x7F0D0078, 0x7F100083, 
-        0x7F120078, 0x7F188099, 0x7F198038, 0x7F1A80B4, 0x7F220006, 0x7F2380B4, 0x7F241006, 0x7F261038, 
-        0x7F286006, 0x7F290078, 0x7F2A600C, 0x7F2B6006, 0x7F2C60B4, 0x7F2F6007, 0x7F306006, 0x7F31600D, 
-        0x7F326019, 0x7F330078, 0x7F346008, 0x7F356006, 0x7F360078, 0x7F38489E, 0x7F39009E, 0x7F3A0078, 
-        0x7F3B489E, 0x7F40409E, 0x7F45389E, 0x7F46409E, 0x7F48389E, 0x7F49409E, 0x7F4B389E, 0x7F4C409E, 
-        0x7F4D389E, 0x7F4E409E, 0x7F4F389E, 0x7F50409E, 0x7F51389E, 0x7F52409E, 0x7F53389E, 0x7F54409E, 
-        0x7F59389E, 0x7F5A409E, 0x7F5B389E, 0x7F5C409E, 0x7F5D389E, 0x7F5E409E, 0x7F5F389E, 0x7F60409E, 
-        0x7F61389E, 0x7F62409E, 0x7F63389E, 0x7F64409E, 0x7F65389E, 0x7F66409E, 0x7F67389E, 0x7F68409E, 
-        0x7F69389E, 0x7F6A409E, 0x7F6B389E, 0x7F6C409E, 0x7F6D389E, 0x7F6E409E, 0x7F6F389E, 0x7F70409E, 
-        0x7F71389E, 0x7F72409E, 0x7F73389E, 0x7F74409E, 0x7F75389E, 0x7F76409E, 0x7F79389E, 0x7F7A409E, 
-        0x7F7E0078, 0x7F7F0057, 0x7F808806, 0x7F818807, 0x7F838806, 0x7F84880A, 0x7F85880B, 0x7F86880D, 
-        0x7F87880C, 0x7F88880F, 0x7F898811, 0x7F8A8813, 0x7F8B8815, 0x7F8C8817, 0x7F8D8806, 0x7F8E8819, 
-        0x7F8F8806, 0x7F908860, 0x7F9D8835, 0x7F9E8836, 0x7F9F8838, 0x7FA08861, 0x7FAD8835, 0x7FAE8836, 
-        0x7FAF8809, 0x7FB05006, 0x7FB1500A, 0x7FB25006, 0x7FB35071, 0x7FCF5081, 0x7FD05071, 0x7FDF0078, 
-        0x7FE15071, 0x7FE40078, 0x7FE55071, 0x7FE80078, 0x7FE95071, 0x7FEC0078, 0x7FED5071, 0x7FEE0078, 
-        0x7FF08808, 0x7FF18837, 0x7FF28808, 0x7FF30078, 0x7FF45019, 0x7FF65054, 0x7FF70078, 0x7FFC0141, 
-        0x7FFE0054, 0x7FFF0078, 0x80000071, 0x80130078, 0x80140071, 0x801D0078, 0x801E0071, 0x80270078, 
-        0x80280071, 0x802F0078, 0x80400071, 0x807D0078, 0x80800006, 0x80810078, 0x808300AD, 0x808400AE, 
-        0x8085012D, 0x8086012E, 0x8087012F, 0x80880185, 0x80890186, 0x808A0187, 0x808B0188, 0x808C0184, 
-        0x808D01C9, 0x808E01CA, 0x808F01CB, 0x809001CC, 0x809101CD, 0x809201CE, 0x809301CF, 0x809401D0, 
-        0x809500BE, 0x809601D1, 0x809701D2, 0x809801D3, 0x809901D4, 0x809A0078, 0x809B0094, 0x80A0014E, 
-        0x80A10152, 0x80A20153, 0x80A30157, 0x80A40154, 0x80A50155, 0x80A60156, 0x80A70152, 0x80A80150, 
-        0x80A90153, 0x80AA01D5, 0x80AB0154, 0x80AC014F, 0x80AD0158, 0x80AF0152, 0x80B00154, 0x80B201D6, 
-        0x80B30150, 0x80B501D7, 0x80B60153, 0x80B80156, 0x80B90152, 0x80BA005F, 0x80BC0054, 0x80C50078, 
-        0x81800071, 0x818F0078, 0x8190012D, 0x819100BB, 0x81920078, 0x81980071, 0x81A50078, 0x81C00071, 
-        0x81CF0097, 0x81D00071, 0x81E20078, 0x81E40071, 0x81E8014F, 0x81E90154, 0x81EA0155, 0x81EB0078, 
-        0x8200015B, 0x8214015C, 0x82280071, 0x824F0078, 0x8250017E, 0x8251017F, 0x82520180, 0x82530181, 
-        0x82540182, 0x82550078, 0x8400009B, 0x84030078, 0x8405009B, 0x841C0078, 0x841F009B, 0x84200078, 
-        0x85000083, 0x85030078, 0x85060083, 0x8508009B, 0x851A0078, 0x851C0083, 0x851D0078, 0x851F0083, 
-        0x852001D8, 0x852101D9, 0x852201DA, 0x852301DB, 0x85240078, 0x8528009A, 0x852C0078, 0xE8000094, 
-        0xE87B0078, 0xE8800094, 0xE8930078, 0xE8950094, 0xE8AF0894, 0xE8B200A7, 0xE8B30083, 0xE8B50094, 
-        0xE8B600A7, 0xE8B90057, 0xE8BD0083, 0xE8C10094, 0xE8C20083, 0xE8C60094, 0xE8D50083, 0xE8D70094, 
-        0xE8DD0894, 0xE8E00094, 0xE8EF0078, 0xE9000054, 0xE9210083, 0xE9220054, 0xE9230078, 0xE9800054, 
-        0xE9AB0078, 0xEA002877, 0xEA0D2855, 0xEA1A2877, 0xEA272855, 0xEA2A0078, 0xEA2B2855, 0xEA342877, 
-        0xEA412855, 0xEA4E0078, 0xEA4F2877, 0xEA500078, 0xEA522877, 0xEA530078, 0xEA542877, 0xEA560078, 
-        0xEA572877, 0xEA5B2855, 0xEA682877, 0xEA752855, 0xEA822877, 0xEA850078, 0xEA862877, 0xEA8A0078, 
-        0xEA8B2877, 0xEA8E0078, 0xEA8F2855, 0xEA9C2877, 0xEA9F0078, 0xEAA02877, 0xEAA20078, 0xEAA52877, 
-        0xEAA80078, 0xEAA92855, 0xEAB62877, 0xEAC32855, 0xEAD02877, 0xEADD2855, 0xEAEA2877, 0xEAF72855, 
-        0xEB042877, 0xEB112855, 0xEB1E2877, 0xEB2B2855, 0xEB382877, 0xEB452855, 0xEB530078, 0xEB542877, 
-        0xEB6029DC, 0xEB612855, 0xEB6D29DC, 0xEB6E2855, 0xEB712877, 0xEB7D29DC, 0xEB7E2855, 0xEB8A29DC, 
-        0xEB8B2855, 0xEB8E2877, 0xEB9A29DC, 0xEB9B2855, 0xEBA729DC, 0xEBA82855, 0xEBAB2877, 0xEBB729DC, 
-        0xEBB82855, 0xEBC429DC, 0xEBC52855, 0xEBC82877, 0xEBD429DC, 0xEBD52855, 0xEBE129DC, 0xEBE22855, 
-        0xEBE50078, 0xEBE7280F, 0xEBE82811, 0xEBE92813, 0xEBEA2815, 0xEBEB2817, 0xEBEC280F, 0xEBED2811, 
-        0xEBEE2813, 0xEBEF2815, 0xEBF02817, 0xEBF1280F, 0xEBF22811, 0xEBF32813, 0xEBF42815, 0xEBF52817, 
-        0xEBF6280F, 0xEBF72811, 0xEBF82813, 0xEBF92815, 0xEBFA2817, 0xEBFB280F, 0xEBFC2811, 0xEBFD2813, 
-        0xEBFE2815, 0xEBFF2817, 0xEC000078
-    };
-
-    static const uint32_t a17[] = {
-        0x00000071, 0x536B0078, 0x7C000871, 0x7D0F0078
-    };
-
-    static const uint32_t a23[] = {
-        0x00000057, 0x00010078, 0x00100057, 0x00400078, 0x00800083, 0x00F80078, 0x8000013F, 0xFFFF0078
-    };
-
-    static const uint32_t a24[] = {
-        0x0000013F, 0x7FFF0078
-    };
-
-
-    // The full set of all arrays to be searched.
-    static const Range FULL_DATA[] = {
-        {sizeof(a0)/sizeof(uint32_t), a0},
-        {sizeof(a1)/sizeof(uint32_t), a1},
-        {0, 0},
-        {0, 0},
-        {0, 0},
-        {0, 0},
-        {0, 0},
-        {sizeof(a7)/sizeof(uint32_t), a7},
-        {sizeof(a8)/sizeof(uint32_t), a8},
-        {0, 0},
-        {0, 0},
-        {0, 0},
-        {0, 0},
-        {0, 0},
-        {0, 0},
-        {0, 0},
-        {sizeof(a16)/sizeof(uint32_t), a16},
-        {sizeof(a17)/sizeof(uint32_t), a17},
-        {0, 0},
-        {0, 0},
-        {0, 0},
-        {0, 0},
-        {0, 0},
-        {sizeof(a23)/sizeof(uint32_t), a23},
-        {sizeof(a24)/sizeof(uint32_t), a24},
-        {0, 0},
-        {0, 0},
-        {0, 0},
-        {0, 0},
-        {0, 0},
-        {0, 0},
-        {0, 0}
-    };
-
-    // Array of mirrored character differences
-    static const short MIRROR_DIFF[] = {
-            0,     1,    -1,     2,    -2,    16,   -16,     3, 
-           -3,  2016,   138,  1824,  2104,  2108,  2106,  -138, 
-            8,     7,    -8,    -7, -1824, -2016, -2104, -2106, 
-        -2108
-    };
-
-    // All possible packed data values, no duplicates
-    static const uint32_t PACKED_DATA[] = {
-        0x00000000, 0x0000012F, 0x0000016F, 0x0000014F, 0x0000018F, 0x0000018C, 0x000001B8, 0x000000B8, 
-        0x000000BA, 0x020005B5, 0x040005B6, 0x00000099, 0x000000F8, 0x00000094, 0x02000069, 0x04000069, 
-        0x06000069, 0x08000069, 0x0A000069, 0x0C000069, 0x0E000069, 0x10000069, 0x12000069, 0x14000069, 
-        0x060005B9, 0x000001B9, 0x080005B9, 0x16020001, 0x18020001, 0x1A020001, 0x1C020001, 0x1E020001, 
-        0x20020001, 0x22020001, 0x24020001, 0x26020001, 0x28020001, 0x2A020001, 0x2C020001, 0x2E020001, 
-        0x30020001, 0x32020001, 0x34020001, 0x36020001, 0x38020001, 0x3A020001, 0x3C020001, 0x3E020001, 
-        0x40020001, 0x42020001, 0x44020001, 0x46020001, 0x48020001, 0x060005B5, 0x080005B6, 0x000001BB, 
-        0x000001B7, 0x16000802, 0x18000802, 0x1A000802, 0x1C000802, 0x1E000802, 0x20000802, 0x22000802, 
-        0x24000802, 0x26000802, 0x28000802, 0x2A000802, 0x2C000802, 0x2E000802, 0x30000802, 0x32000802, 
-        0x34000802, 0x36000802, 0x38000802, 0x3A000802, 0x3C000802, 0x3E000802, 0x40000802, 0x42000802, 
-        0x44000802, 0x46000802, 0x48000802, 0x000000EC, 0x000001BC, 0x00000002, 0x0A0005BD, 0x00000130, 
-        0x000000BC, 0x000000B9, 0x0600006B, 0x0800006B, 0x00001002, 0x0400006B, 0x0C0005BE, 0x4A0001AB, 
-        0x00020001, 0x00000802, 0x00001802, 0x00040001, 0x00060001, 0x00002002, 0x00080001, 0x000C0001, 
-        0x000E0001, 0x00100001, 0x00140001, 0x00160001, 0x00180001, 0x00004002, 0x00004802, 0x00200001, 
-        0x00220001, 0x00000005, 0x00A60001, 0x01805802, 0x01042003, 0x00280001, 0x002C0001, 0x00000001, 
-        0x00000000, 0x00007002, 0x00007802, 0x00009802, 0x0000A802, 0x0000B802, 0x0000C002, 0x0000C802, 
-        0x0000D002, 0x00000004, 0x000001A4, 0x00000106, 0x00320001, 0x00340001, 0x00360001, 0x00380001, 
-        0x0000E002, 0x0000E802, 0x0000F002, 0x0000F802, 0x00010002, 0x00010802, 0x00012002, 0x00012802, 
-        0x00013802, 0x003A0001, 0x003E0001, 0x00013002, 0x0000001C, 0x00000107, 0x00400001, 0x00000018, 
-        0x00014802, 0x000001B4, 0x00000038, 0x00000025, 0x00000050, 0x00000058, 0x00000045, 0x00000044, 
-        0x020000C9, 0x060000C9, 0x0A0000C9, 0x0E0000C9, 0x120000C9, 0x000000D8, 0x0000005C, 0x00000008, 
-        0x02000009, 0x06000009, 0x0A000009, 0x0E000009, 0x12000009, 0x0400000B, 0x0800000B, 0x0000000B, 
-        0x1600000B, 0x4E00000B, 0x00000006, 0x4A00000B, 0x000001B5, 0x00420001, 0x0600000B, 0x0A00000B, 
-        0x0E00000B, 0x1200000B, 0x3E00000B, 0x5200000B, 0x5600000B, 0x5A00000B, 0x5C00000B, 0x000001B6, 
-        0x2400000A, 0x2800000A, 0x00000010, 0x020001AB, 0x060001AB, 0x0A0001AB, 0x0E0001AB, 0x120001AB, 
-        0x00000108, 0x00015802, 0x00440001, 0x00016002, 0x00016802, 0x00017002, 0x00017802, 0x00018002, 
-        0x00018802, 0x00440003, 0x00460001, 0x00480003, 0x00019802, 0x004A0001, 0x004C0001, 0x004E0001, 
-        0x003C0001, 0x00500001, 0x00520001, 0x000001BD, 0x0000018D, 0x000001D0, 0x00000250, 0x00000230, 
-        0x040005BE, 0x000000F9, 0x0200006B, 0x0A00006B, 0x0E00006B, 0x1200006B, 0x00540001, 0x00560001, 
-        0x000005B9, 0x045A000A, 0x085A000A, 0x0C5A000A, 0x105A000A, 0x145A000A, 0x185A000A, 0x525A000A, 
-        0x5E5A000A, 0x0401A00A, 0x0801A00A, 0x0C01A00A, 0x1001A00A, 0x1401A00A, 0x1801A00A, 0x5201A00A, 
-        0x5E01A00A, 0x4E00000A, 0x5C00000A, 0x0E0005B9, 0x100005B9, 0x020005B9, 0x040005B9, 0x160005B9, 
-        0x180005B9, 0x1A0005B9, 0x200005B9, 0x220005B9, 0x240005B9, 0x260005B9, 0x040001AB, 0x080001AB, 
-        0x0C0001AB, 0x100001AB, 0x140001AB, 0x180001AB, 0x1C0001AB, 0x200001AB, 0x240001AB, 0x280001AB, 
-        0x0C00006B, 0x1000006B, 0x1400006B, 0x1800006B, 0x1C00006B, 0x2000006B, 0x2400006B, 0x2800006B, 
-        0x005C001C, 0x0001A81C, 0x1A0001AB, 0x1E0001AB, 0x220001AB, 0x260001AB, 0x2A0001AB, 0x160001AB, 
-        0x020005B6, 0x100005B6, 0x280005B9, 0x2C0005B9, 0x300005B9, 0x0001B002, 0x020005BD, 0x0600000A, 
-        0x0A00000A, 0x0E00000A, 0x1200000A, 0x1600000A, 0x3E00000A, 0x0C00000B, 0x1000000B, 0x1400000B, 
-        0x2E0001AB, 0x320001AB, 0x360001AB, 0x3A0001AB, 0x3E0001AB, 0x420001AB, 0x460001AB, 0x640001AB, 
-        0x680001AB, 0x6A0001AB, 0x6E0001AB, 0x720001AB, 0x760001AB, 0x7A0001AB, 0x00000013, 0x00000012, 
-        0x0000005A, 0x000001B0, 0x7C00000B, 0x8000000B, 0x8200000B, 0x8600000B, 0x8C00000B, 0x6000000B, 
-        0x9200000B, 0x9600000B, 0x9800000B, 0x9C00000B, 0xA000000B, 0xA400000B, 0x4A0001AA, 0x040001AA, 
-        0x520001AA, 0x600001AA, 0x0C0001AA, 0x5E0001AA, 0x160001AA, 0x4C0001AA, 0x4E0001AA, 0x9E0001AA, 
-        0x060001AA, 0x8800000A, 0x2A0001AA, 0x005E0001, 0x0001B802, 0x0400002B, 0x0800002B, 0x1600002B, 
-        0x4C00002B, 0x00002802, 0x00003002, 0x000A0001, 0x00120001, 0x00003802, 0x001A0001, 0x001C0001, 
-        0x001E0001, 0x00240001, 0x00005002, 0x00006002, 0x002A0001, 0x002E0001, 0x00300001, 0x00006802, 
-        0x00008002, 0x00008802, 0x00009002, 0x0000A002, 0x0000B002, 0x0000D906, 0x00011002, 0x00011802, 
-        0x00014002, 0x040000C9, 0x080000C9, 0x0C0000C9, 0x100000C9, 0x140000C9, 0x04000009, 0x08000009, 
-        0x0C000009, 0x10000009, 0x14000009, 0x2200000B, 0x4C00000B, 0x2A00000B, 0x5000000B, 0x5400000B, 
-        0x5800000B, 0x2600000A, 0x00015002, 0x00019002, 0x00000030, 0x000001BE, 0x0000014E, 0x00000210, 
-        0x000001F0, 0x00580001, 0x065A000A, 0x0A5A000A, 0x0E5A000A, 0x125A000A, 0x165A000A, 0x1A5A000A, 
-        0x4C5A000A, 0x4E5A000A, 0x0601A00A, 0x0A01A00A, 0x0E01A00A, 0x1201A00A, 0x1601A00A, 0x1A01A00A, 
-        0x4C01A00A, 0x4E01A00A, 0x6000000A, 0x0000000A, 0x120005B9, 0x140005B9, 0x1C0005B9, 0x1E0005B9, 
-        0x1600006B, 0x1A00006B, 0x1E00006B, 0x2200006B, 0x2600006B, 0x2A00006B, 0x0E0005B5, 0x040005B5, 
-        0x2A0005B9, 0x2E0005B9, 0x0200000A, 0x0400000A, 0x0800000A, 0x0C00000A, 0x1000000A, 0x1400000A, 
-        0x2A00000A, 0x2C0001AB, 0x300001AB, 0x340001AB, 0x380001AB, 0x3C0001AB, 0x400001AB, 0x440001AB, 
-        0x480001AB, 0x620001AB, 0x660001AB, 0x500001AB, 0x6C0001AB, 0x700001AB, 0x740001AB, 0x780001AB, 
-        0x520001AB, 0x7E00000B, 0x5E00000B, 0x8400000B, 0x8800000B, 0x8A00000B, 0x8E00000B, 0x9000000B, 
-        0x9400000B, 0x9A00000B, 0x9E00000B, 0xA200000B, 0xA600000B, 0x5C0001AA, 0x3E0001AA, 0x7E0001AA, 
-        0x0600002B, 0x0A00002B, 0x2A00002B, 0x4E00002B, 0x00000019
-    };
-}
diff --git a/libs/utils/Unicode.cpp b/libs/utils/Unicode.cpp
deleted file mode 100644
index 65dbb4a..0000000
--- a/libs/utils/Unicode.cpp
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <utils/AndroidUnicode.h>
-#include "CharacterData.h"
-
-#define LOG_TAG "Unicode"
-#include <utils/Log.h>
-
-// ICU headers for using macros
-#include <unicode/utf16.h>
-
-#define MIN_RADIX 2
-#define MAX_RADIX 36
-
-#define TYPE_SHIFT 0
-#define TYPE_MASK ((1<<5)-1)
-
-#define DIRECTION_SHIFT (TYPE_SHIFT+5)
-#define DIRECTION_MASK ((1<<5)-1)
-
-#define MIRRORED_SHIFT (DIRECTION_SHIFT+5)
-#define MIRRORED_MASK ((1<<1)-1)
-
-#define TOUPPER_SHIFT (MIRRORED_SHIFT+1)
-#define TOUPPER_MASK ((1<<6)-1)
-
-#define TOLOWER_SHIFT (TOUPPER_SHIFT+6)
-#define TOLOWER_MASK ((1<<6)-1)
-
-#define TOTITLE_SHIFT (TOLOWER_SHIFT+6)
-#define TOTITLE_MASK ((1<<2)-1)
-
-#define MIRROR_SHIFT (TOTITLE_SHIFT+2)
-#define MIRROR_MASK ((1<<5)-1)
-
-#define NUMERIC_SHIFT (TOTITLE_SHIFT+2)
-#define NUMERIC_MASK ((1<<7)-1)
-
-#define DECOMPOSITION_SHIFT (11)
-#define DECOMPOSITION_MASK ((1<<5)-1)
-
-/*
- * Returns the value stored in the CharacterData tables that contains
- * an index into the packed data table and the decomposition type.
- */
-static uint16_t findCharacterValue(UChar32 c)
-{
-    LOG_ASSERT(c >= 0 && c <= 0x10FFFF, "findCharacterValue received an invalid codepoint");
-    if (c < 256)
-        return CharacterData::LATIN1_DATA[c];
-
-    // Rotate the bits because the tables are separated into even and odd codepoints
-    c = (c >> 1) | ((c & 1) << 20);
-
-    CharacterData::Range search = CharacterData::FULL_DATA[c >> 16];
-    const uint32_t* array = search.array;
- 
-    // This trick is so that that compare in the while loop does not
-    // need to shift the array entry down by 16
-    c <<= 16;
-    c |= 0xFFFF;
-
-    int high = (int)search.length - 1;
-    int low = 0;
-
-    if (high < 0)
-        return 0;
-    
-    while (low < high - 1)
-    {
-        int probe = (high + low) >> 1;
-
-        // The entries contain the codepoint in the high 16 bits and the index
-        // into PACKED_DATA in the low 16.
-        if (array[probe] > (unsigned)c)
-            high = probe;
-        else
-            low = probe;
-    }
-
-    LOG_ASSERT((array[low] <= (unsigned)c), "A suitable range was not found");
-    return array[low] & 0xFFFF;
-}
-
-uint32_t android::Unicode::getPackedData(UChar32 c)
-{
-    // findCharacterValue returns a 16-bit value with the top 5 bits containing a decomposition type
-    // and the remaining bits containing an index.
-    return CharacterData::PACKED_DATA[findCharacterValue(c) & 0x7FF];
-}
-
-android::Unicode::Direction android::Unicode::getDirectionality(UChar32 c)
-{
-    uint32_t data = getPackedData(c);
-
-    if (0 == data)
-        return DIRECTIONALITY_UNDEFINED;
-
-    Direction d = (Direction) ((data >> DIRECTION_SHIFT) & DIRECTION_MASK);
-
-    if (DIRECTION_MASK == d)
-        return DIRECTIONALITY_UNDEFINED;
-    
-    return d;
-}
-
-bool android::Unicode::isMirrored(UChar32 c)
-{
-    return ((getPackedData(c) >> MIRRORED_SHIFT) & MIRRORED_MASK) != 0;
-}
-
-UChar32 android::Unicode::toMirror(UChar32 c)
-{
-    if (!isMirrored(c))
-        return c;
-
-    return c + CharacterData::MIRROR_DIFF[(getPackedData(c) >> MIRROR_SHIFT) & MIRROR_MASK];
-}
diff --git a/media/java/android/media/DecoderCapabilities.java b/media/java/android/media/DecoderCapabilities.java
new file mode 100644
index 0000000..f16cccf
--- /dev/null
+++ b/media/java/android/media/DecoderCapabilities.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media;
+
+import java.util.List;
+import java.util.ArrayList;
+
+/**
+ * {@hide}
+ *
+ * The DecoderCapabilities class is used to retrieve the types of the
+ * video and audio decoder(s) supported on a specific Android platform.
+ */
+public class DecoderCapabilities
+{
+    /**
+     * The VideoDecoder class represents the type of a video decoder
+     *
+     */
+    public enum VideoDecoder {
+        VIDEO_DECODER_WMV,
+    };
+
+    /**
+     * The AudioDecoder class represents the type of an audio decoder
+     */
+    public enum AudioDecoder {
+        AUDIO_DECODER_WMA,
+    };
+
+    static {
+        System.loadLibrary("media_jni");
+        native_init();
+    }
+
+    /**
+     * Returns the list of video decoder types
+     * @see android.media.DecoderCapabilities.VideoDecoder
+     */
+    public static List<VideoDecoder> getVideoDecoders() {
+        List<VideoDecoder> decoderList = new ArrayList<VideoDecoder>();
+        int nDecoders = native_get_num_video_decoders();
+        for (int i = 0; i < nDecoders; ++i) {
+            decoderList.add(VideoDecoder.values()[native_get_video_decoder_type(i)]);
+        }
+        return decoderList;
+    }
+
+    /**
+     * Returns the list of audio decoder types
+     * @see android.media.DecoderCapabilities.AudioDecoder
+     */
+    public static List<AudioDecoder> getAudioDecoders() {
+        List<AudioDecoder> decoderList = new ArrayList<AudioDecoder>();
+        int nDecoders = native_get_num_audio_decoders();
+        for (int i = 0; i < nDecoders; ++i) {
+            decoderList.add(AudioDecoder.values()[native_get_audio_decoder_type(i)]);
+        }
+        return decoderList;
+    }
+
+    private DecoderCapabilities() {}  // Don't call me
+
+    // Implemented by JNI
+    private static native final void native_init();
+    private static native final int native_get_num_video_decoders();
+    private static native final int native_get_video_decoder_type(int index);
+    private static native final int native_get_num_audio_decoders();
+    private static native final int native_get_audio_decoder_type(int index);
+}
diff --git a/media/jni/android_media_MediaProfiles.cpp b/media/jni/android_media_MediaProfiles.cpp
index 50380c1..19132c5 100644
--- a/media/jni/android_media_MediaProfiles.cpp
+++ b/media/jni/android_media_MediaProfiles.cpp
@@ -44,14 +44,14 @@
     }
 }
 
-static int
+static jint
 android_media_MediaProfiles_native_get_num_file_formats(JNIEnv *env, jobject thiz)
 {
     LOGV("native_get_num_file_formats");
     return sProfiles->getOutputFileFormats().size();
 }
 
-static int
+static jint
 android_media_MediaProfiles_native_get_file_format(JNIEnv *env, jobject thiz, jint index)
 {
     LOGV("native_get_file_format: %d", index);
@@ -61,11 +61,10 @@
         jniThrowException(env, "java/lang/IllegalArgumentException", "out of array boundary");
         return -1;
     }
-    int format = static_cast<int>(formats[index]);
-    return format;
+    return static_cast<jint>(formats[index]);
 }
 
-static int
+static jint
 android_media_MediaProfiles_native_get_num_video_encoders(JNIEnv *env, jobject thiz)
 {
     LOGV("native_get_num_video_encoders");
@@ -116,7 +115,7 @@
     return cap;
 }
 
-static int
+static jint
 android_media_MediaProfiles_native_get_num_audio_encoders(JNIEnv *env, jobject thiz)
 {
     LOGV("native_get_num_audio_encoders");
@@ -209,6 +208,48 @@
                           audioChannels);
 }
 
+static jint
+android_media_MediaProfiles_native_get_num_video_decoders(JNIEnv *env, jobject thiz)
+{
+    LOGV("native_get_num_video_decoders");
+    return sProfiles->getVideoDecoders().size();
+}
+
+static jint
+android_media_MediaProfiles_native_get_video_decoder_type(JNIEnv *env, jobject thiz, jint index)
+{
+    LOGV("native_get_video_decoder_type: %d", index);
+    Vector<video_decoder> decoders = sProfiles->getVideoDecoders();
+    int nSize = decoders.size();
+    if (index < 0 || index >= nSize) {
+        jniThrowException(env, "java/lang/IllegalArgumentException", "out of array boundary");
+        return -1;
+    }
+
+    return static_cast<jint>(decoders[index]);
+}
+
+static jint
+android_media_MediaProfiles_native_get_num_audio_decoders(JNIEnv *env, jobject thiz)
+{
+    LOGV("native_get_num_audio_decoders");
+    return sProfiles->getAudioDecoders().size();
+}
+
+static jint
+android_media_MediaProfiles_native_get_audio_decoder_type(JNIEnv *env, jobject thiz, jint index)
+{
+    LOGV("native_get_audio_decoder_type: %d", index);
+    Vector<audio_decoder> decoders = sProfiles->getAudioDecoders();
+    int nSize = decoders.size();
+    if (index < 0 || index >= nSize) {
+        jniThrowException(env, "java/lang/IllegalArgumentException", "out of array boundary");
+        return -1;
+    }
+
+    return static_cast<jint>(decoders[index]);
+}
+
 static JNINativeMethod gMethodsForEncoderCapabilitiesClass[] = {
     {"native_init",                            "()V",                    (void *)android_media_MediaProfiles_native_init},
     {"native_get_num_file_formats",            "()I",                    (void *)android_media_MediaProfiles_native_get_num_file_formats},
@@ -229,7 +270,16 @@
                                                                          (void *)android_media_MediaProfiles_native_get_camcorder_profile},
 };
 
+static JNINativeMethod gMethodsForDecoderCapabilitiesClass[] = {
+    {"native_init",                            "()V",                    (void *)android_media_MediaProfiles_native_init},
+    {"native_get_num_video_decoders",          "()I",                    (void *)android_media_MediaProfiles_native_get_num_video_decoders},
+    {"native_get_num_audio_decoders",          "()I",                    (void *)android_media_MediaProfiles_native_get_num_audio_decoders},
+    {"native_get_video_decoder_type",          "(I)I",                   (void *)android_media_MediaProfiles_native_get_video_decoder_type},
+    {"native_get_audio_decoder_type",          "(I)I",                   (void *)android_media_MediaProfiles_native_get_audio_decoder_type},
+};
+
 static const char* const kEncoderCapabilitiesClassPathName = "android/media/EncoderCapabilities";
+static const char* const kDecoderCapabilitiesClassPathName = "android/media/DecoderCapabilities";
 static const char* const kCamcorderProfileClassPathName = "android/media/CamcorderProfile";
 
 // This function only registers the native methods, and is called from
@@ -246,6 +296,11 @@
                gMethodsForCamcorderProfileClass,
                NELEM(gMethodsForCamcorderProfileClass));
 
-    // Success if ret1 == 0 && ret2 == 0
-    return (ret1 || ret2);
+    int ret3 = AndroidRuntime::registerNativeMethods(env,
+               kDecoderCapabilitiesClassPathName,
+               gMethodsForDecoderCapabilitiesClass,
+               NELEM(gMethodsForDecoderCapabilitiesClass));
+
+    // Success if ret1 == 0 && ret2 == 0 && ret3 == 0
+    return (ret1 || ret2 || ret3);
 }
diff --git a/media/libmediaplayerservice/Android.mk b/media/libmediaplayerservice/Android.mk
index a9a0fde..cf97b23 100644
--- a/media/libmediaplayerservice/Android.mk
+++ b/media/libmediaplayerservice/Android.mk
@@ -59,15 +59,8 @@
 	$(JNI_H_INCLUDE)                                                \
 	$(call include-path-for, graphics corecg)                       \
 	$(TOP)/external/opencore/extern_libs_v2/khronos/openmax/include \
-	$(TOP)/frameworks/base/media/libstagefright/include
-
-ifeq ($(TARGET_ARCH),arm)
-    LOCAL_C_INCLUDES += \
+	$(TOP)/frameworks/base/media/libstagefright/include             \
         $(TOP)/external/tremolo/Tremolo
-else
-    LOCAL_C_INCLUDES += \
-        $(TOP)/external/tremor/Tremor
-endif
 
 LOCAL_MODULE:= libmediaplayerservice
 
diff --git a/media/libstagefright/AMRExtractor.cpp b/media/libstagefright/AMRExtractor.cpp
index 3193d5e..2a16d26 100644
--- a/media/libstagefright/AMRExtractor.cpp
+++ b/media/libstagefright/AMRExtractor.cpp
@@ -225,27 +225,32 @@
         return ERROR_IO;
     }
 
-    MediaBuffer *buffer;
-    status_t err = mGroup->acquire_buffer(&buffer);
-    if (err != OK) {
-        return err;
-    }
-
     if (header & 0x83) {
         // Padding bits must be 0.
 
+        LOGE("padding bits must be 0, header is 0x%02x", header);
+
         return ERROR_MALFORMED;
     }
 
     unsigned FT = (header >> 3) & 0x0f;
 
     if (FT > 8 || (!mIsWide && FT > 7)) {
+
+        LOGE("illegal AMR frame type %d", FT);
+
         return ERROR_MALFORMED;
     }
 
     size_t frameSize = getFrameSize(mIsWide, FT);
     CHECK_EQ(frameSize, mFrameSize);
 
+    MediaBuffer *buffer;
+    status_t err = mGroup->acquire_buffer(&buffer);
+    if (err != OK) {
+        return err;
+    }
+
     n = mDataSource->readAt(mOffset, buffer->data(), frameSize);
 
     if (n != (ssize_t)frameSize) {
diff --git a/media/libstagefright/Android.mk b/media/libstagefright/Android.mk
index 1db398e..071bb9e 100644
--- a/media/libstagefright/Android.mk
+++ b/media/libstagefright/Android.mk
@@ -48,15 +48,8 @@
 LOCAL_C_INCLUDES:= \
 	$(JNI_H_INCLUDE) \
         $(TOP)/external/opencore/extern_libs_v2/khronos/openmax/include \
-        $(TOP)/external/opencore/android
-
-ifeq ($(TARGET_ARCH),arm)
-    LOCAL_C_INCLUDES += \
+        $(TOP)/external/opencore/android \
         $(TOP)/external/tremolo/Tremolo
-else
-    LOCAL_C_INCLUDES += \
-        $(TOP)/external/tremor/Tremor
-endif
 
 LOCAL_SHARED_LIBRARIES := \
         libbinder         \
diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp
index 41e6911..1c9f4fd 100644
--- a/media/libstagefright/AwesomePlayer.cpp
+++ b/media/libstagefright/AwesomePlayer.cpp
@@ -84,6 +84,7 @@
 
 struct AwesomeLocalRenderer : public AwesomeRenderer {
     AwesomeLocalRenderer(
+            bool previewOnly,
             const char *componentName,
             OMX_COLOR_FORMATTYPE colorFormat,
             const sp<ISurface> &surface,
@@ -91,15 +92,18 @@
             size_t decodedWidth, size_t decodedHeight)
         : mTarget(NULL),
           mLibHandle(NULL) {
-            init(componentName,
+            init(previewOnly, componentName,
                  colorFormat, surface, displayWidth,
                  displayHeight, decodedWidth, decodedHeight);
     }
 
     virtual void render(MediaBuffer *buffer) {
-        mTarget->render(
-                (const uint8_t *)buffer->data() + buffer->range_offset(),
-                buffer->range_length(), NULL);
+        render((const uint8_t *)buffer->data() + buffer->range_offset(),
+               buffer->range_length());
+    }
+
+    void render(const void *data, size_t size) {
+        mTarget->render(data, size, NULL);
     }
 
 protected:
@@ -118,6 +122,7 @@
     void *mLibHandle;
 
     void init(
+            bool previewOnly,
             const char *componentName,
             OMX_COLOR_FORMATTYPE colorFormat,
             const sp<ISurface> &surface,
@@ -129,31 +134,39 @@
 };
 
 void AwesomeLocalRenderer::init(
+        bool previewOnly,
         const char *componentName,
         OMX_COLOR_FORMATTYPE colorFormat,
         const sp<ISurface> &surface,
         size_t displayWidth, size_t displayHeight,
         size_t decodedWidth, size_t decodedHeight) {
-    mLibHandle = dlopen("libstagefrighthw.so", RTLD_NOW);
+    if (!previewOnly) {
+        // We will stick to the vanilla software-color-converting renderer
+        // for "previewOnly" mode, to avoid unneccessarily switching overlays
+        // more often than necessary.
 
-    if (mLibHandle) {
-        typedef VideoRenderer *(*CreateRendererFunc)(
-                const sp<ISurface> &surface,
-                const char *componentName,
-                OMX_COLOR_FORMATTYPE colorFormat,
-                size_t displayWidth, size_t displayHeight,
-                size_t decodedWidth, size_t decodedHeight);
+        mLibHandle = dlopen("libstagefrighthw.so", RTLD_NOW);
 
-        CreateRendererFunc func =
-            (CreateRendererFunc)dlsym(
-                    mLibHandle,
-                    "_Z14createRendererRKN7android2spINS_8ISurfaceEEEPKc20"
-                    "OMX_COLOR_FORMATTYPEjjjj");
+        if (mLibHandle) {
+            typedef VideoRenderer *(*CreateRendererFunc)(
+                    const sp<ISurface> &surface,
+                    const char *componentName,
+                    OMX_COLOR_FORMATTYPE colorFormat,
+                    size_t displayWidth, size_t displayHeight,
+                    size_t decodedWidth, size_t decodedHeight);
 
-        if (func) {
-            mTarget =
-                (*func)(surface, componentName, colorFormat,
-                    displayWidth, displayHeight, decodedWidth, decodedHeight);
+            CreateRendererFunc func =
+                (CreateRendererFunc)dlsym(
+                        mLibHandle,
+                        "_Z14createRendererRKN7android2spINS_8ISurfaceEEEPKc20"
+                        "OMX_COLOR_FORMATTYPEjjjj");
+
+            if (func) {
+                mTarget =
+                    (*func)(surface, componentName, colorFormat,
+                        displayWidth, displayHeight,
+                        decodedWidth, decodedHeight);
+            }
         }
     }
 
@@ -166,6 +179,7 @@
 
 AwesomePlayer::AwesomePlayer()
     : mTimeSource(NULL),
+      mVideoRendererIsPreview(false),
       mAudioPlayer(NULL),
       mFlags(0),
       mLastVideoBuffer(NULL),
@@ -532,6 +546,7 @@
             // Other decoders are instantiated locally and as a consequence
             // allocate their buffers in local address space.
             mVideoRenderer = new AwesomeLocalRenderer(
+                false,  // previewOnly
                 component,
                 (OMX_COLOR_FORMATTYPE)format,
                 mISurface,
@@ -765,6 +780,7 @@
                     LOGV("VideoSource signalled format change.");
 
                     if (mVideoRenderer != NULL) {
+                        mVideoRendererIsPreview = false;
                         initRenderer_l();
                     }
                     continue;
@@ -843,7 +859,9 @@
         return;
     }
 
-    if (mVideoRenderer == NULL) {
+    if (mVideoRendererIsPreview || mVideoRenderer == NULL) {
+        mVideoRendererIsPreview = false;
+
         initRenderer_l();
     }
 
@@ -1062,6 +1080,26 @@
     state->mFlags = mFlags & (PLAYING | LOOPING);
     getPosition_l(&state->mPositionUs);
 
+    if (mLastVideoBuffer) {
+        size_t size = mLastVideoBuffer->range_length();
+        if (size) {
+            state->mLastVideoFrameSize = size;
+            state->mLastVideoFrame = malloc(size);
+            memcpy(state->mLastVideoFrame,
+                   (const uint8_t *)mLastVideoBuffer->data()
+                        + mLastVideoBuffer->range_offset(),
+                   size);
+
+            state->mVideoWidth = mVideoWidth;
+            state->mVideoHeight = mVideoHeight;
+
+            sp<MetaData> meta = mVideoSource->getFormat();
+            CHECK(meta->findInt32(kKeyColorFormat, &state->mColorFormat));
+            CHECK(meta->findInt32(kKeyWidth, &state->mDecodedWidth));
+            CHECK(meta->findInt32(kKeyHeight, &state->mDecodedHeight));
+        }
+    }
+
     reset_l();
 
     mSuspensionState = state;
@@ -1102,6 +1140,24 @@
 
     mFlags = state->mFlags & LOOPING;
 
+    if (state->mLastVideoFrame && mISurface != NULL) {
+        mVideoRenderer =
+            new AwesomeLocalRenderer(
+                    true,  // previewOnly
+                    "",
+                    (OMX_COLOR_FORMATTYPE)state->mColorFormat,
+                    mISurface,
+                    state->mVideoWidth,
+                    state->mVideoHeight,
+                    state->mDecodedWidth,
+                    state->mDecodedHeight);
+
+        mVideoRendererIsPreview = true;
+
+        ((AwesomeLocalRenderer *)mVideoRenderer.get())->render(
+                state->mLastVideoFrame, state->mLastVideoFrameSize);
+    }
+
     if (state->mFlags & PLAYING) {
         play_l();
     }
diff --git a/media/libstagefright/include/AwesomePlayer.h b/media/libstagefright/include/AwesomePlayer.h
index ee2aca0..114d4c6 100644
--- a/media/libstagefright/include/AwesomePlayer.h
+++ b/media/libstagefright/include/AwesomePlayer.h
@@ -21,6 +21,7 @@
 #include "TimedEventQueue.h"
 
 #include <media/MediaPlayerInterface.h>
+#include <media/stagefright/DataSource.h>
 #include <media/stagefright/OMXClient.h>
 #include <utils/threads.h>
 
@@ -111,6 +112,7 @@
 
     sp<MediaSource> mVideoSource;
     sp<AwesomeRenderer> mVideoRenderer;
+    bool mVideoRendererIsPreview;
 
     sp<MediaSource> mAudioSource;
     AudioPlayer *mAudioPlayer;
@@ -162,6 +164,22 @@
         uint32_t mFlags;
         int64_t mPositionUs;
 
+        void *mLastVideoFrame;
+        size_t mLastVideoFrameSize;
+        int32_t mColorFormat;
+        int32_t mVideoWidth, mVideoHeight;
+        int32_t mDecodedWidth, mDecodedHeight;
+
+        SuspensionState()
+            : mLastVideoFrame(NULL) {
+        }
+
+        ~SuspensionState() {
+            if (mLastVideoFrame) {
+                free(mLastVideoFrame);
+                mLastVideoFrame = NULL;
+            }
+        }
     } *mSuspensionState;
 
     status_t setDataSource_l(
diff --git a/mms-common/java/com/android/mmscommon/mms/pdu/Base64.java b/mms-common/java/com/android/mmscommon/mms/pdu/Base64.java
deleted file mode 100644
index 4c95dec..0000000
--- a/mms-common/java/com/android/mmscommon/mms/pdu/Base64.java
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * Copyright (C) 2007 Esmertec AG.
- * 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.
- */
-
-package com.android.mmscommon.mms.pdu;
-
-public class Base64 {
-    /**
-     * Used to get the number of Quadruples.
-     */
-    static final int FOURBYTE = 4;
-
-    /**
-     * Byte used to pad output.
-     */
-    static final byte PAD = (byte) '=';
-
-    /**
-     * The base length.
-     */
-    static final int BASELENGTH = 255;
-
-    // Create arrays to hold the base64 characters
-    private static byte[] base64Alphabet = new byte[BASELENGTH];
-
-    // Populating the character arrays
-    static {
-        for (int i = 0; i < BASELENGTH; i++) {
-            base64Alphabet[i] = (byte) -1;
-        }
-        for (int i = 'Z'; i >= 'A'; i--) {
-            base64Alphabet[i] = (byte) (i - 'A');
-        }
-        for (int i = 'z'; i >= 'a'; i--) {
-            base64Alphabet[i] = (byte) (i - 'a' + 26);
-        }
-        for (int i = '9'; i >= '0'; i--) {
-            base64Alphabet[i] = (byte) (i - '0' + 52);
-        }
-
-        base64Alphabet['+'] = 62;
-        base64Alphabet['/'] = 63;
-    }
-
-    /**
-     * Decodes Base64 data into octects
-     *
-     * @param base64Data Byte array containing Base64 data
-     * @return Array containing decoded data.
-     */
-    public static byte[] decodeBase64(byte[] base64Data) {
-        // RFC 2045 requires that we discard ALL non-Base64 characters
-        base64Data = discardNonBase64(base64Data);
-
-        // handle the edge case, so we don't have to worry about it later
-        if (base64Data.length == 0) {
-            return new byte[0];
-        }
-
-        int numberQuadruple = base64Data.length / FOURBYTE;
-        byte decodedData[] = null;
-        byte b1 = 0, b2 = 0, b3 = 0, b4 = 0, marker0 = 0, marker1 = 0;
-
-        // Throw away anything not in base64Data
-
-        int encodedIndex = 0;
-        int dataIndex = 0;
-        {
-            // this sizes the output array properly - rlw
-            int lastData = base64Data.length;
-            // ignore the '=' padding
-            while (base64Data[lastData - 1] == PAD) {
-                if (--lastData == 0) {
-                    return new byte[0];
-                }
-            }
-            decodedData = new byte[lastData - numberQuadruple];
-        }
-
-        for (int i = 0; i < numberQuadruple; i++) {
-            dataIndex = i * 4;
-            marker0 = base64Data[dataIndex + 2];
-            marker1 = base64Data[dataIndex + 3];
-
-            b1 = base64Alphabet[base64Data[dataIndex]];
-            b2 = base64Alphabet[base64Data[dataIndex + 1]];
-
-            if (marker0 != PAD && marker1 != PAD) {
-                //No PAD e.g 3cQl
-                b3 = base64Alphabet[marker0];
-                b4 = base64Alphabet[marker1];
-
-                decodedData[encodedIndex] = (byte) (b1 << 2 | b2 >> 4);
-                decodedData[encodedIndex + 1] =
-                    (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));
-                decodedData[encodedIndex + 2] = (byte) (b3 << 6 | b4);
-            } else if (marker0 == PAD) {
-                //Two PAD e.g. 3c[Pad][Pad]
-                decodedData[encodedIndex] = (byte) (b1 << 2 | b2 >> 4);
-            } else if (marker1 == PAD) {
-                //One PAD e.g. 3cQ[Pad]
-                b3 = base64Alphabet[marker0];
-
-                decodedData[encodedIndex] = (byte) (b1 << 2 | b2 >> 4);
-                decodedData[encodedIndex + 1] =
-                    (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));
-            }
-            encodedIndex += 3;
-        }
-        return decodedData;
-    }
-
-    /**
-     * Check octect wheter it is a base64 encoding.
-     *
-     * @param octect to be checked byte
-     * @return ture if it is base64 encoding, false otherwise.
-     */
-    private static boolean isBase64(byte octect) {
-        if (octect == PAD) {
-            return true;
-        } else if (base64Alphabet[octect] == -1) {
-            return false;
-        } else {
-            return true;
-        }
-    }
-
-    /**
-     * Discards any characters outside of the base64 alphabet, per
-     * the requirements on page 25 of RFC 2045 - "Any characters
-     * outside of the base64 alphabet are to be ignored in base64
-     * encoded data."
-     *
-     * @param data The base-64 encoded data to groom
-     * @return The data, less non-base64 characters (see RFC 2045).
-     */
-    static byte[] discardNonBase64(byte[] data) {
-        byte groomedData[] = new byte[data.length];
-        int bytesCopied = 0;
-
-        for (int i = 0; i < data.length; i++) {
-            if (isBase64(data[i])) {
-                groomedData[bytesCopied++] = data[i];
-            }
-        }
-
-        byte packedData[] = new byte[bytesCopied];
-
-        System.arraycopy(groomedData, 0, packedData, 0, bytesCopied);
-
-        return packedData;
-    }
-}
diff --git a/mms-common/java/com/android/mmscommon/mms/pdu/PduParser.java b/mms-common/java/com/android/mmscommon/mms/pdu/PduParser.java
index 9253f83..6a58ba6 100644
--- a/mms-common/java/com/android/mmscommon/mms/pdu/PduParser.java
+++ b/mms-common/java/com/android/mmscommon/mms/pdu/PduParser.java
@@ -17,14 +17,15 @@
 
 package com.android.mmscommon.mms.pdu;
 
-import com.android.mmscommon.ContentType;
 import com.android.mmscommon.CharacterSets;
+import com.android.mmscommon.ContentType;
 import com.android.mmscommon.EncodedStringValue;
 import com.android.mmscommon.InvalidHeaderValueException;
 import com.android.mmscommon.PduHeaders;
 
 import android.util.Config;
 import android.util.Log;
+import android.util.base64.Base64;
 
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
@@ -790,7 +791,7 @@
                     String encoding = new String(partDataEncoding);
                     if (encoding.equalsIgnoreCase(PduPart.P_BASE64)) {
                         // Decode "base64" into "binary".
-                        partData = Base64.decodeBase64(partData);
+                        partData = Base64.decode(partData, Base64.DEFAULT);
                     } else if (encoding.equalsIgnoreCase(PduPart.P_QUOTED_PRINTABLE)) {
                         // Decode "quoted-printable" into "binary".
                         partData = QuotedPrintable.decodeQuotedPrintable(partData);
diff --git a/packages/DefaultContainerService/AndroidManifest.xml b/packages/DefaultContainerService/AndroidManifest.xml
index 5ec72df..078daa7 100755
--- a/packages/DefaultContainerService/AndroidManifest.xml
+++ b/packages/DefaultContainerService/AndroidManifest.xml
@@ -6,6 +6,7 @@
     <uses-permission android:name="android.permission.ASEC_DESTROY"/>
     <uses-permission android:name="android.permission.ASEC_MOUNT_UNMOUNT"/>
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+    <uses-permission android:name="android.permission.ACCESS_CACHE_FILESYSTEM" />
 
     <application android:label="@string/service_name">
 
diff --git a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
index c418ccb..8e030e5 100644
--- a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
+++ b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
@@ -1,10 +1,13 @@
 package com.android.defcontainer;
 
 import com.android.internal.app.IMediaContainerService;
-
+import com.android.internal.content.PackageHelper;
 import android.content.Intent;
 import android.content.pm.IPackageManager;
+import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
+import android.content.pm.PackageParser;
+import android.content.pm.PackageParser.Package;
 import android.net.Uri;
 import android.os.Debug;
 import android.os.Environment;
@@ -15,8 +18,10 @@
 import android.os.Process;
 import android.os.RemoteException;
 import android.os.ServiceManager;
+import android.os.StatFs;
 import android.app.IntentService;
 import android.app.Service;
+import android.util.DisplayMetrics;
 import android.util.Log;
 
 import java.io.File;
@@ -28,6 +33,7 @@
 import java.io.OutputStream;
 
 import android.os.FileUtils;
+import android.provider.Settings;
 
 /*
  * This service copies a downloaded apk to a file passed in as
@@ -79,6 +85,44 @@
             autoOut = new ParcelFileDescriptor.AutoCloseOutputStream(outStream);
             return copyFile(packageURI, autoOut);
         }
+
+        /*
+         * Determine the recommended install location for package
+         * specified by file uri location.
+         * @param fileUri the uri of resource to be copied. Should be a
+         * file uri
+         * @return Returns
+         *  PackageHelper.RECOMMEND_INSTALL_INTERNAL to install on internal storage
+         *  PackageHelper.RECOMMEND_INSTALL_EXTERNAL to install on external media
+         *  PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE for storage errors
+         *  PackageHelper.RECOMMEND_FAILED_INVALID_APK for parse errors.
+         */
+        public int getRecommendedInstallLocation(final Uri fileUri) {
+            if (!fileUri.getScheme().equals("file")) {
+                Log.w(TAG, "Falling back to installing on internal storage only");
+                return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
+            }
+            final String archiveFilePath = fileUri.getPath();
+            PackageParser packageParser = new PackageParser(archiveFilePath);
+            File sourceFile = new File(archiveFilePath);
+            DisplayMetrics metrics = new DisplayMetrics();
+            metrics.setToDefaults();
+            PackageParser.Package pkg = packageParser.parsePackage(sourceFile, archiveFilePath, metrics, 0);
+            if (pkg == null) {
+                Log.w(TAG, "Failed to parse package");
+                return PackageHelper.RECOMMEND_FAILED_INVALID_APK;
+            }
+            int loc = recommendAppInstallLocation(pkg);
+            if (loc == PackageManager.INSTALL_EXTERNAL) {
+                return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
+            } else if (loc == ERR_LOC) {
+                Log.i(TAG, "Failed to install insufficient storage");
+                return PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE;
+            } else {
+                // Implies install on internal storage.
+                return 0;
+            }
+        }
     };
 
     public DefaultContainerService() {
@@ -111,7 +155,6 @@
                 }
             }
         }
-        //Log.i(TAG, "Deleting: " + path);
         path.delete();
     }
     
@@ -341,4 +384,104 @@
         }
         return true;
     }
+
+    // Constants related to app heuristics
+    // No-installation limit for internal flash: 10% or less space available
+    private static final double LOW_NAND_FLASH_TRESHOLD = 0.1;
+
+    // SD-to-internal app size threshold: currently set to 1 MB
+    private static final long INSTALL_ON_SD_THRESHOLD = (1024 * 1024);
+    private static final int ERR_LOC = -1;
+
+    public int recommendAppInstallLocation(Package pkg) {
+        // Initial implementation:
+        // Package size = code size + cache size + data size
+        // If code size > 1 MB, install on SD card.
+        // Else install on internal NAND flash, unless space on NAND is less than 10%
+
+        if (pkg == null) {
+            return ERR_LOC;
+        }
+
+        StatFs internalFlashStats = new StatFs(Environment.getDataDirectory().getPath());
+        StatFs sdcardStats = new StatFs(Environment.getExternalStorageDirectory().getPath());
+
+        long totalInternalFlashSize = (long)internalFlashStats.getBlockCount() *
+                (long)internalFlashStats.getBlockSize();
+        long availInternalFlashSize = (long)internalFlashStats.getAvailableBlocks() *
+                (long)internalFlashStats.getBlockSize();
+        long availSDSize = (long)sdcardStats.getAvailableBlocks() *
+                (long)sdcardStats.getBlockSize();
+
+        double pctNandFree = (double)availInternalFlashSize / (double)totalInternalFlashSize;
+
+        final String archiveFilePath = pkg.mScanPath;
+        File apkFile = new File(archiveFilePath);
+        long pkgLen = apkFile.length();
+
+        boolean auto = true;
+        // To make final copy
+        long reqInstallSize = pkgLen;
+        // For dex files
+        long reqInternalSize = 1 * pkgLen;
+        boolean intThresholdOk = (pctNandFree >= LOW_NAND_FLASH_TRESHOLD);
+        boolean intAvailOk = ((reqInstallSize + reqInternalSize) < availInternalFlashSize);
+        boolean fitsOnSd = (reqInstallSize < availSDSize) && intThresholdOk &&
+                (reqInternalSize < availInternalFlashSize);
+        boolean fitsOnInt = intThresholdOk && intAvailOk;
+
+        // Consider application flags preferences as well...
+        boolean installOnlyOnSd = (pkg.installLocation ==
+                PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
+        boolean installOnlyInternal = (pkg.installLocation ==
+                PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
+        if (installOnlyInternal) {
+            // If set explicitly in manifest,
+            // let that override everything else
+            auto = false;
+        } else if (installOnlyOnSd){
+            // Check if this can be accommodated on the sdcard
+            if (fitsOnSd) {
+                auto = false;
+            }
+        } else {
+            // Check if user option is enabled
+            boolean setInstallLoc = Settings.System.getInt(getApplicationContext()
+                    .getContentResolver(),
+                    Settings.System.SET_INSTALL_LOCATION, 0) != 0;
+            if (setInstallLoc) {
+                // Pick user preference
+                int installPreference = Settings.System.getInt(getApplicationContext()
+                        .getContentResolver(),
+                        Settings.System.DEFAULT_INSTALL_LOCATION,
+                        PackageInfo.INSTALL_LOCATION_AUTO);
+                if (installPreference == 1) {
+                    installOnlyInternal = true;
+                    auto = false;
+                } else if (installPreference == 2) {
+                    installOnlyOnSd = true;
+                    auto = false;
+                }
+            }
+        }
+        if (!auto) {
+            if (installOnlyOnSd) {
+                return fitsOnSd ? PackageManager.INSTALL_EXTERNAL : ERR_LOC;
+            } else if (installOnlyInternal){
+                // Check on internal flash
+                return fitsOnInt ? 0 : ERR_LOC;
+            }
+        }
+        // Try to install internally
+        if (fitsOnInt) {
+            return 0;
+        }
+        // Try the sdcard now.
+        if (fitsOnSd) {
+            return PackageManager.INSTALL_EXTERNAL;
+        }
+        // Return error code
+        return ERR_LOC;
+    }
+
 }
diff --git a/packages/SettingsProvider/AndroidManifest.xml b/packages/SettingsProvider/AndroidManifest.xml
index a542518..c92b9d7 100644
--- a/packages/SettingsProvider/AndroidManifest.xml
+++ b/packages/SettingsProvider/AndroidManifest.xml
@@ -2,8 +2,6 @@
         package="com.android.providers.settings"
         android:sharedUserId="android.uid.system">
 
-    <uses-permission android:name="android.permission.BACKUP_DATA" />
-
     <application android:allowClearUserData="false"
                  android:label="@string/app_label"
                  android:process="system"
diff --git a/packages/SettingsProvider/res/values/defaults.xml b/packages/SettingsProvider/res/values/defaults.xml
index ba6024f..654ca32 100644
--- a/packages/SettingsProvider/res/values/defaults.xml
+++ b/packages/SettingsProvider/res/values/defaults.xml
@@ -58,4 +58,16 @@
     <bool name="def_mount_ums_notify_enabled">true</bool>
     <bool name="set_install_location">true</bool>
 
+    <!-- user interface sound effects -->
+    <integer name="def_power_sounds_enabled">1</integer>
+    <string name="def_low_battery_sound">/system/media/ui/LowBattery.ogg</string>
+    <integer name="def_dock_sounds_enabled">1</integer>
+    <string name="def_desk_dock_sound">/system/media/audio/ui/dock.ogg</string>
+    <string name="def_desk_undock_sound">/system/media/audio/ui/undock.ogg</string>
+    <string name="def_car_dock_sound">/system/media/audio/ui/Dock.ogg</string>
+    <string name="def_car_undock_sound">/system/media/audio/ui/Undock.ogg</string>
+    <integer name="def_lockscreen_sounds_enabled">1</integer>
+    <string name="def_lock_sound">/system/media/audio/ui/Lock.ogg</string>
+    <string name="def_unlock_sound">/system/media/audio/ui/Unlock.ogg</string>
+
 </resources>
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
index b26607f4..cf34d4e 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
@@ -76,7 +76,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 = 49;
+    private static final int DATABASE_VERSION = 50;
 
     private Context mContext;
 
@@ -600,7 +600,7 @@
            upgradeVersion = 47;
        }
 
-        
+
         if (upgradeVersion == 47) {
             /*
              * The password mode constants have changed again; reset back to no
@@ -615,7 +615,7 @@
             }
            upgradeVersion = 48;
        }
-        
+
        if (upgradeVersion == 48) {
            /*
             * Adding a new setting for which voice recognition service to use.
@@ -633,6 +633,24 @@
            upgradeVersion = 49;
        }
 
+       if (upgradeVersion == 49) {
+           /*
+            * New settings for new user interface noises.
+            */
+           db.beginTransaction();
+           try {
+                SQLiteStatement stmt = db.compileStatement("INSERT INTO system(name,value)"
+                        + " VALUES(?,?);");
+                loadUISoundEffectsSettings(stmt);
+                stmt.close();
+                db.setTransactionSuccessful();
+            } finally {
+                db.endTransaction();
+            }
+
+           upgradeVersion = 50;
+       }
+
        if (upgradeVersion != currentVersion) {
             Log.w(TAG, "Got stuck trying to upgrade from version " + upgradeVersion
                     + ", must wipe the settings provider");
@@ -648,6 +666,11 @@
             db.execSQL("DROP INDEX IF EXISTS bookmarksIndex2");
             db.execSQL("DROP TABLE IF EXISTS favorites");
             onCreate(db);
+
+            // Added for diagnosing settings.db wipes after the fact
+            String wipeReason = oldVersion + "/" + upgradeVersion + "/" + currentVersion;
+            db.execSQL("INSERT INTO secure(name,value) values('" +
+                    "wiped_db_reason" + "','" + wipeReason + "');");
         }
     }
 
@@ -889,9 +912,37 @@
         loadBooleanSetting(stmt, Settings.System.SET_INSTALL_LOCATION, R.bool.set_install_location);
         loadSetting(stmt, Settings.System.DEFAULT_INSTALL_LOCATION,
                 PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
+
+        loadUISoundEffectsSettings(stmt);
+
         stmt.close();
     }
 
+    private void loadUISoundEffectsSettings(SQLiteStatement stmt) {
+        loadIntegerSetting(stmt, Settings.System.POWER_SOUNDS_ENABLED,
+            R.integer.def_power_sounds_enabled);
+        loadStringSetting(stmt, Settings.System.LOW_BATTERY_SOUND,
+            R.string.def_low_battery_sound);
+
+        loadIntegerSetting(stmt, Settings.System.DOCK_SOUNDS_ENABLED,
+            R.integer.def_dock_sounds_enabled);
+        loadStringSetting(stmt, Settings.System.DESK_DOCK_SOUND,
+            R.string.def_desk_dock_sound);
+        loadStringSetting(stmt, Settings.System.DESK_UNDOCK_SOUND,
+            R.string.def_desk_undock_sound);
+        loadStringSetting(stmt, Settings.System.CAR_DOCK_SOUND,
+            R.string.def_car_dock_sound);
+        loadStringSetting(stmt, Settings.System.CAR_UNDOCK_SOUND,
+            R.string.def_car_undock_sound);
+
+        loadIntegerSetting(stmt, Settings.System.LOCKSCREEN_SOUNDS_ENABLED,
+            R.integer.def_lockscreen_sounds_enabled);
+        loadStringSetting(stmt, Settings.System.LOCK_SOUND,
+            R.string.def_lock_sound);
+        loadStringSetting(stmt, Settings.System.UNLOCK_SOUND,
+            R.string.def_unlock_sound);
+    }
+
     private void loadDefaultAnimationSettings(SQLiteStatement stmt) {
         loadFractionSetting(stmt, Settings.System.WINDOW_ANIMATION_SCALE,
                 R.fraction.def_window_animation_scale, 1);
@@ -976,7 +1027,7 @@
 
         loadBooleanSetting(stmt, Settings.Secure.MOUNT_UMS_NOTIFY_ENABLED,
                 R.bool.def_mount_ums_notify_enabled);
-        
+
         loadVoiceRecognitionServiceSetting(stmt);
 
         stmt.close();
@@ -989,7 +1040,7 @@
         loadStringSetting(stmt, Settings.Secure.BACKUP_TRANSPORT,
                 R.string.def_backup_transport);
     }
-    
+
     /**
      * Introduced in database version 49.
      */
@@ -999,19 +1050,19 @@
                 mContext.getPackageManager().queryIntentServices(
                         new Intent(RecognitionService.SERVICE_INTERFACE), 0);
         int numAvailable = availableRecognitionServices.size();
-        
+
         if (numAvailable == 0) {
             Log.w(TAG, "no available voice recognition services found");
         } else {
             if (numAvailable > 1) {
                 Log.w(TAG, "more than one voice recognition service found, picking first");
             }
-            
+
             ServiceInfo serviceInfo = availableRecognitionServices.get(0).serviceInfo;
             selectedService =
                     new ComponentName(serviceInfo.packageName, serviceInfo.name).flattenToString();
         }
-        
+
         loadSetting(stmt, Settings.Secure.VOICE_RECOGNITION_SERVICE,
                 selectedService == null ? "" : selectedService);
     }
diff --git a/services/java/com/android/server/BackupManagerService.java b/services/java/com/android/server/BackupManagerService.java
index 27055ed..a7a6df5 100644
--- a/services/java/com/android/server/BackupManagerService.java
+++ b/services/java/com/android/server/BackupManagerService.java
@@ -896,9 +896,7 @@
             try {
                 ApplicationInfo app = pkg.applicationInfo;
                 if (((app.flags&ApplicationInfo.FLAG_ALLOW_BACKUP) == 0)
-                        || app.backupAgentName == null
-                        || (mPackageManager.checkPermission(android.Manifest.permission.BACKUP_DATA,
-                                pkg.packageName) != PackageManager.PERMISSION_GRANTED)) {
+                        || app.backupAgentName == null) {
                     packages.remove(a);
                 }
                 else {
@@ -1282,15 +1280,6 @@
             for (BackupRequest request : mQueue) {
                 Log.d(TAG, "starting agent for backup of " + request);
 
-                // Don't run backup, even if requested, if the target app does not have
-                // the requisite permission
-                if (mPackageManager.checkPermission(android.Manifest.permission.BACKUP_DATA,
-                        request.appInfo.packageName) != PackageManager.PERMISSION_GRANTED) {
-                    Log.w(TAG, "Skipping backup of unprivileged package "
-                            + request.appInfo.packageName);
-                    continue;
-                }
-
                 IBackupAgent agent = null;
                 int mode = (request.fullBackup)
                         ? IApplicationThread.BACKUP_MODE_FULL
@@ -1760,12 +1749,6 @@
 
             if (DEBUG) Log.d(TAG, "processOneRestore packageName=" + packageName);
 
-            // Don't restore to unprivileged packages
-            if (mPackageManager.checkPermission(android.Manifest.permission.BACKUP_DATA,
-                    packageName) != PackageManager.PERMISSION_GRANTED) {
-                Log.d(TAG, "Skipping restore of unprivileged package " + packageName);
-            }
-
             // !!! TODO: get the dirs from the transport
             File backupDataName = new File(mDataDir, packageName + ".restore");
             File newStateName = new File(mStateDir, packageName + ".new");
diff --git a/services/java/com/android/server/DockObserver.java b/services/java/com/android/server/DockObserver.java
index c907368..d280475 100644
--- a/services/java/com/android/server/DockObserver.java
+++ b/services/java/com/android/server/DockObserver.java
@@ -26,10 +26,14 @@
 import android.bluetooth.BluetoothDevice;
 import android.content.ActivityNotFoundException;
 import android.content.BroadcastReceiver;
+import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.res.Configuration;
 import android.os.Binder;
+import android.media.Ringtone;
+import android.media.RingtoneManager;
+import android.net.Uri;
 import android.os.Handler;
 import android.os.Message;
 import android.os.RemoteException;
@@ -60,8 +64,11 @@
     public static final int MODE_NIGHT_YES = Configuration.UI_MODE_NIGHT_YES >> 4;
 
     private int mDockState = Intent.EXTRA_DOCK_STATE_UNDOCKED;
+    private int mPreviousDockState = Intent.EXTRA_DOCK_STATE_UNDOCKED;
+
     private int mNightMode = MODE_NIGHT_NO;
     private boolean mCarModeEnabled = false;
+
     private boolean mSystemReady;
 
     private final Context mContext;
@@ -129,7 +136,7 @@
             try {
                 int newState = Integer.parseInt(event.get("SWITCH_STATE"));
                 if (newState != mDockState) {
-                    int oldState = mDockState;
+                    mPreviousDockState = mDockState;
                     mDockState = newState;
                     boolean carModeEnabled = mDockState == Intent.EXTRA_DOCK_STATE_CAR;
                     if (mCarModeEnabled != carModeEnabled) {
@@ -143,8 +150,8 @@
                         // Don't force screen on when undocking from the desk dock.
                         // The change in power state will do this anyway.
                         // FIXME - we should be configurable.
-                        if (oldState != Intent.EXTRA_DOCK_STATE_DESK ||
-                                newState != Intent.EXTRA_DOCK_STATE_UNDOCKED) {
+                        if (mPreviousDockState != Intent.EXTRA_DOCK_STATE_DESK ||
+                                mDockState != Intent.EXTRA_DOCK_STATE_UNDOCKED) {
                             mPowerManager.userActivityWithForce(SystemClock.uptimeMillis(),
                                     false, true);
                         }
@@ -163,7 +170,7 @@
         try {
             FileReader file = new FileReader(DOCK_STATE_PATH);
             int len = file.read(buffer, 0, 1024);
-            mDockState = Integer.valueOf((new String(buffer, 0, len)).trim());
+            mPreviousDockState = mDockState = Integer.valueOf((new String(buffer, 0, len)).trim());
 
         } catch (FileNotFoundException e) {
             Log.w(TAG, "This kernel does not have dock station support");
@@ -195,7 +202,10 @@
         public void handleMessage(Message msg) {
             synchronized (this) {
                 Log.i(TAG, "Dock state changed: " + mDockState);
-                if (Settings.Secure.getInt(mContext.getContentResolver(),
+
+                final ContentResolver cr = mContext.getContentResolver();
+
+                if (Settings.Secure.getInt(cr,
                         Settings.Secure.DEVICE_PROVISIONED, 0) == 0) {
                     Log.i(TAG, "Device not provisioned, skipping dock broadcast");
                     return;
@@ -217,6 +227,38 @@
                     intent.putExtra(BluetoothDevice.EXTRA_DEVICE,
                             BluetoothAdapter.getDefaultAdapter().getRemoteDevice(address));
 
+                // User feedback to confirm dock connection. Particularly
+                // useful for flaky contact pins...
+                if (Settings.System.getInt(cr,
+                        Settings.System.DOCK_SOUNDS_ENABLED, 1) == 1)
+                {
+                    String whichSound = null;
+                    if (mDockState == Intent.EXTRA_DOCK_STATE_UNDOCKED) {
+                        if (mPreviousDockState == Intent.EXTRA_DOCK_STATE_DESK) {
+                            whichSound = Settings.System.DESK_UNDOCK_SOUND;
+                        } else if (mPreviousDockState == Intent.EXTRA_DOCK_STATE_CAR) {
+                            whichSound = Settings.System.CAR_UNDOCK_SOUND;
+                        }
+                    } else {
+                        if (mDockState == Intent.EXTRA_DOCK_STATE_DESK) {
+                            whichSound = Settings.System.DESK_DOCK_SOUND;
+                        } else if (mDockState == Intent.EXTRA_DOCK_STATE_CAR) {
+                            whichSound = Settings.System.CAR_DOCK_SOUND;
+                        }
+                    }
+
+                    if (whichSound != null) {
+                        final String soundPath = Settings.System.getString(cr, whichSound);
+                        if (soundPath != null) {
+                            final Uri soundUri = Uri.parse("file://" + soundPath);
+                            if (soundUri != null) {
+                                final Ringtone sfx = RingtoneManager.getRingtone(mContext, soundUri);
+                                if (sfx != null) sfx.play();
+                            }
+                        }
+                    }
+                }
+
                 // Send the ordered broadcast; the result receiver will receive after all
                 // broadcasts have been sent. If any broadcast receiver changes the result
                 // code from the initial value of RESULT_OK, then the result receiver will
diff --git a/services/java/com/android/server/FallbackCheckinService.java b/services/java/com/android/server/FallbackCheckinService.java
deleted file mode 100644
index 195eb63..0000000
--- a/services/java/com/android/server/FallbackCheckinService.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server;
-
-import android.content.Context;
-import android.content.pm.PackageManager;
-import android.os.Binder;
-import android.os.ICheckinService;
-import android.os.IParentalControlCallback;
-import android.os.RecoverySystem;
-import android.util.Log;
-
-import java.io.IOException;
-
-import com.google.android.net.ParentalControlState;
-
-/**
- * @hide
- */
-public final class FallbackCheckinService extends ICheckinService.Stub {
-    static final String TAG = "FallbackCheckinService";
-    final Context mContext;
-
-    public FallbackCheckinService(Context context) {
-        mContext = context;
-    }
-
-    public void getParentalControlState(IParentalControlCallback p, String requestingApp)
-            throws android.os.RemoteException {
-        ParentalControlState state = new ParentalControlState();
-        state.isEnabled = false;
-        p.onResult(state);
-    }
-}
diff --git a/services/java/com/android/server/InputDevice.java b/services/java/com/android/server/InputDevice.java
index 6f207e0..d3bb6dc 100644
--- a/services/java/com/android/server/InputDevice.java
+++ b/services/java/com/android/server/InputDevice.java
@@ -570,14 +570,14 @@
                         mDownTime = curTime;
                     } else {
                         action = MotionEvent.ACTION_POINTER_DOWN
-                                | (upOrDownPointer << MotionEvent.ACTION_POINTER_ID_SHIFT);
+                                | (upOrDownPointer << MotionEvent.ACTION_POINTER_INDEX_SHIFT);
                     }
                 } else {
                     if (numPointers == 1) {
                         action = MotionEvent.ACTION_UP;
                     } else {
                         action = MotionEvent.ACTION_POINTER_UP
-                                | (upOrDownPointer << MotionEvent.ACTION_POINTER_ID_SHIFT);
+                                | (upOrDownPointer << MotionEvent.ACTION_POINTER_INDEX_SHIFT);
                     }
                 }
                 currentMove = null;
diff --git a/services/java/com/android/server/PackageManagerService.java b/services/java/com/android/server/PackageManagerService.java
index a5213a0..812ff64 100644
--- a/services/java/com/android/server/PackageManagerService.java
+++ b/services/java/com/android/server/PackageManagerService.java
@@ -20,6 +20,7 @@
 import com.android.internal.app.ResolverActivity;
 import com.android.common.FastXmlSerializer;
 import com.android.common.XmlUtils;
+import com.android.internal.content.PackageHelper;
 import com.android.server.JournaledFile;
 
 import org.xmlpull.v1.XmlPullParser;
@@ -304,6 +305,7 @@
     static final int INIT_COPY = 5;
     static final int MCS_UNBIND = 6;
     static final int START_CLEANING_PACKAGE = 7;
+    static final int FIND_INSTALL_LOC = 8;
     // Delay time in millisecs
     static final int BROADCAST_DELAY = 10 * 1000;
     private ServiceConnection mDefContainerConn = new ServiceConnection() {
@@ -319,8 +321,8 @@
     };
 
     class PackageHandler extends Handler {
-        final ArrayList<InstallArgs> mPendingInstalls =
-            new ArrayList<InstallArgs>();
+        final ArrayList<InstallParams> mPendingInstalls =
+            new ArrayList<InstallParams>();
         // Service Connection to remote media container service to copy
         // package uri's from external media onto secure containers
         // or internal storage.
@@ -332,21 +334,20 @@
         public void handleMessage(Message msg) {
             switch (msg.what) {
                 case INIT_COPY: {
-                    InstallArgs args = (InstallArgs) msg.obj;
-                    args.createCopyFile();
+                    InstallParams params = (InstallParams) msg.obj;
                     Intent service = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
                     if (mContainerService != null) {
                         // No need to add to pending list. Use remote stub directly
-                        handleStartCopy(args);
+                        handleStartCopy(params);
                     } else {
                         if (mContext.bindService(service, mDefContainerConn,
                                 Context.BIND_AUTO_CREATE)) {
-                            mPendingInstalls.add(args);
+                            mPendingInstalls.add(params);
                         } else {
                             Log.e(TAG, "Failed to bind to media container service");
                             // Indicate install failure TODO add new error code
-                            processPendingInstall(args,
-                                    PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE);
+                            processPendingInstall(createInstallArgs(params),
+                                    PackageManager.INSTALL_FAILED_INTERNAL_ERROR);
                         }
                     }
                     break;
@@ -357,9 +358,9 @@
                         mContainerService = (IMediaContainerService) msg.obj;
                     }
                     if (mPendingInstalls.size() > 0) {
-                        InstallArgs args = mPendingInstalls.remove(0);
-                        if (args != null) {
-                            handleStartCopy(args);
+                        InstallParams params = mPendingInstalls.remove(0);
+                        if (params != null) {
+                            handleStartCopy(params);
                         }
                     }
                     break;
@@ -423,22 +424,56 @@
 
         // Utility method to initiate copying apk via media
         // container service.
-        private void handleStartCopy(InstallArgs args) {
-            int ret = PackageManager.INSTALL_SUCCEEDED;
-            if (mContainerService == null) {
-                // Install error
-                ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
-            } else {
-                ret = args.copyApk(mContainerService);
+        private void handleStartCopy(InstallParams params) {
+            int ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
+            if (mContainerService != null) {
+                // Remote call to find out default install location
+                int loc = params.getInstallLocation(mContainerService);
+                // Use install location to create InstallArgs and temporary
+                // install location
+                if (loc == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE){
+                    ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
+                } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_APK) {
+                    ret = PackageManager.INSTALL_FAILED_INVALID_APK;
+                } else {
+                    if ((params.flags & PackageManager.INSTALL_EXTERNAL) == 0){
+                        if (loc == PackageHelper.RECOMMEND_INSTALL_EXTERNAL) {
+                            // Set the flag to install on external media.
+                            params.flags |= PackageManager.INSTALL_EXTERNAL;
+                        } else {
+                            // Make sure the flag for installing on external
+                            // media is unset
+                            params.flags &= ~PackageManager.INSTALL_EXTERNAL;
+                        }
+                    }
+                    // Disable forward locked apps on sdcard.
+                    if ((params.flags & PackageManager.INSTALL_FORWARD_LOCK) != 0 &&
+                            (params.flags & PackageManager.INSTALL_EXTERNAL) != 0) {
+                        // Make sure forward locked apps can only be installed
+                        // on internal storage
+                        Log.w(TAG, "Cannot install protected apps on sdcard");
+                        ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
+                    } else {
+                        ret = PackageManager.INSTALL_SUCCEEDED;
+                    }
+                }
             }
             mHandler.sendEmptyMessage(MCS_UNBIND);
+            // Create the file args now.
+            InstallArgs args = createInstallArgs(params);
+            if (ret == PackageManager.INSTALL_SUCCEEDED) {
+                // Create copy only if we are not in an erroneous state.
+                args.createCopyFile();
+                // Remote call to initiate copy
+                ret = args.copyApk(mContainerService);
+            }
             processPendingInstall(args, ret);
         }
     }
 
     static boolean installOnSd(int flags) {
         if (((flags & PackageManager.INSTALL_FORWARD_LOCK) != 0) ||
-                ((flags & PackageManager.INSTALL_ON_SDCARD) == 0)) {
+                ((flags & PackageManager.INSTALL_EXTERNAL) == 0)) {
             return false;
         }
         return true;
@@ -4249,29 +4284,11 @@
                 android.Manifest.permission.INSTALL_PACKAGES, null);
 
         Message msg = mHandler.obtainMessage(INIT_COPY);
-        msg.obj = createInstallArgs(packageURI, observer, flags, installerPackageName);
+        msg.obj = new InstallParams(packageURI, observer, flags,
+                installerPackageName);
         mHandler.sendMessage(msg);
     }
 
-    private InstallArgs createInstallArgs(Uri packageURI, IPackageInstallObserver observer,
-            int flags, String installerPackageName) {
-        if (installOnSd(flags)) {
-            return new SdInstallArgs(packageURI, observer, flags,
-                    installerPackageName);
-        } else {
-            return new FileInstallArgs(packageURI, observer, flags,
-                    installerPackageName);
-        }
-    }
-
-    private InstallArgs createInstallArgs(int flags, String fullCodePath, String fullResourcePath) {
-        if (installOnSd(flags)) {
-            return new SdInstallArgs(fullCodePath, fullResourcePath);
-        } else {
-            return new FileInstallArgs(fullCodePath, fullResourcePath);
-        }
-    }
-
     private void processPendingInstall(final InstallArgs args, final int currentStatus) {
         // Queue up an async operation since the package installation may take a little while.
         mHandler.post(new Runnable() {
@@ -4327,6 +4344,45 @@
         });
     }
 
+    static final class InstallParams {
+        final IPackageInstallObserver observer;
+        int flags;
+        final Uri packageURI;
+        final String installerPackageName;
+        InstallParams(Uri packageURI,
+                IPackageInstallObserver observer, int flags,
+                String installerPackageName) {
+            this.packageURI = packageURI;
+            this.flags = flags;
+            this.observer = observer;
+            this.installerPackageName = installerPackageName;
+        }
+
+        public int getInstallLocation(IMediaContainerService imcs) {
+            try {
+                return imcs.getRecommendedInstallLocation(packageURI);
+            } catch (RemoteException e) {
+            }
+            return  -1;
+        }
+    };
+
+    private InstallArgs createInstallArgs(InstallParams params) {
+        if (installOnSd(params.flags)) {
+            return new SdInstallArgs(params);
+        } else {
+            return new FileInstallArgs(params);
+        }
+    }
+
+    private InstallArgs createInstallArgs(int flags, String fullCodePath, String fullResourcePath) {
+        if (installOnSd(flags)) {
+            return new SdInstallArgs(fullCodePath, fullResourcePath);
+        } else {
+            return new FileInstallArgs(fullCodePath, fullResourcePath);
+        }
+    }
+
     static abstract class InstallArgs {
         final IPackageInstallObserver observer;
         final int flags;
@@ -4359,10 +4415,9 @@
         String codeFileName;
         String resourceFileName;
 
-        FileInstallArgs(Uri packageURI,
-                IPackageInstallObserver observer, int flags,
-                String installerPackageName) {
-            super(packageURI, observer, flags, installerPackageName);
+        FileInstallArgs(InstallParams params) {
+            super(params.packageURI, params.observer,
+                    params.flags, params.installerPackageName);
         }
 
         FileInstallArgs(String fullCodePath, String fullResourcePath) {
@@ -4373,6 +4428,10 @@
             resourceFileName = fullResourcePath;
         }
 
+        String getCodePath() {
+            return codeFileName;
+        }
+
         void createCopyFile() {
             boolean fwdLocked = isFwdLocked(flags);
             installDir = fwdLocked ? mDrmAppPrivateInstallDir : mAppInstallDir;
@@ -4380,10 +4439,6 @@
             resourceFileName = getResourcePathFromCodePath();
         }
 
-        String getCodePath() {
-            return codeFileName;
-        }
-
         int copyApk(IMediaContainerService imcs) {
             // Get a ParcelFileDescriptor to write to the output file
             File codeFile = new File(codeFileName);
@@ -4528,10 +4583,9 @@
         String cachePath;
         static final String RES_FILE_NAME = "pkg.apk";
 
-        SdInstallArgs(Uri packageURI,
-                IPackageInstallObserver observer, int flags,
-                String installerPackageName) {
-           super(packageURI, observer, flags, installerPackageName);
+        SdInstallArgs(InstallParams params) {
+            super(params.packageURI, params.observer,
+                    params.flags, params.installerPackageName);
         }
 
         SdInstallArgs(String fullCodePath, String fullResourcePath) {
@@ -5105,7 +5159,7 @@
         String installerPackageName = args.installerPackageName;
         File tmpPackageFile = new File(args.getCodePath());
         boolean forwardLocked = ((pFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0);
-        boolean onSd = ((pFlags & PackageManager.INSTALL_ON_SDCARD) != 0);
+        boolean onSd = ((pFlags & PackageManager.INSTALL_EXTERNAL) != 0);
         boolean replace = false;
         int scanMode = SCAN_MONITOR | SCAN_FORCE_DEX | SCAN_UPDATE_SIGNATURE
                 | (newInstall ? SCAN_NEW_INSTALL : 0);
@@ -5136,14 +5190,6 @@
             res.returnCode = pp.getParseError();
             return;
         }
-        // Some preinstall checks
-        if (forwardLocked && onSd) {
-            // Make sure forward locked apps can only be installed
-            // on internal storage
-            Log.w(TAG, "Cannot install protected apps on sdcard");
-            res.returnCode = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
-            return;
-        }
         // Get rid of all references to package scan path via parser.
         pp = null;
         String oldCodePath = null;
@@ -5560,7 +5606,7 @@
         if (deleteCodeAndResources) {
             // TODO can pick up from PackageSettings as well
             int installFlags = ((p.applicationInfo.flags & ApplicationInfo.FLAG_ON_SDCARD)!=0) ?
-                    PackageManager.INSTALL_ON_SDCARD : 0;
+                    PackageManager.INSTALL_EXTERNAL : 0;
             installFlags |= ((p.applicationInfo.flags & ApplicationInfo.FLAG_FORWARD_LOCK)!=0) ?
                     PackageManager.INSTALL_FORWARD_LOCK : 0;
             outInfo.args = createInstallArgs(installFlags,
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 6e9c21b..28b4b28 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -329,19 +329,6 @@
             }
 
             try {
-                Log.i(TAG, "Checkin Service");
-                Intent intent = new Intent().setComponent(new ComponentName(
-                        "com.google.android.server.checkin",
-                        "com.google.android.server.checkin.CheckinService"));
-                if (context.startService(intent) == null) {
-                    Log.w(TAG, "Using fallback Checkin Service.");
-                    ServiceManager.addService("checkin", new FallbackCheckinService(context));
-                }
-            } catch (Throwable e) {
-                Log.e(TAG, "Failure starting Checkin Service", e);
-            }
-
-            try {
                 Log.i(TAG, "Wallpaper Service");
                 wallpaper = new WallpaperManagerService(context);
                 ServiceManager.addService(Context.WALLPAPER_SERVICE, wallpaper);
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index d0f6a7c..8a73e99 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -9493,7 +9493,7 @@
         String[] newArgs;
         String componentNameString;
         ServiceRecord r;
-        if (opti <= args.length) {
+        if (opti >= args.length) {
             componentNameString = null;
             newArgs = EMPTY_STRING_ARRAY;
             r = null;
@@ -13463,6 +13463,12 @@
                             app.hidden = false;
                         }
                     }
+                    // If we have let the service slide into the background
+                    // state, still have some text describing what it is doing
+                    // even though the service no longer has an impact.
+                    if (adj > SECONDARY_SERVER_ADJ) {
+                        app.adjType = "started-bg-services";
+                    }
                 }
                 if (s.connections.size() > 0 && (adj > FOREGROUND_APP_ADJ
                         || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
@@ -13853,6 +13859,15 @@
 
         mAdjSeq++;
 
+        // Let's determine how many processes we have running vs.
+        // how many slots we have for background processes; we may want
+        // to put multiple processes in a slot of there are enough of
+        // them.
+        int numSlots = HIDDEN_APP_MAX_ADJ - HIDDEN_APP_MIN_ADJ + 1;
+        int factor = (mLruProcesses.size()-4)/numSlots;
+        if (factor < 1) factor = 1;
+        int step = 0;
+        
         // First try updating the OOM adjustment for each of the
         // application processes based on their current state.
         int i = mLruProcesses.size();
@@ -13864,7 +13879,11 @@
             if (updateOomAdjLocked(app, curHiddenAdj, TOP_APP)) {
                 if (curHiddenAdj < EMPTY_APP_ADJ
                     && app.curAdj == curHiddenAdj) {
-                    curHiddenAdj++;
+                    step++;
+                    if (step >= factor) {
+                        step = 0;
+                        curHiddenAdj++;
+                    }
                 }
             } else {
                 didOomAdj = false;
diff --git a/services/java/com/android/server/status/StatusBarPolicy.java b/services/java/com/android/server/status/StatusBarPolicy.java
index 20209e4..d13f9d3 100644
--- a/services/java/com/android/server/status/StatusBarPolicy.java
+++ b/services/java/com/android/server/status/StatusBarPolicy.java
@@ -22,6 +22,7 @@
 import android.bluetooth.BluetoothHeadset;
 import android.bluetooth.BluetoothPbap;
 import android.content.BroadcastReceiver;
+import android.content.ContentResolver;
 import android.content.Context;
 import android.content.DialogInterface;
 import android.content.Intent;
@@ -30,7 +31,10 @@
 import android.graphics.PixelFormat;
 import android.graphics.drawable.Drawable;
 import android.media.AudioManager;
+import android.media.Ringtone;
+import android.media.RingtoneManager;
 import android.net.NetworkInfo;
+import android.net.Uri;
 import android.net.wifi.WifiManager;
 import android.os.Binder;
 import android.os.Handler;
@@ -109,6 +113,7 @@
     private int mBatteryViewSequence;
     private boolean mBatteryShowLowOnEndCall = false;
     private static final boolean SHOW_LOW_BATTERY_WARNING = true;
+    private static final boolean SHOW_BATTERY_WARNINGS_IN_CALL = true;
 
     // phone
     private TelephonyManager mPhone;
@@ -686,7 +691,7 @@
                       + " mBatteryShowLowOnEndCall=" + mBatteryShowLowOnEndCall);
             }
 
-            if (mPhoneState == TelephonyManager.CALL_STATE_IDLE) {
+            if (SHOW_BATTERY_WARNINGS_IN_CALL || mPhoneState == TelephonyManager.CALL_STATE_IDLE) {
                 showLowBatteryWarning();
             } else {
                 mBatteryShowLowOnEndCall = true;
@@ -810,6 +815,21 @@
             d.show();
             mLowBatteryDialog = d;
         }
+
+        final ContentResolver cr = mContext.getContentResolver();
+        if (Settings.System.getInt(cr,
+                Settings.System.POWER_SOUNDS_ENABLED, 1) == 1) 
+        {
+            final String soundPath = Settings.System.getString(cr,
+                Settings.System.LOW_BATTERY_SOUND);
+            if (soundPath != null) {
+                final Uri soundUri = Uri.parse("file://" + soundPath);
+                if (soundUri != null) {
+                    final Ringtone sfx = RingtoneManager.getRingtone(mContext, soundUri);
+                    if (sfx != null) sfx.play();
+                }
+            }
+        }
     }
 
     private final void updateCallState(int state) {
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
index c351289..39fe007 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
@@ -1203,32 +1203,23 @@
         } else {
             int[] ints = (int[])ar.result;
             int offset = 2;
-
             int cdmaDbm = (ints[offset] > 0) ? -ints[offset] : -120;
             int cdmaEcio = (ints[offset+1] > 0) ? -ints[offset+1] : -160;
+            int evdoRssi = (ints[offset+2] > 0) ? -ints[offset+2] : -120;
+            int evdoEcio = (ints[offset+3] > 0) ? -ints[offset+3] : -1;
+            int evdoSnr  = ((ints[offset+4] > 0) && (ints[offset+4] <= 8)) ? ints[offset+4] : -1;
 
-            int evdoRssi = -1;
-            int evdoEcio = -1;
-            int evdoSnr = -1;
-            if ((networkType == ServiceState.RADIO_TECHNOLOGY_EVDO_0)
-                    || (networkType == ServiceState.RADIO_TECHNOLOGY_EVDO_A)) {
-                evdoRssi = (ints[offset+2] > 0) ? -ints[offset+2] : -120;
-                evdoEcio = (ints[offset+3] > 0) ? -ints[offset+3] : -1;
-                evdoSnr  = ((ints[offset+4] > 0) && (ints[offset+4] <= 8)) ? ints[offset+4] : -1;
-            }
-
+            //log(String.format("onSignalStrengthResult cdmaDbm=%d cdmaEcio=%d evdoRssi=%d evdoEcio=%d evdoSnr=%d",
+            //        cdmaDbm, cdmaEcio, evdoRssi, evdoEcio, evdoSnr));
             mSignalStrength = new SignalStrength(99, -1, cdmaDbm, cdmaEcio,
                     evdoRssi, evdoEcio, evdoSnr, false);
         }
 
-        if (!mSignalStrength.equals(oldSignalStrength)) {
-            try { // This takes care of delayed EVENT_POLL_SIGNAL_STRENGTH (scheduled after
-                  // POLL_PERIOD_MILLIS) during Radio Technology Change)
-                phone.notifySignalStrength();
-           } catch (NullPointerException ex) {
-                log("onSignalStrengthResult() Phone already destroyed: " + ex
-                        + "SignalStrength not notified");
-           }
+        try {
+            phone.notifySignalStrength();
+        } catch (NullPointerException ex) {
+            log("onSignalStrengthResult() Phone already destroyed: " + ex
+                    + "SignalStrength not notified");
         }
     }
 
diff --git a/test-runner/android/test/mock/MockPackageManager.java b/test-runner/android/test/mock/MockPackageManager.java
index 2a4b3f7..f1ba44a 100644
--- a/test-runner/android/test/mock/MockPackageManager.java
+++ b/test-runner/android/test/mock/MockPackageManager.java
@@ -449,12 +449,4 @@
     public boolean isSafeMode() {
         throw new UnsupportedOperationException();
     }
-
-    /**
-     * @hide
-     */
-    @Override
-    public int recommendAppInstallLocation(PackageParser.Package pkg) {
-        throw new UnsupportedOperationException();
-    }
 }
diff --git a/tests/AndroidTests/src/com/android/unit_tests/PackageManagerTests.java b/tests/AndroidTests/src/com/android/unit_tests/PackageManagerTests.java
index 07bd489..8f4d0a1 100755
--- a/tests/AndroidTests/src/com/android/unit_tests/PackageManagerTests.java
+++ b/tests/AndroidTests/src/com/android/unit_tests/PackageManagerTests.java
@@ -192,6 +192,27 @@
         }
     }
 
+    public boolean invokeInstallPackageFail(Uri packageURI, int flags,
+            final String pkgName, int result) throws Exception {
+        PackageInstallObserver observer = new PackageInstallObserver();
+        try {
+            // Wait on observer
+            synchronized(observer) {
+                getPm().installPackage(packageURI, observer, flags, null);
+                long waitTime = 0;
+                while((!observer.isDone()) && (waitTime < MAX_WAIT_TIME) ) {
+                    observer.wait(WAIT_TIME_INCR);
+                    waitTime += WAIT_TIME_INCR;
+                }
+                if(!observer.isDone()) {
+                    throw new Exception("Timed out waiting for packageInstalled callback");
+                }
+                return (observer.returnCode == result);
+            }
+        } finally {
+        }
+    }
+
     Uri getInstallablePackage(int fileResId, File outFile) {
         Resources res = mContext.getResources();
         InputStream is = null;
@@ -238,7 +259,7 @@
             assertEquals(publicSrcPath, appInstallPath);
         } else {
             assertFalse((info.flags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0);
-            if ((flags & PackageManager.INSTALL_ON_SDCARD) != 0) {
+            if ((flags & PackageManager.INSTALL_EXTERNAL) != 0) {
                 assertTrue((info.flags & ApplicationInfo.FLAG_ON_SDCARD) != 0);
                 // Hardcoded for now
                 assertTrue(srcPath.startsWith("/asec"));
@@ -253,6 +274,13 @@
             failStr("failed with exception : " + e);
         }
     }
+    private void assertNotInstalled(String pkgName) {
+        try {
+            ApplicationInfo info = getPm().getApplicationInfo(pkgName, 0);
+            fail(pkgName + " shouldnt be installed");
+        } catch (NameNotFoundException e) {
+        }
+    }
 
     class InstallParams {
         String outFileName;
@@ -265,30 +293,42 @@
         }
     }
 
+    private InstallParams sampleInstallFromRawResource(int flags, boolean cleanUp) {
+        return installFromRawResource("install.apk", R.raw.install, flags, cleanUp,
+                false, -1);
+    }
     /*
      * Utility function that reads a apk bundled as a raw resource
      * copies it into own data directory and invokes
      * PackageManager api to install it.
      */
-    public InstallParams installFromRawResource(int flags, boolean cleanUp) {
-        String outFileName = "install.apk";
+    private InstallParams installFromRawResource(String outFileName,
+            int rawResId, int flags, boolean cleanUp, boolean fail, int result) {
         File filesDir = mContext.getFilesDir();
         File outFile = new File(filesDir, outFileName);
-        Uri packageURI = getInstallablePackage(R.raw.install, outFile);
+        Uri packageURI = getInstallablePackage(rawResId, outFile);
         PackageParser.Package pkg = parsePackage(packageURI);
         assertNotNull(pkg);
-        InstallReceiver receiver = new InstallReceiver(pkg.packageName);
         InstallParams ip = null;
         try {
             try {
-                assertTrue(invokeInstallPackage(packageURI, flags,
-                        pkg.packageName, receiver));
+                if (fail) {
+                    // Make sure it doesn't exist
+                    getPm().deletePackage(pkg.packageName, null, 0);
+                    assertTrue(invokeInstallPackageFail(packageURI, flags,
+                            pkg.packageName, result));
+                    assertNotInstalled(pkg.packageName);
+                } else {
+                    InstallReceiver receiver = new InstallReceiver(pkg.packageName);
+                    assertTrue(invokeInstallPackage(packageURI, flags,
+                            pkg.packageName, receiver));
+                    // Verify installed information
+                    assertInstall(pkg.packageName, flags);
+                    ip = new InstallParams(pkg, outFileName, packageURI);
+                }
             } catch (Exception e) {
                 failStr("Failed with exception : " + e);
             }
-            // Verify installed information
-            assertInstall(pkg.packageName, flags);
-            ip = new InstallParams(pkg, outFileName, packageURI);
             return ip;
         } finally {
             if (cleanUp) {
@@ -299,17 +339,17 @@
 
     @MediumTest
     public void testInstallNormalInternal() {
-        installFromRawResource(0, true);
+        sampleInstallFromRawResource(0, true);
     }
 
     @MediumTest
     public void testInstallFwdLockedInternal() {
-        installFromRawResource(PackageManager.INSTALL_FORWARD_LOCK, true);
+        sampleInstallFromRawResource(PackageManager.INSTALL_FORWARD_LOCK, true);
     }
 
     @MediumTest
     public void testInstallSdcard() {
-        installFromRawResource(PackageManager.INSTALL_ON_SDCARD, true);
+        sampleInstallFromRawResource(PackageManager.INSTALL_EXTERNAL, true);
     }
 
     /* ------------------------- Test replacing packages --------------*/
@@ -373,7 +413,7 @@
      * again.
      */
     public void replaceFromRawResource(int flags) {
-        InstallParams ip = installFromRawResource(flags, false);
+        InstallParams ip = sampleInstallFromRawResource(flags, false);
         boolean replace = ((flags & PackageManager.INSTALL_REPLACE_EXISTING) != 0);
         GenericReceiver receiver;
         if (replace) {
@@ -409,7 +449,7 @@
 
     @MediumTest
     public void testReplaceFailSdcard() {
-        replaceFromRawResource(PackageManager.INSTALL_ON_SDCARD);
+        replaceFromRawResource(PackageManager.INSTALL_EXTERNAL);
     }
 
     @MediumTest
@@ -426,7 +466,7 @@
     @MediumTest
     public void testReplaceSdcard() {
         replaceFromRawResource(PackageManager.INSTALL_REPLACE_EXISTING |
-                PackageManager.INSTALL_ON_SDCARD);
+                PackageManager.INSTALL_EXTERNAL);
     }
 
     /* -------------- Delete tests ---*/
@@ -508,7 +548,7 @@
     }
 
     public void deleteFromRawResource(int iFlags, int dFlags) {
-        InstallParams ip = installFromRawResource(iFlags, false);
+        InstallParams ip = sampleInstallFromRawResource(iFlags, false);
         boolean retainData = ((dFlags & PackageManager.DONT_DELETE_DATA) != 0);
         GenericReceiver receiver = new DeleteReceiver(ip.pkg.packageName);
         DeleteObserver observer = new DeleteObserver();
@@ -550,7 +590,7 @@
 
     @MediumTest
     public void testDeleteSdcard() {
-        deleteFromRawResource(PackageManager.INSTALL_ON_SDCARD, 0);
+        deleteFromRawResource(PackageManager.INSTALL_EXTERNAL, 0);
     }
 
     @MediumTest
@@ -565,7 +605,7 @@
 
     @MediumTest
     public void testDeleteSdcardRetainData() {
-        deleteFromRawResource(PackageManager.INSTALL_ON_SDCARD, PackageManager.DONT_DELETE_DATA);
+        deleteFromRawResource(PackageManager.INSTALL_EXTERNAL, PackageManager.DONT_DELETE_DATA);
     }
 
     /* sdcard mount/unmount tests ******/
@@ -696,7 +736,7 @@
 
     private boolean mountFromRawResource() {
         // Install pkg on sdcard
-        InstallParams ip = installFromRawResource(PackageManager.INSTALL_ON_SDCARD |
+        InstallParams ip = sampleInstallFromRawResource(PackageManager.INSTALL_EXTERNAL |
                 PackageManager.INSTALL_REPLACE_EXISTING, false);
         if (localLOGV) Log.i(TAG, "Installed pkg on sdcard");
         boolean origState = getMediaState();
@@ -764,169 +804,32 @@
         }
     }
 
-    public void invokeRecommendAppInstallLocation(String outFileName,
-            int fileResId, int expected) {
-        int origSetting = Settings.System.getInt(mContext.getContentResolver(),
-                Settings.System.SET_INSTALL_LOCATION, 0);
-        try {
-            // Make sure the set install location setting is diabled.
-            Settings.System.putInt(mContext.getContentResolver(),
-                    Settings.System.SET_INSTALL_LOCATION, 0);
-            File filesDir = mContext.getFilesDir();
-            File outFile = new File(filesDir, outFileName);
-            Uri packageURI = getInstallablePackage(fileResId, outFile);
-            PackageParser.Package pkg = parsePackage(packageURI);
-            assertNotNull(pkg);
-            int installLoc = getPm().recommendAppInstallLocation(pkg);
-            Log.i(TAG, "expected=" + expected +", installLoc="+installLoc);
-            // Atleast one of the specified expected flags should be set.
-            boolean onFlash = (installLoc &
-                    PackageManager.INSTALL_ON_INTERNAL_FLASH) != 0;
-            boolean onSd = (installLoc &
-                    PackageManager.INSTALL_ON_SDCARD) != 0;
-            boolean expOnFlash = (expected &
-                    PackageManager.INSTALL_ON_INTERNAL_FLASH) != 0;
-            boolean expOnSd = (expected &
-                    PackageManager.INSTALL_ON_SDCARD) != 0;
-            assertTrue(expOnFlash == onFlash || expOnSd == onSd);
-        } finally {
-            // Restore original setting
-            Settings.System.putInt(mContext.getContentResolver(),
-                    Settings.System.SET_INSTALL_LOCATION, origSetting);
-        }
+    public void testManifestInstallLocationInternal() {
+        installFromRawResource("install.apk", R.raw.install_loc_internal,
+                0, true, false, -1);
     }
 
-    /*
-     * Tests if an apk can be installed on internal flash by
-     * explicitly specifying in its manifest.
-     */
-    public void testInstallLocationInternal() {
-        invokeRecommendAppInstallLocation("install.apk",
-                R.raw.install_loc_internal, PackageManager.INSTALL_ON_INTERNAL_FLASH);
+    public void testManifestInstallLocationSdcard() {
+        installFromRawResource("install.apk", R.raw.install_loc_sdcard,
+                PackageManager.INSTALL_EXTERNAL, true, false, -1);
     }
 
-    /*
-     * Tests if an apk can be installed on internal flash by
-     * explicitly specifying in its manifest and filling up
-     * internal flash. Should fail to install.
-     * TODO
-     */
-    public void xxxtestInstallLocationInternalFail() {
+    public void testManifestInstallLocationAuto() {
+        installFromRawResource("install.apk", R.raw.install_loc_auto,
+                0, true, false, -1);
     }
 
-    /*
-     * Tests if an apk can be installed on sdcard by
-     * explicitly specifying in its manifest.
-     */
-    public void testInstallLocationSdcard() {
-        // TODO No guarantee this will be on sdcard.
-        invokeRecommendAppInstallLocation("install.apk",
-                R.raw.install_loc_sdcard, PackageManager.INSTALL_ON_SDCARD
-                | PackageManager.INSTALL_ON_INTERNAL_FLASH);
+    public void testManifestInstallLocationUnspecified() {
+        installFromRawResource("install.apk", R.raw.install_loc_unspecified,
+                0, true, false, -1);
     }
 
-    /*
-     * Tests if an apk can be installed on sdcard by
-     * explicitly specifying in its manifest and filling up
-     * the sdcard. Should result in install failure
-     * TODO
-     */
-    public void xxxtestInstallLocationSdcardFail() {
+    public void testManifestInstallLocationFwdLockedSdcard() {
+        installFromRawResource("install.apk", R.raw.install_loc_sdcard,
+                PackageManager.INSTALL_FORWARD_LOCK |
+                PackageManager.INSTALL_EXTERNAL, true, true,
+                PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION);
     }
-
-    /*
-     * Tests if an apk can be installed by specifying
-     * auto for install location
-     */
-    public void xxxtestInstallLocationAutoInternal() {
-        // TODO clear and make room on internal flash
-        invokeRecommendAppInstallLocation("install.apk",
-                R.raw.install_loc_auto, PackageManager.INSTALL_ON_INTERNAL_FLASH);
-    }
-
-    /*
-     * Tests if an apk can be installed by specifying
-     * auto for install location
-     */
-    public void testInstallLocationAutoSdcard() {
-        // TODO clear and make room on sdcard.
-        // Fill up internal
-        invokeRecommendAppInstallLocation("install.apk",
-                R.raw.install_loc_auto, PackageManager.INSTALL_ON_SDCARD |
-                PackageManager.INSTALL_ON_INTERNAL_FLASH);
-    }
-
-    /*
-     * Tests if an apk can be installed by specifying
-     * auto for install location
-     * fill up both internal and sdcard
-     * TODO
-     */
-    public void xxxtestInstallLocationAutoFail() {
-    }
-    /*
-     * Tests where an apk gets installed based
-     * on a not specifying anything in manifest.
-     */
-    public void testInstallLocationUnspecifiedInt() {
-        invokeRecommendAppInstallLocation("install.apk",
-                R.raw.install_loc_unspecified, PackageManager.INSTALL_ON_INTERNAL_FLASH);
-    }
-
-    public void xxxtestInstallLocationUnspecifiedStorage() {
-        // TODO Fill up internal storage
-        invokeRecommendAppInstallLocation("install.apk",
-                R.raw.install_loc_unspecified, PackageManager.INSTALL_ON_SDCARD
-                | PackageManager.INSTALL_ON_INTERNAL_FLASH);
-    }
-
-    /*
-     * Tests where an apk gets installed by expcitly setting
-     * the user specified install location
-     */
-    public void testInstallLocationUserSpecifiedInternal() {
-        // Enable user setting
-        Settings.System.putInt(mContext.getContentResolver(),
-                Settings.System.SET_INSTALL_LOCATION, 1);
-        Settings.System.putInt(mContext.getContentResolver(),
-                Settings.System.DEFAULT_INSTALL_LOCATION, 1);
-        invokeRecommendAppInstallLocation("install.apk",
-                R.raw.install_loc_unspecified, PackageManager.INSTALL_ON_INTERNAL_FLASH);
-    }
-
-    /*
-     * Tests where an apk gets installed by expcitly setting
-     * the user specified install location
-     */
-    public void testInstallLocationUserSpecifiedSdcard() {
-        // Enable user setting
-        Settings.System.putInt(mContext.getContentResolver(),
-                Settings.System.SET_INSTALL_LOCATION, 1);
-        Settings.System.putInt(mContext.getContentResolver(),
-                Settings.System.DEFAULT_INSTALL_LOCATION, 2);
-        int i = Settings.System.getInt(mContext.getContentResolver(),
-                Settings.System.DEFAULT_INSTALL_LOCATION, 0);
-        invokeRecommendAppInstallLocation("install.apk",
-                R.raw.install_loc_unspecified, PackageManager.INSTALL_ON_SDCARD);
-        Settings.System.putInt(mContext.getContentResolver(),
-                Settings.System.SET_INSTALL_LOCATION, 0);
-    }
-    /*
-     * Tests where an apk gets installed by expcitly setting
-     * the user specified install location
-     */
-    public void testInstallLocationUserSpecifiedAuto() {
-        // Enable user setting
-        Settings.System.putInt(mContext.getContentResolver(),
-                Settings.System.SET_INSTALL_LOCATION, 1);
-        Settings.System.putInt(mContext.getContentResolver(),
-                Settings.System.DEFAULT_INSTALL_LOCATION, 0);
-        invokeRecommendAppInstallLocation("install.apk",
-                R.raw.install_loc_unspecified, PackageManager.INSTALL_ON_INTERNAL_FLASH);
-        Settings.System.putInt(mContext.getContentResolver(),
-                Settings.System.SET_INSTALL_LOCATION, 0);
-    }
-
     /*
      * TODO's
      * check version numbers for upgrades
diff --git a/tests/backup/AndroidManifest.xml b/tests/backup/AndroidManifest.xml
index d992627..3778742 100644
--- a/tests/backup/AndroidManifest.xml
+++ b/tests/backup/AndroidManifest.xml
@@ -1,6 +1,5 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
         package="com.android.backuptest">
-    <uses-permission android:name="android.permission.BACKUP_DATA" />
     <application android:backupAgent="BackupTestAgent">
         <activity android:name="BackupTestActivity" android:label="_BackupTest">
             <intent-filter>