diff --git a/api/current.xml b/api/current.xml
index 41714ef..af9c67d 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -23672,6 +23672,17 @@
 </implements>
 <implements name="android.content.DialogInterface.OnDismissListener">
 </implements>
+<method name="getSearchablesInGlobalSearch"
+ return="java.util.List&lt;android.app.SearchableInfo&gt;"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
 <method name="onCancel"
  return="void"
  abstract="false"
@@ -24131,6 +24142,444 @@
 >
 </method>
 </interface>
+<class name="SearchableInfo"
+ extends="java.lang.Object"
+ abstract="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<implements name="android.os.Parcelable">
+</implements>
+<method name="autoUrlDetect"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="describeContents"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="findActionKey"
+ return="android.app.SearchableInfo.ActionKeyInfo"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="keyCode" type="int">
+</parameter>
+</method>
+<method name="getHintId"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getIconId"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getImeOptions"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getInputType"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getLabelId"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getSearchActivity"
+ return="android.content.ComponentName"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getSearchButtonText"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getSettingsDescription"
+ return="java.lang.String"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getSuggestAuthority"
+ return="java.lang.String"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getSuggestIntentAction"
+ return="java.lang.String"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getSuggestIntentData"
+ return="java.lang.String"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getSuggestPackage"
+ return="java.lang.String"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getSuggestPath"
+ return="java.lang.String"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getSuggestSelection"
+ return="java.lang.String"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getSuggestThreshold"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getVoiceLanguageId"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getVoiceLanguageModeId"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getVoiceMaxResults"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getVoicePromptTextId"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getVoiceSearchEnabled"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getVoiceSearchLaunchRecognizer"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getVoiceSearchLaunchWebSearch"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="queryAfterZeroResults"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="shouldIncludeInGlobalSearch"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="shouldRewriteQueryFromData"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="shouldRewriteQueryFromText"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="writeToParcel"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="dest" type="android.os.Parcel">
+</parameter>
+<parameter name="flags" type="int">
+</parameter>
+</method>
+<field name="CREATOR"
+ type="android.os.Parcelable.Creator"
+ transient="false"
+ volatile="false"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+</class>
+<class name="SearchableInfo.ActionKeyInfo"
+ extends="java.lang.Object"
+ abstract="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<implements name="android.os.Parcelable">
+</implements>
+<method name="describeContents"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getKeyCode"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getQueryActionMsg"
+ return="java.lang.String"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getSuggestActionMsg"
+ return="java.lang.String"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getSuggestActionMsgColumn"
+ return="java.lang.String"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="writeToParcel"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="dest" type="android.os.Parcel">
+</parameter>
+<parameter name="flags" type="int">
+</parameter>
+</method>
+</class>
 <class name="Service"
  extends="android.content.ContextWrapper"
  abstract="true"
@@ -31903,6 +32352,17 @@
  visibility="public"
 >
 </field>
+<field name="BIND_NOT_FOREGROUND"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="4"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="CLIPBOARD_SERVICE"
  type="java.lang.String"
  transient="false"
@@ -83994,6 +84454,148 @@
 >
 </method>
 </class>
+<class name="TrafficStats"
+ extends="java.lang.Object"
+ abstract="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<constructor name="TrafficStats"
+ type="android.net.TrafficStats"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</constructor>
+<method name="getMobileRxBytes"
+ return="long"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getMobileRxPkts"
+ return="long"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getMobileTxBytes"
+ return="long"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getMobileTxPkts"
+ return="long"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getTotalRxBytes"
+ return="long"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getTotalRxPkts"
+ return="long"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getTotalTxBytes"
+ return="long"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getTotalTxPkts"
+ return="long"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getUidRxBytes"
+ return="long"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="uid" type="int">
+</parameter>
+</method>
+<method name="getUidTxBytes"
+ return="long"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="uid" type="int">
+</parameter>
+</method>
+<field name="UNSUPPORTED"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="-1"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+</class>
 <class name="Uri"
  extends="java.lang.Object"
  abstract="true"
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 467812e..1115f92 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -691,6 +691,20 @@
                     if (rd != null) {
                         rd.performReceive(intent, resultCode, data, extras,
                                 ordered, sticky);
+                    } else {
+                        // The activity manager dispatched a broadcast to a registered
+                        // receiver in this process, but before it could be delivered the
+                        // receiver was unregistered.  Acknowledge the broadcast on its
+                        // behalf so that the system's broadcast sequence can continue.
+                        if (DEBUG_BROADCAST) {
+                            Log.i(TAG, "Broadcast to unregistered receiver");
+                        }
+                        IActivityManager mgr = ActivityManagerNative.getDefault();
+                        try {
+                            mgr.finishReceiver(this, resultCode, data, extras, false);
+                        } catch (RemoteException e) {
+                            Log.w(TAG, "Couldn't finish broadcast to unregistered receiver");
+                        }
                     }
                 }
             }
@@ -716,8 +730,8 @@
                     BroadcastReceiver receiver = mReceiver;
                     if (DEBUG_BROADCAST) {
                         int seq = mCurIntent.getIntExtra("seq", -1);
-                        Log.i(TAG, "Dispathing broadcast " + mCurIntent.getAction() + " seq=" + seq
-                                + " to " + mReceiver);
+                        Log.i(TAG, "Dispatching broadcast " + mCurIntent.getAction()
+                                + " seq=" + seq + " to " + mReceiver);
                     }
                     if (receiver == null) {
                         return;
diff --git a/core/java/android/app/SearchManager.java b/core/java/android/app/SearchManager.java
index ab5e102..1f17476 100644
--- a/core/java/android/app/SearchManager.java
+++ b/core/java/android/app/SearchManager.java
@@ -2038,10 +2038,8 @@
      * Returns a list of the searchable activities that can be included in global search.
      * 
      * @return a list containing searchable information for all searchable activities
-     *         that have the <code>exported</code> attribute set in their searchable
-     *         meta-data.
-     * 
-     * @hide because SearchableInfo is not part of the API.
+     *         that have the <code>android:includeInGlobalSearch</code> attribute set
+     *         in their searchable meta-data.
      */
     public List<SearchableInfo> getSearchablesInGlobalSearch() {
         try {
diff --git a/core/java/android/app/SearchableInfo.java b/core/java/android/app/SearchableInfo.java
index cbf7b3d..9897742 100644
--- a/core/java/android/app/SearchableInfo.java
+++ b/core/java/android/app/SearchableInfo.java
@@ -38,8 +38,9 @@
 import java.util.HashMap;
 
 /**
- * 
- * @hide Pending API council approval
+ * Searchability meta-data for an activity.
+ * See <a href="SearchManager.html#SearchabilityMetadata">Searchability meta-data</a>
+ * for more information.
  */
 public final class SearchableInfo implements Parcelable {
 
@@ -87,9 +88,9 @@
     private final String mSuggestProviderPackage;
     
     // Flag values for Searchable_voiceSearchMode
-    private static int VOICE_SEARCH_SHOW_BUTTON = 1;
-    private static int VOICE_SEARCH_LAUNCH_WEB_SEARCH = 2;
-    private static int VOICE_SEARCH_LAUNCH_RECOGNIZER = 4;
+    private static final int VOICE_SEARCH_SHOW_BUTTON = 1;
+    private static final int VOICE_SEARCH_LAUNCH_WEB_SEARCH = 2;
+    private static final int VOICE_SEARCH_LAUNCH_RECOGNIZER = 4;
     private final int mVoiceSearchMode;
     private final int mVoiceLanguageModeId;       // voiceLanguageModel
     private final int mVoicePromptTextId;         // voicePromptText
@@ -123,6 +124,8 @@
 
     /**
      * Checks whether the badge should be a text label.
+     *
+     * @hide This feature is deprecated, no need to add it to the API.
      */
     public boolean useBadgeLabel() {
         return 0 != (mSearchMode & SEARCH_MODE_BADGE_LABEL);
@@ -130,6 +133,8 @@
 
     /**
      * Checks whether the badge should be an icon.
+     *
+     * @hide This feature is deprecated, no need to add it to the API.
      */
     public boolean useBadgeIcon() {
         return (0 != (mSearchMode & SEARCH_MODE_BADGE_ICON)) && (mIconId != 0);
@@ -220,6 +225,7 @@
      * 
      * @param context You need to supply a context to start with
      * @return Returns a context related to the searchable activity
+     * @hide
      */
     public Context getActivityContext(Context context) {
         return createActivityContext(context, mSearchActivity);
@@ -251,6 +257,7 @@
      * @param activityContext If we can determine that the provider and the activity are the
      * same, we'll just return this one.
      * @return Returns a context related to the context provider
+     * @hide
      */
     public Context getProviderContext(Context context, Context activityContext) {
         Context theirContext = null;
@@ -351,7 +358,11 @@
     }
     
     /**
-     * Private class used to hold the "action key" configuration
+     * Information about an action key in searchability meta-data.
+     * See <a href="SearchManager.html#SearchabilityMetadata">Searchability meta-data</a>
+     * for more information.
+     *
+     * @see SearchableInfo#findActionKey(int)
      */
     public static class ActionKeyInfo implements Parcelable {
         
@@ -368,7 +379,7 @@
          * construct the object.
          * @throws IllegalArgumentException if the action key configuration is invalid
          */
-        public ActionKeyInfo(Context activityContext, AttributeSet attr) {
+        ActionKeyInfo(Context activityContext, AttributeSet attr) {
             TypedArray a = activityContext.obtainStyledAttributes(attr,
                     com.android.internal.R.styleable.SearchableActionKey);
 
@@ -399,7 +410,7 @@
          * @param in The Parcel containing the previously written ActionKeyInfo,
          * positioned at the location in the buffer where it was written.
          */
-        public ActionKeyInfo(Parcel in) {
+        private ActionKeyInfo(Parcel in) {
             mKeyCode = in.readInt();
             mQueryActionMsg = in.readString();
             mSuggestActionMsg = in.readString();
@@ -461,6 +472,8 @@
      * @param activityInfo Activity to get search information from.
      * @return Search information about the given activity, or {@code null} if
      *         the activity has no or invalid searchability meta-data.
+     *
+     * @hide For use by SearchManagerService.
      */
     public static SearchableInfo getActivityMetaData(Context context, ActivityInfo activityInfo) {
         // for each component, try to find metadata
@@ -720,7 +733,7 @@
      * @param in The Parcel containing the previously written SearchableInfo,
      * positioned at the location in the buffer where it was written.
      */
-    public SearchableInfo(Parcel in) {
+    SearchableInfo(Parcel in) {
         mLabelId = in.readInt();
         mSearchActivity = ComponentName.readFromParcel(in);
         mHintId = in.readInt();
diff --git a/core/java/android/content/AbstractThreadedSyncAdapter.java b/core/java/android/content/AbstractThreadedSyncAdapter.java
index 0db6155..091d44e 100644
--- a/core/java/android/content/AbstractThreadedSyncAdapter.java
+++ b/core/java/android/content/AbstractThreadedSyncAdapter.java
@@ -17,10 +17,10 @@
 package android.content;
 
 import android.accounts.Account;
+import android.net.TrafficStats;
 import android.os.Bundle;
-import android.os.Process;
-import android.os.NetStat;
 import android.os.IBinder;
+import android.os.Process;
 import android.os.RemoteException;
 import android.util.EventLog;
 
@@ -157,8 +157,8 @@
 
             SyncResult syncResult = new SyncResult();
             int uid = Process.myUid();
-            mInitialTxBytes = NetStat.getUidTxBytes(uid);
-            mInitialRxBytes = NetStat.getUidRxBytes(uid);
+            mInitialTxBytes = TrafficStats.getUidTxBytes(uid);
+            mInitialRxBytes = TrafficStats.getUidRxBytes(uid);
             ContentProviderClient provider = null;
             try {
                 provider = mContext.getContentResolver().acquireContentProviderClient(mAuthority);
@@ -175,8 +175,8 @@
                 if (!isCanceled()) {
                     mSyncContext.onFinished(syncResult);
                 }
-                onLogSyncDetails(NetStat.getUidTxBytes(uid) - mInitialTxBytes,
-                        NetStat.getUidRxBytes(uid) - mInitialRxBytes, syncResult);
+                onLogSyncDetails(TrafficStats.getUidTxBytes(uid) - mInitialTxBytes,
+                        TrafficStats.getUidRxBytes(uid) - mInitialRxBytes, syncResult);
                 // synchronize so that the assignment will be seen by other threads
                 // that also synchronize accesses to mSyncThread
                 synchronized (mSyncThreadLock) {
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 3344158..2ab5357 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -104,6 +104,18 @@
      */
     public static final int BIND_DEBUG_UNBIND = 0x0002;
 
+    /**
+     * Flag for {@link #bindService}: don't allow this binding to raise
+     * the target service's process to the foreground scheduling priority.
+     * It will still be raised to the at least the same memory priority
+     * as the client (so that its process will not be killable in any
+     * situation where the client is not killable), but for CPU scheduling
+     * purposes it may be left in the background.  This only has an impact
+     * in the situation where the binding client is a foreground process
+     * and the target service is in a background process.
+     */
+    public static final int BIND_NOT_FOREGROUND = 0x0004;
+
     /** Return an AssetManager instance for your application's package. */
     public abstract AssetManager getAssets();
 
diff --git a/core/java/android/content/SyncManager.java b/core/java/android/content/SyncManager.java
index 0589ce6..d436365 100644
--- a/core/java/android/content/SyncManager.java
+++ b/core/java/android/content/SyncManager.java
@@ -557,7 +557,7 @@
         intent.setAction("android.content.SyncAdapter");
         intent.setComponent(syncAdapterInfo.componentName);
         mContext.bindService(intent, new InitializerServiceConnection(account, authority),
-                Context.BIND_AUTO_CREATE);
+                Context.BIND_AUTO_CREATE | Context.BIND_NOT_FOREGROUND);
     }
 
     private class InitializerServiceConnection implements ServiceConnection {
@@ -1145,7 +1145,8 @@
                     com.android.internal.R.string.sync_binding_label);
             intent.putExtra(Intent.EXTRA_CLIENT_INTENT, PendingIntent.getActivity(
                     mContext, 0, new Intent(Settings.ACTION_SYNC_SETTINGS), 0));
-            return mContext.bindService(intent, this, Context.BIND_AUTO_CREATE);
+            return mContext.bindService(intent, this,
+                    Context.BIND_AUTO_CREATE | Context.BIND_NOT_FOREGROUND);
         }
 
         void unBindFromSyncAdapter() {
diff --git a/core/java/android/content/TempProviderSyncAdapter.java b/core/java/android/content/TempProviderSyncAdapter.java
index b46c545..5ccaa26 100644
--- a/core/java/android/content/TempProviderSyncAdapter.java
+++ b/core/java/android/content/TempProviderSyncAdapter.java
@@ -1,9 +1,12 @@
 package android.content;
 
+import android.accounts.Account;
+import android.accounts.AuthenticatorException;
+import android.accounts.OperationCanceledException;
 import android.database.SQLException;
+import android.net.TrafficStats;
 import android.os.Bundle;
 import android.os.Debug;
-import android.os.NetStat;
 import android.os.Parcelable;
 import android.os.Process;
 import android.os.SystemProperties;
@@ -12,9 +15,6 @@
 import android.util.EventLog;
 import android.util.Log;
 import android.util.TimingLogger;
-import android.accounts.Account;
-import android.accounts.AuthenticatorException;
-import android.accounts.OperationCanceledException;
 
 import java.io.IOException;
 
@@ -203,8 +203,8 @@
             if (mProviderSyncStarted) mProvider.onSyncCanceled();
             // We may lose the last few sync events when canceling.  Oh well.
             int uid = Process.myUid();
-            logSyncDetails(NetStat.getUidTxBytes(uid) - mInitialTxBytes,
-                    NetStat.getUidRxBytes(uid) - mInitialRxBytes, mResult);
+            logSyncDetails(TrafficStats.getUidTxBytes(uid) - mInitialTxBytes,
+                    TrafficStats.getUidRxBytes(uid) - mInitialRxBytes, mResult);
         }
         
         @Override
@@ -212,8 +212,8 @@
             Process.setThreadPriority(Process.myTid(),
                     Process.THREAD_PRIORITY_BACKGROUND);
             int uid = Process.myUid();
-            mInitialTxBytes = NetStat.getUidTxBytes(uid);
-            mInitialRxBytes = NetStat.getUidRxBytes(uid);
+            mInitialTxBytes = TrafficStats.getUidTxBytes(uid);
+            mInitialRxBytes = TrafficStats.getUidRxBytes(uid);
             try {
                 sync(mSyncContext, mAccount, mAuthority, mExtras);
             } catch (SQLException e) {
@@ -222,8 +222,8 @@
             } finally {
                 mSyncThread = null;
                 if (!mIsCanceled) {
-                    logSyncDetails(NetStat.getUidTxBytes(uid) - mInitialTxBytes,
-                    NetStat.getUidRxBytes(uid) - mInitialRxBytes, mResult);
+                    logSyncDetails(TrafficStats.getUidTxBytes(uid) - mInitialTxBytes,
+                    TrafficStats.getUidRxBytes(uid) - mInitialRxBytes, mResult);
                     mSyncContext.onFinished(mResult);
                 }
             }
diff --git a/core/java/android/inputmethodservice/KeyboardView.java b/core/java/android/inputmethodservice/KeyboardView.java
index 0f7ef22..76131fc 100755
--- a/core/java/android/inputmethodservice/KeyboardView.java
+++ b/core/java/android/inputmethodservice/KeyboardView.java
@@ -1127,7 +1127,7 @@
         
         // Needs to be called after the gesture detector gets a turn, as it may have
         // displayed the mini keyboard
-        if (mMiniKeyboardOnScreen) {
+        if (mMiniKeyboardOnScreen && action != MotionEvent.ACTION_CANCEL) {
             return true;
         }
 
@@ -1222,6 +1222,7 @@
                 break;
             case MotionEvent.ACTION_CANCEL:
                 removeMessages();
+                dismissPopupKeyboard();
                 mAbortKey = true;
                 showPreview(NOT_A_KEY);
                 invalidateKey(mCurrentKey);
diff --git a/core/java/android/os/NetStat.java b/core/java/android/net/TrafficStats.java
similarity index 71%
rename from core/java/android/os/NetStat.java
rename to core/java/android/net/TrafficStats.java
index e294cdf..62e9f1f 100644
--- a/core/java/android/os/NetStat.java
+++ b/core/java/android/net/TrafficStats.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package android.os;
+package android.net;
 
 import android.util.Log;
 
@@ -22,11 +22,22 @@
 import java.io.RandomAccessFile;
 import java.io.IOException;
 
-/** @hide */
-public class NetStat {
+/**
+ * Class that provides network traffic statistics.  These statistics include bytes transmitted and
+ * received and network packets transmitted and received, over all interfaces, over the mobile
+ * interface, and on a per-UID basis.
+ * <p>
+ * These statistics may not be available on all platforms.  If the statistics are not supported
+ * by this device, {@link #UNSUPPORTED} will be returned.
+ */
+public class TrafficStats {
+    /**
+     * The return value to indicate that the device does not support the statistic.
+     */
+    public final static int UNSUPPORTED = -1;
 
     // Logging tag.
-    private final static String TAG = "netstat";
+    private final static String TAG = "trafficstats";
 
     // We pre-create all the File objects so we don't spend a lot of
     // CPU at runtime converting from Java Strings to byte[] for the
@@ -38,36 +49,40 @@
     private final static File SYS_CLASS_NET_DIR = new File("/sys/class/net");
 
     /**
-     * Get total number of tx packets sent through rmnet0 or ppp0
+     * Get the total number of packets transmitted through the mobile interface.
      *
-     * @return number of Tx packets through rmnet0 or ppp0
+     * @return number of packets.  If the statistics are not supported by this device,
+     * {@link #UNSUPPORTED} will be returned.
      */
     public static long getMobileTxPkts() {
         return getMobileStat(MOBILE_TX_PACKETS);
     }
 
     /**
-     *  Get total number of rx packets received through rmnet0 or ppp0
+     * Get the total number of packets received through the mobile interface.
      *
-     * @return number of Rx packets through rmnet0 or ppp0
+     * @return number of packets.  If the statistics are not supported by this device,
+     * {@link #UNSUPPORTED} will be returned.
      */
     public static long getMobileRxPkts() {
         return getMobileStat(MOBILE_RX_PACKETS);
     }
 
     /**
-     *  Get total number of tx bytes received through rmnet0 or ppp0
+     * Get the total number of bytes transmitted through the mobile interface.
      *
-     * @return number of Tx bytes through rmnet0 or ppp0
+     * @return number of bytes.  If the statistics are not supported by this device,
+     * {@link #UNSUPPORTED} will be returned.
      */
       public static long getMobileTxBytes() {
           return getMobileStat(MOBILE_TX_BYTES);
       }
 
     /**
-     *  Get total number of rx bytes received through rmnet0 or ppp0
+     * Get the total number of bytes received through the mobile interface.
      *
-     * @return number of Rx bytes through rmnet0 or ppp0
+     * @return number of bytes.  If the statistics are not supported by this device,
+     * {@link #UNSUPPORTED} will be returned.
      */
     public static long getMobileRxBytes() {
         return getMobileStat(MOBILE_RX_BYTES);
@@ -76,7 +91,8 @@
     /**
      * Get the total number of packets sent through all network interfaces.
      *
-     * @return the number of packets sent through all network interfaces
+     * @return the number of packets.  If the statistics are not supported by this device,
+     * {@link #UNSUPPORTED} will be returned.
      */
     public static long getTotalTxPkts() {
         return getTotalStat("tx_packets");
@@ -85,7 +101,8 @@
     /**
      * Get the total number of packets received through all network interfaces.
      *
-     * @return the number of packets received through all network interfaces
+     * @return number of packets.  If the statistics are not supported by this device,
+     * {@link #UNSUPPORTED} will be returned.
      */
     public static long getTotalRxPkts() {
         return getTotalStat("rx_packets");
@@ -94,7 +111,8 @@
     /**
      * Get the total number of bytes sent through all network interfaces.
      *
-     * @return the number of bytes sent through all network interfaces
+     * @return number of bytes.  If the statistics are not supported by this device,
+     * {@link #UNSUPPORTED} will be returned.
      */
     public static long getTotalTxBytes() {
         return getTotalStat("tx_bytes");
@@ -103,35 +121,35 @@
     /**
      * Get the total number of bytes received through all network interfaces.
      *
-     * @return the number of bytes received through all network interfaces
+     * @return number of bytes.  If the statistics are not supported by this device,
+     * {@link #UNSUPPORTED} will be returned.
      */
     public static long getTotalRxBytes() {
         return getTotalStat("rx_bytes");
     }
 
     /**
-     * Gets network bytes sent for this UID.
+     * Get the number of bytes sent through the network for this UID.
      * The statistics are across all interfaces.
-     * The statistics come from /proc/uid_stat.
      *
      * {@see android.os.Process#myUid()}.
      *
-     * @param uid
-     * @return byte count
+     * @param uid The UID of the process to examine.
+     * @return number of bytes.  If the statistics are not supported by this device,
+     * {@link #UNSUPPORTED} will be returned.
      */
     public static long getUidTxBytes(int uid) {
         return getNumberFromFilePath("/proc/uid_stat/" + uid + "/tcp_snd");
     }
 
     /**
-     * Gets network bytes received for this UID.
+     * Get the number of bytes received through the network for this UID.
      * The statistics are across all interfaces.
-     * The statistics come from /proc/uid_stat.
      *
      * {@see android.os.Process#myUid()}.
      *
-     * @param uid
-     * @return byte count
+     * @param uid The UID of the process to examine.
+     * @return number of bytes
      */
     public static long getUidRxBytes(int uid) {
         return getNumberFromFilePath("/proc/uid_stat/" + uid + "/tcp_rcv");
@@ -159,7 +177,7 @@
 
         File[] nets = SYS_CLASS_NET_DIR.listFiles();
         if (nets == null) {
-            return 0;
+            return UNSUPPORTED;
         }
         long total = 0;
         StringBuffer strbuf = new StringBuffer();
@@ -187,14 +205,14 @@
                       e);
             }
         }
-        return 0L;
+        return UNSUPPORTED;
     }
 
     // File will have format <number><newline>
     private static long getNumberFromFilePath(String filename) {
         RandomAccessFile raf = getFile(filename);
         if (raf == null) {
-            return 0L;
+            return UNSUPPORTED;
         }
         return getNumberFromFile(raf, filename);
     }
@@ -209,7 +227,7 @@
             raf.close();
         } catch (IOException e) {
             Log.w(TAG, "Exception getting TCP bytes from " + filename, e);
-            return 0L;
+            return UNSUPPORTED;
         } finally {
             if (raf != null) {
                 try {
diff --git a/core/java/android/provider/Gmail.java b/core/java/android/provider/Gmail.java
deleted file mode 100644
index 8bb7adf..0000000
--- a/core/java/android/provider/Gmail.java
+++ /dev/null
@@ -1,2468 +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.provider;
-
-import com.google.android.collect.Lists;
-import com.google.android.collect.Maps;
-import com.google.android.collect.Sets;
-
-import android.content.AsyncQueryHandler;
-import android.content.ContentQueryMap;
-import android.content.ContentResolver;
-import android.content.ContentUris;
-import android.content.ContentValues;
-import android.database.ContentObserver;
-import android.database.Cursor;
-import android.database.DataSetObserver;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.Handler;
-import android.text.Html;
-import android.text.SpannableStringBuilder;
-import android.text.Spanned;
-import android.text.TextUtils;
-import android.text.TextUtils.SimpleStringSplitter;
-import android.text.style.CharacterStyle;
-import android.util.Log;
-
-import com.android.common.Patterns;
-
-import java.io.UnsupportedEncodingException;
-import java.net.URLEncoder;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Observable;
-import java.util.Observer;
-import java.util.Set;
-import java.util.SortedSet;
-import java.util.TreeSet;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * A thin wrapper over the content resolver for accessing the gmail provider.
- *
- * @hide
- */
-public final class Gmail {
-    // Set to true to enable extra debugging.
-    private static final boolean DEBUG = false;
-
-    public static final String GMAIL_AUTH_SERVICE = "mail";
-    // These constants come from google3/java/com/google/caribou/backend/MailLabel.java.
-    public static final String LABEL_SENT = "^f";
-    public static final String LABEL_INBOX = "^i";
-    public static final String LABEL_DRAFT = "^r";
-    public static final String LABEL_UNREAD = "^u";
-    public static final String LABEL_TRASH = "^k";
-    public static final String LABEL_SPAM = "^s";
-    public static final String LABEL_STARRED = "^t";
-    public static final String LABEL_CHAT = "^b"; // 'b' for 'buzz'
-    public static final String LABEL_VOICEMAIL = "^vm";
-    public static final String LABEL_IGNORED = "^g";
-    public static final String LABEL_ALL = "^all";
-    // These constants (starting with "^^") are only used locally and are not understood by the
-    // server.
-    public static final String LABEL_VOICEMAIL_INBOX = "^^vmi";
-    public static final String LABEL_CACHED = "^^cached";
-    public static final String LABEL_OUTBOX = "^^out";
-
-    public static final String AUTHORITY = "gmail-ls";
-    private static final String TAG = "Gmail";
-    private static final String AUTHORITY_PLUS_CONVERSATIONS =
-            "content://" + AUTHORITY + "/conversations/";
-    private static final String AUTHORITY_PLUS_LABELS =
-            "content://" + AUTHORITY + "/labels/";
-    private static final String AUTHORITY_PLUS_MESSAGES =
-            "content://" + AUTHORITY + "/messages/";
-    private static final String AUTHORITY_PLUS_SETTINGS =
-            "content://" + AUTHORITY + "/settings/";
-
-    public static final Uri BASE_URI = Uri.parse(
-            "content://" + AUTHORITY);
-    private static final Uri LABELS_URI =
-            Uri.parse(AUTHORITY_PLUS_LABELS);
-    private static final Uri CONVERSATIONS_URI =
-            Uri.parse(AUTHORITY_PLUS_CONVERSATIONS);
-    private static final Uri SETTINGS_URI =
-            Uri.parse(AUTHORITY_PLUS_SETTINGS);
-
-    /** Separates email addresses in strings in the database. */
-    public static final String EMAIL_SEPARATOR = "\n";
-    public static final Pattern EMAIL_SEPARATOR_PATTERN = Pattern.compile(EMAIL_SEPARATOR);
-
-    /**
-     * Space-separated lists have separators only between items.
-     */
-    private static final char SPACE_SEPARATOR = ' ';
-    public static final Pattern SPACE_SEPARATOR_PATTERN = Pattern.compile(" ");
-
-    /**
-     * Comma-separated lists have separators between each item, before the first and after the last
-     * item. The empty list is <tt>,</tt>.
-     *
-     * <p>This makes them easier to modify with SQL since it is not a special case to add or
-     * remove the last item. Having a separator on each side of each value also makes it safe to use
-     * SQL's REPLACE to remove an item from a string by using REPLACE(',value,', ',').
-     *
-     * <p>We could use the same separator for both lists but this makes it easier to remember which
-     * kind of list one is dealing with.
-     */
-    private static final char COMMA_SEPARATOR = ',';
-    public static final Pattern COMMA_SEPARATOR_PATTERN = Pattern.compile(",");
-
-    /** Separates attachment info parts in strings in the database. */
-    public static final String ATTACHMENT_INFO_SEPARATOR = "\n";
-    public static final Pattern ATTACHMENT_INFO_SEPARATOR_PATTERN =
-            Pattern.compile(ATTACHMENT_INFO_SEPARATOR);
-
-    public static final Character SENDER_LIST_SEPARATOR = '\n';
-    public static final String SENDER_LIST_TOKEN_ELIDED = "e";
-    public static final String SENDER_LIST_TOKEN_NUM_MESSAGES = "n";
-    public static final String SENDER_LIST_TOKEN_NUM_DRAFTS = "d";
-    public static final String SENDER_LIST_TOKEN_LITERAL = "l";
-    public static final String SENDER_LIST_TOKEN_SENDING = "s";
-    public static final String SENDER_LIST_TOKEN_SEND_FAILED = "f";
-
-    /** Used for finding status in a cursor's extras. */
-    public static final String EXTRA_STATUS = "status";
-
-    public static final String RESPOND_INPUT_COMMAND = "command";
-    public static final String COMMAND_RETRY = "retry";
-    public static final String COMMAND_ACTIVATE = "activate";
-    public static final String COMMAND_SET_VISIBLE = "setVisible";
-    public static final String SET_VISIBLE_PARAM_VISIBLE = "visible";
-    public static final String RESPOND_OUTPUT_COMMAND_RESPONSE = "commandResponse";
-    public static final String COMMAND_RESPONSE_OK =  "ok";
-    public static final String COMMAND_RESPONSE_UNKNOWN =  "unknownCommand";
-
-    public static final String INSERT_PARAM_ATTACHMENT_ORIGIN = "origin";
-    public static final String INSERT_PARAM_ATTACHMENT_ORIGIN_EXTRAS = "originExtras";
-
-    private static final Pattern NAME_ADDRESS_PATTERN = Pattern.compile("\"(.*)\"");
-    private static final Pattern UNNAMED_ADDRESS_PATTERN = Pattern.compile("([^<]+)@");
-
-    private static final Map<Integer, Integer> sPriorityToLength = Maps.newHashMap();
-    public static final SimpleStringSplitter sSenderListSplitter = 
-            new SimpleStringSplitter(SENDER_LIST_SEPARATOR);
-    public static String[] sSenderFragments = new String[8];
-
-    /**
-     * Returns the name in an address string
-     * @param addressString such as &quot;bobby&quot; &lt;bob@example.com&gt;
-     * @return returns the quoted name in the addressString, otherwise the username from the email
-     *   address
-     */
-    public static String getNameFromAddressString(String addressString) {
-        Matcher namedAddressMatch = NAME_ADDRESS_PATTERN.matcher(addressString);
-        if (namedAddressMatch.find()) {
-            String name = namedAddressMatch.group(1);
-            if (name.length() > 0) return name;
-            addressString =
-                    addressString.substring(namedAddressMatch.end(), addressString.length());
-        }
-
-        Matcher unnamedAddressMatch = UNNAMED_ADDRESS_PATTERN.matcher(addressString);
-        if (unnamedAddressMatch.find()) {
-            return unnamedAddressMatch.group(1);
-        }
-
-        return addressString;
-    }
-
-    /**
-     * Returns the email address in an address string
-     * @param addressString such as &quot;bobby&quot; &lt;bob@example.com&gt;
-     * @return returns the email address, such as bob@example.com from the example above
-     */
-    public static String getEmailFromAddressString(String addressString) {
-        String result = addressString;
-        Matcher match = Patterns.EMAIL_ADDRESS.matcher(addressString);
-        if (match.find()) {
-            result = addressString.substring(match.start(), match.end());
-        }
-
-        return result;
-    }
-
-    /**
-     * Returns whether the label is user-defined (versus system-defined labels such as inbox, whose
-     * names start with "^").
-     */
-    public static boolean isLabelUserDefined(String label) {
-        // TODO: label should never be empty so we should be able to say [label.charAt(0) != '^'].
-        // However, it's a release week and I'm too scared to make that change.
-        return !label.startsWith("^");
-    }
-
-    private static final Set<String> USER_SETTABLE_BUILTIN_LABELS = Sets.newHashSet(
-            Gmail.LABEL_INBOX,
-            Gmail.LABEL_UNREAD,
-            Gmail.LABEL_TRASH,
-            Gmail.LABEL_SPAM,
-            Gmail.LABEL_STARRED,
-            Gmail.LABEL_IGNORED);
-
-    /**
-     * Returns whether the label is user-settable. For example, labels such as LABEL_DRAFT should
-     * only be set internally.
-     */
-    public static boolean isLabelUserSettable(String label) {
-        return USER_SETTABLE_BUILTIN_LABELS.contains(label) || isLabelUserDefined(label);
-    }
-
-    /**
-     * Returns the set of labels using the raw labels from a previous getRawLabels()
-     * as input.
-     * @return a copy of the set of labels. To add or remove labels call
-     * MessageCursor.addOrRemoveLabel on each message in the conversation.
-     */
-    public static Set<Long> getLabelIdsFromLabelIdsString(
-            TextUtils.StringSplitter splitter) {
-        Set<Long> labelIds = Sets.newHashSet();
-        for (String labelIdString : splitter) {
-            labelIds.add(Long.valueOf(labelIdString));
-        }
-        return labelIds;
-    }
-
-    /**
-     * @deprecated remove when the activities stop using canonical names to identify labels
-     */
-    public static Set<String> getCanonicalNamesFromLabelIdsString(
-            LabelMap labelMap, TextUtils.StringSplitter splitter) {
-        Set<String> canonicalNames = Sets.newHashSet();
-        for (long labelId : getLabelIdsFromLabelIdsString(splitter)) {
-            final String canonicalName = labelMap.getCanonicalName(labelId);
-            // We will sometimes see labels that the label map does not yet know about or that
-            // do not have names yet.
-            if (!TextUtils.isEmpty(canonicalName)) {
-                canonicalNames.add(canonicalName);
-            } else {
-                Log.w(TAG, "getCanonicalNamesFromLabelIdsString skipping label id: " + labelId);
-            }
-        }
-        return canonicalNames;
-    }
-
-    /**
-     * @return a StringSplitter that is configured to split message label id strings
-     */
-    public static TextUtils.StringSplitter newMessageLabelIdsSplitter() {
-        return new TextUtils.SimpleStringSplitter(SPACE_SEPARATOR);
-    }
-
-    /**
-     * @return a StringSplitter that is configured to split conversation label id strings
-     */
-    public static TextUtils.StringSplitter newConversationLabelIdsSplitter() {
-        return new CommaStringSplitter();
-    }
-
-    /**
-     * A splitter for strings of the form described in the docs for COMMA_SEPARATOR.
-     */
-    private static class CommaStringSplitter extends TextUtils.SimpleStringSplitter {
-
-        public CommaStringSplitter() {
-            super(COMMA_SEPARATOR);
-        }
-
-        @Override
-        public void setString(String string) {
-            // The string should always be at least a single comma.
-            super.setString(string.substring(1));
-        }
-    }
-
-    /**
-     * Creates a single string of the form that getLabelIdsFromLabelIdsString can split.
-     */
-    public static String getLabelIdsStringFromLabelIds(Set<Long> labelIds) {
-        StringBuilder sb = new StringBuilder();
-        sb.append(COMMA_SEPARATOR);
-        for (Long labelId : labelIds) {
-            sb.append(labelId);
-            sb.append(COMMA_SEPARATOR);
-        }
-        return sb.toString();
-    }
-
-    public static final class ConversationColumns {
-        public static final String ID = "_id";
-        public static final String SUBJECT = "subject";
-        public static final String SNIPPET = "snippet";
-        public static final String FROM = "fromAddress";
-        public static final String DATE = "date";
-        public static final String PERSONAL_LEVEL = "personalLevel";
-        /** A list of label names with a space after each one (including the last one). This makes
-         * it easier remove individual labels from this list using SQL. */
-        public static final String LABEL_IDS = "labelIds";
-        public static final String NUM_MESSAGES = "numMessages";
-        public static final String MAX_MESSAGE_ID = "maxMessageId";
-        public static final String HAS_ATTACHMENTS = "hasAttachments";
-        public static final String HAS_MESSAGES_WITH_ERRORS = "hasMessagesWithErrors";
-        public static final String FORCE_ALL_UNREAD = "forceAllUnread";
-
-        private ConversationColumns() {}
-    }
-
-    public static final class MessageColumns {
-
-        public static final String ID = "_id";
-        public static final String MESSAGE_ID = "messageId";
-        public static final String CONVERSATION_ID = "conversation";
-        public static final String SUBJECT = "subject";
-        public static final String SNIPPET = "snippet";
-        public static final String FROM = "fromAddress";
-        public static final String TO = "toAddresses";
-        public static final String CC = "ccAddresses";
-        public static final String BCC = "bccAddresses";
-        public static final String REPLY_TO = "replyToAddresses";
-        public static final String DATE_SENT_MS = "dateSentMs";
-        public static final String DATE_RECEIVED_MS = "dateReceivedMs";
-        public static final String LIST_INFO = "listInfo";
-        public static final String PERSONAL_LEVEL = "personalLevel";
-        public static final String BODY = "body";
-        public static final String EMBEDS_EXTERNAL_RESOURCES = "bodyEmbedsExternalResources";
-        public static final String LABEL_IDS = "labelIds";
-        public static final String JOINED_ATTACHMENT_INFOS = "joinedAttachmentInfos";
-        public static final String ERROR = "error";
-        // TODO: add a method for accessing this
-        public static final String REF_MESSAGE_ID = "refMessageId";
-
-        // Fake columns used only for saving or sending messages.
-        public static final String FAKE_SAVE = "save";
-        public static final String FAKE_REF_MESSAGE_ID = "refMessageId";
-
-        private MessageColumns() {}
-    }
-
-    public static final class LabelColumns {
-        public static final String CANONICAL_NAME = "canonicalName";
-        public static final String NAME = "name";
-        public static final String NUM_CONVERSATIONS = "numConversations";
-        public static final String NUM_UNREAD_CONVERSATIONS =
-                "numUnreadConversations";
-
-        private LabelColumns() {}
-    }
-
-    public static final class SettingsColumns {
-        public static final String LABELS_INCLUDED = "labelsIncluded";
-        public static final String LABELS_PARTIAL = "labelsPartial";
-        public static final String CONVERSATION_AGE_DAYS =
-                "conversationAgeDays";
-        public static final String MAX_ATTACHMENET_SIZE_MB =
-                "maxAttachmentSize";
-    }
-
-    /**
-     * These flags can be included as Selection Arguments when
-     * querying the provider.
-     */
-    public static class SelectionArguments {
-        private SelectionArguments() {
-            // forbid instantiation
-        }
-
-        /**
-         * Specifies that you do NOT wish the returned cursor to
-         * become the Active Network Cursor.  If you do not include
-         * this flag as a selectionArg, the new cursor will become the
-         * Active Network Cursor by default.
-         */
-        public static final String DO_NOT_BECOME_ACTIVE_NETWORK_CURSOR =
-                "SELECTION_ARGUMENT_DO_NOT_BECOME_ACTIVE_NETWORK_CURSOR";
-    }
-
-    // These are the projections that we need when getting cursors from the
-    // content provider.
-    private static String[] CONVERSATION_PROJECTION = {
-            ConversationColumns.ID,
-            ConversationColumns.SUBJECT,
-            ConversationColumns.SNIPPET,
-            ConversationColumns.FROM,
-            ConversationColumns.DATE,
-            ConversationColumns.PERSONAL_LEVEL,
-            ConversationColumns.LABEL_IDS,
-            ConversationColumns.NUM_MESSAGES,
-            ConversationColumns.MAX_MESSAGE_ID,
-            ConversationColumns.HAS_ATTACHMENTS,
-            ConversationColumns.HAS_MESSAGES_WITH_ERRORS,
-            ConversationColumns.FORCE_ALL_UNREAD};
-    private static String[] MESSAGE_PROJECTION = {
-            MessageColumns.ID,
-            MessageColumns.MESSAGE_ID,
-            MessageColumns.CONVERSATION_ID,
-            MessageColumns.SUBJECT,
-            MessageColumns.SNIPPET,
-            MessageColumns.FROM,
-            MessageColumns.TO,
-            MessageColumns.CC,
-            MessageColumns.BCC,
-            MessageColumns.REPLY_TO,
-            MessageColumns.DATE_SENT_MS,
-            MessageColumns.DATE_RECEIVED_MS,
-            MessageColumns.LIST_INFO,
-            MessageColumns.PERSONAL_LEVEL,
-            MessageColumns.BODY,
-            MessageColumns.EMBEDS_EXTERNAL_RESOURCES,
-            MessageColumns.LABEL_IDS,
-            MessageColumns.JOINED_ATTACHMENT_INFOS,
-            MessageColumns.ERROR};
-    private static String[] LABEL_PROJECTION = {
-            BaseColumns._ID,
-            LabelColumns.CANONICAL_NAME,
-            LabelColumns.NAME,
-            LabelColumns.NUM_CONVERSATIONS,
-            LabelColumns.NUM_UNREAD_CONVERSATIONS};
-    private static String[] SETTINGS_PROJECTION = {
-            SettingsColumns.LABELS_INCLUDED,
-            SettingsColumns.LABELS_PARTIAL,
-            SettingsColumns.CONVERSATION_AGE_DAYS,
-            SettingsColumns.MAX_ATTACHMENET_SIZE_MB,
-    };
-
-    private ContentResolver mContentResolver;
-
-    public Gmail(ContentResolver contentResolver) {
-        mContentResolver = contentResolver;
-    }
-
-    /**
-     * Returns source if source is non-null. Returns the empty string otherwise.
-     */
-    private static String toNonnullString(String source) {
-        if (source == null) {
-            return "";
-        } else {
-            return source;
-        }
-    }
-
-    /**
-     * Behavior for a new cursor: should it become the Active Network
-     * Cursor?  This could potentially lead to bad behavior if someone
-     * else is using the Active Network Cursor, since theirs will stop
-     * being the Active Network Cursor.
-     */
-    public static enum BecomeActiveNetworkCursor {
-        /**
-         * The new cursor should become the one and only Active
-         * Network Cursor.  Any other cursor that might already be the
-         * Active Network Cursor will cease to be so.
-         */
-        YES,
-
-        /**
-         * The new cursor should not become the Active Network
-         * Cursor. Any other cursor that might already be the Active
-         * Network Cursor will continue to be so.
-         */
-        NO
-    }
-
-    /**
-     * Wraps a Cursor in a ConversationCursor
-     *
-     * @param account the account the cursor is associated with
-     * @param cursor The Cursor to wrap
-     * @return a new ConversationCursor
-     */
-    public ConversationCursor getConversationCursorForCursor(String account, Cursor cursor) {
-        if (TextUtils.isEmpty(account)) {
-            throw new IllegalArgumentException("account is empty");
-        }
-        return new ConversationCursor(this, account, cursor);
-    }
-
-    /**
-     * Creates an array of SelectionArguments suitable for passing to the provider's query.
-     * Currently this only handles one flag, but it could be expanded in the future.
-     */
-    private static String[] getSelectionArguments(
-            BecomeActiveNetworkCursor becomeActiveNetworkCursor) {
-        if (BecomeActiveNetworkCursor.NO == becomeActiveNetworkCursor) {
-            return new String[] {SelectionArguments.DO_NOT_BECOME_ACTIVE_NETWORK_CURSOR};
-        } else {
-            // Default behavior; no args required.
-            return null;
-        }
-    }
-
-    /**
-     * Asynchronously gets a cursor over all conversations matching a query. The
-     * query is in Gmail's query syntax. When the operation is complete the handler's
-     * onQueryComplete() method is called with the resulting Cursor.
-     *
-     * @param account run the query on this account
-     * @param handler An AsyncQueryHanlder that will be used to run the query
-     * @param token The token to pass to startQuery, which will be passed back to onQueryComplete
-     * @param query a query in Gmail's query syntax
-     * @param becomeActiveNetworkCursor whether or not the returned
-     * cursor should become the Active Network Cursor
-     */
-    public void runQueryForConversations(String account, AsyncQueryHandler handler, int token,
-            String query, BecomeActiveNetworkCursor becomeActiveNetworkCursor) {
-        if (TextUtils.isEmpty(account)) {
-            throw new IllegalArgumentException("account is empty");
-        }
-        String[] selectionArgs = getSelectionArguments(becomeActiveNetworkCursor);
-        handler.startQuery(token, null, Uri.withAppendedPath(CONVERSATIONS_URI, account),
-                CONVERSATION_PROJECTION, query, selectionArgs, null);
-    }
-
-    /**
-     * Synchronously gets a cursor over all conversations matching a query. The
-     * query is in Gmail's query syntax.
-     *
-     * @param account run the query on this account
-     * @param query a query in Gmail's query syntax
-     * @param becomeActiveNetworkCursor whether or not the returned
-     * cursor should become the Active Network Cursor
-     */
-    public ConversationCursor getConversationCursorForQuery(
-            String account, String query, BecomeActiveNetworkCursor becomeActiveNetworkCursor) {
-        String[] selectionArgs = getSelectionArguments(becomeActiveNetworkCursor);
-        Cursor cursor = mContentResolver.query(
-                Uri.withAppendedPath(CONVERSATIONS_URI, account), CONVERSATION_PROJECTION,
-                query, selectionArgs, null);
-        return new ConversationCursor(this, account, cursor);
-    }
-
-    /**
-     * Gets a message cursor over the single message with the given id.
-     *
-     * @param account get the cursor for messages in this account
-     * @param messageId the id of the message
-     * @return a cursor over the message
-     */
-    public MessageCursor getMessageCursorForMessageId(String account, long messageId) {
-        if (TextUtils.isEmpty(account)) {
-            throw new IllegalArgumentException("account is empty");
-        }
-        Uri uri = Uri.parse(AUTHORITY_PLUS_MESSAGES + account + "/" + messageId);
-        Cursor cursor = mContentResolver.query(uri, MESSAGE_PROJECTION, null, null, null);
-        return new MessageCursor(this, mContentResolver, account, cursor);
-    }
-
-    /**
-     * Gets a message cursor over the messages that match the query. Note that
-     * this simply finds all of the messages that match and returns them. It
-     * does not return all messages in conversations where any message matches.
-     *
-     * @param account get the cursor for messages in this account
-     * @param query a query in GMail's query syntax. Currently only queries of
-     *     the form [label:<label>] are supported
-     * @return a cursor over the messages
-     */
-    public MessageCursor getLocalMessageCursorForQuery(String account, String query) {
-        if (TextUtils.isEmpty(account)) {
-            throw new IllegalArgumentException("account is empty");
-        }
-        Uri uri = Uri.parse(AUTHORITY_PLUS_MESSAGES + account + "/");
-        Cursor cursor = mContentResolver.query(uri, MESSAGE_PROJECTION, query, null, null);
-        return new MessageCursor(this, mContentResolver, account, cursor);
-    }
-
-    /**
-     * Gets a cursor over all of the messages in a conversation.
-     *
-     * @param account get the cursor for messages in this account
-     * @param conversationId the id of the converstion to fetch messages for
-     * @return a cursor over messages in the conversation
-     */
-    public MessageCursor getMessageCursorForConversationId(String account, long conversationId) {
-        if (TextUtils.isEmpty(account)) {
-            throw new IllegalArgumentException("account is empty");
-        }
-        Uri uri = Uri.parse(
-                AUTHORITY_PLUS_CONVERSATIONS + account + "/" + conversationId + "/messages");
-        Cursor cursor = mContentResolver.query(
-                uri, MESSAGE_PROJECTION, null, null, null);
-        return new MessageCursor(this, mContentResolver, account, cursor);
-    }
-
-    /**
-     * Expunge the indicated message. One use of this is to discard drafts.
-     *
-     * @param account the account of the message id
-     * @param messageId the id of the message to expunge
-     */
-    public void expungeMessage(String account, long messageId) {
-        if (TextUtils.isEmpty(account)) {
-            throw new IllegalArgumentException("account is empty");
-        }
-        Uri uri = Uri.parse(AUTHORITY_PLUS_MESSAGES + account + "/" + messageId);
-        mContentResolver.delete(uri, null, null);
-    }
-
-    /**
-     * Adds or removes the label on the conversation.
-     *
-     * @param account the account of the conversation
-     * @param conversationId the conversation
-     * @param maxServerMessageId the highest message id to whose labels should be changed. Note that
-     *   everywhere else in this file messageId means local message id but here you need to use a
-     *   server message id.
-     * @param label the label to add or remove
-     * @param add true to add the label, false to remove it
-     */
-    public void addOrRemoveLabelOnConversation(
-            String account, long conversationId, long maxServerMessageId, String label,
-            boolean add) {
-        if (TextUtils.isEmpty(account)) {
-            throw new IllegalArgumentException("account is empty");
-        }
-        if (add) {
-            Uri uri = Uri.parse(
-                    AUTHORITY_PLUS_CONVERSATIONS + account + "/" + conversationId + "/labels");
-            ContentValues values = new ContentValues();
-            values.put(LabelColumns.CANONICAL_NAME, label);
-            values.put(ConversationColumns.MAX_MESSAGE_ID, maxServerMessageId);
-            mContentResolver.insert(uri, values);
-        } else {
-            String encodedLabel;
-            try {
-                encodedLabel = URLEncoder.encode(label, "utf-8");
-            } catch (UnsupportedEncodingException e) {
-                throw new RuntimeException(e);
-            }
-            Uri uri = Uri.parse(
-                    AUTHORITY_PLUS_CONVERSATIONS + account + "/"
-                            + conversationId + "/labels/" + encodedLabel);
-            mContentResolver.delete(
-                    uri, ConversationColumns.MAX_MESSAGE_ID, new String[]{"" + maxServerMessageId});
-        }
-    }
-
-    /**
-     * Adds or removes the label on the message.
-     *
-     * @param contentResolver the content resolver.
-     * @param account the account of the message
-     * @param conversationId the conversation containing the message
-     * @param messageId the id of the message to whose labels should be changed
-     * @param label the label to add or remove
-     * @param add true to add the label, false to remove it
-     */
-    public static void addOrRemoveLabelOnMessage(ContentResolver contentResolver, String account,
-            long conversationId, long messageId, String label, boolean add) {
-
-        // conversationId is unused but we want to start passing it whereever we pass a message id.
-        if (add) {
-            Uri uri = Uri.parse(
-                    AUTHORITY_PLUS_MESSAGES + account + "/" + messageId + "/labels");
-            ContentValues values = new ContentValues();
-            values.put(LabelColumns.CANONICAL_NAME, label);
-            contentResolver.insert(uri, values);
-        } else {
-            String encodedLabel;
-            try {
-                encodedLabel = URLEncoder.encode(label, "utf-8");
-            } catch (UnsupportedEncodingException e) {
-                throw new RuntimeException(e);
-            }
-            Uri uri = Uri.parse(
-                    AUTHORITY_PLUS_MESSAGES + account + "/" + messageId
-                    + "/labels/" + encodedLabel);
-            contentResolver.delete(uri, null, null);
-        }
-    }
-
-    /**
-     * The mail provider will send an intent when certain changes happen in certain labels.
-     * Currently those labels are inbox and voicemail.
-     *
-     * <p>The intent will have the action ACTION_PROVIDER_CHANGED and the extras mentioned below.
-     * The data for the intent will be content://gmail-ls/unread/<name of label>.
-     *
-     * <p>The goal is to support the following user experience:<ul>
-     *   <li>When present the new mail indicator reports the number of unread conversations in the
-     *   inbox (or some other label).</li>
-     *   <li>When the user views the inbox the indicator is removed immediately. They do not have to
-     *   read all of the conversations.</li>
-     *   <li>If more mail arrives the indicator reappears and shows the total number of unread
-     *   conversations in the inbox.</li>
-     *   <li>If the user reads the new conversations on the web the indicator disappears on the
-     *   phone since there is no unread mail in the inbox that the user hasn't seen.</li>
-     *   <li>The phone should vibrate/etc when it transitions from having no unseen unread inbox
-     *   mail to having some.</li>
-     */
-
-    /** The account in which the change occurred. */
-    static public final String PROVIDER_CHANGED_EXTRA_ACCOUNT = "account";
-
-    /** The number of unread conversations matching the label. */
-    static public final String PROVIDER_CHANGED_EXTRA_COUNT = "count";
-
-    /** Whether to get the user's attention, perhaps by vibrating. */
-    static public final String PROVIDER_CHANGED_EXTRA_GET_ATTENTION = "getAttention";
-
-    /**
-     * A label that is attached to all of the conversations being notified about. This enables the
-     * receiver of a notification to get a list of matching conversations.
-     */
-    static public final String PROVIDER_CHANGED_EXTRA_TAG_LABEL = "tagLabel";
-
-    /**
-     * Settings for which conversations should be synced to the phone.
-     * Conversations are synced if any message matches any of the following
-     * criteria:
-     *
-     * <ul>
-     *   <li>the message has a label in the include set</li>
-     *   <li>the message is no older than conversationAgeDays and has a label in the partial set.
-     *   </li>
-     *   <li>also, pending changes on the server: the message has no user-controllable labels.</li>
-     * </ul>
-     *
-     * <p>A user-controllable label is a user-defined label or star, inbox,
-     * trash, spam, etc. LABEL_UNREAD is not considered user-controllable.
-     */
-    public static class Settings {
-        public long conversationAgeDays;
-        public long maxAttachmentSizeMb;
-        public String[] labelsIncluded;
-        public String[] labelsPartial;
-    }
-
-    /**
-     * Returns the settings.
-     * @param account the account whose setting should be retrieved
-     */
-    public Settings getSettings(String account) {
-        if (TextUtils.isEmpty(account)) {
-            throw new IllegalArgumentException("account is empty");
-        }
-        Settings settings = new Settings();
-        Cursor cursor = mContentResolver.query(
-                Uri.withAppendedPath(SETTINGS_URI, account), SETTINGS_PROJECTION, null, null, null);
-        cursor.moveToNext();
-        settings.labelsIncluded = TextUtils.split(cursor.getString(0), SPACE_SEPARATOR_PATTERN);
-        settings.labelsPartial = TextUtils.split(cursor.getString(1), SPACE_SEPARATOR_PATTERN);
-        settings.conversationAgeDays = Long.parseLong(cursor.getString(2));
-        settings.maxAttachmentSizeMb = Long.parseLong(cursor.getString(3));
-        cursor.close();
-        return settings;
-    }
-
-    /**
-     * Sets the settings. A sync will be scheduled automatically.
-     */
-    public void setSettings(String account, Settings settings) {
-        if (TextUtils.isEmpty(account)) {
-            throw new IllegalArgumentException("account is empty");
-        }
-        ContentValues values = new ContentValues();
-        values.put(
-                SettingsColumns.LABELS_INCLUDED,
-                TextUtils.join(" ", settings.labelsIncluded));
-        values.put(
-                SettingsColumns.LABELS_PARTIAL,
-                TextUtils.join(" ", settings.labelsPartial));
-        values.put(
-                SettingsColumns.CONVERSATION_AGE_DAYS,
-                settings.conversationAgeDays);
-        values.put(
-                SettingsColumns.MAX_ATTACHMENET_SIZE_MB,
-                settings.maxAttachmentSizeMb);
-        mContentResolver.update(Uri.withAppendedPath(SETTINGS_URI, account), values, null, null);
-    }
-
-    /**
-     * Uses sender instructions to build a formatted string.
-     *
-     * <p>Sender list instructions contain compact information about the sender list. Most work that
-     * can be done without knowing how much room will be availble for the sender list is done when
-     * creating the instructions.
-     *
-     * <p>The instructions string consists of tokens separated by SENDER_LIST_SEPARATOR. Here are
-     * the tokens, one per line:<ul>
-     * <li><tt>n</tt></li>
-     * <li><em>int</em>, the number of non-draft messages in the conversation</li>
-     * <li><tt>d</tt</li>
-     * <li><em>int</em>, the number of drafts in the conversation</li>
-     * <li><tt>l</tt></li>
-     * <li><em>literal html to be included in the output</em></li>
-     * <li><tt>s</tt> indicates that the message is sending (in the outbox without errors)</li>
-     * <li><tt>f</tt> indicates that the message failed to send (in the outbox with errors)</li>
-     * <li><em>for each message</em><ul>
-     *   <li><em>int</em>, 0 for read, 1 for unread</li>
-     *   <li><em>int</em>, the priority of the message. Zero is the most important</li>
-     *   <li><em>text</em>, the sender text or blank for messages from 'me'</li>
-     * </ul></li>
-     * <li><tt>e</tt> to indicate that one or more messages have been elided</li>
-     *
-     * <p>The instructions indicate how many messages and drafts are in the conversation and then
-     * describe the most important messages in order, indicating the priority of each message and
-     * whether the message is unread.
-     *
-     * @param instructions instructions as described above
-     * @param sb the SpannableStringBuilder to append to
-     * @param maxChars the number of characters available to display the text
-     * @param unreadStyle the CharacterStyle for unread messages, or null
-     * @param draftsStyle the CharacterStyle for draft messages, or null
-     * @param sendingString the string to use when there are messages scheduled to be sent
-     * @param sendFailedString the string to use when there are messages that mailed to send
-     * @param meString the string to use for messages sent by this user
-     * @param draftString the string to use for "Draft"
-     * @param draftPluralString the string to use for "Drafts" 
-     */
-    public static void getSenderSnippet(
-            String instructions, SpannableStringBuilder sb, int maxChars,
-            CharacterStyle unreadStyle,
-            CharacterStyle draftsStyle,
-            CharSequence meString, CharSequence draftString, CharSequence draftPluralString,
-            CharSequence sendingString, CharSequence sendFailedString,
-            boolean forceAllUnread, boolean forceAllRead) {
-        assert !(forceAllUnread && forceAllRead);
-        boolean unreadStatusIsForced = forceAllUnread || forceAllRead;
-        boolean forcedUnreadStatus = forceAllUnread;
-
-        // Measure each fragment. It's ok to iterate over the entire set of fragments because it is
-        // never a long list, even if there are many senders.
-        final Map<Integer, Integer> priorityToLength = sPriorityToLength;
-        priorityToLength.clear();
-
-        int maxFoundPriority = Integer.MIN_VALUE;
-        int numMessages = 0;
-        int numDrafts = 0;
-        CharSequence draftsFragment = "";
-        CharSequence sendingFragment = "";
-        CharSequence sendFailedFragment = "";
-        
-        sSenderListSplitter.setString(instructions);
-        int numFragments = 0;
-        String[] fragments = sSenderFragments;
-        int currentSize = fragments.length;
-        while (sSenderListSplitter.hasNext()) {
-            fragments[numFragments++] = sSenderListSplitter.next();
-            if (numFragments == currentSize) {
-                sSenderFragments = new String[2 * currentSize];
-                System.arraycopy(fragments, 0, sSenderFragments, 0, currentSize);
-                currentSize *= 2;
-                fragments = sSenderFragments;
-            }
-        }
-        
-        for (int i = 0; i < numFragments;) {
-            String fragment0 = fragments[i++];
-            if ("".equals(fragment0)) {
-                // This should be the final fragment.
-            } else if (Gmail.SENDER_LIST_TOKEN_ELIDED.equals(fragment0)) {
-                // ignore
-            } else if (Gmail.SENDER_LIST_TOKEN_NUM_MESSAGES.equals(fragment0)) {
-                numMessages = Integer.valueOf(fragments[i++]);
-            } else if (Gmail.SENDER_LIST_TOKEN_NUM_DRAFTS.equals(fragment0)) {
-                String numDraftsString = fragments[i++];
-                numDrafts = Integer.parseInt(numDraftsString);
-                draftsFragment = numDrafts == 1 ? draftString :
-                        draftPluralString + " (" + numDraftsString + ")";
-            } else if (Gmail.SENDER_LIST_TOKEN_LITERAL.equals(fragment0)) {
-                sb.append(Html.fromHtml(fragments[i++]));
-                return;
-            } else if (Gmail.SENDER_LIST_TOKEN_SENDING.equals(fragment0)) {
-                sendingFragment = sendingString;
-            } else if (Gmail.SENDER_LIST_TOKEN_SEND_FAILED.equals(fragment0)) {
-                sendFailedFragment = sendFailedString;
-            } else {
-                String priorityString = fragments[i++];
-                CharSequence nameString = fragments[i++];
-                if (nameString.length() == 0) nameString = meString;
-                int priority = Integer.parseInt(priorityString);
-                priorityToLength.put(priority, nameString.length());
-                maxFoundPriority = Math.max(maxFoundPriority, priority);
-            }
-        }
-        String numMessagesFragment =
-                (numMessages != 0) ? " (" + Integer.toString(numMessages + numDrafts) + ")" : "";
-
-        // Don't allocate fixedFragment unless we need it
-        SpannableStringBuilder fixedFragment = null;
-        int fixedFragmentLength = 0;
-        if (draftsFragment.length() != 0) {
-            if (fixedFragment == null) {
-                fixedFragment = new SpannableStringBuilder();
-            }
-            fixedFragment.append(draftsFragment);
-            if (draftsStyle != null) {
-                fixedFragment.setSpan(
-                        CharacterStyle.wrap(draftsStyle),
-                        0, fixedFragment.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
-            }
-        }
-        if (sendingFragment.length() != 0) {
-            if (fixedFragment == null) {
-                fixedFragment = new SpannableStringBuilder();
-            }
-            if (fixedFragment.length() != 0) fixedFragment.append(", ");
-            fixedFragment.append(sendingFragment);
-        }
-        if (sendFailedFragment.length() != 0) {
-            if (fixedFragment == null) {
-                fixedFragment = new SpannableStringBuilder();
-            }
-            if (fixedFragment.length() != 0) fixedFragment.append(", ");
-            fixedFragment.append(sendFailedFragment);
-        }
-
-        if (fixedFragment != null) {
-            fixedFragmentLength = fixedFragment.length();
-        }
-
-        final boolean normalMessagesExist =
-                numMessagesFragment.length() != 0 || maxFoundPriority != Integer.MIN_VALUE;
-        String preFixedFragement = "";
-        if (normalMessagesExist && fixedFragmentLength != 0) {
-            preFixedFragement = ", ";
-        }
-        int maxPriorityToInclude = -1; // inclusive
-        int numCharsUsed =
-                numMessagesFragment.length() + preFixedFragement.length() + fixedFragmentLength;
-        int numSendersUsed = 0;
-        while (maxPriorityToInclude < maxFoundPriority) {
-            if (priorityToLength.containsKey(maxPriorityToInclude + 1)) {
-                int length = numCharsUsed + priorityToLength.get(maxPriorityToInclude + 1);
-                if (numCharsUsed > 0) length += 2;
-                // We must show at least two senders if they exist. If we don't have space for both
-                // then we will truncate names.
-                if (length > maxChars && numSendersUsed >= 2) {
-                    break;
-                }
-                numCharsUsed = length;
-                numSendersUsed++;
-            }
-            maxPriorityToInclude++;
-        }
-
-        int numCharsToRemovePerWord = 0;
-        if (numCharsUsed > maxChars) {
-            numCharsToRemovePerWord = (numCharsUsed - maxChars) / numSendersUsed;
-        }
-
-        boolean elided = false;
-        for (int i = 0; i < numFragments;) {
-            String fragment0 = fragments[i++];
-            if ("".equals(fragment0)) {
-                // This should be the final fragment.
-            } else if (SENDER_LIST_TOKEN_ELIDED.equals(fragment0)) {
-                elided = true;
-            } else if (SENDER_LIST_TOKEN_NUM_MESSAGES.equals(fragment0)) {
-                i++;
-            } else if (SENDER_LIST_TOKEN_NUM_DRAFTS.equals(fragment0)) {
-                i++;
-            } else if (SENDER_LIST_TOKEN_SENDING.equals(fragment0)) {
-            } else if (SENDER_LIST_TOKEN_SEND_FAILED.equals(fragment0)) {
-            } else {
-                final String unreadString = fragment0;
-                final String priorityString = fragments[i++];
-                String nameString = fragments[i++];
-                if (nameString.length() == 0) nameString = meString.toString();
-                if (numCharsToRemovePerWord != 0) {
-                    nameString = nameString.substring(
-                            0, Math.max(nameString.length() - numCharsToRemovePerWord, 0));
-                }
-                final boolean unread = unreadStatusIsForced
-                        ? forcedUnreadStatus : Integer.parseInt(unreadString) != 0;
-                final int priority = Integer.parseInt(priorityString);
-                if (priority <= maxPriorityToInclude) {
-                    if (sb.length() != 0) {
-                        sb.append(elided ? " .. " : ", ");
-                    }
-                    elided = false;
-                    int pos = sb.length();
-                    sb.append(nameString);
-                    if (unread && unreadStyle != null) {
-                        sb.setSpan(CharacterStyle.wrap(unreadStyle),
-                                pos, sb.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
-                    }
-                } else {
-                    elided = true;
-                }
-            }
-        }
-        sb.append(numMessagesFragment);
-        if (fixedFragmentLength != 0) {
-            sb.append(preFixedFragement);
-            sb.append(fixedFragment);
-        }
-    }
-
-    /**
-     * This is a cursor that only defines methods to move throught the results
-     * and register to hear about changes. All access to the data is left to
-     * subinterfaces.
-     */
-    public static class MailCursor extends ContentObserver {
-
-        // A list of observers of this cursor.
-        private Set<MailCursorObserver> mObservers;
-
-        // Updated values are accumulated here before being written out if the
-        // cursor is asked to persist the changes.
-        private ContentValues mUpdateValues;
-
-        protected Cursor mCursor;
-        protected String mAccount;
-
-        public Cursor getCursor() {
-            return mCursor;
-        }
-
-        /**
-         * Constructs the MailCursor given a regular cursor, registering as a
-         * change observer of the cursor.
-         * @param account the account the cursor is associated with
-         * @param cursor the underlying cursor
-         */
-        protected MailCursor(String account, Cursor cursor) {
-            super(new Handler());
-            mObservers = new HashSet<MailCursorObserver>();
-            mCursor = cursor;
-            mAccount = account;
-            if (mCursor != null) mCursor.registerContentObserver(this);
-        }
-
-        /**
-         * Gets the account associated with this cursor.
-         * @return the account.
-         */
-        public String getAccount() {
-            return mAccount;
-        }
-
-        protected void checkThread() {
-            // Turn this on when activity code no longer runs in the sync thread
-            // after notifications of changes.
-//            Thread currentThread = Thread.currentThread();
-//            if (currentThread != mThread) {
-//                throw new RuntimeException("Accessed from the wrong thread");
-//            }
-        }
-
-        /**
-         * Lazily constructs a map of update values to apply to the database
-         * if requested. This map is cleared out when we move to a different
-         * item in the result set.
-         *
-         * @return a map of values to be applied by an update.
-         */
-        protected ContentValues getUpdateValues() {
-            if (mUpdateValues == null) {
-                mUpdateValues = new ContentValues();
-            }
-            return mUpdateValues;
-        }
-
-        /**
-         * Called whenever mCursor is changed to point to a different row.
-         * Subclasses should override this if they need to clear out state
-         * when this happens.
-         *
-         * Subclasses must call the inherited version if they override this.
-         */
-        protected void onCursorPositionChanged() {
-            mUpdateValues = null;
-        }
-
-        // ********* MailCursor
-
-        /**
-         * Returns the numbers of rows in the cursor.
-         *
-         * @return the number of rows in the cursor.
-         */
-        final public int count() {
-            if (mCursor != null) {
-                return mCursor.getCount();
-            } else {
-                return 0;
-            }
-        }
-
-        /**
-         * @return the current position of this cursor, or -1 if this cursor
-         * has not been initialized.
-         */
-        final public int position() {
-            if (mCursor != null) {
-                return mCursor.getPosition();
-            } else {
-                return -1;
-            }
-        }
-
-        /**
-         * Move the cursor to an absolute position. The valid
-         * range of vaues is -1 &lt;= position &lt;= count.
-         *
-         * <p>This method will return true if the request destination was
-         * reachable, otherwise it returns false.
-         *
-         * @param position the zero-based position to move to.
-         * @return whether the requested move fully succeeded.
-         */
-        final public boolean moveTo(int position) {
-            checkCursor();
-            checkThread();
-            boolean moved = mCursor.moveToPosition(position);
-            if (moved) onCursorPositionChanged();
-            return moved;
-        }
-
-        /**
-         * Move the cursor to the next row.
-         *
-         * <p>This method will return false if the cursor is already past the
-         * last entry in the result set.
-         *
-         * @return whether the move succeeded.
-         */
-        final public boolean next() {
-            checkCursor();
-            checkThread();
-            boolean moved = mCursor.moveToNext();
-            if (moved) onCursorPositionChanged();
-            return moved;
-        }
-
-        /**
-         * Release all resources and locks associated with the cursor. The
-         * cursor will not be valid after this function is called.
-         */
-        final public void release() {
-            if (mCursor != null) {
-                mCursor.unregisterContentObserver(this);
-                mCursor.deactivate();
-            }
-        }
-
-        final public void registerContentObserver(ContentObserver observer) {
-            mCursor.registerContentObserver(observer);
-        }
-
-        final public void unregisterContentObserver(ContentObserver observer) {
-            mCursor.unregisterContentObserver(observer);
-        }
-
-        final public void registerDataSetObserver(DataSetObserver observer) {
-            mCursor.registerDataSetObserver(observer);
-        }
-
-        final public void unregisterDataSetObserver(DataSetObserver observer) {
-            mCursor.unregisterDataSetObserver(observer);
-        }
-
-        /**
-         * Register an observer to hear about changes to the cursor.
-         *
-         * @param observer the observer to register
-         */
-        final public void registerObserver(MailCursorObserver observer) {
-            mObservers.add(observer);
-        }
-
-        /**
-         * Unregister an observer.
-         *
-         * @param observer the observer to unregister
-         */
-        final public void unregisterObserver(MailCursorObserver observer) {
-            mObservers.remove(observer);
-        }
-
-        // ********* ContentObserver
-
-        @Override
-        final public boolean deliverSelfNotifications() {
-            return false;
-        }
-
-        @Override
-        public void onChange(boolean selfChange) {
-            if (DEBUG) {
-                Log.d(TAG, "MailCursor is notifying " + mObservers.size() + " observers");
-            }
-            for (MailCursorObserver o: mObservers) {
-                o.onCursorChanged(this);
-            }
-        }
-
-        protected void checkCursor() {
-            if (mCursor == null) {
-                throw new IllegalStateException(
-                        "cannot read from an insertion cursor");
-            }
-        }
-
-        /**
-         * Returns the string value of the column, or "" if the value is null.
-         */
-        protected String getStringInColumn(int columnIndex) {
-            checkCursor();
-            return toNonnullString(mCursor.getString(columnIndex));
-        }
-    }
-
-    /**
-     * A MailCursor observer is notified of changes to the result set of a
-     * cursor.
-     */
-    public interface MailCursorObserver {
-
-        /**
-         * Called when the result set of a cursor has changed.
-         *
-         * @param cursor the cursor whose result set has changed.
-         */
-        void onCursorChanged(MailCursor cursor);
-    }
-
-    /**
-     * A cursor over labels.
-     */
-    public final class LabelCursor extends MailCursor {
-
-        private int mNameIndex;
-        private int mNumConversationsIndex;
-        private int mNumUnreadConversationsIndex;
-
-        private LabelCursor(String account, Cursor cursor) {
-            super(account, cursor);
-
-            mNameIndex = mCursor.getColumnIndexOrThrow(LabelColumns.CANONICAL_NAME);
-            mNumConversationsIndex =
-                    mCursor.getColumnIndexOrThrow(LabelColumns.NUM_CONVERSATIONS);
-            mNumUnreadConversationsIndex = mCursor.getColumnIndexOrThrow(
-                    LabelColumns.NUM_UNREAD_CONVERSATIONS);
-        }
-
-        /**
-         * Gets the canonical name of the current label.
-         *
-         * @return the current label's name.
-         */
-        public String getName() {
-            return getStringInColumn(mNameIndex);
-        }
-
-        /**
-         * Gets the number of conversations with this label.
-         *
-         * @return the number of conversations with this label.
-         */
-        public int getNumConversations() {
-            return mCursor.getInt(mNumConversationsIndex);
-        }
-
-        /**
-         * Gets the number of unread conversations with this label.
-         *
-         * @return the number of unread conversations with this label.
-         */
-        public int getNumUnreadConversations() {
-            return mCursor.getInt(mNumUnreadConversationsIndex);
-        }
-    }
-
-    /**
-     * This is a map of labels. TODO: make it observable.
-     */
-    public static final class LabelMap extends Observable {
-        private final static ContentValues EMPTY_CONTENT_VALUES = new ContentValues();
-
-        private ContentQueryMap mQueryMap;
-        private SortedSet<String> mSortedUserLabels;
-        private Map<String, Long> mCanonicalNameToId;
-
-        private long mLabelIdSent;
-        private long mLabelIdInbox;
-        private long mLabelIdDraft;
-        private long mLabelIdUnread;
-        private long mLabelIdTrash;
-        private long mLabelIdSpam;
-        private long mLabelIdStarred;
-        private long mLabelIdChat;
-        private long mLabelIdVoicemail;
-        private long mLabelIdIgnored;
-        private long mLabelIdVoicemailInbox;
-        private long mLabelIdCached;
-        private long mLabelIdOutbox;
-
-        private boolean mLabelsSynced = false;
-
-        public LabelMap(ContentResolver contentResolver, String account, boolean keepUpdated) {
-            if (TextUtils.isEmpty(account)) {
-                throw new IllegalArgumentException("account is empty");
-            }
-            Cursor cursor = contentResolver.query(
-                    Uri.withAppendedPath(LABELS_URI, account), LABEL_PROJECTION, null, null, null);
-            init(cursor, keepUpdated);
-        }
-
-        public LabelMap(Cursor cursor, boolean keepUpdated) {
-            init(cursor, keepUpdated);
-        }
-
-        private void init(Cursor cursor, boolean keepUpdated) {
-            mQueryMap = new ContentQueryMap(cursor, BaseColumns._ID, keepUpdated, null);
-            mSortedUserLabels = new TreeSet<String>(java.text.Collator.getInstance());
-            mCanonicalNameToId = Maps.newHashMap();
-            updateDataStructures();
-            mQueryMap.addObserver(new Observer() {
-                public void update(Observable observable, Object data) {
-                    updateDataStructures();
-                    setChanged();
-                    notifyObservers();
-                }
-            });
-        }
-
-        /**
-         * @return whether at least some labels have been synced.
-         */
-        public boolean labelsSynced() {
-            return mLabelsSynced;
-        }
-
-        /**
-         * Updates the data structures that are maintained separately from mQueryMap after the query
-         * map has changed.
-         */
-        private void updateDataStructures() {
-            mSortedUserLabels.clear();
-            mCanonicalNameToId.clear();
-            for (Map.Entry<String, ContentValues> row : mQueryMap.getRows().entrySet()) {
-                long labelId = Long.valueOf(row.getKey());
-                String canonicalName = row.getValue().getAsString(LabelColumns.CANONICAL_NAME);
-                if (isLabelUserDefined(canonicalName)) {
-                    mSortedUserLabels.add(canonicalName);
-                }
-                mCanonicalNameToId.put(canonicalName, labelId);
-
-                if (LABEL_SENT.equals(canonicalName)) {
-                    mLabelIdSent = labelId;
-                } else if (LABEL_INBOX.equals(canonicalName)) {
-                    mLabelIdInbox = labelId;
-                } else if (LABEL_DRAFT.equals(canonicalName)) {
-                    mLabelIdDraft = labelId;
-                } else if (LABEL_UNREAD.equals(canonicalName)) {
-                    mLabelIdUnread = labelId;
-                } else if (LABEL_TRASH.equals(canonicalName)) {
-                    mLabelIdTrash = labelId;
-                } else if (LABEL_SPAM.equals(canonicalName)) {
-                    mLabelIdSpam = labelId;
-                } else if (LABEL_STARRED.equals(canonicalName)) {
-                    mLabelIdStarred = labelId;
-                } else if (LABEL_CHAT.equals(canonicalName)) {
-                    mLabelIdChat = labelId;
-                } else if (LABEL_IGNORED.equals(canonicalName)) {
-                    mLabelIdIgnored = labelId;
-                } else if (LABEL_VOICEMAIL.equals(canonicalName)) {
-                    mLabelIdVoicemail = labelId;
-                } else if (LABEL_VOICEMAIL_INBOX.equals(canonicalName)) {
-                    mLabelIdVoicemailInbox = labelId;
-                } else if (LABEL_CACHED.equals(canonicalName)) {
-                    mLabelIdCached = labelId;
-                } else if (LABEL_OUTBOX.equals(canonicalName)) {
-                    mLabelIdOutbox = labelId;
-                }
-                mLabelsSynced = mLabelIdSent != 0
-                    && mLabelIdInbox != 0
-                    && mLabelIdDraft != 0
-                    && mLabelIdUnread != 0
-                    && mLabelIdTrash != 0
-                    && mLabelIdSpam != 0
-                    && mLabelIdStarred != 0
-                    && mLabelIdChat != 0
-                    && mLabelIdIgnored != 0
-                    && mLabelIdVoicemail != 0;
-            }
-        }
-
-        public long getLabelIdSent() {
-            checkLabelsSynced();
-            return mLabelIdSent;
-        }
-
-        public long getLabelIdInbox() {
-            checkLabelsSynced();
-            return mLabelIdInbox;
-        }
-
-        public long getLabelIdDraft() {
-            checkLabelsSynced();
-            return mLabelIdDraft;
-        }
-
-        public long getLabelIdUnread() {
-            checkLabelsSynced();
-            return mLabelIdUnread;
-        }
-
-        public long getLabelIdTrash() {
-            checkLabelsSynced();
-            return mLabelIdTrash;
-        }
-
-        public long getLabelIdSpam() {
-            checkLabelsSynced();
-            return mLabelIdSpam;
-        }
-
-        public long getLabelIdStarred() {
-            checkLabelsSynced();
-            return mLabelIdStarred;
-        }
-
-        public long getLabelIdChat() {
-            checkLabelsSynced();
-            return mLabelIdChat;
-        }
-
-        public long getLabelIdIgnored() {
-            checkLabelsSynced();
-            return mLabelIdIgnored;
-        }
-
-        public long getLabelIdVoicemail() {
-            checkLabelsSynced();
-            return mLabelIdVoicemail;
-        }
-
-        public long getLabelIdVoicemailInbox() {
-            checkLabelsSynced();
-            return mLabelIdVoicemailInbox;
-        }
-
-        public long getLabelIdCached() {
-            checkLabelsSynced();
-            return mLabelIdCached;
-        }
-
-        public long getLabelIdOutbox() {
-            checkLabelsSynced();
-            return mLabelIdOutbox;
-        }
-
-        private void checkLabelsSynced() {
-            if (!labelsSynced()) {
-                throw new IllegalStateException("LabelMap not initalized");
-            }
-        }
-
-        /** Returns the list of user-defined labels in alphabetical order. */
-        public SortedSet<String> getSortedUserLabels() {
-            return mSortedUserLabels;
-        }
-
-        private static final List<String> SORTED_USER_MEANINGFUL_SYSTEM_LABELS =
-                Lists.newArrayList(
-                        LABEL_INBOX, LABEL_STARRED, LABEL_CHAT, LABEL_SENT,
-                        LABEL_OUTBOX, LABEL_DRAFT, LABEL_ALL,
-                        LABEL_SPAM, LABEL_TRASH);
-
-
-        private static final Set<String> USER_MEANINGFUL_SYSTEM_LABELS_SET =
-                Sets.newHashSet(
-                        SORTED_USER_MEANINGFUL_SYSTEM_LABELS.toArray(
-                                new String[]{}));
-
-        public static List<String> getSortedUserMeaningfulSystemLabels() {
-            return SORTED_USER_MEANINGFUL_SYSTEM_LABELS;
-        }
-
-        public static Set<String> getUserMeaningfulSystemLabelsSet() {
-            return USER_MEANINGFUL_SYSTEM_LABELS_SET;
-        }
-
-        /**
-         * If you are ever tempted to remove outbox or draft from this set make sure you have a
-         * way to stop draft and outbox messages from getting purged before they are sent to the
-         * server.
-         */
-        private static final Set<String> FORCED_INCLUDED_LABELS =
-                Sets.newHashSet(LABEL_OUTBOX, LABEL_DRAFT);
-
-        public static Set<String> getForcedIncludedLabels() {
-            return FORCED_INCLUDED_LABELS;
-        }
-
-        private static final Set<String> FORCED_INCLUDED_OR_PARTIAL_LABELS =
-                Sets.newHashSet(LABEL_INBOX);
-
-        public static Set<String> getForcedIncludedOrPartialLabels() {
-            return FORCED_INCLUDED_OR_PARTIAL_LABELS;
-        }
-
-        private static final Set<String> FORCED_UNSYNCED_LABELS =
-                Sets.newHashSet(LABEL_ALL, LABEL_CHAT, LABEL_SPAM, LABEL_TRASH);
-
-        public static Set<String> getForcedUnsyncedLabels() {
-            return FORCED_UNSYNCED_LABELS;
-        }
-
-        /**
-         * Returns the number of conversation with a given label.
-         * @deprecated Use {@link #getLabelId} instead.
-         */
-        @Deprecated
-        public int getNumConversations(String label) {
-            return getNumConversations(getLabelId(label));
-        }
-
-        /** Returns the number of conversation with a given label. */
-        public int getNumConversations(long labelId) {
-            return getLabelIdValues(labelId).getAsInteger(LabelColumns.NUM_CONVERSATIONS);
-        }
-
-        /**
-         * Returns the number of unread conversation with a given label.
-         * @deprecated Use {@link #getLabelId} instead.
-         */
-        @Deprecated
-        public int getNumUnreadConversations(String label) {
-            return getNumUnreadConversations(getLabelId(label));
-        }
-
-        /** Returns the number of unread conversation with a given label. */
-        public int getNumUnreadConversations(long labelId) {
-            Integer unreadConversations =
-                    getLabelIdValues(labelId).getAsInteger(LabelColumns.NUM_UNREAD_CONVERSATIONS);
-            // There seems to be a race condition here that can get the label maps into a bad
-            // state and lose state on a particular label.
-            int result = 0;
-            if (unreadConversations != null) {
-                result = unreadConversations < 0 ? 0 : unreadConversations;
-            }
-
-            return result;
-        }
-
-        /**
-         * @return the canonical name for a label
-         */
-        public String getCanonicalName(long labelId) {
-            return getLabelIdValues(labelId).getAsString(LabelColumns.CANONICAL_NAME);
-        }
-
-        /**
-         * @return the human name for a label
-         */
-        public String getName(long labelId) {
-            return getLabelIdValues(labelId).getAsString(LabelColumns.NAME);
-        }
-
-        /**
-         * @return whether a given label is known
-         */
-        public boolean hasLabel(long labelId) {
-            return mQueryMap.getRows().containsKey(Long.toString(labelId));
-        }
-
-        /**
-         * @return returns the id of a label given the canonical name
-         * @deprecated this is only needed because most of the UI uses label names instead of ids
-         */
-        public long getLabelId(String canonicalName) {
-            if (mCanonicalNameToId.containsKey(canonicalName)) {
-                return mCanonicalNameToId.get(canonicalName);
-            } else {
-                throw new IllegalArgumentException("Unknown canonical name: " + canonicalName);
-            }
-        }
-
-        private ContentValues getLabelIdValues(long labelId) {
-            final ContentValues values = mQueryMap.getValues(Long.toString(labelId));
-            if (values != null) {
-                return values;
-            } else {
-                return EMPTY_CONTENT_VALUES;
-            }
-        }
-
-        /** Force the map to requery. This should not be necessary outside tests. */
-        public void requery() {
-            mQueryMap.requery();
-        }
-
-        public void close() {
-            mQueryMap.close();
-        }
-    }
-
-    private Map<String, Gmail.LabelMap> mLabelMaps = Maps.newHashMap();
-
-    public LabelMap getLabelMap(String account) {
-        Gmail.LabelMap labelMap = mLabelMaps.get(account);
-        if (labelMap == null) {
-            labelMap = new Gmail.LabelMap(mContentResolver, account, true /* keepUpdated */);
-            mLabelMaps.put(account, labelMap);
-        }
-        return labelMap;
-    }
-
-    public enum PersonalLevel {
-        NOT_TO_ME(0),
-        TO_ME_AND_OTHERS(1),
-        ONLY_TO_ME(2);
-
-        private int mLevel;
-
-        PersonalLevel(int level) {
-            mLevel = level;
-        }
-
-        public int toInt() {
-            return mLevel;
-        }
-
-        public static PersonalLevel fromInt(int level) {
-            switch (level) {
-                case 0: return NOT_TO_ME;
-                case 1: return TO_ME_AND_OTHERS;
-                case 2: return ONLY_TO_ME;
-                default:
-                    throw new IllegalArgumentException(
-                            level + " is not a personal level");
-            }
-        }
-    }
-
-    /**
-     * Indicates a version of an attachment.
-     */
-    public enum AttachmentRendition {
-        /**
-         * The full version of an attachment if it can be handled on the device, otherwise the
-         * preview.
-         */
-        BEST,
-
-        /** A smaller or simpler version of the attachment, such as a scaled-down image or an HTML
-         * version of a document. Not always available.
-         */
-        SIMPLE,
-    }
-
-    /**
-     * The columns that can be requested when querying an attachment's download URI. See
-     * getAttachmentDownloadUri.
-     */
-    public static final class AttachmentColumns implements BaseColumns {
-
-        /** Contains a STATUS value from {@link android.provider.Downloads} */
-        public static final String STATUS = "status";
-
-        /**
-         * The name of the file to open (with ContentProvider.open). If this is empty then continue
-         * to use the attachment's URI.
-         *
-         * TODO: I'm not sure that we need this. See the note in CL 66853-p9.
-         */
-        public static final String FILENAME = "filename";
-    }
-
-    /**
-     * We track where an attachment came from so that we know how to download it and include it
-     * in new messages.
-     */
-    public enum AttachmentOrigin {
-        /** Extras are "<conversationId>-<messageId>-<partId>". */
-        SERVER_ATTACHMENT,
-        /** Extras are "<path>". */
-        LOCAL_FILE;
-
-        private static final String SERVER_EXTRAS_SEPARATOR = "_";
-
-        public static String serverExtras(
-                long conversationId, long messageId, String partId) {
-            return conversationId + SERVER_EXTRAS_SEPARATOR
-                    + messageId + SERVER_EXTRAS_SEPARATOR + partId;
-        }
-
-        /**
-         * @param extras extras as returned by serverExtras
-         * @return an array of conversationId, messageId, partId (all as strings)
-         */
-        public static String[] splitServerExtras(String extras) {
-            return TextUtils.split(extras, SERVER_EXTRAS_SEPARATOR);
-        }
-
-        public static String localFileExtras(Uri path) {
-            return path.toString();
-        }
-    }
-
-    public static final class Attachment {
-        /** Identifies the attachment uniquely when combined wih a message id.*/
-        public String partId;
-
-        /** The intended filename of the attachment.*/
-        public String name;
-
-        /** The native content type.*/
-        public String contentType;
-
-        /** The size of the attachment in its native form.*/
-        public int size;
-
-        /**
-         * The content type of the simple version of the attachment. Blank if no simple version is
-         * available.
-         */
-        public String simpleContentType;
-
-        public AttachmentOrigin origin;
-
-        public String originExtras;
-
-        public String toJoinedString() {
-            return TextUtils.join(
-                "|", Lists.newArrayList(partId == null ? "" : partId,
-                                        name.replace("|", ""), contentType,
-                                        size, simpleContentType,
-                                        origin.toString(), originExtras));
-        }
-
-        public static Attachment parseJoinedString(String joinedString) {
-            String[] fragments = TextUtils.split(joinedString, "\\|");
-            int i = 0;
-            Attachment attachment = new Attachment();
-            attachment.partId = fragments[i++];
-            if (TextUtils.isEmpty(attachment.partId)) {
-                attachment.partId = null;
-            }
-            attachment.name = fragments[i++];
-            attachment.contentType = fragments[i++];
-            attachment.size = Integer.parseInt(fragments[i++]);
-            attachment.simpleContentType = fragments[i++];
-            attachment.origin = AttachmentOrigin.valueOf(fragments[i++]);
-            attachment.originExtras = fragments[i++];
-            return attachment;
-        }
-    }
-
-    /**
-     * Any given attachment can come in two different renditions (see
-     * {@link android.provider.Gmail.AttachmentRendition}) and can be saved to the sd card or to a
-     * cache. The gmail provider automatically syncs some attachments to the cache. Other
-     * attachments can be downloaded on demand. Attachments in the cache will be purged as needed to
-     * save space. Attachments on the SD card must be managed by the user or other software.
-     *
-     * @param account which account to use
-     * @param messageId the id of the mesage with the attachment
-     * @param attachment the attachment
-     * @param rendition the desired rendition
-     * @param saveToSd whether the attachment should be saved to (or loaded from) the sd card or
-     * @return the URI to ask the content provider to open in order to open an attachment.
-     */
-    public static Uri getAttachmentUri(
-            String account, long messageId, Attachment attachment,
-            AttachmentRendition rendition, boolean saveToSd) {
-        if (TextUtils.isEmpty(account)) {
-            throw new IllegalArgumentException("account is empty");
-        }
-        if (attachment.origin == AttachmentOrigin.LOCAL_FILE) {
-            return Uri.parse(attachment.originExtras);
-        } else {
-            return Uri.parse(
-                    AUTHORITY_PLUS_MESSAGES).buildUpon()
-                    .appendPath(account).appendPath(Long.toString(messageId))
-                    .appendPath("attachments").appendPath(attachment.partId)
-                    .appendPath(rendition.toString())
-                    .appendPath(Boolean.toString(saveToSd))
-                    .build();
-        }
-    }
-
-    /**
-     * Return the URI to query in order to find out whether an attachment is downloaded.
-     *
-     * <p>Querying this will also start a download if necessary. The cursor returned by querying
-     * this URI can contain the columns in {@link android.provider.Gmail.AttachmentColumns}.
-     *
-     * <p>Deleting this URI will cancel the download if it was not started automatically by the
-     * provider. It will also remove bookkeeping for saveToSd downloads.
-     *
-     * @param attachmentUri the attachment URI as returned by getAttachmentUri. The URI's authority
-     *   Gmail.AUTHORITY. If it is not then you should open the file directly.
-     */
-    public static Uri getAttachmentDownloadUri(Uri attachmentUri) {
-        if (!"content".equals(attachmentUri.getScheme())) {
-            throw new IllegalArgumentException("Uri's scheme must be 'content': " + attachmentUri);
-        }
-        return attachmentUri.buildUpon().appendPath("download").build();
-    }
-
-    public enum CursorStatus {
-        LOADED,
-        LOADING,
-        ERROR, // A network error occurred.
-    }
-
-    /**
-     * A cursor over messages.
-     */
-    public static final class MessageCursor extends MailCursor {
-
-        private LabelMap mLabelMap;
-
-        private ContentResolver mContentResolver;
-
-        /**
-         * Only valid if mCursor == null, in which case we are inserting a new
-         * message.
-         */
-        long mInReplyToLocalMessageId;
-        boolean mPreserveAttachments;
-
-        private int mIdIndex;
-        private int mConversationIdIndex;
-        private int mSubjectIndex;
-        private int mSnippetIndex;
-        private int mFromIndex;
-        private int mToIndex;
-        private int mCcIndex;
-        private int mBccIndex;
-        private int mReplyToIndex;
-        private int mDateSentMsIndex;
-        private int mDateReceivedMsIndex;
-        private int mListInfoIndex;
-        private int mPersonalLevelIndex;
-        private int mBodyIndex;
-        private int mBodyEmbedsExternalResourcesIndex;
-        private int mLabelIdsIndex;
-        private int mJoinedAttachmentInfosIndex;
-        private int mErrorIndex;
-
-        private TextUtils.StringSplitter mLabelIdsSplitter = newMessageLabelIdsSplitter();
-
-        public MessageCursor(Gmail gmail, ContentResolver cr, String account, Cursor cursor) {
-            super(account, cursor);
-            mLabelMap = gmail.getLabelMap(account);
-            if (cursor == null) {
-                throw new IllegalArgumentException(
-                        "null cursor passed to MessageCursor()");
-            }
-
-            mContentResolver = cr;
-
-            mIdIndex = mCursor.getColumnIndexOrThrow(MessageColumns.ID);
-            mConversationIdIndex =
-                    mCursor.getColumnIndexOrThrow(MessageColumns.CONVERSATION_ID);
-            mSubjectIndex = mCursor.getColumnIndexOrThrow(MessageColumns.SUBJECT);
-            mSnippetIndex = mCursor.getColumnIndexOrThrow(MessageColumns.SNIPPET);
-            mFromIndex = mCursor.getColumnIndexOrThrow(MessageColumns.FROM);
-            mToIndex = mCursor.getColumnIndexOrThrow(MessageColumns.TO);
-            mCcIndex = mCursor.getColumnIndexOrThrow(MessageColumns.CC);
-            mBccIndex = mCursor.getColumnIndexOrThrow(MessageColumns.BCC);
-            mReplyToIndex = mCursor.getColumnIndexOrThrow(MessageColumns.REPLY_TO);
-            mDateSentMsIndex =
-                    mCursor.getColumnIndexOrThrow(MessageColumns.DATE_SENT_MS);
-            mDateReceivedMsIndex =
-                    mCursor.getColumnIndexOrThrow(MessageColumns.DATE_RECEIVED_MS);
-            mListInfoIndex = mCursor.getColumnIndexOrThrow(MessageColumns.LIST_INFO);
-            mPersonalLevelIndex =
-                    mCursor.getColumnIndexOrThrow(MessageColumns.PERSONAL_LEVEL);
-            mBodyIndex = mCursor.getColumnIndexOrThrow(MessageColumns.BODY);
-            mBodyEmbedsExternalResourcesIndex =
-                    mCursor.getColumnIndexOrThrow(MessageColumns.EMBEDS_EXTERNAL_RESOURCES);
-            mLabelIdsIndex = mCursor.getColumnIndexOrThrow(MessageColumns.LABEL_IDS);
-            mJoinedAttachmentInfosIndex =
-                    mCursor.getColumnIndexOrThrow(MessageColumns.JOINED_ATTACHMENT_INFOS);
-            mErrorIndex = mCursor.getColumnIndexOrThrow(MessageColumns.ERROR);
-
-            mInReplyToLocalMessageId = 0;
-            mPreserveAttachments = false;
-        }
-
-        protected MessageCursor(ContentResolver cr, String account, long inReplyToMessageId,
-                boolean preserveAttachments) {
-            super(account, null);
-            mContentResolver = cr;
-            mInReplyToLocalMessageId = inReplyToMessageId;
-            mPreserveAttachments = preserveAttachments;
-        }
-
-        @Override
-        protected void onCursorPositionChanged() {
-            super.onCursorPositionChanged();
-        }
-
-        public CursorStatus getStatus() {
-            Bundle extras = mCursor.getExtras();
-            String stringStatus = extras.getString(EXTRA_STATUS);
-            return CursorStatus.valueOf(stringStatus);
-        }
-
-        /** Retry a network request after errors. */
-        public void retry() {
-            Bundle input = new Bundle();
-            input.putString(RESPOND_INPUT_COMMAND, COMMAND_RETRY);
-            Bundle output = mCursor.respond(input);
-            String response = output.getString(RESPOND_OUTPUT_COMMAND_RESPONSE);
-            assert COMMAND_RESPONSE_OK.equals(response);
-        }
-
-        /**
-         * Gets the message id of the current message. Note that this is an
-         * immutable local message (not, for example, GMail's message id, which
-         * is immutable).
-         *
-         * @return the message's id
-         */
-        public long getMessageId() {
-            checkCursor();
-            return mCursor.getLong(mIdIndex);
-        }
-
-        /**
-         * Gets the message's conversation id. This must be immutable. (For
-         * example, with GMail this should be the original conversation id
-         * rather than the default notion of converation id.)
-         *
-         * @return the message's conversation id
-         */
-        public long getConversationId() {
-            checkCursor();
-            return mCursor.getLong(mConversationIdIndex);
-        }
-
-        /**
-         * Gets the message's subject.
-         *
-         * @return the message's subject
-         */
-        public String getSubject() {
-            return getStringInColumn(mSubjectIndex);
-        }
-
-        /**
-         * Gets the message's snippet (the short piece of the body). The snippet
-         * is generated from the body and cannot be set directly.
-         *
-         * @return the message's snippet
-         */
-        public String getSnippet() {
-            return getStringInColumn(mSnippetIndex);
-        }
-
-        /**
-         * Gets the message's from address.
-         *
-         * @return the message's from address
-         */
-        public String getFromAddress() {
-            return getStringInColumn(mFromIndex);
-        }
-
-        /**
-         * Returns the addresses for the key, if it has been updated, or index otherwise.
-         */
-        private String[] getAddresses(String key, int index) {
-            ContentValues updated = getUpdateValues();
-            String addresses;
-            if (updated.containsKey(key)) {
-                addresses = (String)getUpdateValues().get(key);
-            } else {
-                addresses = getStringInColumn(index);
-            }
-
-            return TextUtils.split(addresses, EMAIL_SEPARATOR_PATTERN);
-        }
-
-        /**
-         * Gets the message's to addresses.
-         * @return the message's to addresses
-         */
-        public String[] getToAddresses() {
-           return getAddresses(MessageColumns.TO, mToIndex);
-        }
-
-        /**
-         * Gets the message's cc addresses.
-         * @return the message's cc addresses
-         */
-        public String[] getCcAddresses() {
-            return getAddresses(MessageColumns.CC, mCcIndex);
-        }
-
-        /**
-         * Gets the message's bcc addresses.
-         * @return the message's bcc addresses
-         */
-        public String[] getBccAddresses() {
-            return getAddresses(MessageColumns.BCC, mBccIndex);
-        }
-
-        /**
-         * Gets the message's replyTo address.
-         *
-         * @return the message's replyTo address
-         */
-        public String[] getReplyToAddress() {
-            return TextUtils.split(getStringInColumn(mReplyToIndex), EMAIL_SEPARATOR_PATTERN);
-        }
-
-        public long getDateSentMs() {
-            checkCursor();
-            return mCursor.getLong(mDateSentMsIndex);
-        }
-
-        public long getDateReceivedMs() {
-            checkCursor();
-            return mCursor.getLong(mDateReceivedMsIndex);
-        }
-
-        public String getListInfo() {
-            return getStringInColumn(mListInfoIndex);
-        }
-
-        public PersonalLevel getPersonalLevel() {
-            checkCursor();
-            int personalLevelInt = mCursor.getInt(mPersonalLevelIndex);
-            return PersonalLevel.fromInt(personalLevelInt);
-        }
-
-        /**
-         * @deprecated Always returns true.
-         */
-        @Deprecated
-        public boolean getExpanded() {
-            return true;
-        }
-
-        /**
-         * Gets the message's body.
-         *
-         * @return the message's body
-         */
-        public String getBody() {
-            return getStringInColumn(mBodyIndex);
-        }
-
-        /**
-         * @return whether the message's body contains embedded references to external resources. In
-         * that case the resources should only be displayed if the user explicitly asks for them to
-         * be
-         */
-        public boolean getBodyEmbedsExternalResources() {
-            checkCursor();
-            return mCursor.getInt(mBodyEmbedsExternalResourcesIndex) != 0;
-        }
-
-        /**
-         * @return a copy of the set of label ids
-         */
-        public Set<Long> getLabelIds() {
-            String labelNames = mCursor.getString(mLabelIdsIndex);
-            mLabelIdsSplitter.setString(labelNames);
-            return getLabelIdsFromLabelIdsString(mLabelIdsSplitter);
-        }
-
-        /**
-         * @return a joined string of labels separated by spaces.
-         */
-        public String getRawLabelIds() {
-            return mCursor.getString(mLabelIdsIndex);
-        }
-
-        /**
-         * Adds a label to a message (if add is true) or removes it (if add is
-         * false).
-         *
-         * @param label the label to add or remove
-         * @param add whether to add or remove the label
-         */
-        public void addOrRemoveLabel(String label, boolean add) {
-            addOrRemoveLabelOnMessage(mContentResolver, mAccount, getConversationId(),
-                    getMessageId(), label, add);
-        }
-
-        public ArrayList<Attachment> getAttachmentInfos() {
-            ArrayList<Attachment> attachments = Lists.newArrayList();
-
-            String joinedAttachmentInfos = mCursor.getString(mJoinedAttachmentInfosIndex);
-            if (joinedAttachmentInfos != null) {
-                for (String joinedAttachmentInfo :
-                        TextUtils.split(joinedAttachmentInfos, ATTACHMENT_INFO_SEPARATOR_PATTERN)) {
-
-                    Attachment attachment = Attachment.parseJoinedString(joinedAttachmentInfo);
-                    attachments.add(attachment);
-                }
-            }
-            return attachments;
-        }
-
-        /**
-         * @return the error text for the message. Error text gets set if the server rejects a
-         * message that we try to save or send. If there is error text then the message is no longer
-         * scheduled to be saved or sent. Calling save() or send() will clear any error as well as
-         * scheduling another atempt to save or send the message.
-         */
-        public String getErrorText() {
-            return mCursor.getString(mErrorIndex);
-        }
-    }
-
-    /**
-     * A helper class for creating or updating messags. Use the putXxx methods to provide initial or
-     * new values for the message. Then save or send the message. To save or send an existing
-     * message without making other changes to it simply provide an emty ContentValues.
-     */
-    public static class MessageModification {
-
-        /**
-         * Sets the message's subject. Only valid for drafts.
-         *
-         * @param values the ContentValues that will be used to create or update the message
-         * @param subject the new subject
-         */
-        public static void putSubject(ContentValues values, String subject) {
-            values.put(MessageColumns.SUBJECT, subject);
-        }
-
-        /**
-         * Sets the message's to address. Only valid for drafts.
-         *
-         * @param values the ContentValues that will be used to create or update the message
-         * @param toAddresses the new to addresses
-         */
-        public static void putToAddresses(ContentValues values, String[] toAddresses) {
-            values.put(MessageColumns.TO, TextUtils.join(EMAIL_SEPARATOR, toAddresses));
-        }
-
-        /**
-         * Sets the message's cc address. Only valid for drafts.
-         *
-         * @param values the ContentValues that will be used to create or update the message
-         * @param ccAddresses the new cc addresses
-         */
-        public static void putCcAddresses(ContentValues values, String[] ccAddresses) {
-            values.put(MessageColumns.CC, TextUtils.join(EMAIL_SEPARATOR, ccAddresses));
-        }
-
-        /**
-         * Sets the message's bcc address. Only valid for drafts.
-         *
-         * @param values the ContentValues that will be used to create or update the message
-         * @param bccAddresses the new bcc addresses
-         */
-        public static void putBccAddresses(ContentValues values, String[] bccAddresses) {
-            values.put(MessageColumns.BCC, TextUtils.join(EMAIL_SEPARATOR, bccAddresses));
-        }
-
-        /**
-         * Saves a new body for the message. Only valid for drafts.
-         *
-         * @param values the ContentValues that will be used to create or update the message
-         * @param body the new body of the message
-         */
-        public static void putBody(ContentValues values, String body) {
-            values.put(MessageColumns.BODY, body);
-        }
-
-        /**
-         * Sets the attachments on a message. Only valid for drafts.
-         *
-         * @param values the ContentValues that will be used to create or update the message
-         * @param attachments
-         */
-        public static void putAttachments(ContentValues values, List<Attachment> attachments) {
-            values.put(
-                    MessageColumns.JOINED_ATTACHMENT_INFOS, joinedAttachmentsString(attachments));
-        }
-
-        /**
-         * Create a new message and save it as a draft or send it.
-         *
-         * @param contentResolver the content resolver to use
-         * @param account the account to use
-         * @param values the values for the new message
-         * @param refMessageId the message that is being replied to or forwarded
-         * @param save whether to save or send the message
-         * @return the id of the new message
-         */
-        public static long sendOrSaveNewMessage(
-                ContentResolver contentResolver, String account,
-                ContentValues values, long refMessageId, boolean save) {
-            values.put(MessageColumns.FAKE_SAVE, save);
-            values.put(MessageColumns.FAKE_REF_MESSAGE_ID, refMessageId);
-            Uri uri = Uri.parse(AUTHORITY_PLUS_MESSAGES + account + "/");
-            Uri result = contentResolver.insert(uri, values);
-            return ContentUris.parseId(result);
-        }
-
-        /**
-         * Update an existing draft and save it as a new draft or send it.
-         *
-         * @param contentResolver the content resolver to use
-         * @param account the account to use
-         * @param messageId the id of the message to update
-         * @param updateValues the values to change. Unspecified fields will not be altered
-         * @param save whether to resave the message as a draft or send it
-         */
-        public static void sendOrSaveExistingMessage(
-                ContentResolver contentResolver, String account, long messageId,
-                ContentValues updateValues, boolean save) {
-            updateValues.put(MessageColumns.FAKE_SAVE, save);
-            updateValues.put(MessageColumns.FAKE_REF_MESSAGE_ID, 0);
-            Uri uri = Uri.parse(
-                    AUTHORITY_PLUS_MESSAGES + account + "/" + messageId);
-            contentResolver.update(uri, updateValues, null, null);
-        }
-
-        /**
-         * The string produced here is parsed by Gmail.MessageCursor#getAttachmentInfos.
-         */
-        public static String joinedAttachmentsString(List<Gmail.Attachment> attachments) {
-            StringBuilder attachmentsSb = new StringBuilder();
-            for (Gmail.Attachment attachment : attachments) {
-                if (attachmentsSb.length() != 0) {
-                    attachmentsSb.append(Gmail.ATTACHMENT_INFO_SEPARATOR);
-                }
-                attachmentsSb.append(attachment.toJoinedString());
-            }
-            return attachmentsSb.toString();
-        }
-
-    }
-
-    /**
-     * A cursor over conversations.
-     *
-     * "Conversation" refers to the information needed to populate a list of
-     * conversations, not all of the messages in a conversation.
-     */
-    public static final class ConversationCursor extends MailCursor {
-
-        private LabelMap mLabelMap;
-
-        private int mConversationIdIndex;
-        private int mSubjectIndex;
-        private int mSnippetIndex;
-        private int mFromIndex;
-        private int mDateIndex;
-        private int mPersonalLevelIndex;
-        private int mLabelIdsIndex;
-        private int mNumMessagesIndex;
-        private int mMaxMessageIdIndex;
-        private int mHasAttachmentsIndex;
-        private int mHasMessagesWithErrorsIndex;
-        private int mForceAllUnreadIndex;
-
-        private TextUtils.StringSplitter mLabelIdsSplitter = newConversationLabelIdsSplitter();
-
-        private ConversationCursor(Gmail gmail, String account, Cursor cursor) {
-            super(account, cursor);
-            mLabelMap = gmail.getLabelMap(account);
-
-            mConversationIdIndex =
-                    mCursor.getColumnIndexOrThrow(ConversationColumns.ID);
-            mSubjectIndex = mCursor.getColumnIndexOrThrow(ConversationColumns.SUBJECT);
-            mSnippetIndex = mCursor.getColumnIndexOrThrow(ConversationColumns.SNIPPET);
-            mFromIndex = mCursor.getColumnIndexOrThrow(ConversationColumns.FROM);
-            mDateIndex = mCursor.getColumnIndexOrThrow(ConversationColumns.DATE);
-            mPersonalLevelIndex =
-                    mCursor.getColumnIndexOrThrow(ConversationColumns.PERSONAL_LEVEL);
-            mLabelIdsIndex =
-                    mCursor.getColumnIndexOrThrow(ConversationColumns.LABEL_IDS);
-            mNumMessagesIndex = mCursor.getColumnIndexOrThrow(ConversationColumns.NUM_MESSAGES);
-            mMaxMessageIdIndex = mCursor.getColumnIndexOrThrow(ConversationColumns.MAX_MESSAGE_ID);
-            mHasAttachmentsIndex =
-                    mCursor.getColumnIndexOrThrow(ConversationColumns.HAS_ATTACHMENTS);
-            mHasMessagesWithErrorsIndex =
-                    mCursor.getColumnIndexOrThrow(ConversationColumns.HAS_MESSAGES_WITH_ERRORS);
-            mForceAllUnreadIndex =
-                    mCursor.getColumnIndexOrThrow(ConversationColumns.FORCE_ALL_UNREAD);
-        }
-
-        @Override
-        protected void onCursorPositionChanged() {
-            super.onCursorPositionChanged();
-        }
-
-        public CursorStatus getStatus() {
-            Bundle extras = mCursor.getExtras();
-            String stringStatus = extras.getString(EXTRA_STATUS);
-            return CursorStatus.valueOf(stringStatus);
-        }
-
-        /** Retry a network request after errors. */
-        public void retry() {
-            Bundle input = new Bundle();
-            input.putString(RESPOND_INPUT_COMMAND, COMMAND_RETRY);
-            Bundle output = mCursor.respond(input);
-            String response = output.getString(RESPOND_OUTPUT_COMMAND_RESPONSE);
-            assert COMMAND_RESPONSE_OK.equals(response);
-        }
-
-        /**
-         * When a conversation cursor is created it becomes the active network cursor, which means
-         * that it will fetch results from the network if it needs to in order to show all mail that
-         * matches its query. If you later want to requery an older cursor and would like that
-         * cursor to be the active cursor you need to call this method before requerying.
-         */
-        public void becomeActiveNetworkCursor() {
-            Bundle input = new Bundle();
-            input.putString(RESPOND_INPUT_COMMAND, COMMAND_ACTIVATE);
-            Bundle output = mCursor.respond(input);
-            String response = output.getString(RESPOND_OUTPUT_COMMAND_RESPONSE);
-            assert COMMAND_RESPONSE_OK.equals(response);
-        }
-
-        /**
-         * Tells the cursor whether its contents are visible to the user. The cursor will
-         * automatically broadcast intents to remove any matching new-mail notifications when this
-         * cursor's results become visible and, if they are visible, when the cursor is requeried.
-         *
-         * Note that contents shown in an activity that is resumed but not focused
-         * (onWindowFocusChanged/hasWindowFocus) then results shown in that activity do not count
-         * as visible. (This happens when the activity is behind the lock screen or a dialog.)
-         *
-         * @param visible whether the contents of this cursor are visible to the user.
-         */
-        public void setContentsVisibleToUser(boolean visible) {
-            Bundle input = new Bundle();
-            input.putString(RESPOND_INPUT_COMMAND, COMMAND_SET_VISIBLE);
-            input.putBoolean(SET_VISIBLE_PARAM_VISIBLE, visible);
-            Bundle output = mCursor.respond(input);
-            String response = output.getString(RESPOND_OUTPUT_COMMAND_RESPONSE);
-            assert COMMAND_RESPONSE_OK.equals(response);
-        }
-
-        /**
-         * Gets the conversation id. This is immutable. (The server calls it the original
-         * conversation id.)
-         *
-         * @return the conversation id
-         */
-        public long getConversationId() {
-            return mCursor.getLong(mConversationIdIndex);
-        }
-
-        /**
-         * Returns the instructions for building from snippets. Pass this to getFromSnippetHtml
-         * in order to actually build the snippets.
-         * @return snippet instructions for use by getFromSnippetHtml()
-         */
-        public String getFromSnippetInstructions() {
-            return getStringInColumn(mFromIndex);
-        }
-
-        /**
-         * Gets the conversation's subject.
-         *
-         * @return the subject
-         */
-        public String getSubject() {
-            return getStringInColumn(mSubjectIndex);
-        }
-
-        /**
-         * Gets the conversation's snippet.
-         *
-         * @return the snippet
-         */
-        public String getSnippet() {
-            return getStringInColumn(mSnippetIndex);
-        }
-
-        /**
-         * Get's the conversation's personal level.
-         *
-         * @return the personal level.
-         */
-        public PersonalLevel getPersonalLevel() {
-            int personalLevelInt = mCursor.getInt(mPersonalLevelIndex);
-            return PersonalLevel.fromInt(personalLevelInt);
-        }
-
-        /**
-         * @return a copy of the set of labels. To add or remove labels call
-         *         MessageCursor.addOrRemoveLabel on each message in the conversation.
-         * @deprecated use getLabelIds
-         */
-        public Set<String> getLabels() {
-            return getLabels(getRawLabelIds(), mLabelMap);
-        }
-
-        /**
-         * @return a copy of the set of labels. To add or remove labels call
-         *         MessageCursor.addOrRemoveLabel on each message in the conversation.
-         */
-        public Set<Long> getLabelIds() {
-            mLabelIdsSplitter.setString(getRawLabelIds());
-            return getLabelIdsFromLabelIdsString(mLabelIdsSplitter);
-        }
-
-        /**
-         * Returns the set of labels using the raw labels from a previous getRawLabels()
-         * as input.
-         * @return a copy of the set of labels. To add or remove labels call
-         * MessageCursor.addOrRemoveLabel on each message in the conversation.
-         */
-        public Set<String> getLabels(String rawLabelIds, LabelMap labelMap) {
-            mLabelIdsSplitter.setString(rawLabelIds);
-            return getCanonicalNamesFromLabelIdsString(labelMap, mLabelIdsSplitter);
-        }
-
-        /**
-         * @return a joined string of labels separated by spaces. Use
-         * getLabels(rawLabels) to convert this to a Set of labels.
-         */
-        public String getRawLabelIds() {
-            return mCursor.getString(mLabelIdsIndex);
-        }
-
-        /**
-         * @return the number of messages in the conversation
-         */
-        public int getNumMessages() {
-            return mCursor.getInt(mNumMessagesIndex);
-        }
-
-        /**
-         * @return the max message id in the conversation
-         */
-        public long getMaxServerMessageId() {
-            return mCursor.getLong(mMaxMessageIdIndex);
-        }
-
-        public long getDateMs() {
-            return mCursor.getLong(mDateIndex);
-        }
-
-        public boolean hasAttachments() {
-            return mCursor.getInt(mHasAttachmentsIndex) != 0;
-        }
-
-        public boolean hasMessagesWithErrors() {
-            return mCursor.getInt(mHasMessagesWithErrorsIndex) != 0;
-        }
-
-        public boolean getForceAllUnread() {
-            return !mCursor.isNull(mForceAllUnreadIndex)
-                    && mCursor.getInt(mForceAllUnreadIndex) != 0;
-        }
-    }
-}
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 1fc3678..d3f46b8 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -2589,8 +2589,8 @@
      * @param gainFocus True if the View has focus; false otherwise.
      * @param direction The direction focus has moved when requestFocus()
      *                  is called to give this view focus. Values are
-     *                  View.FOCUS_UP, View.FOCUS_DOWN, View.FOCUS_LEFT or
-     *                  View.FOCUS_RIGHT. It may not always apply, in which
+     *                  {@link #FOCUS_UP}, {@link #FOCUS_DOWN}, {@link #FOCUS_LEFT} or
+     *                  {@link #FOCUS_RIGHT}. It may not always apply, in which
      *                  case use the default.
      * @param previouslyFocusedRect The rectangle, in this view's coordinate
      *        system, of the previously focused view.  If applicable, this will be
@@ -5961,7 +5961,11 @@
     protected void onRestoreInstanceState(Parcelable state) {
         mPrivateFlags |= SAVE_STATE_CALLED;
         if (state != BaseSavedState.EMPTY_STATE && state != null) {
-            throw new IllegalArgumentException("Wrong state class -- expecting View State");
+            throw new IllegalArgumentException("Wrong state class, expecting View State but "
+                    + "received " + state.getClass().toString() + " instead. This usually happens "
+                    + "when two views of different type have the same id in the same hierarchy. " 
+                    + "This view's id is " + ViewDebug.resolveId(mContext, getId()) + ". Make sure " 
+                    + "other views do not use the same id.");
         }
     }
 
diff --git a/core/java/android/view/ViewDebug.java b/core/java/android/view/ViewDebug.java
index 4baf612..2fd974e 100644
--- a/core/java/android/view/ViewDebug.java
+++ b/core/java/android/view/ViewDebug.java
@@ -1300,7 +1300,7 @@
         }
     }
 
-    private static Object resolveId(Context context, int id) {
+    static Object resolveId(Context context, int id) {
         Object fieldValue;
         final Resources resources = context.getResources();
         if (id >= 0) {
diff --git a/core/java/android/webkit/WebTextView.java b/core/java/android/webkit/WebTextView.java
index 924398e..608c8a24 100644
--- a/core/java/android/webkit/WebTextView.java
+++ b/core/java/android/webkit/WebTextView.java
@@ -789,7 +789,6 @@
         // Set up a measure spec so a layout can always be recreated.
         mWidthSpec = MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY);
         mHeightSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
-        requestFocus();
     }
 
     /**
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 3be6a3f..7c79fd9 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -3205,6 +3205,8 @@
         // Note that sendOurVisibleRect calls viewToContent, so the coordinates
         // should be in content coordinates.
         Rect bounds = nativeFocusCandidateNodeBounds();
+        Rect vBox = contentToViewRect(bounds);
+        mWebTextView.setRect(vBox.left, vBox.top, vBox.width(), vBox.height());
         if (!Rect.intersects(bounds, visibleRect)) {
             mWebTextView.bringIntoView();
         }
@@ -3215,25 +3217,14 @@
             // i.e. In the case of opening/closing the screen.
             // In that case, we need to set the dimensions, but not the other
             // aspects.
-            // We also need to restore the selection, which gets wrecked by
-            // calling setTextEntryRect.
-            Spannable spannable = (Spannable) mWebTextView.getText();
-            int start = Selection.getSelectionStart(spannable);
-            int end = Selection.getSelectionEnd(spannable);
             // If the text has been changed by webkit, update it.  However, if
             // there has been more UI text input, ignore it.  We will receive
             // another update when that text is recognized.
-            if (text != null && !text.equals(spannable.toString())
+            if (text != null && !text.equals(mWebTextView.getText().toString())
                     && nativeTextGeneration() == mTextGeneration) {
                 mWebTextView.setTextAndKeepSelection(text);
-            } else {
-                // FIXME: Determine whether this is necessary.
-                Selection.setSelection(spannable, start, end);
             }
         } else {
-            Rect vBox = contentToViewRect(bounds);
-            mWebTextView.setRect(vBox.left, vBox.top, vBox.width(),
-                    vBox.height());
             mWebTextView.setGravity(nativeFocusCandidateIsRtlText() ?
                     Gravity.RIGHT : Gravity.NO_GRAVITY);
             // This needs to be called before setType, which may call
@@ -3247,8 +3238,8 @@
                 text = "";
             }
             mWebTextView.setTextAndKeepSelection(text);
-            mWebTextView.requestFocus();
         }
+        mWebTextView.requestFocus();
     }
 
     /**
diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java
index 6079773..5ded240 100644
--- a/core/java/android/webkit/WebViewCore.java
+++ b/core/java/android/webkit/WebViewCore.java
@@ -1592,9 +1592,6 @@
     // Used to avoid posting more than one split picture message.
     private boolean mSplitPictureIsScheduled;
 
-    // Used to suspend drawing.
-    private boolean mDrawIsPaused;
-
     // mRestoreState is set in didFirstLayout(), and reset in the next
     // webkitDraw after passing it to the UI thread.
     private RestoreState mRestoreState = null;
@@ -1713,17 +1710,6 @@
         sWebCoreHandler.removeMessages(WebCoreThread.RESUME_PRIORITY);
         sWebCoreHandler.sendMessageAtFrontOfQueue(sWebCoreHandler
                 .obtainMessage(WebCoreThread.REDUCE_PRIORITY));
-        // Note: there is one possible failure mode. If pauseUpdate() is called
-        // from UI thread while in webcore thread WEBKIT_DRAW is just pulled out
-        // of the queue and about to be executed. mDrawIsScheduled may be set to
-        // false in webkitDraw(). So update won't be blocked. But at least the
-        // webcore thread priority is still lowered.
-        if (core != null) {
-            synchronized (core) {
-                core.mDrawIsPaused = true;
-                core.mEventHub.removeMessages(EventHub.WEBKIT_DRAW);
-            }
-        }
     }
 
     static void resumeUpdate(WebViewCore core) {
@@ -1732,14 +1718,6 @@
         sWebCoreHandler.removeMessages(WebCoreThread.RESUME_PRIORITY);
         sWebCoreHandler.sendMessageAtFrontOfQueue(sWebCoreHandler
                 .obtainMessage(WebCoreThread.RESUME_PRIORITY));
-        if (core != null) {
-            synchronized (core) {
-                core.mDrawIsScheduled = false;
-                core.mDrawIsPaused = false;
-                if (DebugFlags.WEB_VIEW_CORE) Log.v(LOGTAG, "resumeUpdate");
-                core.contentDraw();
-            }
-        }
     }
 
     static void startCacheTransaction() {
@@ -1778,9 +1756,7 @@
         }
         // only fire an event if this is our first request
         synchronized (this) {
-            if (mDrawIsPaused || mDrawIsScheduled) {
-                return;
-            }
+            if (mDrawIsScheduled) return;
             mDrawIsScheduled = true;
             mEventHub.sendMessage(Message.obtain(null, EventHub.WEBKIT_DRAW));
         }
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 5199ada..e964a8f 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -17,8 +17,8 @@
 package com.android.internal.os;
 
 import android.bluetooth.BluetoothHeadset;
+import android.net.TrafficStats;
 import android.os.BatteryStats;
-import android.os.NetStat;
 import android.os.Parcel;
 import android.os.ParcelFormatException;
 import android.os.Parcelable;
@@ -1022,8 +1022,8 @@
     public void doUnplug(long batteryUptime, long batteryRealtime) {
         for (int iu = mUidStats.size() - 1; iu >= 0; iu--) {
             Uid u = mUidStats.valueAt(iu);
-            u.mStartedTcpBytesReceived = NetStat.getUidRxBytes(u.mUid);
-            u.mStartedTcpBytesSent = NetStat.getUidTxBytes(u.mUid);
+            u.mStartedTcpBytesReceived = TrafficStats.getUidRxBytes(u.mUid);
+            u.mStartedTcpBytesSent = TrafficStats.getUidTxBytes(u.mUid);
             u.mTcpBytesReceivedAtLastUnplug = u.mCurrentTcpBytesReceived;
             u.mTcpBytesSentAtLastUnplug = u.mCurrentTcpBytesSent;
         }
@@ -1031,10 +1031,10 @@
             mUnpluggables.get(i).unplug(batteryUptime, batteryRealtime);
         }
         // Track total mobile data
-        doDataUnplug(mMobileDataRx, NetStat.getMobileRxBytes());
-        doDataUnplug(mMobileDataTx, NetStat.getMobileTxBytes());
-        doDataUnplug(mTotalDataRx, NetStat.getTotalRxBytes());
-        doDataUnplug(mTotalDataTx, NetStat.getTotalTxBytes());
+        doDataUnplug(mMobileDataRx, TrafficStats.getMobileRxBytes());
+        doDataUnplug(mMobileDataTx, TrafficStats.getMobileTxBytes());
+        doDataUnplug(mTotalDataRx, TrafficStats.getTotalRxBytes());
+        doDataUnplug(mTotalDataTx, TrafficStats.getTotalTxBytes());
         // Track radio awake time
         mRadioDataStart = getCurrentRadioDataUptime();
         mRadioDataUptime = 0;
@@ -1058,10 +1058,10 @@
         for (int i = mUnpluggables.size() - 1; i >= 0; i--) {
             mUnpluggables.get(i).plug(batteryUptime, batteryRealtime);
         }
-        doDataPlug(mMobileDataRx, NetStat.getMobileRxBytes());
-        doDataPlug(mMobileDataTx, NetStat.getMobileTxBytes());
-        doDataPlug(mTotalDataRx, NetStat.getTotalRxBytes());
-        doDataPlug(mTotalDataTx, NetStat.getTotalTxBytes());
+        doDataPlug(mMobileDataRx, TrafficStats.getMobileRxBytes());
+        doDataPlug(mMobileDataTx, TrafficStats.getMobileTxBytes());
+        doDataPlug(mTotalDataRx, TrafficStats.getTotalRxBytes());
+        doDataPlug(mTotalDataTx, TrafficStats.getTotalTxBytes());
         // Track radio awake time
         mRadioDataUptime = getRadioDataUptime();
         mRadioDataStart = -1;
@@ -1519,7 +1519,7 @@
         
         public long computeCurrentTcpBytesReceived() {
             return mCurrentTcpBytesReceived + (mStartedTcpBytesReceived >= 0
-                    ? (NetStat.getUidRxBytes(mUid) - mStartedTcpBytesReceived) : 0);
+                    ? (TrafficStats.getUidRxBytes(mUid) - mStartedTcpBytesReceived) : 0);
         }
 
         @Override
@@ -1696,7 +1696,7 @@
         
         public long computeCurrentTcpBytesSent() {
             return mCurrentTcpBytesSent + (mStartedTcpBytesSent >= 0
-                    ? (NetStat.getUidTxBytes(mUid) - mStartedTcpBytesSent) : 0);
+                    ? (TrafficStats.getUidTxBytes(mUid) - mStartedTcpBytesSent) : 0);
         }
 
         void writeToParcelLocked(Parcel out, long batteryRealtime) {
@@ -2919,22 +2919,22 @@
 
     /** Only STATS_UNPLUGGED works properly */
     public long getMobileTcpBytesSent(int which) {
-        return getTcpBytes(NetStat.getMobileTxBytes(), mMobileDataTx, which);
+        return getTcpBytes(TrafficStats.getMobileTxBytes(), mMobileDataTx, which);
     }
 
     /** Only STATS_UNPLUGGED works properly */
     public long getMobileTcpBytesReceived(int which) {
-        return getTcpBytes(NetStat.getMobileRxBytes(), mMobileDataRx, which);
+        return getTcpBytes(TrafficStats.getMobileRxBytes(), mMobileDataRx, which);
     }
 
     /** Only STATS_UNPLUGGED works properly */
     public long getTotalTcpBytesSent(int which) {
-        return getTcpBytes(NetStat.getTotalTxBytes(), mTotalDataTx, which);
+        return getTcpBytes(TrafficStats.getTotalTxBytes(), mTotalDataTx, which);
     }
 
     /** Only STATS_UNPLUGGED works properly */
     public long getTotalTcpBytesReceived(int which) {
-        return getTcpBytes(NetStat.getTotalRxBytes(), mTotalDataRx, which);
+        return getTcpBytes(TrafficStats.getTotalRxBytes(), mTotalDataRx, which);
     }
 
     @Override
diff --git a/core/java/com/android/internal/os/BinderInternal.java b/core/java/com/android/internal/os/BinderInternal.java
index eacf0ce..ba0bf0d 100644
--- a/core/java/com/android/internal/os/BinderInternal.java
+++ b/core/java/com/android/internal/os/BinderInternal.java
@@ -76,6 +76,13 @@
      */
     public static final native IBinder getContextObject();
     
+    /**
+     * Special for system process to not allow incoming calls to run at
+     * background scheduling priority.
+     * @hide
+     */
+    public static final native void disableBackgroundScheduling(boolean disable);
+    
     static native final void handleGc();
     
     public static void forceGc(String reason) {
diff --git a/core/java/com/google/android/net/GoogleHttpClient.java b/core/java/com/google/android/net/GoogleHttpClient.java
index 8a1298f..7bdc7f8 100644
--- a/core/java/com/google/android/net/GoogleHttpClient.java
+++ b/core/java/com/google/android/net/GoogleHttpClient.java
@@ -19,13 +19,14 @@
 import android.content.ContentResolver;
 import android.content.ContentValues;
 import android.content.Context;
+import android.net.TrafficStats;
 import android.net.http.AndroidHttpClient;
 import android.os.Build;
-import android.os.NetStat;
 import android.os.SystemClock;
 import android.provider.Checkin;
 import android.util.Config;
 import android.util.Log;
+import org.apache.harmony.xnet.provider.jsse.SSLClientSessionCache;
 import org.apache.http.HttpEntity;
 import org.apache.http.HttpEntityEnclosingRequest;
 import org.apache.http.HttpHost;
@@ -45,7 +46,6 @@
 import org.apache.http.impl.client.RequestWrapper;
 import org.apache.http.params.HttpParams;
 import org.apache.http.protocol.HttpContext;
-import org.apache.harmony.xnet.provider.jsse.SSLClientSessionCache;
 
 import java.io.IOException;
 import java.net.InetAddress;
@@ -205,8 +205,8 @@
                 // to follow redirects, count each redirect as an additional round trip.
 
                 int uid = android.os.Process.myUid();
-                long startTx = NetStat.getUidTxBytes(uid);
-                long startRx = NetStat.getUidRxBytes(uid);
+                long startTx = TrafficStats.getUidTxBytes(uid);
+                long startRx = TrafficStats.getUidRxBytes(uid);
 
                 response = mClient.execute(request, context);
                 HttpEntity origEntity = response == null ? null : response.getEntity();
diff --git a/core/java/com/google/android/net/NetworkStatsEntity.java b/core/java/com/google/android/net/NetworkStatsEntity.java
index f5d2349..a22fa1e 100644
--- a/core/java/com/google/android/net/NetworkStatsEntity.java
+++ b/core/java/com/google/android/net/NetworkStatsEntity.java
@@ -16,11 +16,10 @@
 
 package com.google.android.net;
 
-import android.os.NetStat;
+import android.net.TrafficStats;
 import android.os.SystemClock;
 import android.os.SystemProperties;
 import android.util.EventLog;
-
 import org.apache.http.HttpEntity;
 import org.apache.http.entity.HttpEntityWrapper;
 
@@ -45,8 +44,8 @@
                 super.close();
             } finally {
                 long processingTime = SystemClock.elapsedRealtime() - mProcessingStartTime;
-                long tx = NetStat.getUidTxBytes(mUid);
-                long rx = NetStat.getUidRxBytes(mUid);
+                long tx = TrafficStats.getUidTxBytes(mUid);
+                long rx = TrafficStats.getUidRxBytes(mUid);
 
                 EventLog.writeEvent(HTTP_STATS_EVENT, mUa, mResponseLatency, processingTime,
                         tx - mStartTx, rx - mStartRx);
diff --git a/core/jni/android_util_Binder.cpp b/core/jni/android_util_Binder.cpp
index f0885fd..627fcbf 100644
--- a/core/jni/android_util_Binder.cpp
+++ b/core/jni/android_util_Binder.cpp
@@ -670,6 +670,12 @@
     android::IPCThreadState::self()->joinThreadPool();
 }
 
+static void android_os_BinderInternal_disableBackgroundScheduling(JNIEnv* env,
+        jobject clazz, jboolean disable)
+{
+    IPCThreadState::disableBackgroundScheduling(disable ? true : false);
+}
+
 static void android_os_BinderInternal_handleGc(JNIEnv* env, jobject clazz)
 {
     LOGV("Gc has executed, clearing binder ops");
@@ -682,6 +688,7 @@
      /* name, signature, funcPtr */
     { "getContextObject", "()Landroid/os/IBinder;", (void*)android_os_BinderInternal_getContextObject },
     { "joinThreadPool", "()V", (void*)android_os_BinderInternal_joinThreadPool },
+    { "disableBackgroundScheduling", "(Z)V", (void*)android_os_BinderInternal_disableBackgroundScheduling },
     { "handleGc", "()V", (void*)android_os_BinderInternal_handleGc }
 };
 
diff --git a/core/jni/android_util_Process.cpp b/core/jni/android_util_Process.cpp
index 094b02d..e84f2e5 100644
--- a/core/jni/android_util_Process.cpp
+++ b/core/jni/android_util_Process.cpp
@@ -120,11 +120,7 @@
 
 jint android_os_Process_myTid(JNIEnv* env, jobject clazz)
 {
-#ifdef HAVE_GETTID
-    return gettid();
-#else
-    return getpid();
-#endif
+    return androidGetTid();
 }
 
 jint android_os_Process_getUidForName(JNIEnv* env, jobject clazz, jstring name)
@@ -191,15 +187,11 @@
 
 void android_os_Process_setThreadGroup(JNIEnv* env, jobject clazz, int pid, jint grp)
 {
-    if (grp > ANDROID_TGROUP_MAX || grp < 0) { 
-        signalExceptionForGroupError(env, clazz, EINVAL);
+    int res = androidSetThreadSchedulingGroup(pid, grp);
+    if (res != NO_ERROR) {
+        signalExceptionForGroupError(env, clazz, res == BAD_VALUE ? EINVAL : errno);
         return;
     }
-
-    if (set_sched_policy(pid, (grp == ANDROID_TGROUP_BG_NONINTERACT) ?
-                                      SP_BACKGROUND : SP_FOREGROUND)) {
-        signalExceptionForGroupError(env, clazz, errno);
-    }
 }
 
 void android_os_Process_setProcessGroup(JNIEnv* env, jobject clazz, int pid, jint grp) 
@@ -275,22 +267,15 @@
 void android_os_Process_setThreadPriority(JNIEnv* env, jobject clazz,
                                               jint pid, jint pri)
 {
-    int rc = 0;
-
-    if (pri >= ANDROID_PRIORITY_BACKGROUND) {
-        rc = set_sched_policy(pid, SP_BACKGROUND);
-    } else if (getpriority(PRIO_PROCESS, pid) >= ANDROID_PRIORITY_BACKGROUND) {
-        rc = set_sched_policy(pid, SP_FOREGROUND);
+    int rc = androidSetThreadPriority(pid, pri);
+    if (rc != 0) {
+        if (rc == INVALID_OPERATION) {
+            signalExceptionForPriorityError(env, clazz, errno);
+        } else {
+            signalExceptionForGroupError(env, clazz, errno);
+        }
     }
-
-    if (rc) {
-        signalExceptionForGroupError(env, clazz, errno);
-        return;
-    }
-
-    if (setpriority(PRIO_PROCESS, pid, pri) < 0) {
-        signalExceptionForPriorityError(env, clazz, errno);
-    }
+    
     //LOGI("Setting priority of %d: %d, getpriority returns %d\n",
     //     pid, pri, getpriority(PRIO_PROCESS, pid));
 }
diff --git a/include/binder/IBinder.h b/include/binder/IBinder.h
index 884b5c1..749a977 100644
--- a/include/binder/IBinder.h
+++ b/include/binder/IBinder.h
@@ -52,7 +52,7 @@
         DUMP_TRANSACTION        = B_PACK_CHARS('_','D','M','P'),
         INTERFACE_TRANSACTION   = B_PACK_CHARS('_', 'N', 'T', 'F'),
 
-        // Corresponds to tfOneWay -- an asynchronous call.
+        // Corresponds to TF_ONE_WAY -- an asynchronous call.
         FLAG_ONEWAY             = 0x00000001
     };
 
diff --git a/include/binder/IPCThreadState.h b/include/binder/IPCThreadState.h
index 78306b2b..3ab985d 100644
--- a/include/binder/IPCThreadState.h
+++ b/include/binder/IPCThreadState.h
@@ -68,6 +68,13 @@
 
     static  void                shutdown();
     
+    // Call this to disable switching threads to background scheduling when
+    // receiving incoming IPC calls.  This is specifically here for the
+    // Android system process, since it expects to have background apps calling
+    // in to it but doesn't want to acquire locks in its services while in
+    // the background.
+    static  void                disableBackgroundScheduling(bool disable);
+    
 private:
                                 IPCThreadState();
                                 ~IPCThreadState();
@@ -93,9 +100,10 @@
                                            void* cookie);
     
     const   sp<ProcessState>    mProcess;
+    const   pid_t               mMyThreadId;
             Vector<BBinder*>    mPendingStrongDerefs;
             Vector<RefBase::weakref_type*> mPendingWeakDerefs;
-                                
+            
             Parcel              mIn;
             Parcel              mOut;
             status_t            mLastError;
diff --git a/include/utils/ResourceTypes.h b/include/utils/ResourceTypes.h
index 49145e8..a845908 100644
--- a/include/utils/ResourceTypes.h
+++ b/include/utils/ResourceTypes.h
@@ -393,7 +393,10 @@
     enum {
         // If set, the string index is sorted by the string values (based
         // on strcmp16()).
-        SORTED_FLAG = 1<<0
+        SORTED_FLAG = 1<<0,
+
+        // String pool is encoded in UTF-8
+        UTF8_FLAG = 1<<8
     };
     uint32_t flags;
 
@@ -456,9 +459,11 @@
     void*                       mOwnedData;
     const ResStringPool_header* mHeader;
     size_t                      mSize;
+    mutable Mutex               mDecodeLock;
     const uint32_t*             mEntries;
     const uint32_t*             mEntryStyles;
-    const char16_t*             mStrings;
+    const void*                 mStrings;
+    char16_t**                  mCache;
     uint32_t                    mStringPoolSize;    // number of uint16_t
     const uint32_t*             mStyles;
     uint32_t                    mStylePoolSize;    // number of uint32_t
diff --git a/include/utils/String16.h b/include/utils/String16.h
index a2d22ee..07a0c11 100644
--- a/include/utils/String16.h
+++ b/include/utils/String16.h
@@ -49,12 +49,17 @@
 // Version of strzcmp16 for comparing strings in different endianness.
 int strzcmp16_h_n(const char16_t *s1H, size_t n1, const char16_t *s2N, size_t n2);
 
+// Convert UTF-8 to UTF-16 including surrogate pairs
+void utf8_to_utf16(const uint8_t *src, size_t srcLen, char16_t* dst, const size_t dstLen);
+
 }
 
 // ---------------------------------------------------------------------------
 
 namespace android {
 
+// ---------------------------------------------------------------------------
+
 class String8;
 class TextOutput;
 
diff --git a/include/utils/String8.h b/include/utils/String8.h
index ecc5774..c4b18a4 100644
--- a/include/utils/String8.h
+++ b/include/utils/String8.h
@@ -60,6 +60,11 @@
 /*
  * Returns the UTF-8 length of "src".
  */
+size_t utf8_length_from_utf16(const char16_t *src, size_t src_len);
+
+/*
+ * Returns the UTF-8 length of "src".
+ */
 size_t utf8_length_from_utf32(const char32_t *src, size_t src_len);
 
 /*
@@ -120,6 +125,9 @@
 size_t utf32_to_utf8(const char32_t* src, size_t src_len,
                      char* dst, size_t dst_len);
 
+size_t utf16_to_utf8(const char16_t* src, size_t src_len,
+                     char* dst, size_t dst_len);
+
 }
 
 // ---------------------------------------------------------------------------
diff --git a/include/utils/threads.h b/include/utils/threads.h
index 0fc533f..130d83c 100644
--- a/include/utils/threads.h
+++ b/include/utils/threads.h
@@ -124,6 +124,24 @@
 
 extern void androidSetCreateThreadFunc(android_create_thread_fn func);
 
+// ------------------------------------------------------------------
+// Extra functions working with raw pids.
+
+// Get pid for the current thread.
+extern pid_t androidGetTid();
+
+// Change the scheduling group of a particular thread.  The group
+// should be one of the ANDROID_TGROUP constants.  Returns BAD_VALUE if
+// grp is out of range, else another non-zero value with errno set if
+// the operation failed.
+extern int androidSetThreadSchedulingGroup(pid_t tid, int grp);
+
+// Change the priority AND scheduling group of a particular thread.  The priority
+// should be one of the ANDROID_PRIORITY constants.  Returns INVALID_OPERATION
+// if the priority set failed, else another value if just the group set failed;
+// in either case errno is set.
+extern int androidSetThreadPriority(pid_t tid, int prio);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/libs/binder/IPCThreadState.cpp b/libs/binder/IPCThreadState.cpp
index b2a7db8..473f580 100644
--- a/libs/binder/IPCThreadState.cpp
+++ b/libs/binder/IPCThreadState.cpp
@@ -292,6 +292,7 @@
 static bool gHaveTLS = false;
 static pthread_key_t gTLS = 0;
 static bool gShutdown = false;
+static bool gDisableBackgroundScheduling = false;
 
 IPCThreadState* IPCThreadState::self()
 {
@@ -332,6 +333,11 @@
     }
 }
 
+void IPCThreadState::disableBackgroundScheduling(bool disable)
+{
+    gDisableBackgroundScheduling = disable;
+}
+
 sp<ProcessState> IPCThreadState::process()
 {
     return mProcess;
@@ -386,6 +392,11 @@
 
     mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER);
     
+    // This thread may have been spawned by a thread that was in the background
+    // scheduling group, so first we will make sure it is in the default/foreground
+    // one to avoid performing an initial transaction in the background.
+    androidSetThreadSchedulingGroup(mMyThreadId, ANDROID_TGROUP_DEFAULT);
+        
     status_t result;
     do {
         int32_t cmd;
@@ -427,19 +438,13 @@
         }
         
         // After executing the command, ensure that the thread is returned to the
-        // default cgroup and priority before rejoining the pool.  This is a failsafe
-        // in case the command implementation failed to properly restore the thread's
-        // scheduling parameters upon completion.
-        int my_id;
-#ifdef HAVE_GETTID
-        my_id = gettid();
-#else
-        my_id = getpid();
-#endif
-        if (!set_sched_policy(my_id, SP_FOREGROUND)) {
-            // success; reset the priority as well
-            setpriority(PRIO_PROCESS, my_id, ANDROID_PRIORITY_NORMAL);
-        }
+        // default cgroup before rejoining the pool.  The driver takes care of
+        // restoring the priority, but doesn't do anything with cgroups so we
+        // need to take care of that here in userspace.  Note that we do make
+        // sure to go in the foreground after executing a transaction, but
+        // there are other callbacks into user code that could have changed
+        // our group so we want to make absolutely sure it is put back.
+        androidSetThreadSchedulingGroup(mMyThreadId, ANDROID_TGROUP_DEFAULT);
 
         // Let this thread exit the thread pool if it is no longer
         // needed and it is not the main process thread.
@@ -583,10 +588,10 @@
 }
 
 IPCThreadState::IPCThreadState()
-    : mProcess(ProcessState::self())
+    : mProcess(ProcessState::self()), mMyThreadId(androidGetTid())
 {
     pthread_setspecific(gTLS, this);
-        clearCaller();
+    clearCaller();
     mIn.setDataCapacity(256);
     mOut.setDataCapacity(256);
 }
@@ -930,6 +935,17 @@
             mCallingPid = tr.sender_pid;
             mCallingUid = tr.sender_euid;
             
+            bool doBackground = !gDisableBackgroundScheduling &&
+                    getpriority(PRIO_PROCESS, mMyThreadId)
+                            >= ANDROID_PRIORITY_BACKGROUND;
+            if (doBackground) {
+                // We have inherited a background priority from the caller.
+                // Ensure this thread is in the background scheduling class,
+                // since the driver won't modify scheduling classes for us.
+                androidSetThreadSchedulingGroup(mMyThreadId,
+                        ANDROID_TGROUP_BG_NONINTERACT);
+            }
+            
             //LOGI(">>>> TRANSACT from pid %d uid %d\n", mCallingPid, mCallingUid);
             
             Parcel reply;
@@ -967,6 +983,13 @@
             mCallingPid = origPid;
             mCallingUid = origUid;
             
+            if (doBackground) {
+                // We moved to the background scheduling group to execute
+                // this transaction, so now that we are done go back in the
+                // foreground.
+                androidSetThreadSchedulingGroup(mMyThreadId, ANDROID_TGROUP_DEFAULT);
+            }
+            
             IF_LOG_TRANSACTIONS() {
                 TextOutput::Bundle _b(alog);
                 alog << "BC_REPLY thr " << (void*)pthread_self() << " / obj "
diff --git a/libs/utils/ResourceTypes.cpp b/libs/utils/ResourceTypes.cpp
index 450af8d..afca814 100644
--- a/libs/utils/ResourceTypes.cpp
+++ b/libs/utils/ResourceTypes.cpp
@@ -229,12 +229,12 @@
 // --------------------------------------------------------------------
 
 ResStringPool::ResStringPool()
-    : mError(NO_INIT), mOwnedData(NULL)
+    : mError(NO_INIT), mOwnedData(NULL), mHeader(NULL), mCache(NULL)
 {
 }
 
 ResStringPool::ResStringPool(const void* data, size_t size, bool copyData)
-    : mError(NO_INIT), mOwnedData(NULL)
+    : mError(NO_INIT), mOwnedData(NULL), mHeader(NULL), mCache(NULL)
 {
     setTo(data, size, copyData);
 }
@@ -296,7 +296,17 @@
                     (int)size);
             return (mError=BAD_TYPE);
         }
-        mStrings = (const char16_t*)
+
+        size_t charSize;
+        if (mHeader->flags&ResStringPool_header::UTF8_FLAG) {
+            charSize = sizeof(uint8_t);
+            mCache = (char16_t**)malloc(sizeof(char16_t**)*mHeader->stringCount);
+            memset(mCache, 0, sizeof(char16_t**)*mHeader->stringCount);
+        } else {
+            charSize = sizeof(char16_t);
+        }
+
+        mStrings = (const void*)
             (((const uint8_t*)data)+mHeader->stringsStart);
         if (mHeader->stringsStart >= (mHeader->header.size-sizeof(uint16_t))) {
             LOGW("Bad string block: string pool starts at %d, after total size %d\n",
@@ -305,7 +315,7 @@
         }
         if (mHeader->styleCount == 0) {
             mStringPoolSize =
-                (mHeader->header.size-mHeader->stringsStart)/sizeof(uint16_t);
+                (mHeader->header.size-mHeader->stringsStart)/charSize;
         } else {
             // check invariant: styles follow the strings
             if (mHeader->stylesStart <= mHeader->stringsStart) {
@@ -314,7 +324,7 @@
                 return (mError=BAD_TYPE);
             }
             mStringPoolSize =
-                (mHeader->stylesStart-mHeader->stringsStart)/sizeof(uint16_t);
+                (mHeader->stylesStart-mHeader->stringsStart)/charSize;
         }
 
         // check invariant: stringCount > 0 requires a string pool to exist
@@ -329,13 +339,19 @@
             for (i=0; i<mHeader->stringCount; i++) {
                 e[i] = dtohl(mEntries[i]);
             }
-            char16_t* s = const_cast<char16_t*>(mStrings);
-            for (i=0; i<mStringPoolSize; i++) {
-                s[i] = dtohs(mStrings[i]);
+            if (!(mHeader->flags&ResStringPool_header::UTF8_FLAG)) {
+                const char16_t* strings = (const char16_t*)mStrings;
+                char16_t* s = const_cast<char16_t*>(strings);
+                for (i=0; i<mStringPoolSize; i++) {
+                    s[i] = dtohs(strings[i]);
+                }
             }
         }
 
-        if (mStrings[mStringPoolSize-1] != 0) {
+        if ((mHeader->flags&ResStringPool_header::UTF8_FLAG &&
+                ((uint8_t*)mStrings)[mStringPoolSize-1] != 0) ||
+                (!mHeader->flags&ResStringPool_header::UTF8_FLAG &&
+                ((char16_t*)mStrings)[mStringPoolSize-1] != 0)) {
             LOGW("Bad string block: last string is not 0-terminated\n");
             return (mError=BAD_TYPE);
         }
@@ -410,24 +426,67 @@
         free(mOwnedData);
         mOwnedData = NULL;
     }
+    if (mHeader != NULL && mCache != NULL) {
+        for (size_t x = 0; x < mHeader->stringCount; x++) {
+            if (mCache[x] != NULL) {
+                free(mCache[x]);
+                mCache[x] = NULL;
+            }
+        }
+        free(mCache);
+        mCache = NULL;
+    }
 }
 
+#define DECODE_LENGTH(str, chrsz, len) \
+    len = *(str); \
+    if (*(str)&(1<<(chrsz*8-1))) { \
+        (str)++; \
+        len = (((len)&((1<<(chrsz*8-1))-1))<<(chrsz*8)) + *(str); \
+    } \
+    (str)++;
+
 const uint16_t* ResStringPool::stringAt(size_t idx, size_t* outLen) const
 {
     if (mError == NO_ERROR && idx < mHeader->stringCount) {
-        const uint32_t off = (mEntries[idx]/sizeof(uint16_t));
+        const bool isUTF8 = (mHeader->flags&ResStringPool_header::UTF8_FLAG) != 0;
+        const uint32_t off = mEntries[idx]/(isUTF8?sizeof(char):sizeof(char16_t));
         if (off < (mStringPoolSize-1)) {
-            const char16_t* str = mStrings+off;
-            *outLen = *str;
-            if ((*str)&0x8000) {
-                str++;
-                *outLen = (((*outLen)&0x7fff)<<16) + *str;
-            }
-            if ((uint32_t)(str+1+*outLen-mStrings) < mStringPoolSize) {
-                return str+1;
+            if (!isUTF8) {
+                const char16_t* strings = (char16_t*)mStrings;
+                const char16_t* str = strings+off;
+                DECODE_LENGTH(str, sizeof(char16_t), *outLen)
+                if ((uint32_t)(str+*outLen-strings) < mStringPoolSize) {
+                    return str;
+                } else {
+                    LOGW("Bad string block: string #%d extends to %d, past end at %d\n",
+                            (int)idx, (int)(str+*outLen-strings), (int)mStringPoolSize);
+                }
             } else {
-                LOGW("Bad string block: string #%d extends to %d, past end at %d\n",
-                        (int)idx, (int)(str+1+*outLen-mStrings), (int)mStringPoolSize);
+                const uint8_t* strings = (uint8_t*)mStrings;
+                const uint8_t* str = strings+off;
+                DECODE_LENGTH(str, sizeof(uint8_t), *outLen)
+                size_t encLen;
+                DECODE_LENGTH(str, sizeof(uint8_t), encLen)
+                if ((uint32_t)(str+encLen-strings) < mStringPoolSize) {
+                    AutoMutex lock(mDecodeLock);
+                    if (mCache[idx] != NULL) {
+                        return mCache[idx];
+                    }
+                    char16_t *u16str = (char16_t *)calloc(*outLen+1, sizeof(char16_t));
+                    if (!u16str) {
+                        LOGW("No memory when trying to allocate decode cache for string #%d\n",
+                                (int)idx);
+                        return NULL;
+                    }
+                    const unsigned char *u8src = reinterpret_cast<const unsigned char *>(str);
+                    utf8_to_utf16(u8src, encLen, u16str, *outLen);
+                    mCache[idx] = u16str;
+                    return u16str;
+                } else {
+                    LOGW("Bad string block: string #%d extends to %d, past end at %d\n",
+                            (int)idx, (int)(str+encLen-strings), (int)mStringPoolSize);
+                }
             }
         } else {
             LOGW("Bad string block: string #%d entry is at %d, past end at %d\n",
@@ -466,6 +525,10 @@
 
     size_t len;
 
+    // TODO optimize searching for UTF-8 strings taking into account
+    // the cache fill to determine when to convert the searched-for
+    // string key to UTF-8.
+
     if (mHeader->flags&ResStringPool_header::SORTED_FLAG) {
         // Do a binary search for the string...
         ssize_t l = 0;
@@ -1043,6 +1106,7 @@
 void ResXMLTree::uninit()
 {
     mError = NO_INIT;
+    mStrings.uninit();
     if (mOwnedData) {
         free(mOwnedData);
         mOwnedData = NULL;
diff --git a/libs/utils/String16.cpp b/libs/utils/String16.cpp
index aef67f2..eab7b2b 100644
--- a/libs/utils/String16.cpp
+++ b/libs/utils/String16.cpp
@@ -172,10 +172,6 @@
            : 0);
 }
 
-// ---------------------------------------------------------------------------
-
-namespace android {
-
 static inline size_t
 utf8_char_len(uint8_t ch)
 {
@@ -215,8 +211,38 @@
     //printf("Char at %p: len=%d, utf-16=%p\n", src, length, (void*)result);
 }
 
+void
+utf8_to_utf16(const uint8_t *src, size_t srcLen,
+        char16_t* dst, const size_t dstLen)
+{
+    const uint8_t* const end = src + srcLen;
+    const char16_t* const dstEnd = dst + dstLen;
+    while (src < end && dst < dstEnd) {
+        size_t len = utf8_char_len(*src);
+        uint32_t codepoint = utf8_to_utf32((const uint8_t*)src, len);
+
+        // Convert the UTF32 codepoint to one or more UTF16 codepoints
+        if (codepoint <= 0xFFFF) {
+            // Single UTF16 character
+            *dst++ = (char16_t) codepoint;
+        } else {
+            // Multiple UTF16 characters with surrogates
+            codepoint = codepoint - 0x10000;
+            *dst++ = (char16_t) ((codepoint >> 10) + 0xD800);
+            *dst++ = (char16_t) ((codepoint & 0x3FF) + 0xDC00);
+        }
+
+        src += len;
+    }
+    if (dst < dstEnd) {
+        *dst = 0;
+    }
+}
+
 // ---------------------------------------------------------------------------
 
+namespace android {
+
 static SharedBuffer* gEmptyStringBuf = NULL;
 static char16_t* gEmptyString = NULL;
 
@@ -260,30 +286,14 @@
         p += utf8len;
     }
     
-    SharedBuffer* buf = SharedBuffer::alloc((chars+1)*sizeof(char16_t));
+    size_t bufSize = (chars+1)*sizeof(char16_t);
+    SharedBuffer* buf = SharedBuffer::alloc(bufSize);
     if (buf) {
         p = in;
         char16_t* str = (char16_t*)buf->data();
-        char16_t* d = str;
-        while (p < end) {
-            size_t len = utf8_char_len(*p);
-            uint32_t codepoint = utf8_to_utf32((const uint8_t*)p, len);
-
-            // Convert the UTF32 codepoint to one or more UTF16 codepoints
-            if (codepoint <= 0xFFFF) {
-                // Single UTF16 character
-                *d++ = (char16_t) codepoint;
-            } else {
-                // Multiple UTF16 characters with surrogates
-                codepoint = codepoint - 0x10000;
-                *d++ = (char16_t) ((codepoint >> 10) + 0xD800);
-                *d++ = (char16_t) ((codepoint & 0x3FF) + 0xDC00);
-            }
-
-            p += len;
-        }
-        *d = 0;
         
+        utf8_to_utf16((const uint8_t*)p, len, str, bufSize);
+
         //printf("Created UTF-16 string from UTF-8 \"%s\":", in);
         //printHexData(1, str, buf->size(), 16, 1);
         //printf("\n");
diff --git a/libs/utils/String8.cpp b/libs/utils/String8.cpp
index e908ec1..3a34838 100644
--- a/libs/utils/String8.cpp
+++ b/libs/utils/String8.cpp
@@ -208,10 +208,23 @@
     return getEmptyString();
 }
 
-// Note: not dealing with expanding surrogate pairs.
 static char* allocFromUTF16(const char16_t* in, size_t len)
 {
-    return allocFromUTF16OrUTF32<char16_t, size_t>(in, len);
+    if (len == 0) return getEmptyString();
+
+    const size_t bytes = utf8_length_from_utf16(in, len);
+
+    SharedBuffer* buf = SharedBuffer::alloc(bytes+1);
+    LOG_ASSERT(buf, "Unable to allocate shared buffer");
+    if (buf) {
+        char* str = (char*)buf->data();
+
+        utf16_to_utf8(in, len, str, bytes+1);
+
+        return str;
+    }
+
+    return getEmptyString();
 }
 
 static char* allocFromUTF32(const char32_t* in, size_t len)
@@ -762,6 +775,26 @@
     return ret;
 }
 
+size_t utf8_length_from_utf16(const char16_t *src, size_t src_len)
+{
+    if (src == NULL || src_len == 0) {
+        return 0;
+    }
+    size_t ret = 0;
+    const char16_t* const end = src + src_len;
+    while (src < end) {
+        if ((*src & 0xFC00) == 0xD800 && (src + 1) < end
+                && (*++src & 0xFC00) == 0xDC00) {
+            // surrogate pairs are always 4 bytes.
+            ret += 4;
+            src++;
+        } else {
+            ret += android::utf32_to_utf8_bytes((char32_t) *src++);
+        }
+    }
+    return ret;
+}
+
 static int32_t utf32_at_internal(const char* cur, size_t *num_read)
 {
     const char first_char = *cur;
@@ -848,3 +881,33 @@
     }
     return cur - dst;
 }
+
+size_t utf16_to_utf8(const char16_t* src, size_t src_len,
+                     char* dst, size_t dst_len)
+{
+    if (src == NULL || src_len == 0 || dst == NULL || dst_len == 0) {
+        return 0;
+    }
+    const char16_t* cur_utf16 = src;
+    const char16_t* const end_utf16 = src + src_len;
+    char *cur = dst;
+    const char* const end = dst + dst_len;
+    while (cur_utf16 < end_utf16 && cur < end) {
+        char32_t utf32;
+        // surrogate pairs
+        if ((*cur_utf16 & 0xFC00) == 0xD800 && (cur_utf16 + 1) < end_utf16) {
+            utf32 = (*cur_utf16++ - 0xD800) << 10;
+            utf32 |= *cur_utf16++ - 0xDC00;
+            utf32 += 0x10000;
+        } else {
+            utf32 = (char32_t) *cur_utf16++;
+        }
+        size_t len = android::utf32_to_utf8_bytes(utf32);
+        android::utf32_to_utf8((uint8_t*)cur, utf32, len);
+        cur += len;
+    }
+    if (cur < end) {
+        *cur = '\0';
+    }
+    return cur - dst;
+}
diff --git a/libs/utils/Threads.cpp b/libs/utils/Threads.cpp
index ec3db09..6ca2603 100644
--- a/libs/utils/Threads.cpp
+++ b/libs/utils/Threads.cpp
@@ -20,6 +20,8 @@
 #include <utils/threads.h>
 #include <utils/Log.h>
 
+#include <cutils/sched_policy.h>
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <memory.h>
@@ -269,6 +271,53 @@
     gCreateThreadFn = func;
 }
 
+pid_t androidGetTid()
+{
+#ifdef HAVE_GETTID
+    return gettid();
+#else
+    return getpid();
+#endif
+}
+
+int androidSetThreadSchedulingGroup(pid_t tid, int grp)
+{
+    if (grp > ANDROID_TGROUP_MAX || grp < 0) { 
+        return BAD_VALUE;
+    }
+
+    if (set_sched_policy(tid, (grp == ANDROID_TGROUP_BG_NONINTERACT) ?
+                                      SP_BACKGROUND : SP_FOREGROUND)) {
+        return PERMISSION_DENIED;
+    }
+    
+    return NO_ERROR;
+}
+
+int androidSetThreadPriority(pid_t tid, int pri)
+{
+    int rc = 0;
+    int lasterr = 0;
+
+    if (pri >= ANDROID_PRIORITY_BACKGROUND) {
+        rc = set_sched_policy(tid, SP_BACKGROUND);
+    } else if (getpriority(PRIO_PROCESS, tid) >= ANDROID_PRIORITY_BACKGROUND) {
+        rc = set_sched_policy(tid, SP_FOREGROUND);
+    }
+
+    if (rc) {
+        lasterr = errno;
+    }
+
+    if (setpriority(PRIO_PROCESS, tid, pri) < 0) {
+        rc = INVALID_OPERATION;
+    } else {
+        errno = lasterr;
+    }
+    
+    return rc;
+}
+
 namespace android {
 
 /*
diff --git a/preloaded-classes b/preloaded-classes
index af74b33..f86555c 100644
--- a/preloaded-classes
+++ b/preloaded-classes
@@ -435,6 +435,7 @@
 android.net.NetworkInfo$DetailedState
 android.net.NetworkInfo$State
 android.net.NetworkUtils
+android.net.TrafficStats
 android.net.Uri
 android.net.Uri$HierarchicalUri
 android.net.Uri$OpaqueUri
@@ -515,7 +516,6 @@
 android.os.Looper
 android.os.MemoryFile
 android.os.Message
-android.os.NetStat
 android.os.Parcel
 android.os.Parcel$1
 android.os.ParcelFileDescriptor
@@ -600,16 +600,6 @@
 android.provider.ContactsContract$RawContacts
 android.provider.Downloads
 android.provider.DrmStore$Audio
-android.provider.Gmail
-android.provider.Gmail$AttachmentOrigin
-android.provider.Gmail$AttachmentRendition
-android.provider.Gmail$BecomeActiveNetworkCursor
-android.provider.Gmail$ConversationCursor
-android.provider.Gmail$CursorStatus
-android.provider.Gmail$LabelMap
-android.provider.Gmail$MailCursor
-android.provider.Gmail$MessageCursor
-android.provider.Gmail$PersonalLevel
 android.provider.Im$Account
 android.provider.Im$Avatars
 android.provider.Im$Chats
diff --git a/services/java/com/android/server/NetStatService.java b/services/java/com/android/server/NetStatService.java
index 1ea0bac..0834405 100644
--- a/services/java/com/android/server/NetStatService.java
+++ b/services/java/com/android/server/NetStatService.java
@@ -17,8 +17,8 @@
 package com.android.server;
 
 import android.content.Context;
+import android.net.TrafficStats;
 import android.os.INetStatService;
-import android.os.NetStat;
 
 public class NetStatService extends INetStatService.Stub {
 
@@ -27,34 +27,34 @@
     }
 
     public long getMobileTxPackets() {
-        return NetStat.getMobileTxPkts();
+        return TrafficStats.getMobileTxPkts();
     }
 
     public long getMobileRxPackets() {
-        return NetStat.getMobileRxPkts();
+        return TrafficStats.getMobileRxPkts();
     }
 
     public long getMobileTxBytes() {
-        return NetStat.getMobileTxBytes();
+        return TrafficStats.getMobileTxBytes();
     }
 
     public long getMobileRxBytes() {
-        return NetStat.getMobileRxBytes();
+        return TrafficStats.getMobileRxBytes();
     }
 
     public long getTotalTxPackets() {
-        return NetStat.getTotalTxPkts();
+        return TrafficStats.getTotalTxPkts();
     }
 
     public long getTotalRxPackets() {
-        return NetStat.getTotalRxPkts();
+        return TrafficStats.getTotalRxPkts();
     }
 
     public long getTotalTxBytes() {
-        return NetStat.getTotalTxBytes();
+        return TrafficStats.getTotalTxBytes();
     }
 
     public long getTotalRxBytes() {
-        return NetStat.getTotalRxBytes();
+        return TrafficStats.getTotalRxBytes();
     }
 }
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 73f930d..214ecc1 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -18,6 +18,7 @@
 
 import com.android.server.am.ActivityManagerService;
 import com.android.server.status.StatusBarService;
+import com.android.internal.os.BinderInternal;
 import com.android.internal.os.SamplingProfilerIntegration;
 
 import dalvik.system.VMRuntime;
@@ -80,6 +81,8 @@
         android.os.Process.setThreadPriority(
                 android.os.Process.THREAD_PRIORITY_FOREGROUND);
 
+        BinderInternal.disableBackgroundScheduling(true);
+        
         String factoryTestStr = SystemProperties.get("ro.factorytest");
         int factoryTest = "".equals(factoryTestStr) ? SystemServer.FACTORY_TEST_OFF
                 : Integer.parseInt(factoryTestStr);
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 65070dd..6c5c52f 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -5258,7 +5258,8 @@
         
         app.thread = thread;
         app.curAdj = app.setAdj = -100;
-        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
+        app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
+        app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
         app.forcingToForeground = null;
         app.foregroundServices = false;
         app.debugging = false;
@@ -9133,7 +9134,7 @@
                 if (needSep) pw.println(" ");
                 needSep = true;
                 pw.println("  Running processes (most recent first):");
-                dumpProcessList(pw, mLRUProcesses, "    ",
+                dumpProcessList(pw, this, mLRUProcesses, "    ",
                         "App ", "PERS", true);
                 needSep = true;
             }
@@ -9164,7 +9165,7 @@
                 if (needSep) pw.println(" ");
                 needSep = true;
                 pw.println("  Persisent processes that are starting:");
-                dumpProcessList(pw, mPersistentStartingProcesses, "    ",
+                dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
                         "Starting Norm", "Restarting PERS", false);
             }
 
@@ -9172,7 +9173,7 @@
                 if (needSep) pw.println(" ");
                 needSep = true;
                 pw.println("  Processes that are starting:");
-                dumpProcessList(pw, mStartingProcesses, "    ",
+                dumpProcessList(pw, this, mStartingProcesses, "    ",
                         "Starting Norm", "Starting PERS", false);
             }
 
@@ -9180,7 +9181,7 @@
                 if (needSep) pw.println(" ");
                 needSep = true;
                 pw.println("  Processes that are being removed:");
-                dumpProcessList(pw, mRemovedProcesses, "    ",
+                dumpProcessList(pw, this, mRemovedProcesses, "    ",
                         "Removed Norm", "Removed PERS", false);
             }
             
@@ -9188,7 +9189,7 @@
                 if (needSep) pw.println(" ");
                 needSep = true;
                 pw.println("  Processes that are on old until the system is ready:");
-                dumpProcessList(pw, mProcessesOnHold, "    ",
+                dumpProcessList(pw, this, mProcessesOnHold, "    ",
                         "OnHold Norm", "OnHold PERS", false);
             }
 
@@ -9617,7 +9618,16 @@
         }
     }
 
-    private static final int dumpProcessList(PrintWriter pw, List list,
+    private static String buildOomTag(String prefix, String space, int val, int base) {
+        if (val == base) {
+            if (space == null) return prefix;
+            return prefix + "  ";
+        }
+        return prefix + "+" + Integer.toString(val-base);
+    }
+    
+    private static final int dumpProcessList(PrintWriter pw,
+            ActivityManagerService service, List list,
             String prefix, String normalLabel, String persistentLabel,
             boolean inclOomAdj) {
         int numPers = 0;
@@ -9628,9 +9638,55 @@
                       + " #" + i + ":");
                 r.dump(pw, prefix + "  ");
             } else if (inclOomAdj) {
-                pw.println(String.format("%s%s #%2d: adj=%4d/%d %s (%s)",
+                String oomAdj;
+                if (r.setAdj >= EMPTY_APP_ADJ) {
+                    oomAdj = buildOomTag("empty", null, r.setAdj,
+                            EMPTY_APP_ADJ);
+                } else if (r.setAdj >= CONTENT_PROVIDER_ADJ) {
+                    oomAdj = buildOomTag("cprov", null, r.setAdj,
+                            CONTENT_PROVIDER_ADJ);
+                } else if (r.setAdj >= HIDDEN_APP_MIN_ADJ) {
+                    oomAdj = buildOomTag("hid", "  ", r.setAdj,
+                            HIDDEN_APP_MIN_ADJ);
+                } else if (r.setAdj >= service.HOME_APP_ADJ) {
+                    oomAdj = buildOomTag("home ", null, r.setAdj,
+                            service.HOME_APP_ADJ);
+                } else if (r.setAdj >= service.SECONDARY_SERVER_ADJ) {
+                    oomAdj = buildOomTag("svc", "  ", r.setAdj,
+                            service.SECONDARY_SERVER_ADJ);
+                } else if (r.setAdj >= service.BACKUP_APP_ADJ) {
+                    oomAdj = buildOomTag("bckup", null, r.setAdj,
+                            service.BACKUP_APP_ADJ);
+                } else if (r.setAdj >= service.VISIBLE_APP_ADJ) {
+                    oomAdj = buildOomTag("vis  ", null, r.setAdj,
+                            service.VISIBLE_APP_ADJ);
+                } else if (r.setAdj >= service.FOREGROUND_APP_ADJ) {
+                    oomAdj = buildOomTag("fore ", null, r.setAdj,
+                            service.FOREGROUND_APP_ADJ);
+                } else if (r.setAdj >= CORE_SERVER_ADJ) {
+                    oomAdj = buildOomTag("core ", null, r.setAdj,
+                            CORE_SERVER_ADJ);
+                } else if (r.setAdj >= SYSTEM_ADJ) {
+                    oomAdj = buildOomTag("sys  ", null, r.setAdj,
+                            SYSTEM_ADJ);
+                } else {
+                    oomAdj = Integer.toString(r.setAdj);
+                }
+                String schedGroup;
+                switch (r.setSchedGroup) {
+                    case Process.THREAD_GROUP_BG_NONINTERACTIVE:
+                        schedGroup = "B";
+                        break;
+                    case Process.THREAD_GROUP_DEFAULT:
+                        schedGroup = "F";
+                        break;
+                    default:
+                        schedGroup = Integer.toString(r.setSchedGroup);
+                        break;
+                }
+                pw.println(String.format("%s%s #%2d: adj=%s/%s %s (%s)",
                         prefix, (r.persistent ? persistentLabel : normalLabel),
-                        i, r.setAdj, r.setSchedGroup, r.toString(), r.adjType));
+                        i, oomAdj, schedGroup, r.toString(), r.adjType));
                 if (r.adjSource != null || r.adjTarget != null) {
                     pw.println(prefix + "          " + r.adjTarget
                             + " used by " + r.adjSource);
@@ -13038,6 +13094,7 @@
 
         if (app.thread == null) {
             app.adjSeq = mAdjSeq;
+            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
             return (app.curAdj=EMPTY_APP_ADJ);
         }
 
@@ -13058,52 +13115,63 @@
         // Determine the importance of the process, starting with most
         // important to least, and assign an appropriate OOM adjustment.
         int adj;
+        int schedGroup;
         int N;
         if (app == TOP_APP) {
             // The last app on the list is the foreground app.
             adj = FOREGROUND_APP_ADJ;
+            schedGroup = Process.THREAD_GROUP_DEFAULT;
             app.adjType = "top-activity";
         } else if (app.instrumentationClass != null) {
             // Don't want to kill running instrumentation.
             adj = FOREGROUND_APP_ADJ;
+            schedGroup = Process.THREAD_GROUP_DEFAULT;
             app.adjType = "instrumentation";
         } else if (app.persistentActivities > 0) {
             // Special persistent activities...  shouldn't be used these days.
             adj = FOREGROUND_APP_ADJ;
+            schedGroup = Process.THREAD_GROUP_DEFAULT;
             app.adjType = "persistent";
         } else if (app.curReceiver != null ||
                 (mPendingBroadcast != null && mPendingBroadcast.curApp == app)) {
             // An app that is currently receiving a broadcast also
             // counts as being in the foreground.
             adj = FOREGROUND_APP_ADJ;
+            schedGroup = Process.THREAD_GROUP_DEFAULT;
             app.adjType = "broadcast";
         } else if (app.executingServices.size() > 0) {
             // An app that is currently executing a service callback also
             // counts as being in the foreground.
             adj = FOREGROUND_APP_ADJ;
+            schedGroup = Process.THREAD_GROUP_DEFAULT;
             app.adjType = "exec-service";
         } else if (app.foregroundServices) {
             // The user is aware of this app, so make it visible.
             adj = VISIBLE_APP_ADJ;
+            schedGroup = Process.THREAD_GROUP_DEFAULT;
             app.adjType = "foreground-service";
         } else if (app.forcingToForeground != null) {
             // The user is aware of this app, so make it visible.
             adj = VISIBLE_APP_ADJ;
+            schedGroup = Process.THREAD_GROUP_DEFAULT;
             app.adjType = "force-foreground";
             app.adjSource = app.forcingToForeground;
         } else if (app == mHomeProcess) {
             // This process is hosting what we currently consider to be the
             // home app, so we don't want to let it go into the background.
             adj = HOME_APP_ADJ;
+            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
             app.adjType = "home";
         } else if ((N=app.activities.size()) != 0) {
             // This app is in the background with paused activities.
             adj = hiddenAdj;
+            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
             app.adjType = "bg-activities";
             for (int j=0; j<N; j++) {
                 if (((HistoryRecord)app.activities.get(j)).visible) {
                     // This app has a visible activity!
                     adj = VISIBLE_APP_ADJ;
+                    schedGroup = Process.THREAD_GROUP_DEFAULT;
                     app.adjType = "visible";
                     break;
                 }
@@ -13111,6 +13179,7 @@
         } else {
             // A very not-needed process.
             adj = EMPTY_APP_ADJ;
+            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
             app.adjType = "empty";
         }
 
@@ -13120,7 +13189,6 @@
         // infinite recursion.
         app.adjSeq = mAdjSeq;
         app.curRawAdj = adj;
-        app.curAdj = adj <= app.maxAdj ? adj : app.maxAdj;
 
         if (mBackupTarget != null && app == mBackupTarget.app) {
             // If possible we want to avoid killing apps while they're being backed up
@@ -13131,7 +13199,8 @@
             }
         }
 
-        if (app.services.size() != 0 && adj > FOREGROUND_APP_ADJ) {
+        if (app.services.size() != 0 && (adj > FOREGROUND_APP_ADJ
+                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
             final long now = SystemClock.uptimeMillis();
             // This process is more important if the top activity is
             // bound to the service.
@@ -13149,7 +13218,8 @@
                         }
                     }
                 }
-                if (s.connections.size() > 0 && adj > FOREGROUND_APP_ADJ) {
+                if (s.connections.size() > 0 && (adj > FOREGROUND_APP_ADJ
+                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
                     Iterator<ConnectionRecord> kt
                             = s.connections.values().iterator();
                     while (kt.hasNext() && adj > FOREGROUND_APP_ADJ) {
@@ -13181,6 +13251,11 @@
                                 app.adjSource = cr.binding.client;
                                 app.adjTarget = s.serviceInfo.name;
                             }
+                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
+                                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
+                                    schedGroup = Process.THREAD_GROUP_DEFAULT;
+                                }
+                            }
                         }
                         HistoryRecord a = cr.activity;
                         //if (a != null) {
@@ -13190,6 +13265,7 @@
                                 (a.state == ActivityState.RESUMED
                                  || a.state == ActivityState.PAUSING)) {
                             adj = FOREGROUND_APP_ADJ;
+                            schedGroup = Process.THREAD_GROUP_DEFAULT;
                             app.adjType = "service";
                             app.adjTypeCode = ActivityManager.RunningAppProcessInfo
                                     .REASON_SERVICE_IN_USE;
@@ -13211,9 +13287,11 @@
             }
         }
 
-        if (app.pubProviders.size() != 0 && adj > FOREGROUND_APP_ADJ) {
+        if (app.pubProviders.size() != 0 && (adj > FOREGROUND_APP_ADJ
+                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
             Iterator jt = app.pubProviders.values().iterator();
-            while (jt.hasNext() && adj > FOREGROUND_APP_ADJ) {
+            while (jt.hasNext() && (adj > FOREGROUND_APP_ADJ
+                    || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
                 ContentProviderRecord cpr = (ContentProviderRecord)jt.next();
                 if (cpr.clients.size() != 0) {
                     Iterator<ProcessRecord> kt = cpr.clients.iterator();
@@ -13242,6 +13320,9 @@
                             app.adjSource = client;
                             app.adjTarget = cpr.info.name;
                         }
+                        if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
+                            schedGroup = Process.THREAD_GROUP_DEFAULT;
+                        }
                     }
                 }
                 // If the provider has external (non-framework) process
@@ -13250,6 +13331,7 @@
                 if (cpr.externals != 0) {
                     if (adj > FOREGROUND_APP_ADJ) {
                         adj = FOREGROUND_APP_ADJ;
+                        schedGroup = Process.THREAD_GROUP_DEFAULT;
                         app.adjType = "provider";
                         app.adjTarget = cpr.info.name;
                     }
@@ -13272,12 +13354,13 @@
         //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
         if (adj > app.maxAdj) {
             adj = app.maxAdj;
+            if (app.maxAdj <= VISIBLE_APP_ADJ) {
+                schedGroup = Process.THREAD_GROUP_DEFAULT;
+            }
         }
 
         app.curAdj = adj;
-        app.curSchedGroup = adj > VISIBLE_APP_ADJ
-                ? Process.THREAD_GROUP_BG_NONINTERACTIVE
-                : Process.THREAD_GROUP_DEFAULT;
+        app.curSchedGroup = schedGroup;
         
         return adj;
     }
@@ -13422,7 +13505,7 @@
 
         int adj = computeOomAdjLocked(app, hiddenAdj, TOP_APP);
 
-        if (app.pid != 0 && app.pid != MY_PID) {
+        if ((app.pid != 0 && app.pid != MY_PID) || Process.supportsProcesses()) {
             if (app.curRawAdj != app.setRawAdj) {
                 if (app.curRawAdj > FOREGROUND_APP_ADJ
                         && app.setRawAdj <= FOREGROUND_APP_ADJ) {
diff --git a/tests/LotsOfApps/Android.mk b/tests/LotsOfApps/Android.mk
index 3019f5c..8d0cfa3 100644
--- a/tests/LotsOfApps/Android.mk
+++ b/tests/LotsOfApps/Android.mk
@@ -1,7 +1,7 @@
 LOCAL_PATH:= $(call my-dir)
 include $(CLEAR_VARS)
 
-LOCAL_MODULE_TAGS := tests
+LOCAL_MODULE_TAGS := optional
 
 LOCAL_SRC_FILES := $(call all-subdir-java-files)
 
diff --git a/tools/aapt/Bundle.h b/tools/aapt/Bundle.h
index 1ac13f2..cf70121 100644
--- a/tools/aapt/Bundle.h
+++ b/tools/aapt/Bundle.h
@@ -37,7 +37,7 @@
           mForce(false), mGrayscaleTolerance(0), mMakePackageDirs(false),
           mUpdate(false), mExtending(false),
           mRequireLocalization(false), mPseudolocalize(false),
-          mValues(false),
+          mUTF8(false), mValues(false),
           mCompressionMethod(0), mOutputAPKFile(NULL),
           mAssetSourceDir(NULL), mProguardFile(NULL),
           mAndroidManifestFile(NULL), mPublicOutputFile(NULL),
@@ -76,6 +76,8 @@
     void setRequireLocalization(bool val) { mRequireLocalization = val; }
     bool getPseudolocalize(void) const { return mPseudolocalize; }
     void setPseudolocalize(bool val) { mPseudolocalize = val; }
+    bool getUTF8(void) const { return mUTF8; }
+    void setUTF8(bool val) { mUTF8 = val; }
     bool getValues(void) const { return mValues; }
     void setValues(bool val) { mValues = val; }
     int getCompressionMethod(void) const { return mCompressionMethod; }
@@ -161,6 +163,7 @@
     bool        mExtending;
     bool        mRequireLocalization;
     bool        mPseudolocalize;
+    bool        mUTF8;
     bool        mValues;
     int         mCompressionMethod;
     bool        mJunkPath;
diff --git a/tools/aapt/Command.cpp b/tools/aapt/Command.cpp
index 1a536d6..ff9cc11 100644
--- a/tools/aapt/Command.cpp
+++ b/tools/aapt/Command.cpp
@@ -412,6 +412,7 @@
             }
             tree.restart();
             printXMLBlock(&tree);
+            tree.uninit();
             delete asset;
             asset = NULL;
         }
diff --git a/tools/aapt/Main.cpp b/tools/aapt/Main.cpp
index 98286c0..bd03b74 100644
--- a/tools/aapt/Main.cpp
+++ b/tools/aapt/Main.cpp
@@ -118,6 +118,7 @@
         "   -P  specify where to output public resource definitions\n"
         "   -S  directory in which to find resources.  Multiple directories will be scanned"
         "       and the first match found (left to right) will take precedence."
+        "   -8  Encode string resources in UTF-8.\n"
         "   -0  specifies an additional extension for which such files will not\n"
         "       be stored compressed in the .apk.  An empty string means to not\n"
         "       compress any files at all.\n"
@@ -370,6 +371,9 @@
                     bundle.setCompressionMethod(ZipEntry::kCompressStored);
                 }
                 break;
+            case '8':
+                bundle.setUTF8(true);
+                break;
             case '-':
                 if (strcmp(cp, "-min-sdk-version") == 0) {
                     argc--;
diff --git a/tools/aapt/Resource.cpp b/tools/aapt/Resource.cpp
index fdcada4..d04a873 100644
--- a/tools/aapt/Resource.cpp
+++ b/tools/aapt/Resource.cpp
@@ -613,6 +613,12 @@
 
     NOISY(printf("Found %d included resource packages\n", (int)table.size()));
 
+    // Standard flags for compiled XML and optional UTF-8 encoding
+    int xmlFlags = XML_COMPILE_STANDARD_RESOURCE;
+    if (bundle->getUTF8()) {
+        xmlFlags |= XML_COMPILE_UTF8;
+    }
+
     // --------------------------------------------------------------
     // First, gather all resource information.
     // --------------------------------------------------------------
@@ -763,7 +769,7 @@
         ResourceDirIterator it(layouts, String8("layout"));
         while ((err=it.next()) == NO_ERROR) {
             String8 src = it.getFile()->getPrintableSource();
-            err = compileXmlFile(assets, it.getFile(), &table);
+            err = compileXmlFile(assets, it.getFile(), &table, xmlFlags);
             if (err == NO_ERROR) {
                 ResXMLTree block;
                 block.setTo(it.getFile()->getData(), it.getFile()->getSize(), true);
@@ -782,7 +788,7 @@
     if (anims != NULL) {
         ResourceDirIterator it(anims, String8("anim"));
         while ((err=it.next()) == NO_ERROR) {
-            err = compileXmlFile(assets, it.getFile(), &table);
+            err = compileXmlFile(assets, it.getFile(), &table, xmlFlags);
             if (err != NO_ERROR) {
                 hasErrors = true;
             }
@@ -797,7 +803,7 @@
     if (xmls != NULL) {
         ResourceDirIterator it(xmls, String8("xml"));
         while ((err=it.next()) == NO_ERROR) {
-            err = compileXmlFile(assets, it.getFile(), &table);
+            err = compileXmlFile(assets, it.getFile(), &table, xmlFlags);
             if (err != NO_ERROR) {
                 hasErrors = true;
             }
@@ -819,7 +825,7 @@
     if (colors != NULL) {
         ResourceDirIterator it(colors, String8("color"));
         while ((err=it.next()) == NO_ERROR) {
-          err = compileXmlFile(assets, it.getFile(), &table);
+          err = compileXmlFile(assets, it.getFile(), &table, xmlFlags);
             if (err != NO_ERROR) {
                 hasErrors = true;
             }
@@ -835,7 +841,7 @@
         ResourceDirIterator it(menus, String8("menu"));
         while ((err=it.next()) == NO_ERROR) {
             String8 src = it.getFile()->getPrintableSource();
-            err = compileXmlFile(assets, it.getFile(), &table);
+            err = compileXmlFile(assets, it.getFile(), &table, xmlFlags);
             if (err != NO_ERROR) {
                 hasErrors = true;
             }
diff --git a/tools/aapt/ResourceTable.cpp b/tools/aapt/ResourceTable.cpp
index 19b9b01..a9cbd11 100644
--- a/tools/aapt/ResourceTable.cpp
+++ b/tools/aapt/ResourceTable.cpp
@@ -39,6 +39,10 @@
         root->removeWhitespace(false, NULL);
     }
 
+    if ((options&XML_COMPILE_UTF8) != 0) {
+        root->setUTF8(true);
+    }
+
     bool hasErrors = false;
     
     if ((options&XML_COMPILE_ASSIGN_ATTRIBUTE_IDS) != 0) {
@@ -2505,7 +2509,7 @@
 
     // Iterate through all data, collecting all values (strings,
     // references, etc).
-    StringPool valueStrings;
+    StringPool valueStrings = StringPool(false, bundle->getUTF8());
     for (pi=0; pi<N; pi++) {
         sp<Package> p = mOrderedPackages.itemAt(pi);
         if (p->getTypes().size() == 0) {
@@ -2513,8 +2517,8 @@
             continue;
         }
 
-        StringPool typeStrings;
-        StringPool keyStrings;
+        StringPool typeStrings = StringPool(false, bundle->getUTF8());
+        StringPool keyStrings = StringPool(false, bundle->getUTF8());
 
         const size_t N = p->getOrderedTypes().size();
         for (size_t ti=0; ti<N; ti++) {
diff --git a/tools/aapt/ResourceTable.h b/tools/aapt/ResourceTable.h
index caa01b3..cfa75a71 100644
--- a/tools/aapt/ResourceTable.h
+++ b/tools/aapt/ResourceTable.h
@@ -24,6 +24,7 @@
     XML_COMPILE_COMPACT_WHITESPACE = 1<<2,
     XML_COMPILE_STRIP_WHITESPACE = 1<<3,
     XML_COMPILE_STRIP_RAW_VALUES = 1<<4,
+    XML_COMPILE_UTF8 = 1<<5,
     
     XML_COMPILE_STANDARD_RESOURCE =
             XML_COMPILE_STRIP_COMMENTS | XML_COMPILE_ASSIGN_ATTRIBUTE_IDS
diff --git a/tools/aapt/StringPool.cpp b/tools/aapt/StringPool.cpp
index 715170a..ec58591 100644
--- a/tools/aapt/StringPool.cpp
+++ b/tools/aapt/StringPool.cpp
@@ -30,8 +30,8 @@
     }
 }
 
-StringPool::StringPool(bool sorted)
-    : mSorted(sorted), mValues(-1), mIdents(-1)
+StringPool::StringPool(bool sorted, bool utf8)
+    : mSorted(sorted), mUTF8(utf8), mValues(-1), mIdents(-1)
 {
 }
 
@@ -165,6 +165,16 @@
     return err == NO_ERROR ? pool : NULL;
 }
 
+#define ENCODE_LENGTH(str, chrsz, strSize) \
+{ \
+    size_t maxMask = 1 << ((chrsz*8)-1); \
+    size_t maxSize = maxMask-1; \
+    if (strSize > maxSize) { \
+        *str++ = maxMask | ((strSize>>(chrsz*8))&maxSize); \
+    } \
+    *str++ = strSize; \
+}
+
 status_t StringPool::writeStringBlock(const sp<AaptFile>& pool)
 {
     // Allow appending.  Sorry this is a little wacky.
@@ -213,28 +223,53 @@
         return NO_MEMORY;
     }
 
+    const size_t charSize = mUTF8 ? sizeof(uint8_t) : sizeof(char16_t);
+
     size_t strPos = 0;
     for (i=0; i<STRINGS; i++) {
         entry& ent = mEntries.editItemAt(i);
         const size_t strSize = (ent.value.size());
-        const size_t lenSize = strSize > 0x7fff ? sizeof(uint32_t) : sizeof(uint16_t);
-        const size_t totalSize = lenSize + ((strSize+1)*sizeof(uint16_t));
+        const size_t lenSize = strSize > (size_t)(1<<((charSize*8)-1))-1 ?
+            charSize*2 : charSize;
+
+        String8 encStr;
+        if (mUTF8) {
+            encStr = String8(ent.value);
+        }
+
+        const size_t encSize = mUTF8 ? encStr.size() : 0;
+        const size_t encLenSize = mUTF8 ?
+            (encSize > (size_t)(1<<((charSize*8)-1))-1 ?
+                charSize*2 : charSize) : 0;
 
         ent.offset = strPos;
-        uint16_t* dat = (uint16_t*)pool->editData(preSize + strPos + totalSize);
+
+        const size_t totalSize = lenSize + encLenSize +
+            ((mUTF8 ? encSize : strSize)+1)*charSize;
+
+        void* dat = (void*)pool->editData(preSize + strPos + totalSize);
         if (dat == NULL) {
             fprintf(stderr, "ERROR: Out of memory for string pool\n");
             return NO_MEMORY;
         }
-        dat += (preSize+strPos)/sizeof(uint16_t);
-        if (lenSize > sizeof(uint16_t)) {
-            *dat = htods(0x8000 | ((strSize>>16)&0x7fff));
-            dat++;
-        }
-        *dat++ = htods(strSize);
-        strcpy16_htod(dat, ent.value);
+        dat = (uint8_t*)dat + preSize + strPos;
+        if (mUTF8) {
+            uint8_t* strings = (uint8_t*)dat;
 
-        strPos += lenSize + (strSize+1)*sizeof(uint16_t);
+            ENCODE_LENGTH(strings, sizeof(uint8_t), strSize)
+
+            ENCODE_LENGTH(strings, sizeof(uint8_t), encSize)
+
+            strncpy((char*)strings, encStr, encSize+1);
+        } else {
+            uint16_t* strings = (uint16_t*)dat;
+
+            ENCODE_LENGTH(strings, sizeof(uint16_t), strSize)
+
+            strcpy16_htod(strings, ent.value);
+        }
+
+        strPos += totalSize;
     }
 
     // Pad ending string position up to a uint32_t boundary.
@@ -312,6 +347,9 @@
     if (mSorted) {
         header->flags |= htodl(ResStringPool_header::SORTED_FLAG);
     }
+    if (mUTF8) {
+        header->flags |= htodl(ResStringPool_header::UTF8_FLAG);
+    }
     header->stringsStart = htodl(preSize);
     header->stylesStart = htodl(STYLES > 0 ? (preSize+strPos) : 0);
 
diff --git a/tools/aapt/StringPool.h b/tools/aapt/StringPool.h
index 9082b37..7275259 100644
--- a/tools/aapt/StringPool.h
+++ b/tools/aapt/StringPool.h
@@ -68,8 +68,11 @@
      * lookup with ResStringPool::indexOfString() (O(log n)), at the expense
      * of support for styled string entries (which requires the same string
      * be included multiple times in the pool).
+     *
+     * If 'utf8' is true, strings will be encoded with UTF-8 instead of
+     * left in Java's native UTF-16.
      */
-    explicit StringPool(bool sorted = false);
+    explicit StringPool(bool sorted = false, bool utf8 = false);
 
     /**
      * Add a new string to the pool.  If mergeDuplicates is true, thenif
@@ -123,6 +126,7 @@
 
 private:
     const bool                              mSorted;
+    const bool                              mUTF8;
     // Raw array of unique strings, in some arbitrary order.
     Vector<entry>                           mEntries;
     // Array of indices into mEntries, in the order they were
diff --git a/tools/aapt/XMLNode.cpp b/tools/aapt/XMLNode.cpp
index d4d2a45c..036dde4 100644
--- a/tools/aapt/XMLNode.cpp
+++ b/tools/aapt/XMLNode.cpp
@@ -478,6 +478,7 @@
     , mFilename(filename)
     , mStartLineNumber(0)
     , mEndLineNumber(0)
+    , mUTF8(false)
 {
     if (isNamespace) {
         mNamespacePrefix = s1;
@@ -837,7 +838,7 @@
 status_t XMLNode::flatten(const sp<AaptFile>& dest,
         bool stripComments, bool stripRawValues) const
 {
-    StringPool strings;
+    StringPool strings = StringPool(false, mUTF8);
     Vector<uint32_t> resids;
     
     // First collect just the strings for attribute names that have a
diff --git a/tools/aapt/XMLNode.h b/tools/aapt/XMLNode.h
index a9bea43..dc92fa7 100644
--- a/tools/aapt/XMLNode.h
+++ b/tools/aapt/XMLNode.h
@@ -124,6 +124,8 @@
 
     void removeWhitespace(bool stripAll=true, const char** cDataTags=NULL);
 
+    void setUTF8(bool val) { mUTF8 = val; }
+
     status_t parseValues(const sp<AaptAssets>& assets, ResourceTable* table);
 
     status_t assignResourceIds(const sp<AaptAssets>& assets,
@@ -189,6 +191,9 @@
     String8 mFilename;
     int32_t mStartLineNumber;
     int32_t mEndLineNumber;
+
+    // Encode compiled XML with UTF-8 StringPools?
+    bool mUTF8;
 };
 
 #endif
diff --git a/wifi/java/android/net/wifi/WifiStateTracker.java b/wifi/java/android/net/wifi/WifiStateTracker.java
index 66552e4..0b9c69c 100644
--- a/wifi/java/android/net/wifi/WifiStateTracker.java
+++ b/wifi/java/android/net/wifi/WifiStateTracker.java
@@ -1162,7 +1162,7 @@
                     }
                 }
                 break;
-                
+
             case EVENT_DRIVER_STATE_CHANGED:
                 // Wi-Fi driver state changed:
                 // 0 STARTED
