Merge change 21471 into eclair

* changes:
  Add Galaxy wallpaper
diff --git a/api/current.xml b/api/current.xml
index d571984..ee8d2eb 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -13463,6 +13463,23 @@
 <parameter name="accountType" type="java.lang.String">
 </parameter>
 </method>
+<method name="getAccountRemovalAllowed"
+ return="android.os.Bundle"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="response" type="android.accounts.AccountAuthenticatorResponse">
+</parameter>
+<parameter name="account" type="android.accounts.Account">
+</parameter>
+<exception name="NetworkErrorException" type="android.accounts.NetworkErrorException">
+</exception>
+</method>
 <method name="getAuthToken"
  return="android.os.Bundle"
  abstract="true"
@@ -13615,7 +13632,7 @@
  visibility="public"
 >
 </field>
-<field name="mName"
+<field name="name"
  type="java.lang.String"
  transient="false"
  volatile="false"
@@ -13625,7 +13642,7 @@
  visibility="public"
 >
 </field>
-<field name="mType"
+<field name="type"
  type="java.lang.String"
  transient="false"
  volatile="false"
@@ -13781,7 +13798,7 @@
  visibility="public"
 >
 <method name="addAccount"
- return="android.accounts.Future2"
+ return="android.accounts.AccountManagerFuture&lt;android.os.Bundle&gt;"
  abstract="false"
  native="false"
  synchronized="false"
@@ -13800,13 +13817,13 @@
 </parameter>
 <parameter name="activity" type="android.app.Activity">
 </parameter>
-<parameter name="callback" type="android.accounts.Future2Callback">
+<parameter name="callback" type="android.accounts.AccountManagerCallback&lt;android.os.Bundle&gt;">
 </parameter>
 <parameter name="handler" type="android.os.Handler">
 </parameter>
 </method>
 <method name="addAccountExplicitly"
- return="android.accounts.Future1&lt;java.lang.Boolean&gt;"
+ return="boolean"
  abstract="false"
  native="false"
  synchronized="false"
@@ -13815,16 +13832,12 @@
  deprecated="not deprecated"
  visibility="public"
 >
-<parameter name="callback" type="android.accounts.Future1Callback&lt;java.lang.Boolean&gt;">
-</parameter>
 <parameter name="account" type="android.accounts.Account">
 </parameter>
 <parameter name="password" type="java.lang.String">
 </parameter>
 <parameter name="extras" type="android.os.Bundle">
 </parameter>
-<parameter name="handler" type="android.os.Handler">
-</parameter>
 </method>
 <method name="addOnAccountsUpdatedListener"
  return="void"
@@ -13843,81 +13856,6 @@
 <parameter name="updateImmediately" type="boolean">
 </parameter>
 </method>
-<method name="blockingAddAccountExplicitly"
- return="boolean"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="account" type="android.accounts.Account">
-</parameter>
-<parameter name="password" type="java.lang.String">
-</parameter>
-<parameter name="extras" type="android.os.Bundle">
-</parameter>
-</method>
-<method name="blockingClearPassword"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="account" type="android.accounts.Account">
-</parameter>
-</method>
-<method name="blockingGetAccounts"
- return="android.accounts.Account[]"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="blockingGetAccountsByType"
- return="android.accounts.Account[]"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="accountType" type="java.lang.String">
-</parameter>
-</method>
-<method name="blockingGetAccountsWithTypeAndFeatures"
- return="android.accounts.Account[]"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="type" type="java.lang.String">
-</parameter>
-<parameter name="features" type="java.lang.String[]">
-</parameter>
-<exception name="AuthenticatorException" type="android.accounts.AuthenticatorException">
-</exception>
-<exception name="IOException" type="java.io.IOException">
-</exception>
-<exception name="OperationCanceledException" type="android.accounts.OperationCanceledException">
-</exception>
-</method>
 <method name="blockingGetAuthToken"
  return="java.lang.String"
  abstract="false"
@@ -13941,139 +13879,8 @@
 <exception name="OperationCanceledException" type="android.accounts.OperationCanceledException">
 </exception>
 </method>
-<method name="blockingGetAuthenticatorTypes"
- return="android.accounts.AuthenticatorDescription[]"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="blockingGetPassword"
- return="java.lang.String"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="account" type="android.accounts.Account">
-</parameter>
-</method>
-<method name="blockingGetUserData"
- return="java.lang.String"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="account" type="android.accounts.Account">
-</parameter>
-<parameter name="key" type="java.lang.String">
-</parameter>
-</method>
-<method name="blockingInvalidateAuthToken"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="accountType" type="java.lang.String">
-</parameter>
-<parameter name="authToken" type="java.lang.String">
-</parameter>
-</method>
-<method name="blockingPeekAuthToken"
- return="java.lang.String"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="account" type="android.accounts.Account">
-</parameter>
-<parameter name="authTokenType" type="java.lang.String">
-</parameter>
-</method>
-<method name="blockingRemoveAccount"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="account" type="android.accounts.Account">
-</parameter>
-</method>
-<method name="blockingSetAuthToken"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="account" type="android.accounts.Account">
-</parameter>
-<parameter name="authTokenType" type="java.lang.String">
-</parameter>
-<parameter name="authToken" type="java.lang.String">
-</parameter>
-</method>
-<method name="blockingSetPassword"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="account" type="android.accounts.Account">
-</parameter>
-<parameter name="password" type="java.lang.String">
-</parameter>
-</method>
-<method name="blockingSetUserData"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="account" type="android.accounts.Account">
-</parameter>
-<parameter name="key" type="java.lang.String">
-</parameter>
-<parameter name="value" type="java.lang.String">
-</parameter>
-</method>
 <method name="clearPassword"
- return="android.accounts.Future1&lt;java.lang.Void&gt;"
+ return="void"
  abstract="false"
  native="false"
  synchronized="false"
@@ -14082,15 +13889,11 @@
  deprecated="not deprecated"
  visibility="public"
 >
-<parameter name="callback" type="android.accounts.Future1Callback&lt;java.lang.Void&gt;">
-</parameter>
 <parameter name="account" type="android.accounts.Account">
 </parameter>
-<parameter name="handler" type="android.os.Handler">
-</parameter>
 </method>
 <method name="confirmCredentials"
- return="android.accounts.Future2"
+ return="android.accounts.AccountManagerFuture&lt;android.os.Bundle&gt;"
  abstract="false"
  native="false"
  synchronized="false"
@@ -14103,13 +13906,13 @@
 </parameter>
 <parameter name="activity" type="android.app.Activity">
 </parameter>
-<parameter name="callback" type="android.accounts.Future2Callback">
+<parameter name="callback" type="android.accounts.AccountManagerCallback&lt;android.os.Bundle&gt;">
 </parameter>
 <parameter name="handler" type="android.os.Handler">
 </parameter>
 </method>
 <method name="confirmPassword"
- return="android.accounts.Future1&lt;java.lang.Boolean&gt;"
+ return="android.accounts.AccountManagerFuture&lt;java.lang.Boolean&gt;"
  abstract="false"
  native="false"
  synchronized="false"
@@ -14122,13 +13925,13 @@
 </parameter>
 <parameter name="password" type="java.lang.String">
 </parameter>
-<parameter name="callback" type="android.accounts.Future1Callback&lt;java.lang.Boolean&gt;">
+<parameter name="callback" type="android.accounts.AccountManagerCallback&lt;java.lang.Boolean&gt;">
 </parameter>
 <parameter name="handler" type="android.os.Handler">
 </parameter>
 </method>
 <method name="editProperties"
- return="android.accounts.Future2"
+ return="android.accounts.AccountManagerFuture&lt;android.os.Bundle&gt;"
  abstract="false"
  native="false"
  synchronized="false"
@@ -14141,7 +13944,7 @@
 </parameter>
 <parameter name="activity" type="android.app.Activity">
 </parameter>
-<parameter name="callback" type="android.accounts.Future2Callback">
+<parameter name="callback" type="android.accounts.AccountManagerCallback&lt;android.os.Bundle&gt;">
 </parameter>
 <parameter name="handler" type="android.os.Handler">
 </parameter>
@@ -14160,7 +13963,7 @@
 </parameter>
 </method>
 <method name="getAccounts"
- return="android.accounts.Future1&lt;android.accounts.Account[]&gt;"
+ return="android.accounts.Account[]"
  abstract="false"
  native="false"
  synchronized="false"
@@ -14169,13 +13972,9 @@
  deprecated="not deprecated"
  visibility="public"
 >
-<parameter name="callback" type="android.accounts.Future1Callback&lt;android.accounts.Account[]&gt;">
-</parameter>
-<parameter name="handler" type="android.os.Handler">
-</parameter>
 </method>
 <method name="getAccountsByType"
- return="android.accounts.Future1&lt;android.accounts.Account[]&gt;"
+ return="android.accounts.Account[]"
  abstract="false"
  native="false"
  synchronized="false"
@@ -14184,15 +13983,11 @@
  deprecated="not deprecated"
  visibility="public"
 >
-<parameter name="callback" type="android.accounts.Future1Callback&lt;android.accounts.Account[]&gt;">
-</parameter>
 <parameter name="type" type="java.lang.String">
 </parameter>
-<parameter name="handler" type="android.os.Handler">
-</parameter>
 </method>
-<method name="getAccountsWithTypeAndFeatures"
- return="android.accounts.Future2"
+<method name="getAccountsByTypeAndFeatures"
+ return="android.accounts.AccountManagerFuture&lt;android.accounts.Account[]&gt;"
  abstract="false"
  native="false"
  synchronized="false"
@@ -14205,13 +14000,13 @@
 </parameter>
 <parameter name="features" type="java.lang.String[]">
 </parameter>
-<parameter name="callback" type="android.accounts.Future2Callback">
+<parameter name="callback" type="android.accounts.AccountManagerCallback&lt;android.accounts.Account[]&gt;">
 </parameter>
 <parameter name="handler" type="android.os.Handler">
 </parameter>
 </method>
 <method name="getAuthToken"
- return="android.accounts.Future2"
+ return="android.accounts.AccountManagerFuture&lt;android.os.Bundle&gt;"
  abstract="false"
  native="false"
  synchronized="false"
@@ -14228,13 +14023,13 @@
 </parameter>
 <parameter name="activity" type="android.app.Activity">
 </parameter>
-<parameter name="callback" type="android.accounts.Future2Callback">
+<parameter name="callback" type="android.accounts.AccountManagerCallback&lt;android.os.Bundle&gt;">
 </parameter>
 <parameter name="handler" type="android.os.Handler">
 </parameter>
 </method>
 <method name="getAuthToken"
- return="android.accounts.Future2"
+ return="android.accounts.AccountManagerFuture&lt;android.os.Bundle&gt;"
  abstract="false"
  native="false"
  synchronized="false"
@@ -14249,7 +14044,7 @@
 </parameter>
 <parameter name="notifyAuthFailure" type="boolean">
 </parameter>
-<parameter name="callback" type="android.accounts.Future2Callback">
+<parameter name="callback" type="android.accounts.AccountManagerCallback&lt;android.os.Bundle&gt;">
 </parameter>
 <parameter name="handler" type="android.os.Handler">
 </parameter>
@@ -14276,13 +14071,13 @@
 </parameter>
 <parameter name="loginOptions" type="android.os.Bundle">
 </parameter>
-<parameter name="callback" type="android.accounts.Future2Callback">
+<parameter name="callback" type="android.accounts.AccountManagerCallback&lt;android.os.Bundle&gt;">
 </parameter>
 <parameter name="handler" type="android.os.Handler">
 </parameter>
 </method>
 <method name="getAuthenticatorTypes"
- return="android.accounts.Future1&lt;android.accounts.AuthenticatorDescription[]&gt;"
+ return="android.accounts.AuthenticatorDescription[]"
  abstract="false"
  native="false"
  synchronized="false"
@@ -14291,13 +14086,9 @@
  deprecated="not deprecated"
  visibility="public"
 >
-<parameter name="callback" type="android.accounts.Future1Callback&lt;android.accounts.AuthenticatorDescription[]&gt;">
-</parameter>
-<parameter name="handler" type="android.os.Handler">
-</parameter>
 </method>
 <method name="getPassword"
- return="android.accounts.Future1&lt;java.lang.String&gt;"
+ return="java.lang.String"
  abstract="false"
  native="false"
  synchronized="false"
@@ -14306,15 +14097,11 @@
  deprecated="not deprecated"
  visibility="public"
 >
-<parameter name="callback" type="android.accounts.Future1Callback&lt;java.lang.String&gt;">
-</parameter>
 <parameter name="account" type="android.accounts.Account">
 </parameter>
-<parameter name="handler" type="android.os.Handler">
-</parameter>
 </method>
 <method name="getUserData"
- return="android.accounts.Future1&lt;java.lang.String&gt;"
+ return="java.lang.String"
  abstract="false"
  native="false"
  synchronized="false"
@@ -14323,17 +14110,13 @@
  deprecated="not deprecated"
  visibility="public"
 >
-<parameter name="callback" type="android.accounts.Future1Callback&lt;java.lang.String&gt;">
-</parameter>
 <parameter name="account" type="android.accounts.Account">
 </parameter>
 <parameter name="key" type="java.lang.String">
 </parameter>
-<parameter name="handler" type="android.os.Handler">
-</parameter>
 </method>
 <method name="invalidateAuthToken"
- return="android.accounts.Future1&lt;java.lang.Void&gt;"
+ return="void"
  abstract="false"
  native="false"
  synchronized="false"
@@ -14342,17 +14125,13 @@
  deprecated="not deprecated"
  visibility="public"
 >
-<parameter name="callback" type="android.accounts.Future1Callback&lt;java.lang.Void&gt;">
-</parameter>
 <parameter name="accountType" type="java.lang.String">
 </parameter>
 <parameter name="authToken" type="java.lang.String">
 </parameter>
-<parameter name="handler" type="android.os.Handler">
-</parameter>
 </method>
 <method name="peekAuthToken"
- return="android.accounts.Future1&lt;java.lang.String&gt;"
+ return="java.lang.String"
  abstract="false"
  native="false"
  synchronized="false"
@@ -14361,17 +14140,13 @@
  deprecated="not deprecated"
  visibility="public"
 >
-<parameter name="callback" type="android.accounts.Future1Callback&lt;java.lang.String&gt;">
-</parameter>
 <parameter name="account" type="android.accounts.Account">
 </parameter>
 <parameter name="authTokenType" type="java.lang.String">
 </parameter>
-<parameter name="handler" type="android.os.Handler">
-</parameter>
 </method>
 <method name="removeAccount"
- return="android.accounts.Future1&lt;java.lang.Void&gt;"
+ return="android.accounts.AccountManagerFuture&lt;java.lang.Boolean&gt;"
  abstract="false"
  native="false"
  synchronized="false"
@@ -14380,10 +14155,10 @@
  deprecated="not deprecated"
  visibility="public"
 >
-<parameter name="callback" type="android.accounts.Future1Callback&lt;java.lang.Void&gt;">
-</parameter>
 <parameter name="account" type="android.accounts.Account">
 </parameter>
+<parameter name="callback" type="android.accounts.AccountManagerCallback&lt;java.lang.Boolean&gt;">
+</parameter>
 <parameter name="handler" type="android.os.Handler">
 </parameter>
 </method>
@@ -14401,7 +14176,7 @@
 </parameter>
 </method>
 <method name="setAuthToken"
- return="android.accounts.Future1&lt;java.lang.Void&gt;"
+ return="void"
  abstract="false"
  native="false"
  synchronized="false"
@@ -14410,19 +14185,15 @@
  deprecated="not deprecated"
  visibility="public"
 >
-<parameter name="callback" type="android.accounts.Future1Callback&lt;java.lang.Void&gt;">
-</parameter>
 <parameter name="account" type="android.accounts.Account">
 </parameter>
 <parameter name="authTokenType" type="java.lang.String">
 </parameter>
 <parameter name="authToken" type="java.lang.String">
 </parameter>
-<parameter name="handler" type="android.os.Handler">
-</parameter>
 </method>
 <method name="setPassword"
- return="android.accounts.Future1&lt;java.lang.Void&gt;"
+ return="void"
  abstract="false"
  native="false"
  synchronized="false"
@@ -14431,17 +14202,13 @@
  deprecated="not deprecated"
  visibility="public"
 >
-<parameter name="callback" type="android.accounts.Future1Callback&lt;java.lang.Void&gt;">
-</parameter>
 <parameter name="account" type="android.accounts.Account">
 </parameter>
 <parameter name="password" type="java.lang.String">
 </parameter>
-<parameter name="handler" type="android.os.Handler">
-</parameter>
 </method>
 <method name="setUserData"
- return="android.accounts.Future1&lt;java.lang.Void&gt;"
+ return="void"
  abstract="false"
  native="false"
  synchronized="false"
@@ -14450,19 +14217,15 @@
  deprecated="not deprecated"
  visibility="public"
 >
-<parameter name="callback" type="android.accounts.Future1Callback&lt;java.lang.Void&gt;">
-</parameter>
 <parameter name="account" type="android.accounts.Account">
 </parameter>
 <parameter name="key" type="java.lang.String">
 </parameter>
 <parameter name="value" type="java.lang.String">
 </parameter>
-<parameter name="handler" type="android.os.Handler">
-</parameter>
 </method>
 <method name="updateCredentials"
- return="android.accounts.Future2"
+ return="android.accounts.AccountManagerFuture&lt;android.os.Bundle&gt;"
  abstract="false"
  native="false"
  synchronized="false"
@@ -14479,12 +14242,117 @@
 </parameter>
 <parameter name="activity" type="android.app.Activity">
 </parameter>
-<parameter name="callback" type="android.accounts.Future2Callback">
+<parameter name="callback" type="android.accounts.AccountManagerCallback&lt;android.os.Bundle&gt;">
 </parameter>
 <parameter name="handler" type="android.os.Handler">
 </parameter>
 </method>
 </class>
+<interface name="AccountManagerCallback"
+ abstract="true"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<method name="run"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="future" type="android.accounts.AccountManagerFuture&lt;V&gt;">
+</parameter>
+</method>
+</interface>
+<interface name="AccountManagerFuture"
+ abstract="true"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<implements name="java.util.concurrent.Future">
+</implements>
+<method name="get"
+ return="V"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="deprecated"
+ visibility="public"
+>
+<exception name="ExecutionException" type="java.util.concurrent.ExecutionException">
+</exception>
+<exception name="InterruptedException" type="java.lang.InterruptedException">
+</exception>
+</method>
+<method name="get"
+ return="V"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="deprecated"
+ visibility="public"
+>
+<parameter name="timeout" type="long">
+</parameter>
+<parameter name="unit" type="java.util.concurrent.TimeUnit">
+</parameter>
+<exception name="ExecutionException" type="java.util.concurrent.ExecutionException">
+</exception>
+<exception name="InterruptedException" type="java.lang.InterruptedException">
+</exception>
+<exception name="TimeoutException" type="java.util.concurrent.TimeoutException">
+</exception>
+</method>
+<method name="getResult"
+ return="V"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<exception name="AuthenticatorException" type="android.accounts.AuthenticatorException">
+</exception>
+<exception name="IOException" type="java.io.IOException">
+</exception>
+<exception name="OperationCanceledException" type="android.accounts.OperationCanceledException">
+</exception>
+</method>
+<method name="getResult"
+ return="V"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="timeout" type="long">
+</parameter>
+<parameter name="unit" type="java.util.concurrent.TimeUnit">
+</parameter>
+<exception name="AuthenticatorException" type="android.accounts.AuthenticatorException">
+</exception>
+<exception name="IOException" type="java.io.IOException">
+</exception>
+<exception name="OperationCanceledException" type="android.accounts.OperationCanceledException">
+</exception>
+</method>
+</interface>
 <class name="AuthenticatorDescription"
  extends="java.lang.Object"
  abstract="false"
@@ -14952,6 +14820,17 @@
  visibility="public"
 >
 </field>
+<field name="PASSWORD_KEY"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;password&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="USERDATA_KEY"
  type="java.lang.String"
  transient="false"
@@ -14964,136 +14843,6 @@
 >
 </field>
 </class>
-<interface name="Future1"
- abstract="true"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<implements name="java.util.concurrent.Future">
-</implements>
-<method name="getResult"
- return="V"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<exception name="OperationCanceledException" type="android.accounts.OperationCanceledException">
-</exception>
-</method>
-<method name="getResult"
- return="V"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="timeout" type="long">
-</parameter>
-<parameter name="unit" type="java.util.concurrent.TimeUnit">
-</parameter>
-<exception name="OperationCanceledException" type="android.accounts.OperationCanceledException">
-</exception>
-</method>
-</interface>
-<interface name="Future1Callback"
- abstract="true"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<method name="run"
- return="void"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="future" type="android.accounts.Future1&lt;V&gt;">
-</parameter>
-</method>
-</interface>
-<interface name="Future2"
- abstract="true"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<implements name="java.util.concurrent.Future">
-</implements>
-<method name="getResult"
- return="android.os.Bundle"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<exception name="AuthenticatorException" type="android.accounts.AuthenticatorException">
-</exception>
-<exception name="IOException" type="java.io.IOException">
-</exception>
-<exception name="OperationCanceledException" type="android.accounts.OperationCanceledException">
-</exception>
-</method>
-<method name="getResult"
- return="android.os.Bundle"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="timeout" type="long">
-</parameter>
-<parameter name="unit" type="java.util.concurrent.TimeUnit">
-</parameter>
-<exception name="AuthenticatorException" type="android.accounts.AuthenticatorException">
-</exception>
-<exception name="IOException" type="java.io.IOException">
-</exception>
-<exception name="OperationCanceledException" type="android.accounts.OperationCanceledException">
-</exception>
-</method>
-</interface>
-<interface name="Future2Callback"
- abstract="true"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<method name="run"
- return="void"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="future" type="android.accounts.Future2">
-</parameter>
-</method>
-</interface>
 <interface name="IAccountAuthenticator"
  abstract="true"
  static="false"
@@ -15179,6 +14928,23 @@
 <exception name="RemoteException" type="android.os.RemoteException">
 </exception>
 </method>
+<method name="getAccountRemovalAllowed"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="response" type="android.accounts.IAccountAuthenticatorResponse">
+</parameter>
+<parameter name="account" type="android.accounts.Account">
+</parameter>
+<exception name="RemoteException" type="android.os.RemoteException">
+</exception>
+</method>
 <method name="getAuthToken"
  return="void"
  abstract="true"
diff --git a/core/java/android/accounts/AbstractAccountAuthenticator.java b/core/java/android/accounts/AbstractAccountAuthenticator.java
index 3ce3ca3..38ae962 100644
--- a/core/java/android/accounts/AbstractAccountAuthenticator.java
+++ b/core/java/android/accounts/AbstractAccountAuthenticator.java
@@ -188,6 +188,25 @@
                 response.onResult(result);
             }
         }
+
+        public void getAccountRemovalAllowed(IAccountAuthenticatorResponse response,
+                Account account) throws RemoteException {
+            checkBinderPermission();
+            try {
+                final Bundle result = AbstractAccountAuthenticator.this.getAccountRemovalAllowed(
+                    new AccountAuthenticatorResponse(response), account);
+                if (result != null) {
+                    response.onResult(result);
+                }
+            } catch (UnsupportedOperationException e) {
+                response.onError(Constants.ERROR_CODE_UNSUPPORTED_OPERATION,
+                        "getAccountRemovalAllowed not supported");
+                return;
+            } catch (NetworkErrorException e) {
+                response.onError(Constants.ERROR_CODE_NETWORK_ERROR, e.getMessage());
+                return;
+            }
+        }
     }
 
     private void checkBinderPermission() {
@@ -238,4 +257,10 @@
             Account account, String authTokenType, Bundle loginOptions);
     public abstract Bundle hasFeatures(AccountAuthenticatorResponse response,
             Account account, String[] features) throws NetworkErrorException;
+    public Bundle getAccountRemovalAllowed(AccountAuthenticatorResponse response,
+            Account account) throws NetworkErrorException {
+        final Bundle result = new Bundle();
+        result.putBoolean(Constants.BOOLEAN_RESULT_KEY, true);
+        return result;
+    }
 }
diff --git a/core/java/android/accounts/Account.java b/core/java/android/accounts/Account.java
index 30c91b0..7b83a30 100644
--- a/core/java/android/accounts/Account.java
+++ b/core/java/android/accounts/Account.java
@@ -26,20 +26,20 @@
  * suitable for use as the key of a {@link java.util.Map}
  */
 public class Account implements Parcelable {
-    public final String mName;
-    public final String mType;
+    public final String name;
+    public final String type;
 
     public boolean equals(Object o) {
         if (o == this) return true;
         if (!(o instanceof Account)) return false;
         final Account other = (Account)o;
-        return mName.equals(other.mName) && mType.equals(other.mType);
+        return name.equals(other.name) && type.equals(other.type);
     }
 
     public int hashCode() {
         int result = 17;
-        result = 31 * result + mName.hashCode();
-        result = 31 * result + mType.hashCode();
+        result = 31 * result + name.hashCode();
+        result = 31 * result + type.hashCode();
         return result;
     }
 
@@ -50,13 +50,13 @@
         if (TextUtils.isEmpty(type)) {
             throw new IllegalArgumentException("the type must not be empty: " + type);
         }
-        mName = name;
-        mType = type;
+        this.name = name;
+        this.type = type;
     }
 
     public Account(Parcel in) {
-        mName = in.readString();
-        mType = in.readString();
+        this.name = in.readString();
+        this.type = in.readString();
     }
 
     public int describeContents() {
@@ -64,8 +64,8 @@
     }
 
     public void writeToParcel(Parcel dest, int flags) {
-        dest.writeString(mName);
-        dest.writeString(mType);
+        dest.writeString(name);
+        dest.writeString(type);
     }
 
     public static final Creator<Account> CREATOR = new Creator<Account>() {
@@ -79,6 +79,6 @@
     };
 
     public String toString() {
-        return "Account {name=" + mName + ", type=" + mType + "}";
+        return "Account {name=" + name + ", type=" + type + "}";
     }
 }
diff --git a/core/java/android/accounts/AccountManager.java b/core/java/android/accounts/AccountManager.java
index 502abbb..9f70534 100644
--- a/core/java/android/accounts/AccountManager.java
+++ b/core/java/android/accounts/AccountManager.java
@@ -26,8 +26,6 @@
 import android.os.Looper;
 import android.os.RemoteException;
 import android.os.Parcelable;
-import android.util.Config;
-import android.util.Log;
 
 import java.io.IOException;
 import java.util.concurrent.Callable;
@@ -80,258 +78,132 @@
         return (AccountManager) context.getSystemService(Context.ACCOUNT_SERVICE);
     }
 
-    public String blockingGetPassword(Account account) {
-        ensureNotOnMainThread();
+    public String getPassword(final Account account) {
         try {
             return mService.getPassword(account);
         } catch (RemoteException e) {
-            // if this happens the entire runtime will restart
+            // will never happen
             throw new RuntimeException(e);
         }
     }
 
-    public Future1<String> getPassword(final Future1Callback<String> callback,
-            final Account account, final Handler handler) {
-        return startAsFuture(callback, handler, new Callable<String>() {
-            public String call() throws Exception {
-                return blockingGetPassword(account);
-            }
-        });
-    }
-
-    public String blockingGetUserData(Account account, String key) {
-        ensureNotOnMainThread();
+    public String getUserData(final Account account, final String key) {
         try {
             return mService.getUserData(account, key);
         } catch (RemoteException e) {
-            // if this happens the entire runtime will restart
+            // will never happen
             throw new RuntimeException(e);
         }
     }
 
-    public Future1<String> getUserData(Future1Callback<String> callback,
-            final Account account, final String key, Handler handler) {
-        return startAsFuture(callback, handler, new Callable<String>() {
-            public String call() throws Exception {
-                return blockingGetUserData(account, key);
-            }
-        });
-    }
-
-    public AuthenticatorDescription[] blockingGetAuthenticatorTypes() {
-        ensureNotOnMainThread();
+    public AuthenticatorDescription[] getAuthenticatorTypes() {
         try {
             return mService.getAuthenticatorTypes();
         } catch (RemoteException e) {
-            // if this happens the entire runtime will restart
+            // will never happen
             throw new RuntimeException(e);
         }
     }
 
-    public Future1<AuthenticatorDescription[]> getAuthenticatorTypes(
-            Future1Callback<AuthenticatorDescription[]> callback, Handler handler) {
-        return startAsFuture(callback, handler, new Callable<AuthenticatorDescription[]>() {
-            public AuthenticatorDescription[] call() throws Exception {
-                return blockingGetAuthenticatorTypes();
-            }
-        });
-    }
-
-    public Account[] blockingGetAccounts() {
-        ensureNotOnMainThread();
+    public Account[] getAccounts() {
         try {
-            return mService.getAccounts();
+            return mService.getAccounts(null);
         } catch (RemoteException e) {
-            // if this happens the entire runtime will restart
+            // won't ever happen
             throw new RuntimeException(e);
         }
     }
 
-    public Account[] blockingGetAccountsByType(String accountType) {
-        ensureNotOnMainThread();
+    public Account[] getAccountsByType(String type) {
         try {
-            return mService.getAccountsByType(accountType);
+            return mService.getAccounts(type);
         } catch (RemoteException e) {
-            // if this happens the entire runtime will restart
+            // won't ever happen
             throw new RuntimeException(e);
         }
     }
 
-    public Future1<Account[]> getAccounts(Future1Callback<Account[]> callback, Handler handler) {
-        return startAsFuture(callback, handler, new Callable<Account[]>() {
-            public Account[] call() throws Exception {
-                return blockingGetAccounts();
-            }
-        });
-    }
-
-    public Future1<Account[]> getAccountsByType(Future1Callback<Account[]> callback,
-            final String type, Handler handler) {
-        return startAsFuture(callback, handler, new Callable<Account[]>() {
-            public Account[] call() throws Exception {
-                return blockingGetAccountsByType(type);
-            }
-        });
-    }
-
-    public boolean blockingAddAccountExplicitly(Account account, String password, Bundle extras) {
-        ensureNotOnMainThread();
+    public boolean addAccountExplicitly(Account account, String password, Bundle extras) {
         try {
             return mService.addAccount(account, password, extras);
         } catch (RemoteException e) {
-            // if this happens the entire runtime will restart
+            // won't ever happen
             throw new RuntimeException(e);
         }
     }
 
-    public Future1<Boolean> addAccountExplicitly(final Future1Callback<Boolean> callback,
-            final Account account, final String password, final Bundle extras,
-            final Handler handler) {
-        return startAsFuture(callback, handler, new Callable<Boolean>() {
-            public Boolean call() throws Exception {
-                return blockingAddAccountExplicitly(account, password, extras);
+    public AccountManagerFuture<Boolean> removeAccount(final Account account,
+            AccountManagerCallback<Boolean> callback, Handler handler) {
+        return new Future2Task<Boolean>(handler, callback) {
+            public void doWork() throws RemoteException {
+                mService.removeAccount(mResponse, account);
             }
-        });
-    }
-
-    public void blockingRemoveAccount(Account account) {
-        ensureNotOnMainThread();
-        try {
-            mService.removeAccount(account);
-        } catch (RemoteException e) {
-            // if this happens the entire runtime will restart
-        }
-    }
-
-    public Future1<Void> removeAccount(Future1Callback<Void> callback, final Account account,
-            final Handler handler) {
-        return startAsFuture(callback, handler, new Callable<Void>() {
-            public Void call() throws Exception {
-                blockingRemoveAccount(account);
-                return null;
+            public Boolean bundleToResult(Bundle bundle) throws AuthenticatorException {
+                if (!bundle.containsKey(Constants.BOOLEAN_RESULT_KEY)) {
+                    throw new AuthenticatorException("no result in response");
+                }
+                return bundle.getBoolean(Constants.BOOLEAN_RESULT_KEY);
             }
-        });
+        }.start();
     }
 
-    public void blockingInvalidateAuthToken(String accountType, String authToken) {
-        ensureNotOnMainThread();
+    public void invalidateAuthToken(final String accountType, final String authToken) {
         try {
             mService.invalidateAuthToken(accountType, authToken);
         } catch (RemoteException e) {
-            // if this happens the entire runtime will restart
-        }
-    }
-
-    public Future1<Void> invalidateAuthToken(Future1Callback<Void> callback,
-            final String accountType, final String authToken, final Handler handler) {
-        return startAsFuture(callback, handler, new Callable<Void>() {
-            public Void call() throws Exception {
-                blockingInvalidateAuthToken(accountType, authToken);
-                return null;
-            }
-        });
-    }
-
-    public String blockingPeekAuthToken(Account account, String authTokenType) {
-        ensureNotOnMainThread();
-        try {
-            return mService.peekAuthToken(account, authTokenType);
-        } catch (RemoteException e) {
-            // if this happens the entire runtime will restart
+            // won't ever happen
             throw new RuntimeException(e);
         }
     }
 
-    public Future1<String> peekAuthToken(Future1Callback<String> callback,
-            final Account account, final String authTokenType, final Handler handler) {
-        return startAsFuture(callback, handler, new Callable<String>() {
-            public String call() throws Exception {
-                return blockingPeekAuthToken(account, authTokenType);
-            }
-        });
+    public String peekAuthToken(final Account account, final String authTokenType) {
+        try {
+            return mService.peekAuthToken(account, authTokenType);
+        } catch (RemoteException e) {
+            // won't ever happen
+            throw new RuntimeException(e);
+        }
     }
 
-    public void blockingSetPassword(Account account, String password) {
-        ensureNotOnMainThread();
+    public void setPassword(final Account account, final String password) {
         try {
             mService.setPassword(account, password);
         } catch (RemoteException e) {
-            // if this happens the entire runtime will restart
+            // won't ever happen
+            throw new RuntimeException(e);
         }
     }
 
-    public Future1<Void> setPassword(Future1Callback<Void> callback,
-            final Account account, final String password, final Handler handler) {
-        return startAsFuture(callback, handler, new Callable<Void>() {
-            public Void call() throws Exception {
-                blockingSetPassword(account, password);
-                return null;
-            }
-        });
-    }
-
-    public void blockingClearPassword(Account account) {
-        ensureNotOnMainThread();
+    public void clearPassword(final Account account) {
         try {
             mService.clearPassword(account);
         } catch (RemoteException e) {
-            // if this happens the entire runtime will restart
+            // won't ever happen
+            throw new RuntimeException(e);
         }
     }
 
-    public Future1<Void> clearPassword(final Future1Callback<Void> callback, final Account account,
-            final Handler handler) {
-        return startAsFuture(callback, handler, new Callable<Void>() {
-            public Void call() throws Exception {
-                blockingClearPassword(account);
-                return null;
-            }
-        });
-    }
-
-    public void blockingSetUserData(Account account, String key, String value) {
-        ensureNotOnMainThread();
+    public void setUserData(final Account account, final String key, final String value) {
         try {
             mService.setUserData(account, key, value);
         } catch (RemoteException e) {
-            // if this happens the entire runtime will restart
+            // won't ever happen
+            throw new RuntimeException(e);
         }
     }
 
-    public Future1<Void> setUserData(Future1Callback<Void> callback,
-            final Account account, final String key, final String value, final Handler handler) {
-        return startAsFuture(callback, handler, new Callable<Void>() {
-            public Void call() throws Exception {
-                blockingSetUserData(account, key, value);
-                return null;
-            }
-        });
-    }
-
-    public void blockingSetAuthToken(Account account, String authTokenType, String authToken) {
-        ensureNotOnMainThread();
+    public void setAuthToken(Account account, final String authTokenType, final String authToken) {
         try {
             mService.setAuthToken(account, authTokenType, authToken);
         } catch (RemoteException e) {
-            // if this happens the entire runtime will restart
+            // won't ever happen
+            throw new RuntimeException(e);
         }
     }
 
-    public Future1<Void> setAuthToken(Future1Callback<Void> callback,
-            final Account account, final String authTokenType, final String authToken,
-            final Handler handler) {
-        return startAsFuture(callback, handler, new Callable<Void>() {
-            public Void call() throws Exception {
-                blockingSetAuthToken(account, authTokenType, authToken);
-                return null;
-            }
-        });
-    }
-
     public String blockingGetAuthToken(Account account, String authTokenType,
             boolean notifyAuthFailure)
             throws OperationCanceledException, IOException, AuthenticatorException {
-        ensureNotOnMainThread();
         Bundle bundle = getAuthToken(account, authTokenType, notifyAuthFailure, null /* callback */,
                 null /* handler */).getResult();
         return bundle.getString(Constants.AUTHTOKEN_KEY);
@@ -349,9 +221,9 @@
      * @param loginOptions
      * @param activity the activity to launch the login intent, if necessary, and to which
      */
-    public Future2 getAuthToken(
+    public AccountManagerFuture<Bundle> getAuthToken(
             final Account account, final String authTokenType, final Bundle loginOptions,
-            final Activity activity, Future2Callback callback, Handler handler) {
+            final Activity activity, AccountManagerCallback<Bundle> callback, Handler handler) {
         if (activity == null) throw new IllegalArgumentException("activity is null");
         if (authTokenType == null) throw new IllegalArgumentException("authTokenType is null");
         return new AmsTask(activity, handler, callback) {
@@ -363,9 +235,9 @@
         }.start();
     }
 
-    public Future2 getAuthToken(
+    public AccountManagerFuture<Bundle> getAuthToken(
             final Account account, final String authTokenType, final boolean notifyAuthFailure,
-            Future2Callback callback, Handler handler) {
+            AccountManagerCallback<Bundle> callback, Handler handler) {
         if (account == null) throw new IllegalArgumentException("account is null");
         if (authTokenType == null) throw new IllegalArgumentException("authTokenType is null");
         return new AmsTask(null, handler, callback) {
@@ -376,10 +248,10 @@
         }.start();
     }
 
-    public Future2 addAccount(final String accountType,
+    public AccountManagerFuture<Bundle> addAccount(final String accountType,
             final String authTokenType, final String[] requiredFeatures,
             final Bundle addAccountOptions,
-            final Activity activity, Future2Callback callback, Handler handler) {
+            final Activity activity, AccountManagerCallback<Bundle> callback, Handler handler) {
         return new AmsTask(activity, handler, callback) {
             public void doWork() throws RemoteException {
                 mService.addAcount(mResponse, accountType, authTokenType,
@@ -389,44 +261,45 @@
     }
 
     /** @deprecated use {@link #confirmCredentials} instead */
-    public Future1<Boolean> confirmPassword(final Account account, final String password,
-            Future1Callback<Boolean> callback, Handler handler) {
-        return new AMSTaskBoolean(handler, callback) {
+    public AccountManagerFuture<Boolean> confirmPassword(final Account account, final String password,
+            AccountManagerCallback<Boolean> callback, Handler handler) {
+        return new Future2Task<Boolean>(handler, callback) {
             public void doWork() throws RemoteException {
-                mService.confirmPassword(response, account, password);
+                mService.confirmPassword(mResponse, account, password);
             }
-        };
-    }
-
-    public Account[] blockingGetAccountsWithTypeAndFeatures(String type, String[] features)
-            throws AuthenticatorException, IOException, OperationCanceledException {
-        Future2 future = getAccountsWithTypeAndFeatures(type, features,
-                null /* callback */, null /* handler */);
-        Bundle result = future.getResult();
-        Parcelable[] accountsTemp = result.getParcelableArray(Constants.ACCOUNTS_KEY);
-        if (accountsTemp == null) {
-            throw new AuthenticatorException("accounts should not be null");
-        }
-        Account[] accounts = new Account[accountsTemp.length];
-        for (int i = 0; i < accountsTemp.length; i++) {
-            accounts[i] = (Account) accountsTemp[i];
-        }
-        return accounts;
-    }
-
-    public Future2 getAccountsWithTypeAndFeatures(
-            final String type, final String[] features,
-            Future2Callback callback, Handler handler) {
-        if (type == null) throw new IllegalArgumentException("type is null");
-        return new AmsTask(null /* activity */, handler, callback) {
-            public void doWork() throws RemoteException {
-                mService.getAccountsByTypeAndFeatures(mResponse, type, features);
+            public Boolean bundleToResult(Bundle bundle) throws AuthenticatorException {
+                if (!bundle.containsKey(Constants.BOOLEAN_RESULT_KEY)) {
+                    throw new AuthenticatorException("no result in response");
+                }
+                return bundle.getBoolean(Constants.BOOLEAN_RESULT_KEY);
             }
         }.start();
     }
 
-    public Future2 confirmCredentials(final Account account, final Activity activity,
-            final Future2Callback callback,
+    public AccountManagerFuture<Account[]> getAccountsByTypeAndFeatures(
+            final String type, final String[] features,
+            AccountManagerCallback<Account[]> callback, Handler handler) {
+        if (type == null) throw new IllegalArgumentException("type is null");
+        return new Future2Task<Account[]>(handler, callback) {
+            public void doWork() throws RemoteException {
+                mService.getAccountsByFeatures(mResponse, type, features);
+            }
+            public Account[] bundleToResult(Bundle bundle) throws AuthenticatorException {
+                if (!bundle.containsKey(Constants.ACCOUNTS_KEY)) {
+                    throw new AuthenticatorException("no result in response");
+                }
+                final Parcelable[] parcelables = bundle.getParcelableArray(Constants.ACCOUNTS_KEY);
+                Account[] descs = new Account[parcelables.length];
+                for (int i = 0; i < parcelables.length; i++) {
+                    descs[i] = (Account) parcelables[i];
+                }
+                return descs;
+            }
+        }.start();
+    }
+
+    public AccountManagerFuture<Bundle> confirmCredentials(final Account account, final Activity activity,
+            final AccountManagerCallback<Bundle> callback,
             final Handler handler) {
         return new AmsTask(activity, handler, callback) {
             public void doWork() throws RemoteException {
@@ -435,9 +308,9 @@
         }.start();
     }
 
-    public Future2 updateCredentials(final Account account, final String authTokenType,
+    public AccountManagerFuture<Bundle> updateCredentials(final Account account, final String authTokenType,
             final Bundle loginOptions, final Activity activity,
-            final Future2Callback callback,
+            final AccountManagerCallback<Bundle> callback,
             final Handler handler) {
         return new AmsTask(activity, handler, callback) {
             public void doWork() throws RemoteException {
@@ -447,8 +320,8 @@
         }.start();
     }
 
-    public Future2 editProperties(final String accountType, final Activity activity,
-            final Future2Callback callback,
+    public AccountManagerFuture<Bundle> editProperties(final String accountType, final Activity activity,
+            final AccountManagerCallback<Bundle> callback,
             final Handler handler) {
         return new AmsTask(activity, handler, callback) {
             public void doWork() throws RemoteException {
@@ -471,8 +344,8 @@
         }
     }
 
-    private void postToHandler(Handler handler, final Future2Callback callback,
-            final Future2 future) {
+    private void postToHandler(Handler handler, final AccountManagerCallback<Bundle> callback,
+            final AccountManagerFuture<Bundle> future) {
         handler = handler == null ? mMainHandler : handler;
         handler.post(new Runnable() {
             public void run() {
@@ -483,87 +356,24 @@
 
     private void postToHandler(Handler handler, final OnAccountsUpdatedListener listener,
             final Account[] accounts) {
-        handler = handler == null ? mMainHandler : handler;
+        final Account[] accountsCopy = new Account[accounts.length];
+        // send a copy to make sure that one doesn't
+        // change what another sees
+        System.arraycopy(accounts, 0, accountsCopy, 0, accountsCopy.length);
+        handler = (handler == null) ? mMainHandler : handler;
         handler.post(new Runnable() {
             public void run() {
-                listener.onAccountsUpdated(accounts);
+                listener.onAccountsUpdated(accountsCopy);
             }
         });
     }
 
-    private <V> void postToHandler(Handler handler, final Future1Callback<V> callback,
-            final Future1<V> future) {
-        handler = handler == null ? mMainHandler : handler;
-        handler.post(new Runnable() {
-            public void run() {
-                callback.run(future);
-            }
-        });
-    }
-
-    private <V> Future1<V> startAsFuture(Future1Callback<V> callback, Handler handler,
-            Callable<V> callable) {
-        final FutureTaskWithCallback<V> task =
-                new FutureTaskWithCallback<V>(callback, callable, handler);
-        new Thread(task).start();
-        return task;
-    }
-
-    private class FutureTaskWithCallback<V> extends FutureTask<V> implements Future1<V> {
-        final Future1Callback<V> mCallback;
-        final Handler mHandler;
-
-        public FutureTaskWithCallback(Future1Callback<V> callback, Callable<V> callable,
-                Handler handler) {
-            super(callable);
-            mCallback = callback;
-            mHandler = handler;
-        }
-
-        protected void done() {
-            if (mCallback != null) {
-                postToHandler(mHandler, mCallback, this);
-            }
-        }
-
-        public V internalGetResult(Long timeout, TimeUnit unit) throws OperationCanceledException {
-            try {
-                if (timeout == null) {
-                    return get();
-                } else {
-                    return get(timeout, unit);
-                }
-            } catch (InterruptedException e) {
-                // we will cancel the task below
-            } catch (CancellationException e) {
-                // we will cancel the task below
-            } catch (TimeoutException e) {
-                // we will cancel the task below
-            } catch (ExecutionException e) {
-                // this should never happen
-                throw new IllegalStateException(e.getCause());
-            } finally {
-                cancel(true /* interruptIfRunning */);
-            }
-            throw new OperationCanceledException();
-        }
-
-        public V getResult() throws OperationCanceledException {
-            return internalGetResult(null, null);
-        }
-
-        public V getResult(long timeout, TimeUnit unit) throws OperationCanceledException {
-            return internalGetResult(null, null);
-        }
-    }
-
-    private abstract class AmsTask extends FutureTask<Bundle> implements Future2 {
+    private abstract class AmsTask extends FutureTask<Bundle> implements AccountManagerFuture<Bundle> {
         final IAccountManagerResponse mResponse;
         final Handler mHandler;
-        final Future2Callback mCallback;
+        final AccountManagerCallback<Bundle> mCallback;
         final Activity mActivity;
-        final Thread mThread;
-        public AmsTask(Activity activity, Handler handler, Future2Callback callback) {
+        public AmsTask(Activity activity, Handler handler, AccountManagerCallback<Bundle> callback) {
             super(new Callable<Bundle>() {
                 public Bundle call() throws Exception {
                     throw new IllegalStateException("this should never be called");
@@ -574,19 +384,14 @@
             mCallback = callback;
             mActivity = activity;
             mResponse = new Response();
-            mThread = new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        doWork();
-                    } catch (RemoteException e) {
-                        // never happens
-                    }
-                }
-            }, "AmsTask");
         }
 
-        public final Future2 start() {
-            mThread.start();
+        public final AccountManagerFuture<Bundle> start() {
+            try {
+                doWork();
+            } catch (RemoteException e) {
+                setException(e);
+            }
             return this;
         }
 
@@ -594,6 +399,7 @@
 
         private Bundle internalGetResult(Long timeout, TimeUnit unit)
                 throws OperationCanceledException, IOException, AuthenticatorException {
+            ensureNotOnMainThread();
             try {
                 if (timeout == null) {
                     return get();
@@ -676,92 +482,50 @@
 
     }
 
-    private abstract class AMSTaskBoolean extends FutureTask<Boolean> implements Future1<Boolean> {
-        final IAccountManagerResponse response;
+    private abstract class BaseFutureTask<T> extends FutureTask<T> {
+        final public IAccountManagerResponse mResponse;
         final Handler mHandler;
-        final Future1Callback<Boolean> mCallback;
-        public AMSTaskBoolean(Handler handler, Future1Callback<Boolean> callback) {
-            super(new Callable<Boolean>() {
-                public Boolean call() throws Exception {
+
+        public BaseFutureTask(Handler handler) {
+            super(new Callable<T>() {
+                public T call() throws Exception {
                     throw new IllegalStateException("this should never be called");
                 }
             });
-
             mHandler = handler;
-            mCallback = callback;
-            response = new Response();
-
-            new Thread(new Runnable() {
-                public void run() {
-                    try {
-                        doWork();
-                    } catch (RemoteException e) {
-                        // never happens
-                    }
-                }
-            }).start();
+            mResponse = new Response();
         }
 
         public abstract void doWork() throws RemoteException;
 
+        public abstract T bundleToResult(Bundle bundle) throws AuthenticatorException;
 
-        protected void done() {
-            if (mCallback != null) {
-                postToHandler(mHandler, mCallback, this);
-            }
+        protected void postRunnableToHandler(Runnable runnable) {
+            Handler handler = (mHandler == null) ? mMainHandler : mHandler;
+            handler.post(runnable);
         }
 
-        private Boolean internalGetResult(Long timeout, TimeUnit unit) {
+        protected void startTask() {
             try {
-                if (timeout == null) {
-                    return get();
-                } else {
-                    return get(timeout, unit);
-                }
-            } catch (InterruptedException e) {
-                // fall through and cancel
-            } catch (TimeoutException e) {
-                // fall through and cancel
-            } catch (CancellationException e) {
-                return false;
-            } catch (ExecutionException e) {
-                final Throwable cause = e.getCause();
-                if (cause instanceof IOException) {
-                    return false;
-                } else if (cause instanceof UnsupportedOperationException) {
-                    return false;
-                } else if (cause instanceof AuthenticatorException) {
-                    return false;
-                } else if (cause instanceof RuntimeException) {
-                    throw (RuntimeException) cause;
-                } else if (cause instanceof Error) {
-                    throw (Error) cause;
-                } else {
-                    throw new IllegalStateException(cause);
-                }
-            } finally {
-                cancel(true /* interrupt if running */);
+                doWork();
+            } catch (RemoteException e) {
+                setException(e);
             }
-            return false;
         }
 
-        public Boolean getResult() throws OperationCanceledException {
-            return internalGetResult(null, null);
-        }
-
-        public Boolean getResult(long timeout, TimeUnit unit) throws OperationCanceledException {
-            return internalGetResult(timeout, unit);
-        }
-
-        private class Response extends IAccountManagerResponse.Stub {
+        protected class Response extends IAccountManagerResponse.Stub {
             public void onResult(Bundle bundle) {
                 try {
-                    if (bundle.containsKey(Constants.BOOLEAN_RESULT_KEY)) {
-                        set(bundle.getBoolean(Constants.BOOLEAN_RESULT_KEY));
+                    T result = bundleToResult(bundle);
+                    if (result == null) {
                         return;
                     }
+                    set(result);
+                    return;
                 } catch (ClassCastException e) {
                     // we will set the exception below
+                } catch (AuthenticatorException e) {
+                    // we will set the exception below
                 }
                 onError(Constants.ERROR_CODE_INVALID_RESPONSE, "no result in response");
             }
@@ -774,6 +538,76 @@
                 setException(convertErrorToException(code, message));
             }
         }
+    }
+
+    private abstract class Future2Task<T>
+            extends BaseFutureTask<T> implements AccountManagerFuture<T> {
+        final AccountManagerCallback<T> mCallback;
+        public Future2Task(Handler handler, AccountManagerCallback<T> callback) {
+            super(handler);
+            mCallback = callback;
+        }
+
+        protected void done() {
+            if (mCallback != null) {
+                postRunnableToHandler(new Runnable() {
+                    public void run() {
+                        mCallback.run(Future2Task.this);
+                    }
+                });
+            }
+        }
+
+        public Future2Task<T> start() {
+            startTask();
+            return this;
+        }
+
+        private T internalGetResult(Long timeout, TimeUnit unit)
+                throws OperationCanceledException, IOException, AuthenticatorException {
+            ensureNotOnMainThread();
+            try {
+                if (timeout == null) {
+                    return get();
+                } else {
+                    return get(timeout, unit);
+                }
+            } catch (InterruptedException e) {
+                // fall through and cancel
+            } catch (TimeoutException e) {
+                // fall through and cancel
+            } catch (CancellationException e) {
+                // fall through and cancel
+            } catch (ExecutionException e) {
+                final Throwable cause = e.getCause();
+                if (cause instanceof IOException) {
+                    throw (IOException) cause;
+                } else if (cause instanceof UnsupportedOperationException) {
+                    throw new AuthenticatorException(cause);
+                } else if (cause instanceof AuthenticatorException) {
+                    throw (AuthenticatorException) cause;
+                } else if (cause instanceof RuntimeException) {
+                    throw (RuntimeException) cause;
+                } else if (cause instanceof Error) {
+                    throw (Error) cause;
+                } else {
+                    throw new IllegalStateException(cause);
+                }
+            } finally {
+                cancel(true /* interrupt if running */);
+            }
+            throw new OperationCanceledException();
+        }
+
+        public T getResult()
+                throws OperationCanceledException, IOException, AuthenticatorException {
+            return internalGetResult(null, null);
+        }
+
+        public T getResult(long timeout, TimeUnit unit)
+                throws OperationCanceledException, IOException, AuthenticatorException {
+            return internalGetResult(timeout, unit);
+        }
 
     }
 
@@ -797,11 +631,12 @@
         return new AuthenticatorException(message);
     }
 
-    private class GetAuthTokenByTypeAndFeaturesTask extends AmsTask implements Future2Callback {
+    private class GetAuthTokenByTypeAndFeaturesTask
+            extends AmsTask implements AccountManagerCallback<Bundle> {
         GetAuthTokenByTypeAndFeaturesTask(final String accountType, final String authTokenType,
                 final String[] features, Activity activityForPrompting,
                 final Bundle addAccountOptions, final Bundle loginOptions,
-                Future2Callback callback, Handler handler) {
+                AccountManagerCallback<Bundle> callback, Handler handler) {
             super(activityForPrompting, handler, callback);
             if (accountType == null) throw new IllegalArgumentException("account type is null");
             mAccountType = accountType;
@@ -811,101 +646,100 @@
             mLoginOptions = loginOptions;
             mMyCallback = this;
         }
-        volatile Future2 mFuture = null;
+        volatile AccountManagerFuture<Bundle> mFuture = null;
         final String mAccountType;
         final String mAuthTokenType;
         final String[] mFeatures;
         final Bundle mAddAccountOptions;
         final Bundle mLoginOptions;
-        final Future2Callback mMyCallback;
+        final AccountManagerCallback<Bundle> mMyCallback;
 
         public void doWork() throws RemoteException {
-            getAccountsWithTypeAndFeatures(mAccountType, mFeatures, new Future2Callback() {
-                public void run(Future2 future) {
-                    Bundle getAccountsResult;
-                    try {
-                        getAccountsResult = future.getResult();
-                    } catch (OperationCanceledException e) {
-                        setException(e);
-                        return;
-                    } catch (IOException e) {
-                        setException(e);
-                        return;
-                    } catch (AuthenticatorException e) {
-                        setException(e);
-                        return;
-                    }
-
-                    Parcelable[] accounts =
-                            getAccountsResult.getParcelableArray(Constants.ACCOUNTS_KEY);
-                    if (accounts.length == 0) {
-                        if (mActivity != null) {
-                            // no accounts, add one now. pretend that the user directly
-                            // made this request
-                            mFuture = addAccount(mAccountType, mAuthTokenType, mFeatures,
-                                    mAddAccountOptions, mActivity, mMyCallback, mHandler);
-                        } else {
-                            // send result since we can't prompt to add an account
-                            Bundle result = new Bundle();
-                            result.putString(Constants.ACCOUNT_NAME_KEY, null);
-                            result.putString(Constants.ACCOUNT_TYPE_KEY, null);
-                            result.putString(Constants.AUTHTOKEN_KEY, null);
+            getAccountsByTypeAndFeatures(mAccountType, mFeatures,
+                    new AccountManagerCallback<Account[]>() {
+                        public void run(AccountManagerFuture<Account[]> future) {
+                            Account[] accounts;
                             try {
-                                mResponse.onResult(result);
-                            } catch (RemoteException e) {
-                                // this will never happen
+                                accounts = future.getResult();
+                            } catch (OperationCanceledException e) {
+                                setException(e);
+                                return;
+                            } catch (IOException e) {
+                                setException(e);
+                                return;
+                            } catch (AuthenticatorException e) {
+                                setException(e);
+                                return;
                             }
-                            // we are done
-                        }
-                    } else if (accounts.length == 1) {
-                        // have a single account, return an authtoken for it
-                        if (mActivity == null) {
-                            mFuture = getAuthToken((Account) accounts[0], mAuthTokenType,
-                                    false /* notifyAuthFailure */, mMyCallback, mHandler);
-                        } else {
-                            mFuture = getAuthToken((Account) accounts[0],
-                                    mAuthTokenType, mLoginOptions,
-                                    mActivity, mMyCallback, mHandler);
-                        }
-                    } else {
-                        if (mActivity != null) {
-                            IAccountManagerResponse chooseResponse =
-                                    new IAccountManagerResponse.Stub() {
-                                public void onResult(Bundle value) throws RemoteException {
-                                    Account account = new Account(
-                                            value.getString(Constants.ACCOUNT_NAME_KEY),
-                                            value.getString(Constants.ACCOUNT_TYPE_KEY));
-                                    mFuture = getAuthToken(account, mAuthTokenType, mLoginOptions,
+
+                            if (accounts.length == 0) {
+                                if (mActivity != null) {
+                                    // no accounts, add one now. pretend that the user directly
+                                    // made this request
+                                    mFuture = addAccount(mAccountType, mAuthTokenType, mFeatures,
+                                            mAddAccountOptions, mActivity, mMyCallback, mHandler);
+                                } else {
+                                    // send result since we can't prompt to add an account
+                                    Bundle result = new Bundle();
+                                    result.putString(Constants.ACCOUNT_NAME_KEY, null);
+                                    result.putString(Constants.ACCOUNT_TYPE_KEY, null);
+                                    result.putString(Constants.AUTHTOKEN_KEY, null);
+                                    try {
+                                        mResponse.onResult(result);
+                                    } catch (RemoteException e) {
+                                        // this will never happen
+                                    }
+                                    // we are done
+                                }
+                            } else if (accounts.length == 1) {
+                                // have a single account, return an authtoken for it
+                                if (mActivity == null) {
+                                    mFuture = getAuthToken(accounts[0], mAuthTokenType,
+                                            false /* notifyAuthFailure */, mMyCallback, mHandler);
+                                } else {
+                                    mFuture = getAuthToken(accounts[0],
+                                            mAuthTokenType, mLoginOptions,
                                             mActivity, mMyCallback, mHandler);
                                 }
+                            } else {
+                                if (mActivity != null) {
+                                    IAccountManagerResponse chooseResponse =
+                                            new IAccountManagerResponse.Stub() {
+                                        public void onResult(Bundle value) throws RemoteException {
+                                            Account account = new Account(
+                                                    value.getString(Constants.ACCOUNT_NAME_KEY),
+                                                    value.getString(Constants.ACCOUNT_TYPE_KEY));
+                                            mFuture = getAuthToken(account, mAuthTokenType, mLoginOptions,
+                                                    mActivity, mMyCallback, mHandler);
+                                        }
 
-                                public void onError(int errorCode, String errorMessage)
-                                        throws RemoteException {
-                                    mResponse.onError(errorCode, errorMessage);
+                                        public void onError(int errorCode, String errorMessage)
+                                                throws RemoteException {
+                                            mResponse.onError(errorCode, errorMessage);
+                                        }
+                                    };
+                                    // have many accounts, launch the chooser
+                                    Intent intent = new Intent();
+                                    intent.setClassName("android",
+                                            "android.accounts.ChooseAccountActivity");
+                                    intent.putExtra(Constants.ACCOUNTS_KEY, accounts);
+                                    intent.putExtra(Constants.ACCOUNT_MANAGER_RESPONSE_KEY,
+                                            new AccountManagerResponse(chooseResponse));
+                                    mActivity.startActivity(intent);
+                                    // the result will arrive via the IAccountManagerResponse
+                                } else {
+                                    // send result since we can't prompt to select an account
+                                    Bundle result = new Bundle();
+                                    result.putString(Constants.ACCOUNTS_KEY, null);
+                                    try {
+                                        mResponse.onResult(result);
+                                    } catch (RemoteException e) {
+                                        // this will never happen
+                                    }
+                                    // we are done
                                 }
-                            };
-                            // have many accounts, launch the chooser
-                            Intent intent = new Intent();
-                            intent.setClassName("android",
-                                    "android.accounts.ChooseAccountActivity");
-                            intent.putExtra(Constants.ACCOUNTS_KEY, accounts);
-                            intent.putExtra(Constants.ACCOUNT_MANAGER_RESPONSE_KEY,
-                                    new AccountManagerResponse(chooseResponse));
-                            mActivity.startActivity(intent);
-                            // the result will arrive via the IAccountManagerResponse
-                        } else {
-                            // send result since we can't prompt to select an account
-                            Bundle result = new Bundle();
-                            result.putString(Constants.ACCOUNTS_KEY, null);
-                            try {
-                                mResponse.onResult(result);
-                            } catch (RemoteException e) {
-                                // this will never happen
                             }
-                            // we are done
-                        }
-                    }
-                }}, mHandler);
+                        }}, mHandler);
         }
 
 
@@ -915,7 +749,7 @@
         // or to cause this to be canceled if mFuture isn't set.
         // Once this is done then getAuthTokenByFeatures can be changed to return a Future2.
 
-        public void run(Future2 future) {
+        public void run(AccountManagerFuture<Bundle> future) {
             try {
                 set(future.get());
             } catch (InterruptedException e) {
@@ -932,7 +766,7 @@
             final String accountType, final String authTokenType, final String[] features,
             final Activity activityForPrompting, final Bundle addAccountOptions,
             final Bundle loginOptions,
-            final Future2Callback callback, final Handler handler) {
+            final AccountManagerCallback<Bundle> callback, final Handler handler) {
         if (accountType == null) throw new IllegalArgumentException("account type is null");
         if (authTokenType == null) throw new IllegalArgumentException("authTokenType is null");
         new GetAuthTokenByTypeAndFeaturesTask(accountType, authTokenType,  features,
@@ -942,13 +776,6 @@
     private final HashMap<OnAccountsUpdatedListener, Handler> mAccountsUpdatedListeners =
             Maps.newHashMap();
 
-    // These variable are only used from the LOGIN_ACCOUNTS_CHANGED_ACTION BroadcastReceiver
-    // and its getAccounts() callback which are both invoked only on the main thread. As a
-    // result we don't need to protect against concurrent accesses and any changes are guaranteed
-    // to be visible when used. Basically, these two variables are thread-confined.
-    private Future1<Account[]> mAccountsLookupFuture = null;
-    private boolean mAccountLookupPending = false;
-
     /**
      * BroadcastReceiver that listens for the LOGIN_ACCOUNTS_CHANGED_ACTION intent
      * so that it can read the updated list of accounts and send them to the listener
@@ -956,58 +783,14 @@
      */
     private final BroadcastReceiver mAccountsChangedBroadcastReceiver = new BroadcastReceiver() {
         public void onReceive(final Context context, final Intent intent) {
-            if (mAccountsLookupFuture != null) {
-                // an accounts lookup is already in progress,
-                // don't bother starting another request
-                mAccountLookupPending = true;
-                return;
-            }
-            // initiate a read of the accounts
-            mAccountsLookupFuture = getAccounts(new Future1Callback<Account[]>() {
-                public void run(Future1<Account[]> future) {
-                    // clear the future so that future receives will try the lookup again
-                    mAccountsLookupFuture = null;
-
-                    // get the accounts array
-                    Account[] accounts;
-                    try {
-                        accounts = future.getResult();
-                    } catch (OperationCanceledException e) {
-                        // this should never happen, but if it does pretend we got another
-                        // accounts changed broadcast
-                        if (Config.LOGD) {
-                            Log.d(TAG, "the accounts lookup for listener notifications was "
-                                    + "canceled, try again by simulating the receipt of "
-                                    + "a LOGIN_ACCOUNTS_CHANGED_ACTION broadcast");
-                        }
-                        onReceive(context, intent);
-                        return;
-                    }
-
-                    // send the result to the listeners
-                    synchronized (mAccountsUpdatedListeners) {
-                        for (Map.Entry<OnAccountsUpdatedListener, Handler> entry :
-                                mAccountsUpdatedListeners.entrySet()) {
-                            Account[] accountsCopy = new Account[accounts.length];
-                            // send the listeners a copy to make sure that one doesn't
-                            // change what another sees
-                            System.arraycopy(accounts, 0, accountsCopy, 0, accountsCopy.length);
-                            postToHandler(entry.getValue(), entry.getKey(), accountsCopy);
-                        }
-                    }
-
-                    // If mAccountLookupPending was set when the account lookup finished it
-                    // means that we had previously ignored a LOGIN_ACCOUNTS_CHANGED_ACTION
-                    // intent because a lookup was already in progress. Now that we are done
-                    // with this lookup and notification pretend that another intent
-                    // was received by calling onReceive() directly.
-                    if (mAccountLookupPending) {
-                        mAccountLookupPending = false;
-                        onReceive(context, intent);
-                        return;
-                    }
+            final Account[] accounts = getAccounts();
+            // send the result to the listeners
+            synchronized (mAccountsUpdatedListeners) {
+                for (Map.Entry<OnAccountsUpdatedListener, Handler> entry :
+                        mAccountsUpdatedListeners.entrySet()) {
+                    postToHandler(entry.getValue(), entry.getKey(), accounts);
                 }
-            }, mMainHandler);
+            }
         }
     };
 
@@ -1045,15 +828,7 @@
         }
 
         if (updateImmediately) {
-            getAccounts(new Future1Callback<Account[]>() {
-                public void run(Future1<Account[]> future) {
-                    try {
-                        listener.onAccountsUpdated(future.getResult());
-                    } catch (OperationCanceledException e) {
-                        // ignore
-                    }
-                }
-            }, handler);
+            postToHandler(handler, listener, getAccounts());
         }
     }
 
diff --git a/core/java/android/accounts/Future2Callback.java b/core/java/android/accounts/AccountManagerCallback.java
similarity index 87%
rename from core/java/android/accounts/Future2Callback.java
rename to core/java/android/accounts/AccountManagerCallback.java
index 7ef0c94..4aa7169 100644
--- a/core/java/android/accounts/Future2Callback.java
+++ b/core/java/android/accounts/AccountManagerCallback.java
@@ -15,6 +15,6 @@
  */
 package android.accounts;
 
-public interface Future2Callback {
-    void run(Future2 future);
+public interface AccountManagerCallback<V> {
+    void run(AccountManagerFuture<V> future);
 }
\ No newline at end of file
diff --git a/core/java/android/accounts/AccountManagerFuture.java b/core/java/android/accounts/AccountManagerFuture.java
new file mode 100644
index 0000000..9939398
--- /dev/null
+++ b/core/java/android/accounts/AccountManagerFuture.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.accounts;
+
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeoutException;
+import java.io.IOException;
+
+/**
+ * An extension of {@link java.util.concurrent.Future} that provides wrappers for {@link #get()}
+ * that handle the various
+ * exceptions that  {@link #get()} may return and rethrows them as exceptions specific to
+ * {@link android.accounts.AccountManager}.
+ */
+public interface AccountManagerFuture<V> extends Future<V> {
+    /**
+     * Wrapper for {@link java.util.concurrent.Future#get()}. If the get() throws
+     * {@link InterruptedException} then the
+     * {@link AccountManagerFuture} is canceled and
+     * {@link android.accounts.OperationCanceledException} is thrown.
+     * @return the {@link android.os.Bundle} that is returned by get()
+     * @throws android.accounts.OperationCanceledException if get() throws the unchecked
+     * CancellationException
+     * or if the Future was interrupted.
+     */
+    V getResult() throws OperationCanceledException, IOException, AuthenticatorException;
+
+    /**
+     * Wrapper for {@link java.util.concurrent.Future#get()}. If the get() throws
+     * {@link InterruptedException} then the
+     * {@link AccountManagerFuture} is canceled and
+     * {@link android.accounts.OperationCanceledException} is thrown.
+     * @param timeout the maximum time to wait
+     * @param unit the time unit of the timeout argument
+     * @return the {@link android.os.Bundle} that is returned by
+     * {@link java.util.concurrent.Future#get()}
+     * @throws android.accounts.OperationCanceledException if get() throws the unchecked
+     * {@link java.util.concurrent.CancellationException} or if the {@link AccountManagerFuture}
+     * was interrupted.
+     */
+    V getResult(long timeout, TimeUnit unit)
+            throws OperationCanceledException, IOException, AuthenticatorException;
+
+    @Deprecated
+    V get() throws InterruptedException, ExecutionException;
+
+    @Deprecated
+    V get(long timeout, TimeUnit unit)
+            throws InterruptedException, ExecutionException, TimeoutException;
+}
\ No newline at end of file
diff --git a/core/java/android/accounts/AccountManagerService.java b/core/java/android/accounts/AccountManagerService.java
index 0c941be..140c814 100644
--- a/core/java/android/accounts/AccountManagerService.java
+++ b/core/java/android/accounts/AccountManagerService.java
@@ -214,10 +214,48 @@
 
         long identityToken = clearCallingIdentity();
         try {
-            SQLiteDatabase db = mOpenHelper.getReadableDatabase();
-            Cursor cursor = db.query(TABLE_ACCOUNTS, new String[]{ACCOUNTS_PASSWORD},
-                    ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE+ "=?",
-                    new String[]{account.mName, account.mType}, null, null, null);
+            return readPasswordFromDatabase(account);
+        } finally {
+            restoreCallingIdentity(identityToken);
+        }
+    }
+
+    private String readPasswordFromDatabase(Account account) {
+        SQLiteDatabase db = mOpenHelper.getReadableDatabase();
+        Cursor cursor = db.query(TABLE_ACCOUNTS, new String[]{ACCOUNTS_PASSWORD},
+                ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE+ "=?",
+                new String[]{account.name, account.type}, null, null, null);
+        try {
+            if (cursor.moveToNext()) {
+                return cursor.getString(0);
+            }
+            return null;
+        } finally {
+            cursor.close();
+        }
+    }
+
+    public String getUserData(Account account, String key) {
+        checkAuthenticateAccountsPermission(account);
+        long identityToken = clearCallingIdentity();
+        try {
+            return readUserDataFromDatabase(account, key);
+        } finally {
+            restoreCallingIdentity(identityToken);
+        }
+    }
+
+    private String readUserDataFromDatabase(Account account, String key) {
+        SQLiteDatabase db = mOpenHelper.getReadableDatabase();
+        db.beginTransaction();
+        try {
+            long accountId = getAccountId(db, account);
+            if (accountId < 0) {
+                return null;
+            }
+            Cursor cursor = db.query(TABLE_EXTRAS, new String[]{EXTRAS_VALUE},
+                    EXTRAS_ACCOUNTS_ID + "=" + accountId + " AND " + EXTRAS_KEY + "=?",
+                    new String[]{key}, null, null, null);
             try {
                 if (cursor.moveToNext()) {
                     return cursor.getString(0);
@@ -227,37 +265,7 @@
                 cursor.close();
             }
         } finally {
-            restoreCallingIdentity(identityToken);
-        }
-    }
-
-    public String getUserData(Account account, String key) {
-        checkAuthenticateAccountsPermission(account);
-        long identityToken = clearCallingIdentity();
-        try {
-            SQLiteDatabase db = mOpenHelper.getReadableDatabase();
-            db.beginTransaction();
-            try {
-                long accountId = getAccountId(db, account);
-                if (accountId < 0) {
-                    return null;
-                }
-                Cursor cursor = db.query(TABLE_EXTRAS, new String[]{EXTRAS_VALUE},
-                        EXTRAS_ACCOUNTS_ID + "=" + accountId + " AND " + EXTRAS_KEY + "=?",
-                        new String[]{key}, null, null, null);
-                try {
-                    if (cursor.moveToNext()) {
-                        return cursor.getString(0);
-                    }
-                    return null;
-                } finally {
-                    cursor.close();
-                }
-            } finally {
-                db.endTransaction();
-            }
-        } finally {
-            restoreCallingIdentity(identityToken);
+            db.endTransaction();
         }
     }
 
@@ -280,39 +288,23 @@
         }
     }
 
-    public Account[] getAccounts() {
-        checkReadAccountsPermission();
-        long identityToken = clearCallingIdentity();
-        try {
-            return getAccountsByType(null);
-        } finally {
-            restoreCallingIdentity(identityToken);
-        }
-    }
-
     public Account[] getAccountsByType(String accountType) {
-        checkReadAccountsPermission();
-        long identityToken = clearCallingIdentity();
-        try {
-            SQLiteDatabase db = mOpenHelper.getReadableDatabase();
+        SQLiteDatabase db = mOpenHelper.getReadableDatabase();
 
-            final String selection = accountType == null ? null : (ACCOUNTS_TYPE + "=?");
-            final String[] selectionArgs = accountType == null ? null : new String[]{accountType};
-            Cursor cursor = db.query(TABLE_ACCOUNTS, ACCOUNT_NAME_TYPE_PROJECTION,
-                    selection, selectionArgs, null, null, null);
-            try {
-                int i = 0;
-                Account[] accounts = new Account[cursor.getCount()];
-                while (cursor.moveToNext()) {
-                    accounts[i] = new Account(cursor.getString(1), cursor.getString(2));
-                    i++;
-                }
-                return accounts;
-            } finally {
-                cursor.close();
+        final String selection = accountType == null ? null : (ACCOUNTS_TYPE + "=?");
+        final String[] selectionArgs = accountType == null ? null : new String[]{accountType};
+        Cursor cursor = db.query(TABLE_ACCOUNTS, ACCOUNT_NAME_TYPE_PROJECTION,
+                selection, selectionArgs, null, null, null);
+        try {
+            int i = 0;
+            Account[] accounts = new Account[cursor.getCount()];
+            while (cursor.moveToNext()) {
+                accounts[i] = new Account(cursor.getString(1), cursor.getString(2));
+                i++;
             }
+            return accounts;
         } finally {
-            restoreCallingIdentity(identityToken);
+            cursor.close();
         }
     }
 
@@ -322,43 +314,47 @@
         // fails if the account already exists
         long identityToken = clearCallingIdentity();
         try {
-            SQLiteDatabase db = mOpenHelper.getWritableDatabase();
-            db.beginTransaction();
-            try {
-                long numMatches = DatabaseUtils.longForQuery(db,
-                        "select count(*) from " + TABLE_ACCOUNTS
-                                + " WHERE " + ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE+ "=?",
-                        new String[]{account.mName, account.mType});
-                if (numMatches > 0) {
-                    return false;
-                }
-                ContentValues values = new ContentValues();
-                values.put(ACCOUNTS_NAME, account.mName);
-                values.put(ACCOUNTS_TYPE, account.mType);
-                values.put(ACCOUNTS_PASSWORD, password);
-                long accountId = db.insert(TABLE_ACCOUNTS, ACCOUNTS_NAME, values);
-                if (accountId < 0) {
-                    return false;
-                }
-                if (extras != null) {
-                    for (String key : extras.keySet()) {
-                        final String value = extras.getString(key);
-                        if (insertExtra(db, accountId, key, value) < 0) {
-                            return false;
-                        }
-                    }
-                }
-                db.setTransactionSuccessful();
-                sendAccountsChangedBroadcast();
-                return true;
-            } finally {
-                db.endTransaction();
-            }
+            return insertAccountIntoDatabase(account, password, extras);
         } finally {
             restoreCallingIdentity(identityToken);
         }
     }
 
+    private boolean insertAccountIntoDatabase(Account account, String password, Bundle extras) {
+        SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+        db.beginTransaction();
+        try {
+            long numMatches = DatabaseUtils.longForQuery(db,
+                    "select count(*) from " + TABLE_ACCOUNTS
+                            + " WHERE " + ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE+ "=?",
+                    new String[]{account.name, account.type});
+            if (numMatches > 0) {
+                return false;
+            }
+            ContentValues values = new ContentValues();
+            values.put(ACCOUNTS_NAME, account.name);
+            values.put(ACCOUNTS_TYPE, account.type);
+            values.put(ACCOUNTS_PASSWORD, password);
+            long accountId = db.insert(TABLE_ACCOUNTS, ACCOUNTS_NAME, values);
+            if (accountId < 0) {
+                return false;
+            }
+            if (extras != null) {
+                for (String key : extras.keySet()) {
+                    final String value = extras.getString(key);
+                    if (insertExtra(db, accountId, key, value) < 0) {
+                        return false;
+                    }
+                }
+            }
+            db.setTransactionSuccessful();
+            sendAccountsChangedBroadcast();
+            return true;
+        } finally {
+            db.endTransaction();
+        }
+    }
+
     private long insertExtra(SQLiteDatabase db, long accountId, String key, String value) {
         ContentValues values = new ContentValues();
         values.put(EXTRAS_KEY, key);
@@ -367,19 +363,61 @@
         return db.insert(TABLE_EXTRAS, EXTRAS_KEY, values);
     }
 
-    public void removeAccount(Account account) {
+    public void removeAccount(IAccountManagerResponse response, Account account) {
         checkManageAccountsPermission();
         long identityToken = clearCallingIdentity();
         try {
-            final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
-            db.delete(TABLE_ACCOUNTS, ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE+ "=?",
-                    new String[]{account.mName, account.mType});
-            sendAccountsChangedBroadcast();
+            new RemoveAccountSession(response, account).bind();
         } finally {
             restoreCallingIdentity(identityToken);
         }
     }
 
+    private class RemoveAccountSession extends Session {
+        final Account mAccount;
+        public RemoveAccountSession(IAccountManagerResponse response, Account account) {
+            super(response, account.type, false /* expectActivityLaunch */);
+            mAccount = account;
+        }
+
+        protected String toDebugString(long now) {
+            return super.toDebugString(now) + ", removeAccount"
+                    + ", account " + mAccount;
+        }
+
+        public void run() throws RemoteException {
+            mAuthenticator.getAccountRemovalAllowed(this, mAccount);
+        }
+
+        public void onResult(Bundle result) {
+            if (result != null && result.containsKey(Constants.BOOLEAN_RESULT_KEY)
+                    && !result.containsKey(Constants.INTENT_KEY)) {
+                final boolean removalAllowed = result.getBoolean(Constants.BOOLEAN_RESULT_KEY);
+                if (removalAllowed) {
+                    removeAccount(mAccount);
+                }
+                IAccountManagerResponse response = getResponseAndClose();
+                if (response != null) {
+                    Bundle result2 = new Bundle();
+                    result2.putBoolean(Constants.BOOLEAN_RESULT_KEY, removalAllowed);
+                    try {
+                        response.onResult(result2);
+                    } catch (RemoteException e) {
+                        // ignore
+                    }
+                }
+            }
+            super.onResult(result);
+        }
+    }
+
+    private void removeAccount(Account account) {
+        final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+        db.delete(TABLE_ACCOUNTS, ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE+ "=?",
+                new String[]{account.name, account.type});
+        sendAccountsChangedBroadcast();
+    }
+
     public void invalidateAuthToken(String accountType, String authToken) {
         checkManageAccountsPermission();
         long identityToken = clearCallingIdentity();
@@ -398,6 +436,9 @@
     }
 
     private void invalidateAuthToken(SQLiteDatabase db, String accountType, String authToken) {
+        if (authToken == null || accountType == null) {
+            return;
+        }
         Cursor cursor = db.rawQuery(
                 "SELECT " + TABLE_AUTHTOKENS + "." + AUTHTOKENS_ID
                         + ", " + TABLE_ACCOUNTS + "." + ACCOUNTS_NAME
@@ -488,7 +529,7 @@
             values.put(ACCOUNTS_PASSWORD, password);
             mOpenHelper.getWritableDatabase().update(TABLE_ACCOUNTS, values,
                     ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE+ "=?",
-                    new String[]{account.mName, account.mType});
+                    new String[]{account.name, account.type});
             sendAccountsChangedBroadcast();
         } finally {
             restoreCallingIdentity(identityToken);
@@ -509,40 +550,58 @@
         }
     }
 
+    private void sendResult(IAccountManagerResponse response, Bundle bundle) {
+        if (response != null) {
+            try {
+                response.onResult(bundle);
+            } catch (RemoteException e) {
+                // if the caller is dead then there is no one to care about remote
+                // exceptions
+                if (Log.isLoggable(TAG, Log.VERBOSE)) {
+                    Log.v(TAG, "failure while notifying response", e);
+                }
+            }
+        }
+    }
+
     public void setUserData(Account account, String key, String value) {
         checkAuthenticateAccountsPermission(account);
         long identityToken = clearCallingIdentity();
         try {
-            SQLiteDatabase db = mOpenHelper.getWritableDatabase();
-            db.beginTransaction();
-            try {
-                long accountId = getAccountId(db, account);
-                if (accountId < 0) {
-                    return;
-                }
-                long extrasId = getExtrasId(db, accountId, key);
-                if (extrasId < 0 ) {
-                    extrasId = insertExtra(db, accountId, key, value);
-                    if (extrasId < 0) {
-                        return;
-                    }
-                } else {
-                    ContentValues values = new ContentValues();
-                    values.put(EXTRAS_VALUE, value);
-                    if (1 != db.update(TABLE_EXTRAS, values, EXTRAS_ID + "=" + extrasId, null)) {
-                        return;
-                    }
-
-                }
-                db.setTransactionSuccessful();
-            } finally {
-                db.endTransaction();
-            }
+            writeUserdataIntoDatabase(account, key, value);
         } finally {
             restoreCallingIdentity(identityToken);
         }
     }
 
+    private void writeUserdataIntoDatabase(Account account, String key, String value) {
+        SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+        db.beginTransaction();
+        try {
+            long accountId = getAccountId(db, account);
+            if (accountId < 0) {
+                return;
+            }
+            long extrasId = getExtrasId(db, accountId, key);
+            if (extrasId < 0 ) {
+                extrasId = insertExtra(db, accountId, key, value);
+                if (extrasId < 0) {
+                    return;
+                }
+            } else {
+                ContentValues values = new ContentValues();
+                values.put(EXTRAS_VALUE, value);
+                if (1 != db.update(TABLE_EXTRAS, values, EXTRAS_ID + "=" + extrasId, null)) {
+                    return;
+                }
+
+            }
+            db.setTransactionSuccessful();
+        } finally {
+            db.endTransaction();
+        }
+    }
+
     private void onResult(IAccountManagerResponse response, Bundle result) {
         try {
             response.onResult(result);
@@ -571,14 +630,14 @@
                 if (authToken != null) {
                     Bundle result = new Bundle();
                     result.putString(Constants.AUTHTOKEN_KEY, authToken);
-                    result.putString(Constants.ACCOUNT_NAME_KEY, account.mName);
-                    result.putString(Constants.ACCOUNT_TYPE_KEY, account.mType);
+                    result.putString(Constants.ACCOUNT_NAME_KEY, account.name);
+                    result.putString(Constants.ACCOUNT_TYPE_KEY, account.type);
                     onResult(response, result);
                     return;
                 }
             }
 
-            new Session(response, account.mType, expectActivityLaunch) {
+            new Session(response, account.type, expectActivityLaunch) {
                 protected String toDebugString(long now) {
                     if (loginOptions != null) loginOptions.keySet();
                     return super.toDebugString(now) + ", getAuthToken"
@@ -651,7 +710,7 @@
                 mContext.getText(R.string.permission_request_notification_subtitle);
         n.setLatestEventInfo(mContext,
                 mContext.getText(R.string.permission_request_notification_title),
-                String.format(subtitleFormatString.toString(), account.mName),
+                String.format(subtitleFormatString.toString(), account.name),
                 PendingIntent.getActivity(mContext, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT));
         ((NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE))
                 .notify(getCredentialPermissionNotificationId(account, authTokenType, uid), n);
@@ -661,9 +720,9 @@
             AccountAuthenticatorResponse response, String authTokenType, String authTokenLabel) {
         RegisteredServicesCache.ServiceInfo<AuthenticatorDescription> serviceInfo =
                 mAuthenticatorCache.getServiceInfo(
-                        AuthenticatorDescription.newKey(account.mType));
+                        AuthenticatorDescription.newKey(account.type));
         if (serviceInfo == null) {
-            throw new IllegalArgumentException("unknown account type: " + account.mType);
+            throw new IllegalArgumentException("unknown account type: " + account.type);
         }
 
         final Context authContext;
@@ -671,7 +730,7 @@
             authContext = mContext.createPackageContext(
                 serviceInfo.type.packageName, 0);
         } catch (PackageManager.NameNotFoundException e) {
-            throw new IllegalArgumentException("unknown account type: " + account.mType);
+            throw new IllegalArgumentException("unknown account type: " + account.type);
         }
 
         Intent intent = new Intent(mContext, GrantCredentialsPermissionActivity.class);
@@ -750,7 +809,7 @@
         checkManageAccountsPermission();
         long identityToken = clearCallingIdentity();
         try {
-            new Session(response, account.mType, expectActivityLaunch) {
+            new Session(response, account.type, expectActivityLaunch) {
                 public void run() throws RemoteException {
                     mAuthenticator.confirmCredentials(this, account);
                 }
@@ -769,7 +828,7 @@
         checkManageAccountsPermission();
         long identityToken = clearCallingIdentity();
         try {
-            new Session(response, account.mType, false /* expectActivityLaunch */) {
+            new Session(response, account.type, false /* expectActivityLaunch */) {
                 public void run() throws RemoteException {
                     mAuthenticator.confirmPassword(this, account, password);
                 }
@@ -789,7 +848,7 @@
         checkManageAccountsPermission();
         long identityToken = clearCallingIdentity();
         try {
-            new Session(response, account.mType, expectActivityLaunch) {
+            new Session(response, account.type, expectActivityLaunch) {
                 public void run() throws RemoteException {
                     mAuthenticator.updateCredentials(this, account, authTokenType, loginOptions);
                 }
@@ -898,10 +957,21 @@
                     + ", " + (mFeatures != null ? TextUtils.join(",", mFeatures) : null);
         }
     }
-    public void getAccountsByTypeAndFeatures(IAccountManagerResponse response,
+
+    public Account[] getAccounts(String type) {
+        checkReadAccountsPermission();
+        long identityToken = clearCallingIdentity();
+        try {
+            return getAccountsByType(type);
+        } finally {
+            restoreCallingIdentity(identityToken);
+        }
+    }
+
+    public void getAccountsByFeatures(IAccountManagerResponse response,
             String type, String[] features) {
         checkReadAccountsPermission();
-        if (type == null) {
+        if (features != null && type == null) {
             if (response != null) {
                 try {
                     response.onError(Constants.ERROR_CODE_BAD_ARGUMENTS, "type is null");
@@ -913,6 +983,10 @@
         }
         long identityToken = clearCallingIdentity();
         try {
+            if (features == null || features.length == 0) {
+                getAccountsByType(type);
+                return;
+            }
             new GetAccountsByTypeAndFeatureSession(response, type, features).bind();
         } finally {
             restoreCallingIdentity(identityToken);
@@ -925,7 +999,7 @@
 
     private long getAccountId(SQLiteDatabase db, Account account) {
         Cursor cursor = db.query(TABLE_ACCOUNTS, new String[]{ACCOUNTS_ID},
-                "name=? AND type=?", new String[]{account.mName, account.mType}, null, null, null);
+                "name=? AND type=?", new String[]{account.name, account.type}, null, null, null);
         try {
             if (cursor.moveToNext()) {
                 return cursor.getLong(0);
@@ -1401,7 +1475,7 @@
     }
 
     private boolean permissionIsGranted(Account account, String authTokenType, int callerUid) {
-        final boolean fromAuthenticator = hasAuthenticatorUid(account.mType, callerUid);
+        final boolean fromAuthenticator = hasAuthenticatorUid(account.type, callerUid);
         final boolean hasExplicitGrants = hasExplicitlyGrantedPermission(account, authTokenType);
         if (Log.isLoggable(TAG, Log.VERBOSE)) {
             Log.v(TAG, "checkGrantsOrCallingUidAgainstAuthenticator: caller uid "
@@ -1416,7 +1490,9 @@
         for (RegisteredServicesCache.ServiceInfo<AuthenticatorDescription> serviceInfo :
                 mAuthenticatorCache.getAllServices()) {
             if (serviceInfo.type.type.equals(accountType)) {
-                return serviceInfo.uid == callingUid;
+                return (serviceInfo.uid == callingUid) ||
+                        (mContext.getPackageManager().checkSignatures(serviceInfo.uid, callingUid)
+                                == PackageManager.SIGNATURE_MATCH);
             }
         }
         return false;
@@ -1428,7 +1504,7 @@
         }
         SQLiteDatabase db = mOpenHelper.getReadableDatabase();
         String[] args = {String.valueOf(Binder.getCallingUid()), authTokenType,
-                account.mName, account.mType};
+                account.name, account.type};
         final boolean permissionGranted =
                 DatabaseUtils.longForQuery(db, COUNT_OF_MATCHING_GRANTS, args) != 0;
         if (!permissionGranted && isDebuggableMonkeyBuild) {
@@ -1444,7 +1520,7 @@
 
     private void checkCallingUidAgainstAuthenticator(Account account) {
         final int uid = Binder.getCallingUid();
-        if (!hasAuthenticatorUid(account.mType, uid)) {
+        if (!hasAuthenticatorUid(account.type, uid)) {
             String msg = "caller uid " + uid + " is different than the authenticator's uid";
             Log.w(TAG, msg);
             throw new SecurityException(msg);
diff --git a/core/java/android/accounts/ChooseAccountActivity.java b/core/java/android/accounts/ChooseAccountActivity.java
index 83377f3..bd6f205 100644
--- a/core/java/android/accounts/ChooseAccountActivity.java
+++ b/core/java/android/accounts/ChooseAccountActivity.java
@@ -45,7 +45,7 @@
 
         String[] mAccountNames = new String[mAccounts.length];
         for (int i = 0; i < mAccounts.length; i++) {
-            mAccountNames[i] = ((Account) mAccounts[i]).mName;
+            mAccountNames[i] = ((Account) mAccounts[i]).name;
         }
 
         // Use an existing ListAdapter that will map an array
@@ -59,8 +59,8 @@
         Account account = (Account) mAccounts[position];
         Log.d(TAG, "selected account " + account);
         Bundle bundle = new Bundle();
-        bundle.putString(Constants.ACCOUNT_NAME_KEY, account.mName);
-        bundle.putString(Constants.ACCOUNT_TYPE_KEY, account.mType);
+        bundle.putString(Constants.ACCOUNT_NAME_KEY, account.name);
+        bundle.putString(Constants.ACCOUNT_TYPE_KEY, account.type);
         mResult = bundle;
         finish();
     }
diff --git a/core/java/android/accounts/Constants.java b/core/java/android/accounts/Constants.java
index da8173f..8736f41 100644
--- a/core/java/android/accounts/Constants.java
+++ b/core/java/android/accounts/Constants.java
@@ -31,6 +31,7 @@
     public static final String AUTHENTICATOR_TYPES_KEY = "authenticator_types";
     public static final String USERDATA_KEY = "userdata";
     public static final String AUTHTOKEN_KEY = "authtoken";
+    public static final String PASSWORD_KEY = "password";
     public static final String ACCOUNT_NAME_KEY = "authAccount";
     public static final String ACCOUNT_TYPE_KEY = "accountType";
     public static final String ERROR_CODE_KEY = "errorCode";
diff --git a/core/java/android/accounts/Future1.java b/core/java/android/accounts/Future1.java
deleted file mode 100644
index 386cb6e..0000000
--- a/core/java/android/accounts/Future1.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.accounts;
-
-import java.util.concurrent.Future;
-import java.util.concurrent.TimeUnit;
-
-/**
- * An extension of {@link Future} that provides wrappers for {@link #get()} that handle the various
- * exceptions that  {@link #get()} may return and rethrows them as exceptions specific to
- * {@link AccountManager}.
- */
-public interface Future1<V> extends Future<V> {
-    /**
-     * Wrapper for {@link Future#get()}. If the get() throws {@link InterruptedException} then the
-     * {@link Future1} is canceled and {@link OperationCanceledException} is thrown.
-     * @return the {@link android.os.Bundle} that is returned by get()
-     * @throws OperationCanceledException if get() throws the unchecked CancellationException
-     * or if the Future was interrupted.
-     */
-    V getResult() throws OperationCanceledException;
-
-    /**
-     * Wrapper for {@link Future#get()}. If the get() throws {@link InterruptedException} then the
-     * {@link Future1} is canceled and {@link OperationCanceledException} is thrown.
-     * @param timeout the maximum time to wait
-     * @param unit the time unit of the timeout argument
-     * @return the {@link android.os.Bundle} that is returned by {@link Future#get()}
-     * @throws OperationCanceledException if get() throws the unchecked
-     * {@link java.util.concurrent.CancellationException} or if the {@link Future1} was interrupted.
-     */
-    V getResult(long timeout, TimeUnit unit) throws OperationCanceledException;
-}
\ No newline at end of file
diff --git a/core/java/android/accounts/Future1Callback.java b/core/java/android/accounts/Future1Callback.java
deleted file mode 100644
index 886671b..0000000
--- a/core/java/android/accounts/Future1Callback.java
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.accounts;
-
-public interface Future1Callback<V> {
-    void run(Future1<V> future);
-}
diff --git a/core/java/android/accounts/Future2.java b/core/java/android/accounts/Future2.java
deleted file mode 100644
index b2ea84f..0000000
--- a/core/java/android/accounts/Future2.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.accounts;
-
-import android.os.Bundle;
-
-import java.io.IOException;
-import java.util.concurrent.Future;
-import java.util.concurrent.TimeUnit;
-
-/**
- * An extension of {@link Future} that provides wrappers for {@link #get()} that handle the various
- * exceptions that  {@link #get()} may return and rethrows them as exceptions specific to
- * {@link AccountManager}.
- */
-public interface Future2 extends Future<Bundle> {
-    /**
-     * Wrapper for {@link Future#get()}. If the get() throws {@link InterruptedException} then the
-     * {@link Future2} is canceled and {@link OperationCanceledException} is thrown.
-     * @return the {@link android.os.Bundle} that is returned by {@link Future#get()}
-     * @throws OperationCanceledException if get() throws the unchecked
-     * {@link java.util.concurrent.CancellationException} or if the {@link Future2} was interrupted.
-     * @throws IOException if the request was unable to complete due to a network error
-     * @throws AuthenticatorException if there was an error communicating with the
-     * {@link AbstractAccountAuthenticator}.
-     */
-    Bundle getResult()
-            throws OperationCanceledException, IOException, AuthenticatorException;
-
-    /**
-     * Wrapper for {@link Future#get()}. If the get() throws {@link InterruptedException} then the
-     * {@link Future2} is canceled and {@link OperationCanceledException} is thrown.
-     * @param timeout the maximum time to wait
-     * @param unit the time unit of the timeout argument
-     * @return the {@link android.os.Bundle} that is returned by {@link Future#get()}
-     * @throws OperationCanceledException if get() throws the unchecked
-     * {@link java.util.concurrent.CancellationException} or if the {@link Future2} was interrupted.
-     * @throws IOException if the request was unable to complete due to a network error
-     * @throws AuthenticatorException if there was an error communicating with the
-     * {@link AbstractAccountAuthenticator}.
-     */
-    Bundle getResult(long timeout, TimeUnit unit)
-            throws OperationCanceledException, IOException, AuthenticatorException;
-}
diff --git a/core/java/android/accounts/GrantCredentialsPermissionActivity.java b/core/java/android/accounts/GrantCredentialsPermissionActivity.java
index f92d43f..e06afb4 100644
--- a/core/java/android/accounts/GrantCredentialsPermissionActivity.java
+++ b/core/java/android/accounts/GrantCredentialsPermissionActivity.java
@@ -63,12 +63,12 @@
             CharSequence grantCredentialsPermissionFormat = getResources().getText(
                     R.string.grant_credentials_permission_message_desc);
             messageView.setText(String.format(grantCredentialsPermissionFormat.toString(),
-                    mAccount.mName, accountTypeLabel));
+                    mAccount.name, accountTypeLabel));
         } else {
             CharSequence grantCredentialsPermissionFormat = getResources().getText(
                     R.string.grant_credentials_permission_message_with_authtokenlabel_desc);
             messageView.setText(String.format(grantCredentialsPermissionFormat.toString(),
-                    authTokenLabel, mAccount.mName, accountTypeLabel));
+                    authTokenLabel, mAccount.name, accountTypeLabel));
         }
 
         String[] packageLabels = new String[packages.length];
diff --git a/core/java/android/accounts/IAccountAuthenticator.aidl b/core/java/android/accounts/IAccountAuthenticator.aidl
index 7d4de39..48f053c 100644
--- a/core/java/android/accounts/IAccountAuthenticator.aidl
+++ b/core/java/android/accounts/IAccountAuthenticator.aidl
@@ -70,4 +70,9 @@
      */
     void hasFeatures(in IAccountAuthenticatorResponse response, in Account account, 
         in String[] features);
+
+    /**
+     * Gets whether or not the account is allowed to be removed.
+     */
+    void getAccountRemovalAllowed(in IAccountAuthenticatorResponse response, in Account account);
 }
diff --git a/core/java/android/accounts/IAccountManager.aidl b/core/java/android/accounts/IAccountManager.aidl
index 15ab4e8..411952b 100644
--- a/core/java/android/accounts/IAccountManager.aidl
+++ b/core/java/android/accounts/IAccountManager.aidl
@@ -21,6 +21,7 @@
 import android.accounts.AuthenticatorDescription;
 import android.os.Bundle;
 
+
 /**
  * Central application service that provides account management.
  * @hide
@@ -29,10 +30,10 @@
     String getPassword(in Account account);
     String getUserData(in Account account, String key);
     AuthenticatorDescription[] getAuthenticatorTypes();
-    Account[] getAccounts();
-    Account[] getAccountsByType(String accountType);
+    Account[] getAccounts(String accountType);
+    void getAccountsByFeatures(in IAccountManagerResponse response, String accountType, in String[] features);
     boolean addAccount(in Account account, String password, in Bundle extras);
-    void removeAccount(in Account account);
+    void removeAccount(in IAccountManagerResponse response, in Account account);
     void invalidateAuthToken(String accountType, String authToken);
     String peekAuthToken(in Account account, String authTokenType);
     void setAuthToken(in Account account, String authTokenType, String authToken);
@@ -52,8 +53,6 @@
         boolean expectActivityLaunch);
     void confirmCredentials(in IAccountManagerResponse response, in Account account,
         boolean expectActivityLaunch);
-    void getAccountsByTypeAndFeatures(in IAccountManagerResponse response, String accountType,
-        in String[] features);
 
     /*
      * @deprecated
diff --git a/core/java/android/content/AbstractSyncableContentProvider.java b/core/java/android/content/AbstractSyncableContentProvider.java
index 218f501..808f30c 100644
--- a/core/java/android/content/AbstractSyncableContentProvider.java
+++ b/core/java/android/content/AbstractSyncableContentProvider.java
@@ -170,7 +170,7 @@
                         // AbstractGDataSyncAdapter, which will put acore into a crash loop
                         ArrayList<Account> gaiaAccounts = new ArrayList<Account>();
                         for (Account acct: accounts) {
-                            if (acct.mType.equals("com.google.GAIA")) {
+                            if (acct.type.equals("com.google.GAIA")) {
                                 gaiaAccounts.add(acct);
                             }
                         }
@@ -693,7 +693,7 @@
                 if (!accounts.containsKey(account)) {
                     int numDeleted;
                     numDeleted = db.delete(table, "_sync_account=? AND _sync_account_type=?",
-                            new String[]{account.mName, account.mType});
+                            new String[]{account.name, account.type});
                     if (Config.LOGV) {
                         Log.v(TAG, "deleted " + numDeleted
                                 + " records from table " + table
@@ -726,7 +726,7 @@
             // remove the data in the synced tables
             for (String table : tables) {
                 db.delete(table, SYNC_ACCOUNT_WHERE_CLAUSE,
-                        new String[]{account.mName, account.mType});
+                        new String[]{account.name, account.type});
             }
             db.setTransactionSuccessful();
         } finally {
diff --git a/core/java/android/content/AbstractTableMerger.java b/core/java/android/content/AbstractTableMerger.java
index a3daa01e..9545fd7f 100644
--- a/core/java/android/content/AbstractTableMerger.java
+++ b/core/java/android/content/AbstractTableMerger.java
@@ -174,7 +174,7 @@
         Cursor diffsCursor = null;
         try {
             // load the local database entries, so we can merge them with the server
-            final String[] accountSelectionArgs = new String[]{account.mName, account.mType};
+            final String[] accountSelectionArgs = new String[]{account.name, account.type};
             localCursor = mDb.query(mTable, syncDirtyProjection,
                     SELECT_MARKED, accountSelectionArgs, null, null,
                     mTable + "." + _SYNC_ID);
@@ -487,7 +487,7 @@
         try {
             if (deleteBySyncId) {
                 selectionArgs = new String[]{diffsCursor.getString(serverSyncIdColumn),
-                        account.mName, account.mType};
+                        account.name, account.type};
                 c = mDb.query(mTable, new String[]{BaseColumns._ID}, SELECT_BY_SYNC_ID_AND_ACCOUNT,
                         selectionArgs, null, null, null);
             } else {
@@ -534,7 +534,7 @@
         SyncableContentProvider clientDiffs = mergeResult.tempContentProvider;
         if (Log.isLoggable(TAG, Log.VERBOSE)) Log.v(TAG, "generating client updates");
 
-        final String[] accountSelectionArgs = new String[]{account.mName, account.mType};
+        final String[] accountSelectionArgs = new String[]{account.name, account.type};
 
         // Generate the client updates and insertions
         // Create a cursor for dirty records
diff --git a/core/java/android/content/SyncManager.java b/core/java/android/content/SyncManager.java
index d54e260..f256394 100644
--- a/core/java/android/content/SyncManager.java
+++ b/core/java/android/content/SyncManager.java
@@ -596,7 +596,7 @@
 
         for (String authority : syncableAuthorities) {
             for (Account account : accounts) {
-                if (mSyncAdapters.getServiceInfo(new SyncAdapterType(authority, account.mType))
+                if (mSyncAdapters.getServiceInfo(new SyncAdapterType(authority, account.type))
                         != null) {
                     scheduleSyncOperation(
                             new SyncOperation(account, source, authority, extras, delay));
@@ -1094,8 +1094,8 @@
             for (int i=0; i<N; i++) {
                 SyncStorageEngine.PendingOperation op = ops.get(i);
                 pw.print("  #"); pw.print(i); pw.print(": account=");
-                pw.print(op.account.mName); pw.print(":");
-                pw.print(op.account.mType); pw.print(" authority=");
+                pw.print(op.account.name); pw.print(":");
+                pw.print(op.account.type); pw.print(" authority=");
                 pw.println(op.authority);
                 if (op.extras != null && op.extras.size() > 0) {
                     sb.setLength(0);
@@ -1125,8 +1125,8 @@
                     
                     processedAccounts.add(curAccount);
                     
-                    pw.print("  Account "); pw.print(authority.account.mName);
-                            pw.print(" "); pw.print(authority.account.mType);
+                    pw.print("  Account "); pw.print(authority.account.name);
+                            pw.print(" "); pw.print(authority.account.type);
                             pw.println(":");
                     for (int j=i; j<N; j++) {
                         status = statuses.get(j);
@@ -1248,9 +1248,9 @@
                         = mSyncStorageEngine.getAuthority(item.authorityId);
                 pw.print("  #"); pw.print(i+1); pw.print(": ");
                         if (authority != null) {
-                            pw.print(authority.account.mName);
+                            pw.print(authority.account.name);
                             pw.print(":");
-                            pw.print(authority.account.mType);
+                            pw.print(authority.account.type);
                             pw.print(" ");
                             pw.print(authority.authority);
                         } else {
@@ -1636,7 +1636,7 @@
 
             // connect to the sync adapter
             SyncAdapterType syncAdapterType = new SyncAdapterType(op.authority,
-                    op.account.mType);
+                    op.account.type);
             RegisteredServicesCache.ServiceInfo<SyncAdapterType> syncAdapterInfo =
                     mSyncAdapters.getServiceInfo(syncAdapterType);
             if (syncAdapterInfo == null) {
diff --git a/core/java/android/content/SyncStateContentProviderHelper.java b/core/java/android/content/SyncStateContentProviderHelper.java
index dc728ec..64bbe25 100644
--- a/core/java/android/content/SyncStateContentProviderHelper.java
+++ b/core/java/android/content/SyncStateContentProviderHelper.java
@@ -172,7 +172,7 @@
      */
     public void copySyncState(SQLiteDatabase dbSrc, SQLiteDatabase dbDest,
             Account account) {
-        final String[] whereArgs = new String[]{account.mName, account.mType};
+        final String[] whereArgs = new String[]{account.name, account.type};
         Cursor c = dbSrc.query(SYNC_STATE_TABLE,
                 new String[]{"_sync_account", "_sync_account_type", "data"},
                 ACCOUNT_WHERE, whereArgs, null, null, null);
@@ -209,7 +209,7 @@
 
     public void discardSyncData(SQLiteDatabase db, Account account) {
         if (account != null) {
-            db.delete(SYNC_STATE_TABLE, ACCOUNT_WHERE, new String[]{account.mName, account.mType});
+            db.delete(SYNC_STATE_TABLE, ACCOUNT_WHERE, new String[]{account.name, account.type});
         } else {
             db.delete(SYNC_STATE_TABLE, null, null);
         }
@@ -220,7 +220,7 @@
      */
     public byte[] readSyncDataBytes(SQLiteDatabase db, Account account) {
         Cursor c = db.query(SYNC_STATE_TABLE, null, ACCOUNT_WHERE,
-                new String[]{account.mName, account.mType}, null, null, null);
+                new String[]{account.name, account.type}, null, null, null);
         try {
             if (c.moveToFirst()) {
                 return c.getBlob(c.getColumnIndexOrThrow("data"));
@@ -238,6 +238,6 @@
         ContentValues values = new ContentValues();
         values.put("data", data);
         db.update(SYNC_STATE_TABLE, values, ACCOUNT_WHERE,
-                new String[]{account.mName, account.mType});
+                new String[]{account.name, account.type});
     }
 }
diff --git a/core/java/android/content/SyncStorageEngine.java b/core/java/android/content/SyncStorageEngine.java
index 8cc0642..b3f9bbb 100644
--- a/core/java/android/content/SyncStorageEngine.java
+++ b/core/java/android/content/SyncStorageEngine.java
@@ -1127,8 +1127,8 @@
                 AuthorityInfo authority = mAuthorities.get(i);
                 out.startTag(null, "authority");
                 out.attribute(null, "id", Integer.toString(authority.ident));
-                out.attribute(null, "account", authority.account.mName);
-                out.attribute(null, "type", authority.account.mType);
+                out.attribute(null, "account", authority.account.name);
+                out.attribute(null, "type", authority.account.type);
                 out.attribute(null, "authority", authority.authority);
                 if (!authority.enabled) {
                     out.attribute(null, "enabled", "false");
diff --git a/core/java/android/provider/Calendar.java b/core/java/android/provider/Calendar.java
index 489d936..fab3f3d 100644
--- a/core/java/android/provider/Calendar.java
+++ b/core/java/android/provider/Calendar.java
@@ -174,7 +174,7 @@
             return Calendar.Calendars.delete(cr,
                     Calendar.Calendars._SYNC_ACCOUNT + "=? AND "
                             + Calendar.Calendars._SYNC_ACCOUNT_TYPE + "=?",
-                    new String[] {account.mName, account.mType});
+                    new String[] {account.name, account.type});
         }
 
         /**
diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java
index 7a1a9e4..11cb87f 100644
--- a/core/java/android/provider/ContactsContract.java
+++ b/core/java/android/provider/ContactsContract.java
@@ -1360,6 +1360,14 @@
          * <P>Type: INTEGER</P>
          */
         public static final String DELETED = "deleted";
+
+        /**
+         * Whether this group should be synced if the SYNC_EVERYTHING settings
+         * is false for this group's account.
+         * <p>
+         * Type: INTEGER (boolean)
+         */
+        public static final String SHOULD_SYNC = "should_sync";
     }
 
     /**
diff --git a/core/java/android/provider/Im.java b/core/java/android/provider/Im.java
index b11abe8..b1cf648 100644
--- a/core/java/android/provider/Im.java
+++ b/core/java/android/provider/Im.java
@@ -1620,6 +1620,9 @@
         /** specifies the last heartbeat interval received from the server */
         public static final String SETTING_HEARTBEAT_INTERVAL = "heartbeat_interval";
 
+        /** specifiy the JID resource used for Google Talk connection */
+        public static final String SETTING_JID_RESOURCE = "jid_resource";
+
         /**
          * Used for reliable message queue (RMQ). This is for storing the last rmq id received
          * from the GTalk server
@@ -1861,6 +1864,14 @@
             putLongValue(contentResolver, providerId, SETTING_HEARTBEAT_INTERVAL, interval);
         }
 
+        /**
+         * A convenience method to set the jid resource.
+         */
+        public static void setJidResource(ContentResolver contentResolver,
+                                          long providerId, String jidResource) {
+            putStringValue(contentResolver, providerId, SETTING_JID_RESOURCE, jidResource);
+        }
+
         public static class QueryMap extends ContentQueryMap {
             private ContentResolver mContentResolver;
             private long mProviderId;
@@ -2047,6 +2058,23 @@
             }
 
             /**
+             * Set the JID resource.
+             *
+             * @param jidResource the jid resource to be stored.
+             */
+            public void setJidResource(String jidResource) {
+                ProviderSettings.setJidResource(mContentResolver, mProviderId, jidResource);
+            }
+            /**
+             * Get the JID resource used for the Google Talk connection
+             *
+             * @return the JID resource stored.
+             */
+            public String getJidResource() {
+                return getString(SETTING_JID_RESOURCE, null);
+            }
+
+            /**
              * Convenience function for retrieving a single settings value
              * as a boolean.
              *
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 85a2041..d3e4c4c 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -413,8 +413,6 @@
 
     private static final String TAG = "Settings";
 
-    private static String sJidResource = null;
-
     public static class SettingNotFoundException extends AndroidException {
         public SettingNotFoundException(String msg) {
             super(msg);
@@ -3622,42 +3620,6 @@
     }
 
     /**
-     * Returns the GTalk JID resource associated with this device.
-     *
-     * @return  String  the JID resource of the device. It uses the device IMEI in the computation
-     * of the JID resource. If IMEI is not ready (i.e. telephony module not ready), we'll return
-     * an empty string.
-     * @hide
-     */
-    // TODO: we shouldn't not have a permenant Jid resource, as that's an easy target for
-    // spams. We should change it once a while, like when we resubscribe to the subscription feeds
-    // server.
-    // (also, should this live in GTalkService?)
-    public static synchronized String getJidResource() {
-        if (sJidResource != null) {
-            return sJidResource;
-        }
-
-        MessageDigest digest;
-        try {
-            digest = MessageDigest.getInstance("SHA-1");
-        } catch (NoSuchAlgorithmException e) {
-            throw new RuntimeException("this should never happen");
-        }
-
-        String deviceId = TelephonyManager.getDefault().getDeviceId();
-        if (TextUtils.isEmpty(deviceId)) {
-            return "";
-        }
-
-        byte[] hashedDeviceId = digest.digest(deviceId.getBytes());
-        String id = new String(Base64.encodeBase64(hashedDeviceId), 0, 12);
-        id = id.replaceAll("/", "_");
-        sJidResource = JID_RESOURCE_PREFIX + id;
-        return sJidResource;
-    }
-
-    /**
      * Returns the device ID that we should use when connecting to the mobile gtalk server.
      * This is a string like "android-0x1242", where the hex string is the Android ID obtained
      * from the GoogleLoginService.
diff --git a/core/java/android/provider/SubscribedFeeds.java b/core/java/android/provider/SubscribedFeeds.java
index f94b442..8e9f402 100644
--- a/core/java/android/provider/SubscribedFeeds.java
+++ b/core/java/android/provider/SubscribedFeeds.java
@@ -119,8 +119,8 @@
             String authority, String service) {
         ContentValues values = new ContentValues();
         values.put(SubscribedFeeds.Feeds.FEED, feed);
-        values.put(SubscribedFeeds.Feeds._SYNC_ACCOUNT, account.mName);
-        values.put(SubscribedFeeds.Feeds._SYNC_ACCOUNT_TYPE, account.mType);
+        values.put(SubscribedFeeds.Feeds._SYNC_ACCOUNT, account.name);
+        values.put(SubscribedFeeds.Feeds._SYNC_ACCOUNT_TYPE, account.type);
         values.put(SubscribedFeeds.Feeds.AUTHORITY, authority);
         values.put(SubscribedFeeds.Feeds.SERVICE, service);
         return resolver.insert(SubscribedFeeds.Feeds.CONTENT_URI, values);
@@ -134,7 +134,7 @@
         where.append(" AND " + SubscribedFeeds.Feeds.FEED + "=?");
         where.append(" AND " + SubscribedFeeds.Feeds.AUTHORITY + "=?");
         return resolver.delete(SubscribedFeeds.Feeds.CONTENT_URI,
-                where.toString(), new String[] {account.mName, account.mType, feed, authority});
+                where.toString(), new String[] {account.name, account.type, feed, authority});
     }
 
     public static int deleteFeeds(ContentResolver resolver,
@@ -144,7 +144,7 @@
         where.append(" AND " + SubscribedFeeds.Feeds._SYNC_ACCOUNT_TYPE + "=?");
         where.append(" AND " + SubscribedFeeds.Feeds.AUTHORITY + "=?");
         return resolver.delete(SubscribedFeeds.Feeds.CONTENT_URI,
-                where.toString(), new String[] {account.mName, account.mType, authority});
+                where.toString(), new String[] {account.name, account.type, authority});
     }
 
     /**
diff --git a/core/java/android/provider/SyncStateContract.java b/core/java/android/provider/SyncStateContract.java
index 7927e28..5c93af0 100644
--- a/core/java/android/provider/SyncStateContract.java
+++ b/core/java/android/provider/SyncStateContract.java
@@ -71,7 +71,7 @@
         public static byte[] get(ContentProviderClient provider, Uri uri,
                 Account account) throws RemoteException {
             Cursor c = provider.query(uri, DATA_PROJECTION, SELECT_BY_ACCOUNT,
-                    new String[]{account.mName, account.mType}, null);
+                    new String[]{account.name, account.type}, null);
             try {
                 if (c.moveToNext()) {
                     return c.getBlob(c.getColumnIndexOrThrow(Columns.DATA));
@@ -96,8 +96,8 @@
                 Account account, byte[] data) throws RemoteException {
             ContentValues values = new ContentValues();
             values.put(Columns.DATA, data);
-            values.put(Columns.ACCOUNT_NAME, account.mName);
-            values.put(Columns.ACCOUNT_TYPE, account.mType);
+            values.put(Columns.ACCOUNT_NAME, account.name);
+            values.put(Columns.ACCOUNT_TYPE, account.type);
             provider.insert(uri, values);
         }
 
@@ -116,8 +116,8 @@
             values.put(Columns.DATA, data);
             return ContentProviderOperation
                     .newInsert(uri)
-                    .withValue(Columns.ACCOUNT_NAME, account.mName)
-                    .withValue(Columns.ACCOUNT_TYPE, account.mType)
+                    .withValue(Columns.ACCOUNT_NAME, account.name)
+                    .withValue(Columns.ACCOUNT_TYPE, account.type)
                     .withValues(values)
                     .build();
         }
diff --git a/core/res/res/values-en-rUS/donottranslate-names.xml b/core/res/res/values-en-rUS/donottranslate-names.xml
new file mode 100644
index 0000000..42c8ab4
--- /dev/null
+++ b/core/res/res/values-en-rUS/donottranslate-names.xml
@@ -0,0 +1,155 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    
+    <!-- various string resources for Contacts -->
+    <string-array name="common_nicknames">
+        <item>Albert, Al, Bert, Bertie</item>
+        <item>Alexander, Al, Alex, Lex, Sasha</item>
+        <item>Alexandra, Al, Alex, Allie, Ally, Lex, Lexie, Sandra, Sandy, Sasha</item>
+        <item>Alice, Allie, Ally</item>
+        <item>Alison, Allie, Ally</item>
+        <item>Allison, Allie, Ally</item>
+        <item>Amanda, Mandi, Mandy</item>
+        <item>Andrea, Andie</item>
+        <item>Andrew, Andy, Drew</item>
+        <item>Anthony, Tony, Toni, Tone</item>
+        <item>Arthur, Art, Arty</item>
+        <item>Barbara, Babs, Barb, Barbie</item>
+        <item>Benjamin, Ben, Benji, Benny</item>
+        <item>Bernard, Bern, Bernie</item>
+        <item>Bertram, Bert, Bertie</item>
+        <item>Bradly, Brad</item>
+        <item>Catherine, Cat, Cate, Cath, Catie, Cathy, Kat, Kate, Katie, Kathy</item>
+        <item>Charles, Chuck, Chaz, Charlie, Buck</item>
+        <item>Christine, Chris, Chrissy, Chrissie</item>
+        <item>Christopher, Chris</item>
+        <item>Cynthia, Cindy, Cynth</item>
+        <item>Daniel, Dan, Danny</item>
+        <item>David, Dave</item>
+        <item>Deborah, Deb, Debbie</item>
+        <item>Dennis, Den, Denny, Dean</item>
+        <item>Dolores, Dolly</item>
+        <item>Donald, Don, Donny</item>
+        <item>Donnatella, Donna</item>
+        <item>Dorothea, Dot, Dotty</item>
+        <item>Dorothy, Dot, Dotty</item>
+        <item>Douglas, Doug</item>
+        <item>Edward, Ed, Eddie, Ned, Neddie, Neddy, Ted, Teddy, Teddie</item>
+        <item>Eleanor, Ella, Ellie, Elle</item>
+        <item>Elisabetta, Betta</item>
+        <item>Elizabeth, Beth, Bess, Bessie, Betsy, Betty, Bette, Eliza, Lisa, Liza, Liz</item>
+        <item>Emily, Em, Ems, Emmy</item>
+        <item>Emma, Em, Ems, Emmy</item>
+        <item>Erica, Rikki, Rikkie, Ricky</item>
+        <item>Eugene, Gene</item>
+        <item>Florence, Flo</item>
+        <item>Frances, Fran, Francie</item>
+        <item>Francis, Fran, Frank</item>
+        <item>Frederick, Fred, Freddy</item>
+        <item>Gabriel, Gabe</item>
+        <item>Geoffrey, Jeff</item>
+        <item>Gerald, Gerry</item>
+        <item>Gerard, Gerry</item>
+        <item>Gregory, Greg</item>
+        <item>Harold, Hal, Hank, Harry</item>
+        <item>Henry, Hal, Hank, Harry</item>
+        <item>Herbert, Bert, Bertie</item>
+        <item>Irving, Irv</item>
+        <item>Isabella, Isa, Izzy</item>
+        <item>Jacob, Jake</item>
+        <item>Jacqueline, Jackie</item>
+        <item>James, Jim, Jimmy, Jamie, Jock</item>
+        <item>Janet, Jan</item>
+        <item>Janice, Jan</item>
+        <item>Jason, Jay</item>
+        <item>Jefferson, Jeff</item>
+        <item>Jeffrey, Jeff</item>
+        <item>Jennifer, Jen, Jenny</item>
+        <item>Jerome, Jerry</item>
+        <item>Jessica, Jessie</item>
+        <item>John, Jack, Jacky, Johnny, Jon</item>
+        <item>Jonathan, Jon, John</item>
+        <item>Joseph, Joe, Joey</item>
+        <item>Joshua, Josh</item>
+        <item>Kaitlyn, Cat, Cate, Catie, Cath, Cathy, Kat, Kate, Katie, Kathy</item>
+        <item>Katherine, Cat, Cate, Catie, Cath, Cathy, Kat, Kate, Katie, Kathy</item>
+        <item>Kathleen, Cat, Cate, Catie, Cath, Cathy, Kat, Kate, Katie, Kathy</item>
+        <item>Katrina, Cat, Cate, Catie, Cath, Cathy, Kat, Kate, Katie, Kathy</item>
+        <item>Kenneth, Ken</item>
+        <item>Kevin, Kev</item>
+        <item>Laura, Lauri, Laurie</item>
+        <item>Lauren, Lauri, Laurie</item>
+        <item>Laurence, Larry, Lauri, Laurie</item>
+        <item>Lawrence, Larry, Lauri, Laurie</item>
+        <item>Leonard, Leo, Len, Lenny</item>
+        <item>Leopold, Leo, Len, Lenny</item>
+        <item>Madeline, Maddie, Maddy</item>
+        <item>Margaret, Marge, Marg, Maggie, Mags, Meg, Peggy</item>
+        <item>Matthew, Matt, Mattie</item>
+        <item>Maureen, Mo</item>
+        <item>Maurice, Mo</item>
+        <item>Megan, Meg</item>
+        <item>Michael, Mickey, Mick, Mike, Mikey</item>
+        <item>Morris, Mo</item>
+        <item>Nancy, Nan</item>
+        <item>Nathan, Nat, Nate</item>
+        <item>Nathaniel, Nat, Nate</item>
+        <item>Nicholas, Nick</item>
+        <item>Pamela, Pam</item>
+        <item>Patricia, Pat, Patsy, Patty, Trish, Tricia</item>
+        <item>Patrick, Paddy, Pat, Patty, Patter, Rick, Ricky</item>
+        <item>Peter, Pete</item>
+        <item>Raymond, Ray</item>
+        <item>Philip, Phil</item>
+        <item>Rebecca, Becca</item>
+        <item>Richard, Rick, Rich, Dick</item>
+        <item>Robert, Bob, Rob, Robbie, Bobby, Rab</item>
+        <item>Roberta, Bobbie</item>
+        <item>Rodney. Rod</item>
+        <item>Ronald, Ron, Ronnie</item>
+        <item>Rosemary, Rosie, Rose</item>
+        <item>Russell, Russ, Rusty</item>
+        <item>Ryan, Ry</item>
+        <item>Samantha, Sam</item>
+        <item>Samuel, Sam, Sammy</item>
+        <item>Sophia, Sophie</item>
+        <item>Stephanie, Steph, Stephie</item>
+        <item>Stephen, Steve</item>
+        <item>Steven, Steve</item>
+        <item>Stuart, Stu</item>
+        <item>Susan, Sue, Susie, Suzie</item>
+        <item>Suzanne, Sue, Susie, Suzie</item>
+        <item>Teresa, Terrie, Terry</item>
+        <item>Theodora, Teddie, Thea, Theo</item>
+        <item>Theodore, Ted, Teddy, Theo</item>
+        <item>Thomas, Tom, Thom, Tommy</item>
+        <item>Timothy, Tim, Timmy</item>
+        <item>Valerie, Val</item>
+        <item>Veronica, Ronnie, Roni, Nica, Nikki, Nikka</item>
+        <item>Victor, Vic</item>
+        <item>Victoria, Vicky, Vicki, Vickie, Tori</item>
+        <item>Vincent, Vince, Vin, Vinnie</item>
+        <item>Vivian, Vivi</item>
+        <item>Walter, Walt, Wally</item>
+        <item>Wendy, Wen, Wendel</item>
+        <item>William, Bill, Billy, Will, Willy, Liam</item>
+        <item>Yvonna, Vonna</item>
+        <item>Zachary, Zach, Zack, Zac</item>
+    </string-array>
+    <string name="common_name_prefixes">
+        1LT, 1ST, 2LT, 2ND, 3RD, ADMIRAL, CAPT, CAPTAIN, COL, CPT, DR,
+        GEN, GENERAL, LCDR, LT, LTC, LTG, LTJG, MAJ, MAJOR, MG, MR,
+        MRS, MS, PASTOR, PROF, REP, REVEREND, REV, SEN, ST
+    </string>
+    <string name="common_name_suffixes">
+        B.A., BA, D.D.S., DDS, I, II, III, IV, IX, JR, M.A., M.D, MA,
+        MD, MS, PH.D., PHD, SR, V, VI, VII, VIII, X
+    </string>
+    <string name="common_last_name_prefixes">
+        D', DE, DEL, DI, LA, LE, MC, SAN, ST, TER, VAN, VON
+    </string>
+    <string name="common_name_conjunctions">
+        &amp;, AND, OR
+    </string>
+</resources>
diff --git a/core/res/res/values/donottranslate-names.xml b/core/res/res/values/donottranslate-names.xml
new file mode 100644
index 0000000..56ae47a
--- /dev/null
+++ b/core/res/res/values/donottranslate-names.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    
+    <!-- Various locale-specific string resources for Contacts -->
+    <string-array name="common_nicknames"></string-array>
+    <string name="common_name_prefixes"></string>
+    <string name="common_name_suffixes"></string>
+    <string name="common_last_name_prefixes"></string>
+    <string name="common_name_conjunctions"></string>
+</resources>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 815b767..22f9136 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -1923,157 +1923,6 @@
     <!-- This string appears (on two lines) when you type a number into contacts search, to let you create a contact whose phone number is the number you typed.  The first line will be in bigger type than the second. -->
     <string name="create_contact_using">Create contact\nusing <xliff:g id="number" example="555">%s</xliff:g></string>
 
-    <!-- various string resources for Contacts -->
-    <string-array name="common_nicknames">
-        <item>Albert, Al, Bert, Bertie</item>
-        <item>Alexander, Al, Alex, Lex, Sasha</item>
-        <item>Alexandra, Al, Alex, Allie, Ally, Lex, Lexie, Sandra, Sandy, Sasha</item>
-        <item>Alice, Allie, Ally</item>
-        <item>Alison, Allie, Ally</item>
-        <item>Allison, Allie, Ally</item>
-        <item>Amanda, Mandi, Mandy</item>
-        <item>Andrea, Andie</item>
-        <item>Andrew, Andy, Drew</item>
-        <item>Anthony, Tony, Toni, Tone</item>
-        <item>Arthur, Art, Arty</item>
-        <item>Barbara, Babs, Barb, Barbie</item>
-        <item>Benjamin, Ben, Benji, Benny</item>
-        <item>Bernard, Bern, Bernie</item>
-        <item>Bertram, Bert, Bertie</item>
-        <item>Bradly, Brad</item>
-        <item>Catherine, Cat, Cate, Cath, Catie, Cathy, Kat, Kate, Katie, Kathy</item>
-        <item>Charles, Chuck, Chaz, Charlie, Buck</item>
-        <item>Christine, Chris, Chrissy, Chrissie</item>
-        <item>Christopher, Chris</item>
-        <item>Cynthia, Cindy, Cynth</item>
-        <item>Daniel, Dan, Danny</item>
-        <item>David, Dave</item>
-        <item>Deborah, Deb, Debbie</item>
-        <item>Dennis, Den, Denny, Dean</item>
-        <item>Dolores, Dolly</item>
-        <item>Donald, Don, Donny</item>
-        <item>Donnatella, Donna</item>
-        <item>Dorothea, Dot, Dotty</item>
-        <item>Dorothy, Dot, Dotty</item>
-        <item>Douglas, Doug</item>
-        <item>Edward, Ed, Eddie, Ned, Neddie, Neddy, Ted, Teddy, Teddie</item>
-        <item>Eleanor, Ella, Ellie, Elle</item>
-        <item>Elisabetta, Betta</item>
-        <item>Elizabeth, Beth, Bess, Bessie, Betsy, Betty, Bette, Eliza, Lisa, Liza, Liz</item>
-        <item>Emily, Em, Ems, Emmy</item>
-        <item>Emma, Em, Ems, Emmy</item>
-        <item>Erica, Rikki, Rikkie, Ricky</item>
-        <item>Eugene, Gene</item>
-        <item>Florence, Flo</item>
-        <item>Frances, Fran, Francie</item>
-        <item>Francis, Fran, Frank</item>
-        <item>Frederick, Fred, Freddy</item>
-        <item>Gabriel, Gabe</item>
-        <item>Geoffrey, Jeff</item>
-        <item>Gerald, Gerry</item>
-        <item>Gerard, Gerry</item>
-        <item>Gregory, Greg</item>
-        <item>Harold, Hal, Hank, Harry</item>
-        <item>Henry, Hal, Hank, Harry</item>
-        <item>Herbert, Bert, Bertie</item>
-        <item>Irving, Irv</item>
-        <item>Isabella, Isa, Izzy</item>
-        <item>Jacob, Jake</item>
-        <item>Jacqueline, Jackie</item>
-        <item>James, Jim, Jimmy, Jamie, Jock</item>
-        <item>Janet, Jan</item>
-        <item>Janice, Jan</item>
-        <item>Jason, Jay</item>
-        <item>Jefferson, Jeff</item>
-        <item>Jeffrey, Jeff</item>
-        <item>Jennifer, Jen, Jenny</item>
-        <item>Jerome, Jerry</item>
-        <item>Jessica, Jessie</item>
-        <item>John, Jack, Jacky, Johnny, Jon</item>
-        <item>Jonathan, Jon, John</item>
-        <item>Joseph, Joe, Joey</item>
-        <item>Joshua, Josh</item>
-        <item>Kaitlyn, Cat, Cate, Catie, Cath, Cathy, Kat, Kate, Katie, Kathy</item>
-        <item>Katherine, Cat, Cate, Catie, Cath, Cathy, Kat, Kate, Katie, Kathy</item>
-        <item>Kathleen, Cat, Cate, Catie, Cath, Cathy, Kat, Kate, Katie, Kathy</item>
-        <item>Katrina, Cat, Cate, Catie, Cath, Cathy, Kat, Kate, Katie, Kathy</item>
-        <item>Kenneth, Ken</item>
-        <item>Kevin, Kev</item>
-        <item>Laura, Lauri, Laurie</item>
-        <item>Lauren, Lauri, Laurie</item>
-        <item>Laurence, Larry, Lauri, Laurie</item>
-        <item>Lawrence, Larry, Lauri, Laurie</item>
-        <item>Leonard, Leo, Len, Lenny</item>
-        <item>Leopold, Leo, Len, Lenny</item>
-        <item>Madeline, Maddie, Maddy</item>
-        <item>Margaret, Marge, Marg, Maggie, Mags, Meg, Peggy</item>
-        <item>Matthew, Matt, Mattie</item>
-        <item>Maureen, Mo</item>
-        <item>Maurice, Mo</item>
-        <item>Megan, Meg</item>
-        <item>Michael, Mickey, Mick, Mike, Mikey</item>
-        <item>Morris, Mo</item>
-        <item>Nancy, Nan</item>
-        <item>Nathan, Nat, Nate</item>
-        <item>Nathaniel, Nat, Nate</item>
-        <item>Nicholas, Nick</item>
-        <item>Pamela, Pam</item>
-        <item>Patricia, Pat, Patsy, Patty, Trish, Tricia</item>
-        <item>Patrick, Paddy, Pat, Patty, Patter, Rick, Ricky</item>
-        <item>Peter, Pete</item>
-        <item>Raymond, Ray</item>
-        <item>Philip, Phil</item>
-        <item>Rebecca, Becca</item>
-        <item>Richard, Rick, Rich, Dick</item>
-        <item>Robert, Bob, Rob, Robbie, Bobby, Rab</item>
-        <item>Roberta, Bobbie</item>
-        <item>Rodney. Rod</item>
-        <item>Ronald, Ron, Ronnie</item>
-        <item>Rosemary, Rosie, Rose</item>
-        <item>Russell, Russ, Rusty</item>
-        <item>Ryan, Ry</item>
-        <item>Samantha, Sam</item>
-        <item>Samuel, Sam, Sammy</item>
-        <item>Sophia, Sophie</item>
-        <item>Stephanie, Steph, Stephie</item>
-        <item>Stephen, Steve</item>
-        <item>Steven, Steve</item>
-        <item>Stuart, Stu</item>
-        <item>Susan, Sue, Susie, Suzie</item>
-        <item>Suzanne, Sue, Susie, Suzie</item>
-        <item>Teresa, Terrie, Terry</item>
-        <item>Theodora, Teddie, Thea, Theo</item>
-        <item>Theodore, Ted, Teddy, Theo</item>
-        <item>Thomas, Tom, Thom, Tommy</item>
-        <item>Timothy, Tim, Timmy</item>
-        <item>Valerie, Val</item>
-        <item>Veronica, Ronnie, Roni, Nica, Nikki, Nikka</item>
-        <item>Victor, Vic</item>
-        <item>Victoria, Vicky, Vicki, Vickie, Tori</item>
-        <item>Vincent, Vince, Vin, Vinnie</item>
-        <item>Vivian, Vivi</item>
-        <item>Walter, Walt, Wally</item>
-        <item>Wendy, Wen, Wendel</item>
-        <item>William, Bill, Billy, Will, Willy, Liam</item>
-        <item>Yvonna, Vonna</item>
-        <item>Zachary, Zach, Zack, Zac</item>
-    </string-array>
-    <string name="common_name_prefixes">
-        1LT, 1ST, 2LT, 2ND, 3RD, ADMIRAL, CAPT, CAPTAIN, COL, CPT, DR,
-        GEN, GENERAL, LCDR, LT, LTC, LTG, LTJG, MAJ, MAJOR, MG, MR,
-        MRS, MS, PASTOR, PROF, REP, REVEREND, REV, SEN, ST
-    </string>
-    <string name="common_name_suffixes">
-        B.A., BA, D.D.S., DDS, I, II, III, IV, IX, JR, M.A., M.D, MA,
-        MD, MS, PH.D., PHD, SR, V, VI, VII, VIII, X
-    </string>
-    <string name="common_last_name_prefixes">
-        D', DE, DEL, DI, LA, LE, MC, SAN, ST, TER, VAN, VON
-    </string>
-    <string name="common_name_conjunctions">
-        &amp;, AND, OR
-    </string>
-
     <!-- This string array should be overridden by the manufacture to present a list of carrier-id,locale,wifi-channel sets.  This is used at startup to set system defaults by checking the system property ro.carrier for the carrier-id and searching through this array -->
     <!-- An Array of [[Carrier-ID]                     -->
     <!--              [default-locale]                 -->
diff --git a/include/media/mediametadataretriever.h b/include/media/mediametadataretriever.h
index 3db8a0f..9ea2775 100644
--- a/include/media/mediametadataretriever.h
+++ b/include/media/mediametadataretriever.h
@@ -52,6 +52,7 @@
     METADATA_KEY_VIDEO_FORMAT    = 18,
     METADATA_KEY_VIDEO_HEIGHT    = 19,
     METADATA_KEY_VIDEO_WIDTH     = 20,
+    METADATA_KEY_WRITER          = 21,
     // Add more here...
 };
 
diff --git a/include/ui/Surface.h b/include/ui/Surface.h
index 4ff0e4a..30ab82f 100644
--- a/include/ui/Surface.h
+++ b/include/ui/Surface.h
@@ -146,16 +146,16 @@
     static bool isValid(const sp<Surface>& surface) {
         return (surface != 0) && surface->isValid();
     }
-    bool isValid() {
-        return mToken>=0 && mClient!=0;
-    }
+
     static bool isSameSurface(
             const sp<Surface>& lhs, const sp<Surface>& rhs);
-    SurfaceID   ID() const      { return mToken; }
-    uint32_t    getFlags() const { return mFlags; }
+
+    bool        isValid();
+    SurfaceID   ID() const          { return mToken; }
+    uint32_t    getFlags() const    { return mFlags; }
     uint32_t    getIdentity() const { return mIdentity; }
 
-
+    // the lock/unlock APIs must be used from the same thread
     status_t    lock(SurfaceInfo* info, bool blocking = true);
     status_t    lock(SurfaceInfo* info, Region* dirty, bool blocking = true);
     status_t    unlockAndPost();
@@ -175,14 +175,18 @@
     friend class SurfaceComposerClient;
     friend class SurfaceControl;
 
+    
     // camera and camcorder need access to the ISurface binder interface for preview
     friend class Camera;
     friend class MediaRecorder;
     // mediaplayer needs access to ISurface for display
     friend class MediaPlayer;
-    friend class Test;
     friend class IOMX;
-    const sp<ISurface>& getISurface() const { return mSurface; }
+    // this is just to be able to write some unit tests
+    friend class Test;
+
+    sp<SurfaceComposerClient> getClient() const;
+    sp<ISurface> getISurface() const;
 
     status_t getBufferLocked(int index, int usage);
    
@@ -210,24 +214,38 @@
     status_t queueBuffer(const sp<SurfaceBuffer>& buffer);
 
     
-    alloc_device_t*             mAllocDevice;
+    void setUsage(uint32_t reqUsage);
+    
+    // constants
     sp<SurfaceComposerClient>   mClient;
     sp<ISurface>                mSurface;
-    sp<SurfaceBuffer>           mBuffers[2];
-    sp<SurfaceBuffer>           mLockedBuffer;
     SurfaceID                   mToken;
     uint32_t                    mIdentity;
-    uint32_t                    mWidth;
-    uint32_t                    mHeight;
-    uint32_t                    mUsage;
     PixelFormat                 mFormat;
     uint32_t                    mFlags;
-    mutable Region              mDirtyRegion;
-    mutable Region              mOldDirtyRegion;
-    mutable uint8_t             mBackbufferIndex;
-    mutable Mutex               mSurfaceLock;
-    Rect                        mSwapRectangle;
     BufferMapper&               mBufferMapper;
+
+    // protected by mSurfaceLock
+    Rect                        mSwapRectangle;
+    uint32_t                    mUsage;
+    bool                        mUsageChanged;
+    
+    // protected by mSurfaceLock. These are also used from lock/unlock
+    // but in that case, they must be called form the same thread.
+    sp<SurfaceBuffer>           mBuffers[2];
+    mutable Region              mDirtyRegion;
+    mutable uint8_t             mBackbufferIndex;
+
+    // must be used from the lock/unlock thread
+    sp<SurfaceBuffer>           mLockedBuffer;
+    mutable Region              mOldDirtyRegion;
+
+    // query() must be called from dequeueBuffer() thread
+    uint32_t                    mWidth;
+    uint32_t                    mHeight;
+
+    // Inherently thread-safe
+    mutable Mutex               mSurfaceLock;
 };
 
 }; // namespace android
diff --git a/libs/ui/Surface.cpp b/libs/ui/Surface.cpp
index 2b6905f..f6792c4 100644
--- a/libs/ui/Surface.cpp
+++ b/libs/ui/Surface.cpp
@@ -382,9 +382,9 @@
 Surface::Surface(const sp<SurfaceControl>& surface)
     : mClient(surface->mClient), mSurface(surface->mSurface),
       mToken(surface->mToken), mIdentity(surface->mIdentity),
-      mWidth(surface->mWidth), mHeight(surface->mHeight),
       mFormat(surface->mFormat), mFlags(surface->mFlags),
-      mBufferMapper(BufferMapper::get())
+      mBufferMapper(BufferMapper::get()),
+      mWidth(surface->mWidth), mHeight(surface->mHeight)
 {
     init();
 }
@@ -426,9 +426,9 @@
     const_cast<uint32_t&>(android_native_window_t::flags) = 0;
     // be default we request a hardware surface
     mUsage = GRALLOC_USAGE_HW_RENDER;
+    mUsageChanged = true;
 }
 
-
 Surface::~Surface()
 {
     // this is a client-side operation, the surface is destroyed, unmap
@@ -446,11 +446,24 @@
     IPCThreadState::self()->flushCommands();
 }
 
+sp<SurfaceComposerClient> Surface::getClient() const {
+    return mClient;
+}
+
+sp<ISurface> Surface::getISurface() const {
+    return mSurface;
+}
+
+bool Surface::isValid() {
+    return mToken>=0 && mClient!=0;
+}
+
 status_t Surface::validate(per_client_cblk_t const* cblk) const
 {
+    sp<SurfaceComposerClient> client(getClient());
     if (mToken<0 || mClient==0) {
         LOGE("invalid token (%d, identity=%u) or client (%p)", 
-                mToken, mIdentity, mClient.get());
+                mToken, mIdentity, client.get());
         return NO_INIT;
     }
     if (cblk == 0) {
@@ -477,6 +490,7 @@
 {
     if (lhs == 0 || rhs == 0)
         return false;
+
     return lhs->mSurface->asBinder() == rhs->mSurface->asBinder();
 }
 
@@ -532,10 +546,9 @@
 {
     android_native_buffer_t* out;
     status_t err = dequeueBuffer(&out);
-    *buffer = SurfaceBuffer::getSelf(out);
-    // reset the width/height with the what we get from the buffer
-    mWidth  = uint32_t(out->width);
-    mHeight = uint32_t(out->height);
+    if (err == NO_ERROR) {
+        *buffer = SurfaceBuffer::getSelf(out);
+    }
     return err;
 }
 
@@ -557,7 +570,8 @@
 
     Mutex::Autolock _l(mSurfaceLock);
 
-    per_client_cblk_t* const cblk = mClient->mControl;
+    sp<SurfaceComposerClient> client(getClient());
+    per_client_cblk_t* const cblk = client->mControl;
     status_t err = validate(cblk);
     if (err != NO_ERROR)
         return err;
@@ -572,14 +586,17 @@
 
     mBackbufferIndex = backIdx;
     layer_cblk_t* const lcblk = &(cblk->layers[index]);
-
     volatile const surface_info_t* const back = lcblk->surface + backIdx;
-    if (back->flags & surface_info_t::eNeedNewBuffer) {
+    if ((back->flags & surface_info_t::eNeedNewBuffer) || mUsageChanged) {
+        mUsageChanged = false;
         err = getBufferLocked(backIdx, mUsage);
     }
 
     if (err == NO_ERROR) {
         const sp<SurfaceBuffer>& backBuffer(mBuffers[backIdx]);
+        // reset the width/height with the what we get from the buffer
+        mWidth  = uint32_t(backBuffer->width);
+        mHeight = uint32_t(backBuffer->height);
         mDirtyRegion.set(backBuffer->width, backBuffer->height);
         *buffer = backBuffer.get();
     }
@@ -591,7 +608,8 @@
 {
     Mutex::Autolock _l(mSurfaceLock);
 
-    per_client_cblk_t* const cblk = mClient->mControl;
+    sp<SurfaceComposerClient> client(getClient());
+    per_client_cblk_t* const cblk = client->mControl;
     status_t err = validate(cblk);
     if (err != NO_ERROR)
         return err;
@@ -604,7 +622,8 @@
 {   
     Mutex::Autolock _l(mSurfaceLock);
 
-    per_client_cblk_t* const cblk = mClient->mControl;
+    sp<SurfaceComposerClient> client(getClient());
+    per_client_cblk_t* const cblk = client->mControl;
     status_t err = validate(cblk);
     if (err != NO_ERROR)
         return err;
@@ -620,7 +639,7 @@
 
     uint32_t newstate = cblk->unlock_layer_and_post(size_t(index));
     if (!(newstate & eNextFlipPending))
-        mClient->signalServer();
+        client->signalServer();
 
     return NO_ERROR;
 }
@@ -646,7 +665,7 @@
     int res = NO_ERROR;
     switch (operation) {
         case NATIVE_WINDOW_SET_USAGE:
-            mUsage = va_arg(args, int);
+            setUsage( va_arg(args, int) );
             break;
         default:
             res = NAME_NOT_FOUND;
@@ -655,6 +674,15 @@
     return res;
 }
 
+void Surface::setUsage(uint32_t reqUsage)
+{
+    Mutex::Autolock _l(mSurfaceLock);
+    if (mUsage != reqUsage) {
+        mUsageChanged = true;
+        mUsage = reqUsage;
+    }
+}
+
 // ----------------------------------------------------------------------------
 
 status_t Surface::lock(SurfaceInfo* info, bool blocking) {
@@ -663,11 +691,9 @@
 
 status_t Surface::lock(SurfaceInfo* other, Region* dirtyIn, bool blocking) 
 {
-    // FIXME: needs some locking here
-
     // we're intending to do software rendering from this point
-    mUsage = GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN;
-    
+    setUsage(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN);
+
     sp<SurfaceBuffer> backBuffer;
     status_t err = dequeueBuffer(&backBuffer);
     if (err == NO_ERROR) {
@@ -679,7 +705,8 @@
             Region scratch(bounds);
             Region& newDirtyRegion(dirtyIn ? *dirtyIn : scratch);
 
-            per_client_cblk_t* const cblk = mClient->mControl;
+            sp<SurfaceComposerClient> client(getClient());
+            per_client_cblk_t* const cblk = client->mControl;
             layer_cblk_t* const lcblk = &(cblk->layers[SurfaceID(mToken)]);
             volatile const surface_info_t* const back = lcblk->surface + mBackbufferIndex;
             if (back->flags & surface_info_t::eBufferDirty) {
@@ -725,8 +752,6 @@
     
 status_t Surface::unlockAndPost() 
 {
-    // FIXME: needs some locking here
-
     if (mLockedBuffer == 0)
         return BAD_VALUE;
 
@@ -753,13 +778,17 @@
 }
 
 void Surface::setSwapRectangle(const Rect& r) {
+    Mutex::Autolock _l(mSurfaceLock);
     mSwapRectangle = r;
 }
 
 status_t Surface::getBufferLocked(int index, int usage)
 {
+    sp<ISurface> s(mSurface);
+    if (s == 0) return NO_INIT;
+
     status_t err = NO_MEMORY;
-    sp<SurfaceBuffer> buffer = mSurface->getBuffer(usage);
+    sp<SurfaceBuffer> buffer = s->getBuffer(usage);
     LOGE_IF(buffer==0, "ISurface::getBuffer() returned NULL");
     if (buffer != 0) {
         sp<SurfaceBuffer>& currentBuffer(mBuffers[index]);
diff --git a/media/java/android/media/MediaMetadataRetriever.java b/media/java/android/media/MediaMetadataRetriever.java
index c6a9ae8..cecf4f8 100644
--- a/media/java/android/media/MediaMetadataRetriever.java
+++ b/media/java/android/media/MediaMetadataRetriever.java
@@ -254,5 +254,6 @@
     public static final int METADATA_KEY_VIDEO_FORMAT    = 18;
     public static final int METADATA_KEY_VIDEO_HEIGHT    = 19;
     public static final int METADATA_KEY_VIDEO_WIDTH     = 20;
+    public static final int METADATA_KEY_WRITER          = 21;
     // Add more here...
 }
diff --git a/media/java/android/media/MediaScanner.java b/media/java/android/media/MediaScanner.java
index 71af909..376057e 100644
--- a/media/java/android/media/MediaScanner.java
+++ b/media/java/android/media/MediaScanner.java
@@ -396,6 +396,7 @@
         private String mPath;
         private long mLastModified;
         private long mFileSize;
+        private String mWriter;
 
         public FileCacheEntry beginFile(String path, String mimeType, long lastModified, long fileSize) {
 
@@ -479,6 +480,7 @@
             mDuration = 0;
             mPath = path;
             mLastModified = lastModified;
+            mWriter = null;
 
             return entry;
         }
@@ -593,6 +595,8 @@
                 mTrack = (num * 1000) + (mTrack % 1000);
             } else if (name.equalsIgnoreCase("duration")) {
                 mDuration = parseSubstring(value, 0, 0);
+            } else if (name.equalsIgnoreCase("writer") || name.startsWith("writer;")) {
+                mWriter = value.trim();
             }
         }
 
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaNames.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaNames.java
index e76967d..3f2bc39 100755
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaNames.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaNames.java
@@ -372,81 +372,81 @@
   public static final String META_DATA_MP3 [][] = {
       {"/sdcard/media_api/metaDataTestMedias/MP3/ID3V1_ID3V2.mp3", "1/10", "ID3V2.3 Album", "ID3V2.3 Artist",
           "ID3V2.3 Lyricist", "ID3V2.3 Composer", null, "Blues",
-          "ID3V2.3 Title", "1234", "295", "1"},
+          "ID3V2.3 Title", "1234", "295", "1", null},
       {"/sdcard/media_api/metaDataTestMedias/MP3/ID3V2.mp3", "1/10", "ID3V2.3 Album", "ID3V2.3 Artist",
           "ID3V2.3 Lyricist", "ID3V2.3 Composer", null, "Blues", 
-          "ID3V2.3 Title", "1234", "287", "1"},
+          "ID3V2.3 Title", "1234", "287", "1", null},
       {"/sdcard/media_api/metaDataTestMedias/MP3/ID3V1.mp3", "1", "test ID3V1 Album", "test ID3V1 Artist",
-          null, null, null, "255", "test ID3V1 Title", "1234", "231332", "1"},
+          null, null, null, "255", "test ID3V1 Title", "1234", "231332", "1", null},
       {"/sdcard/media_api/metaDataTestMedias/MP3/Corrupted_ID3V1.mp3" , null, null, null,
-              null, null, null, null, null, null, "231330", "1"},
+              null, null, null, null, null, null, "231330", "1", null},
       //The corrupted TALB field in id3v2 would not switch to id3v1 tag automatically
       {"/sdcard/media_api/metaDataTestMedias/MP3/Corrupted_ID3V2_TALB.mp3", "01", null, "ID3V2.3 Artist",
           "ID3V2.3 Lyricist", "ID3V2.3 Composer", null, 
-          "Blues", "ID3V2.3 Title", "1234", "295", "1"},
+          "Blues", "ID3V2.3 Title", "1234", "295", "1", null},
       {"/sdcard/media_api/metaDataTestMedias/MP3/Corrupted_ID3V2_TCOM.mp3", "01", "ID3V2.3 Album", 
            "ID3V2.3 Artist", "ID3V2.3 Lyricist", null, null, 
-           "Blues", "ID3V2.3 Title", "1234", "295", "1"},
+           "Blues", "ID3V2.3 Title", "1234", "295", "1", null},
       {"/sdcard/media_api/metaDataTestMedias/MP3/Corrupted_ID3V2_TCOM_2.mp3", "01", "ID3V2.3 Album", 
-           "ID3V2.3 Artist", null, null, null, "Blues", "ID3V2.3 Title", "1234", "295", "1"},
+           "ID3V2.3 Artist", null, null, null, "Blues", "ID3V2.3 Title", "1234", "295", "1", null},
       {"/sdcard/media_api/metaDataTestMedias/MP3/Corrupted_ID3V2_TRCK.mp3", "dd", "ID3V2.3 Album", 
            "ID3V2.3 Artist", "ID3V2.3 Lyricist", "ID3V2.3 Composer", null,
-           "Blues", "ID3V2.3 Title", "1234", "295", "1"},
+           "Blues", "ID3V2.3 Title", "1234", "295", "1", null},
       {"/sdcard/media_api/metaDataTestMedias/MP3/Corrupted_ID3V2_TRCK_2.mp3", "01", "ID3V2.3 Album", 
-           "ID3V2.3 Artist", null, null, null, "255", "ID3V2.3 Title", "1234", "295", "1"},
+           "ID3V2.3 Artist", null, null, null, "255", "ID3V2.3 Title", "1234", "295", "1", null},
       {"/sdcard/media_api/metaDataTestMedias/MP3/Corrupted_ID3V2_TYER.mp3", "01", "ID3V2.3 Album",
-           "ID3V2.3 Artist", null, null, null, null, "ID3V2.3 Title", "9999", "295", "1"},
+           "ID3V2.3 Artist", null, null, null, null, "ID3V2.3 Title", "9999", "295", "1", null},
       {"/sdcard/media_api/metaDataTestMedias/MP3/Corrupted_ID3V2_TYER_2.mp3", "01", "ID3V2.3 Album",
            "ID3V2.3 Artist", "ID3V2.3 Lyricist", "ID3V2.3 Composer", null, 
-           "Blues", "ID3V2.3 Title", null, "295", "1"},
+           "Blues", "ID3V2.3 Title", null, "295", "1", null},
       {"/sdcard/media_api/metaDataTestMedias/MP3/Corrupted_ID3V2_TIT.mp3", null, null, null,
-          null, null, null, null, null, null, "295", "1"}
+          null, null, null, null, null, null, "295", "1", null}
   };
 
   public static final String META_DATA_OTHERS [][] = {
       {"/sdcard/media_api/metaDataTestMedias/3GP/cat.3gp", null, null, null,
           null, null, "20080309T002415.000Z", null,
-          null, null, "1404928", "2"},
+          null, null, "1404928", "2", null},
       {"/sdcard/media_api/metaDataTestMedias/AMR/AMR_NB.amr", null, null, null,
           null, null, null, null,
-          null, null, "126540", "1"},
+          null, null, "126540", "1", null},
       {"/sdcard/media_api/metaDataTestMedias/AMRWB/AMR_WB.amr", null, null, null,
           null, null, null, null,
-          null, null, "231180", "1"},     
-      {"/sdcard/media_api/metaDataTestMedias/M4A/Jaws Of Life_ver1.m4a", null, "Suspended Animation", 
+          null, null, "231180", "1", null},
+      {"/sdcard/media_api/metaDataTestMedias/M4A/Jaws Of Life_ver1.m4a", "1/8", "Suspended Animation",
           "John Petrucci", null, null, "20070510T125223.000Z", 
-          null, null, "2005", "231180", "1"},     
+          "13", "Jaws Of Life", "2005", "19815424", "1", "m4a composer"},
       {"/sdcard/media_api/metaDataTestMedias/M4V/sample_iPod.m4v", null, null, 
           null, null, null, "20051220T202015.000Z", 
-          null, null, null, "3771392", "2"}, 
+          null, null, null, "3771392", "2", null},
       {"/sdcard/media_api/metaDataTestMedias/MIDI/MIDI.mid", null, "Suspended Animation", 
           "John Petrucci", null, null, "20070510T125223.000Z", 
-          null, null, "2005", "231180", "1"}, 
-      {"/sdcard/media_api/metaDataTestMedias/MP4/kung_fu_panda_h264.mp4", null, "mp4 album Kung Fu Panda", 
+          null, null, "2005", "231180", "1", null},
+      {"/sdcard/media_api/metaDataTestMedias/MP4/kung_fu_panda_h264.mp4", "2/0", "mp4 album Kung Fu Panda",
           "mp4 artist Kung Fu Panda", null, null, "20080517T091451.000Z", 
-          "41", "Kung Fu Panda", "2008", "5667840", "2"},
+          "41", "Kung Fu Panda", "2008", "5667840", "2", "mp4 composer"},
       {"/sdcard/media_api/metaDataTestMedias/OGG/Ring_Classic_02.ogg", null, "Suspended Animation", 
           "John Petrucci", null, null, "20070510T125223.000Z", 
-          null, null, "2005", "231180", "1"},
+          null, null, "2005", "231180", "1", null},
       {"/sdcard/media_api/metaDataTestMedias/OGG/When You Say Nothing At All.ogg", 
           null, "Suspended Animation", "John Petrucci", 
-          null, null, "20070510T125223.000Z", null, null, "2005", "231180", "1"},
+          null, null, "20070510T125223.000Z", null, null, "2005", "231180", "1", null},
       {"/sdcard/media_api/metaDataTestMedias/WAV/Im With You.wav", null, null, 
           null, null, null, null, 
-          null, null, null, "224000", "1"},
+          null, null, null, "224000", "1", null},
       {"/sdcard/media_api/metaDataTestMedias/WMA/WMA9.wma", "6", "Ten Songs in the Key of Betrayal", 
           "Alien Crime Syndicate", "Alien Crime Syndicate", 
           "wma 9 Composer", "20040521T175729.483Z", 
-          "Rock", "Run for the Money", "2004", "134479", "1"},
+          "Rock", "Run for the Money", "2004", "134479", "1", null},
       {"/sdcard/media_api/metaDataTestMedias/WMA/WMA10.wma", "09", "wma 10 Album", 
           "wma 10 Album Artist", "wma 10 Artist", "wma 10 Composer", "20070705T063625.097Z", 
-          "Acid Jazz", "wma 10 Title", "2010", "126574", "1"},
+          "Acid Jazz", "wma 10 Title", "2010", "126574", "1", null},
       {"/sdcard/media_api/metaDataTestMedias/WMV/bugs.wmv", "8", "wmv 9 Album", 
           null, "wmv 9 Artist ", null, "20051122T155247.540Z", 
-          null, "Looney Tunes - Hare-Breadth Hurry", "2005", "193482", "2"},
+          null, "Looney Tunes - Hare-Breadth Hurry", "2005", "193482", "2", null},
       {"/sdcard/media_api/metaDataTestMedias/WMV/clips_ver7.wmv", "50", "wmv 7 Album", 
           null, "Hallau Shoots & Company", null, "20020226T170045.891Z", 
-          null, "CODEC Shootout", "1986", "43709", "2"}
+          null, "CODEC Shootout", "1986", "43709", "2", null}
   };
   
   //output recorded video
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaMetadataTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaMetadataTest.java
index 3715913..1bf4958 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaMetadataTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaMetadataTest.java
@@ -36,7 +36,7 @@
         FILE_PATH,CD_TRACK, ALBUM,
         ARTIST, AUTHOR, COMPOSER,
         DATE, GENRE, TITLE,
-        YEAR, DURATION, NUM_TRACKS
+        YEAR, DURATION, NUM_TRACKS, WRITER
     }
     
     public static enum MP3_TEST_FILE{
@@ -130,8 +130,6 @@
         validateMetatData(non_mp3_test_file.AMRWB.ordinal(), MediaNames.META_DATA_OTHERS);
     }
     
-    //Bug# 1440173 - skip this test case now
-    @Suppress
     @MediumTest
     public static void testM4A1_Metadata() throws Exception {
         validateMetatData(non_mp3_test_file.M4A1.ordinal(), MediaNames.META_DATA_OTHERS);
@@ -254,6 +252,10 @@
         Log.v(TAG, "Track : "+ value);
         assertEquals(TAG,meta_data_file[fileIndex][meta.NUM_TRACKS.ordinal()], value);
      
+        value = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_WRITER);
+        Log.v(TAG, "Writer : "+ value);
+        assertEquals(TAG,meta_data_file[fileIndex][meta.WRITER.ordinal()], value);
+
         retriever.release();        
     }
 }
diff --git a/packages/SubscribedFeedsProvider/src/com/android/providers/subscribedfeeds/SubscribedFeedsIntentService.java b/packages/SubscribedFeedsProvider/src/com/android/providers/subscribedfeeds/SubscribedFeedsIntentService.java
index 3cd2cc4..b854f86 100644
--- a/packages/SubscribedFeedsProvider/src/com/android/providers/subscribedfeeds/SubscribedFeedsIntentService.java
+++ b/packages/SubscribedFeedsProvider/src/com/android/providers/subscribedfeeds/SubscribedFeedsIntentService.java
@@ -113,7 +113,7 @@
             // TODO(fredq) fix the hardcoded type
             final Account account = new Account(accountName, "com.google.GAIA");
             c = context.getContentResolver().query(SubscribedFeeds.Feeds.CONTENT_URI,
-                    null, where, new String[]{account.mName, account.mType, feed}, null);
+                    null, where, new String[]{account.name, account.type, feed}, null);
             if (c.getCount() == 0) {
                 Log.w(TAG, "received tickle for non-existent feed: "
                         + "account " + accountName + ", feed " + feed);
@@ -171,12 +171,12 @@
         try {
             ContentValues values = new ContentValues();
             for (Account account : accounts) {
-                values.put(SyncConstValue._SYNC_ACCOUNT, account.mName);
-                values.put(SyncConstValue._SYNC_ACCOUNT_TYPE, account.mType);
+                values.put(SyncConstValue._SYNC_ACCOUNT, account.name);
+                values.put(SyncConstValue._SYNC_ACCOUNT_TYPE, account.type);
                 contentResolver.update(SubscribedFeeds.Feeds.CONTENT_URI, values,
                         SubscribedFeeds.Feeds._SYNC_ACCOUNT + "=? AND "
                                 + SubscribedFeeds.Feeds._SYNC_ACCOUNT_TYPE + "=?",
-                        new String[] {account.mName, account.mType});
+                        new String[] {account.name, account.type});
             }
         } catch (SQLiteFullException e) {
             Log.w(TAG, "disk full while trying to mark the feeds as dirty, skipping");
diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java
index 1c60058..72a1192 100644
--- a/services/java/com/android/server/ConnectivityService.java
+++ b/services/java/com/android/server/ConnectivityService.java
@@ -100,6 +100,9 @@
     // a process dies
     private List mFeatureUsers;
 
+    private boolean mSystemReady;
+    private ArrayList<Intent> mDeferredBroadcasts;
+
     private class NetworkAttributes {
         /**
          * Class for holding settings read from resources.
@@ -820,7 +823,7 @@
                 (newNet == null || !newNet.isAvailable() ? "" : " other=" +
                 newNet.getNetworkInfo().getTypeName()));
 
-        mContext.sendStickyBroadcast(intent);
+        sendStickyBroadcast(intent);
         /*
          * If the failover network is already connected, then immediately send
          * out a followup broadcast indicating successful failover
@@ -843,7 +846,7 @@
             intent.putExtra(ConnectivityManager.EXTRA_EXTRA_INFO,
                     info.getExtraInfo());
         }
-        mContext.sendStickyBroadcast(intent);
+        sendStickyBroadcast(intent);
     }
 
     /**
@@ -882,7 +885,33 @@
             intent.putExtra(ConnectivityManager.EXTRA_IS_FAILOVER, true);
             info.setFailover(false);
         }
-        mContext.sendStickyBroadcast(intent);
+        sendStickyBroadcast(intent);
+    }
+
+    private void sendStickyBroadcast(Intent intent) {
+        synchronized(this) {
+            if (mSystemReady) {
+                mContext.sendStickyBroadcast(intent);
+            } else {
+                if (mDeferredBroadcasts == null) {
+                    mDeferredBroadcasts = new ArrayList<Intent>();
+                }
+                mDeferredBroadcasts.add(intent);
+            }
+        }
+    }
+
+    void systemReady() {
+        synchronized(this) {
+            mSystemReady = true;
+            if (mDeferredBroadcasts != null) {
+                int count = mDeferredBroadcasts.size();
+                for (int i = 0; i < count; i++) {
+                    mContext.sendStickyBroadcast(mDeferredBroadcasts.get(i));
+                }
+                mDeferredBroadcasts = null;
+            }
+        }
     }
 
     private void handleConnect(NetworkInfo info) {
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index ad8e8921..38bf63a 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -85,6 +85,7 @@
         HardwareService hardware = null;
         PowerManagerService power = null;
         BatteryService battery = null;
+        ConnectivityService connectivity = null;
         IPackageManager pm = null;
         Context context = null;
         WindowManagerService wm = null;
@@ -231,8 +232,8 @@
 
             try {
                 Log.i(TAG, "Starting Connectivity Service.");
-                ServiceManager.addService(Context.CONNECTIVITY_SERVICE,
-                        ConnectivityService.getInstance(context));
+                connectivity = ConnectivityService.getInstance(context);
+                ServiceManager.addService(Context.CONNECTIVITY_SERVICE, connectivity);
             } catch (Throwable e) {
                 Log.e(TAG, "Failure starting Connectivity Service", e);
             }
@@ -384,7 +385,8 @@
         }
 
         if (wallpaper != null) wallpaper.systemReady();
-        battery.systemReady();
+        if (battery != null) battery.systemReady();
+        if (connectivity != null) connectivity.systemReady();
         Watchdog.getInstance().start();
 
         Looper.loop();
diff --git a/telephony/java/com/android/internal/telephony/DataConnectionTracker.java b/telephony/java/com/android/internal/telephony/DataConnectionTracker.java
index a3f1ad8..fa0ffcd 100644
--- a/telephony/java/com/android/internal/telephony/DataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/DataConnectionTracker.java
@@ -94,6 +94,7 @@
     protected static final int EVENT_PS_RESTRICT_ENABLED = 32;
     protected static final int EVENT_PS_RESTRICT_DISABLED = 33;
     public static final int EVENT_CLEAN_UP_CONNECTION = 34;
+    protected static final int EVENT_CDMA_OTA_PROVISION = 35;
 
     //***** Constants
 
@@ -146,6 +147,9 @@
     protected int mNoRecvPollCount = 0;
     protected boolean netStatPollEnabled = false;
 
+    /** Manage the behavior of data retry after failure */
+    protected final RetryManager mRetryMgr = new RetryManager();
+
     // wifi connection status will be updated by sticky intent
     protected boolean mIsWifiConnected = false;
 
@@ -202,10 +206,13 @@
         if (getDataOnRoamingEnabled() != enabled) {
             Settings.Secure.putInt(phone.getContext().getContentResolver(),
                 Settings.Secure.DATA_ROAMING, enabled ? 1 : 0);
+            if (phone.getServiceState().getRoaming()) {
+                if (enabled) {
+                    mRetryMgr.resetRetryCount();
+                }
+                sendMessage(obtainMessage(EVENT_ROAMING_ON));
+            }
         }
-        Message roamingMsg = phone.getServiceState().getRoaming() ?
-            obtainMessage(EVENT_ROAMING_ON) : obtainMessage(EVENT_ROAMING_OFF);
-        sendMessage(roamingMsg);
     }
 
     //Retrieve the data roaming setting from the shared preferences.
@@ -243,6 +250,9 @@
                 break;
 
             case EVENT_ROAMING_OFF:
+                if (getDataOnRoamingEnabled() == false) {
+                    mRetryMgr.resetRetryCount();
+                }
                 onRoamingOff();
                 break;
 
diff --git a/telephony/java/com/android/internal/telephony/ServiceStateTracker.java b/telephony/java/com/android/internal/telephony/ServiceStateTracker.java
index 46b39a5..39806e9 100644
--- a/telephony/java/com/android/internal/telephony/ServiceStateTracker.java
+++ b/telephony/java/com/android/internal/telephony/ServiceStateTracker.java
@@ -116,6 +116,7 @@
     protected static final int EVENT_NV_READY                          = 35;
     protected static final int EVENT_ERI_FILE_LOADED                   = 36;
     protected static final int EVENT_OTA_PROVISION_STATUS_CHANGE       = 37;
+    protected static final int EVENT_SET_RADIO_POWER_OFF               = 38;
 
     //***** Time Zones
     protected static final String TIMEZONE_PROPERTY = "persist.sys.timezone";
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java
index 38bc24d..8bae483 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java
@@ -48,6 +48,7 @@
 import com.android.internal.telephony.DataConnectionTracker;
 import com.android.internal.telephony.RetryManager;
 import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.ServiceStateTracker;
 import com.android.internal.telephony.TelephonyEventLog;
 
 import java.util.ArrayList;
@@ -76,9 +77,6 @@
     /** Currently active CdmaDataConnection */
     private CdmaDataConnection mActiveDataConnection;
 
-    /** Manage the behavior of data retry after failure */
-    private final RetryManager mRetryMgr = new RetryManager();
-
     /** Defined cdma connection profiles */
     private static final int EXTERNAL_NETWORK_DEFAULT_ID = 0;
     private static final int EXTERNAL_NETWORK_NUM_TYPES  = 1;
@@ -163,6 +161,7 @@
         p.mSST.registerForCdmaDataConnectionDetached(this, EVENT_CDMA_DATA_DETACHED, null);
         p.mSST.registerForRoamingOn(this, EVENT_ROAMING_ON, null);
         p.mSST.registerForRoamingOff(this, EVENT_ROAMING_OFF, null);
+        p.mCM.registerForCdmaOtaProvision(this, EVENT_CDMA_OTA_PROVISION, null);
 
         this.netstat = INetStatService.Stub.asInterface(ServiceManager.getService("netstat"));
 
@@ -210,6 +209,7 @@
         mCdmaPhone.mSST.unregisterForCdmaDataConnectionDetached(this);
         mCdmaPhone.mSST.unregisterForRoamingOn(this);
         mCdmaPhone.mSST.unregisterForRoamingOff(this);
+        phone.mCM.unregisterForCdmaOtaProvision(this);
 
         phone.getContext().unregisterReceiver(this.mIntentReceiver);
         destroyAllDataConnectionList();
@@ -499,7 +499,7 @@
 
     protected void restartRadio() {
         Log.d(LOG_TAG, "************TURN OFF RADIO**************");
-        cleanUpConnection(true, Phone.REASON_RADIO_TURNED_OFF);
+        cleanUpConnection(true, Phone.REASON_CDMA_DATA_DETACHED);
         phone.mCM.setRadioPower(false, null);
         /* Note: no need to call setRadioPower(true).  Assuming the desired
          * radio power state is still ON (as tracked by ServiceStateTracker),
@@ -771,6 +771,10 @@
             reason = (String) ar.userObj;
         }
         setState(State.IDLE);
+
+        CdmaServiceStateTracker ssTracker = mCdmaPhone.mSST;
+        ssTracker.processPendingRadioPowerOffAfterDataOff();
+
         phone.notifyDataConnection(reason);
         if (retryAfterDisconnected(reason)) {
           trySetupData(reason);
@@ -849,6 +853,22 @@
         }
     }
 
+    private void onCdmaOtaProvision(AsyncResult ar) {
+        if (ar.exception != null) {
+            int [] otaPrivision = (int [])ar.result;
+            if ((otaPrivision != null) && (otaPrivision.length > 1)) {
+                switch (otaPrivision[0]) {
+                case Phone.CDMA_OTA_PROVISION_STATUS_COMMITTED:
+                case Phone.CDMA_OTA_PROVISION_STATUS_OTAPA_STOPPED:
+                    mRetryMgr.resetRetryCount();
+                    break;
+                default:
+                    break;
+                }
+            }
+        }
+    }
+
     private void writeEventLogCdmaDataDrop() {
         CdmaCellLocation loc = (CdmaCellLocation)(phone.getCellLocation());
         int bsid = (loc != null) ? loc.getBaseStationId() : -1;
@@ -957,6 +977,10 @@
                 onDataStateChanged((AsyncResult) msg.obj);
                 break;
 
+            case EVENT_CDMA_OTA_PROVISION:
+                onCdmaOtaProvision((AsyncResult) msg.obj);
+                break;
+
             default:
                 // handle the message in the super class DataConnectionTracker
                 super.handleMessage(msg);
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
index b42cffd..b4de09b 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
@@ -131,6 +131,8 @@
     private boolean isEriTextLoaded = false;
     private boolean isSubscriptionFromRuim = false;
 
+    private boolean mPendingRadioPowerOffAfterDataOff = false;
+
     // Registration Denied Reason, General/Authentication Failure, used only for debugging purposes
     private String mRegistrationDeniedReason;
 
@@ -520,6 +522,16 @@
             }
             break;
 
+        case EVENT_SET_RADIO_POWER_OFF:
+            synchronized(this) {
+                if (mPendingRadioPowerOffAfterDataOff) {
+                    if (DBG) log("EVENT_SET_RADIO_OFF, turn radio off now.");
+                    cm.setRadioPower(false, null);
+                    mPendingRadioPowerOffAfterDataOff = false;
+                }
+            }
+            break;
+
         default:
             Log.e(LOG_TAG, "Unhandled message with number: " + msg.what);
         break;
@@ -548,20 +560,23 @@
             msg.obj = CDMAPhone.REASON_RADIO_TURNED_OFF;
             dcTracker.sendMessage(msg);
 
-            // Poll data state up to 50 times, with a 100ms delay
-            // totaling 5 sec.
-            // TODO: change the 5 seconds wait from blocking to non-blocking.
-            for (int i = 0; i < 50; i++) {
-                DataConnectionTracker.State currentState = dcTracker.getState();
-                if (currentState != DataConnectionTracker.State.CONNECTED
-                        && currentState != DataConnectionTracker.State.DISCONNECTING) {
-                    if (DBG) log("Data shutdown complete.");
-                    break;
+            synchronized(this) {
+                if (!mPendingRadioPowerOffAfterDataOff) {
+                    DataConnectionTracker.State currentState = dcTracker.getState();
+                    if (currentState != DataConnectionTracker.State.CONNECTED
+                            && currentState != DataConnectionTracker.State.DISCONNECTING) {
+                        if (DBG) log("Data disconnected, turn off radio right away.");
+                        cm.setRadioPower(false, null);
+                    }
+                    else if (sendEmptyMessageDelayed(EVENT_SET_RADIO_POWER_OFF, 5000)) {
+                        if (DBG) log("Wait 5 sec for data to be disconnected, then turn off radio.");
+                        mPendingRadioPowerOffAfterDataOff = true;
+                    } else {
+                        Log.w(LOG_TAG, "Cannot send delayed Msg, turn off radio right away.");
+                        cm.setRadioPower(false, null);
+                    }
                 }
-                SystemClock.sleep(DATA_STATE_POLL_SLEEP_MS);
             }
-            // If it's on and available and we want it off..
-            cm.setRadioPower(false, null);
         } // Otherwise, we're in the desired state
     }
 
@@ -1582,4 +1597,22 @@
     public boolean isMinInfoReady() {
         return mIsMinInfoReady;
     }
+
+    /**
+     * process the pending request to turn radio off after data is disconnected
+     *
+     * return true if there is pending request to process; false otherwise.
+     */
+    public boolean processPendingRadioPowerOffAfterDataOff() {
+        synchronized(this) {
+            if (mPendingRadioPowerOffAfterDataOff) {
+                if (DBG) log("Process pending request to turn radio off.");
+                removeMessages(EVENT_SET_RADIO_POWER_OFF);
+                cm.setRadioPower(false, null);
+                mPendingRadioPowerOffAfterDataOff = false;
+                return true;
+            }
+            return false;
+        }
+    }
 }
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
index bf60bfe..34d3039 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
@@ -96,8 +96,6 @@
     private int mPdpResetCount = 0;
     private boolean mIsScreenOn = true;
 
-    private final RetryManager mRetryMgr = new RetryManager();
-
     /** Delay between APN attempts */
     protected static final int APN_DELAY_MILLIS = 5000;
 
diff --git a/tests/AndroidTests/src/com/android/unit_tests/accounts/AccountManagerServiceTest.java b/tests/AndroidTests/src/com/android/unit_tests/accounts/AccountManagerServiceTest.java
index 6b8e1f0..1e4f161 100644
--- a/tests/AndroidTests/src/com/android/unit_tests/accounts/AccountManagerServiceTest.java
+++ b/tests/AndroidTests/src/com/android/unit_tests/accounts/AccountManagerServiceTest.java
@@ -28,7 +28,6 @@
 
 import java.util.Arrays;
 import java.util.Comparator;
-import java.util.Map;
 
 public class AccountManagerServiceTest extends AndroidTestCase {
     @Override
@@ -48,9 +47,9 @@
             if (object1 == object2) return 0;
             if (object1 == null) return 1;
             if (object2 == null) return -1;
-            int result = object1.mType.compareTo(object2.mType);
+            int result = object1.type.compareTo(object2.type);
             if (result != 0) return result;
-            return object1.mName.compareTo(object2.mName);
+            return object1.name.compareTo(object2.name);
         }
     }
 
@@ -62,16 +61,14 @@
         Account a12 = new Account("account1", "type2");
         Account a22 = new Account("account2", "type2");
         Account a32 = new Account("account3", "type2");
-        assertTrue(ams.addAccount(a11, "p11", null));
-        assertTrue(ams.addAccount(a12, "p12", null));
-        assertTrue(ams.addAccount(a21, "p21", null));
-        assertTrue(ams.addAccount(a22, "p22", null));
-        assertTrue(ams.addAccount(a31, "p31", null));
-        assertTrue(ams.addAccount(a32, "p32", null));
+        ams.addAccount(a11, "p11", null);
+        ams.addAccount(a12, "p12", null);
+        ams.addAccount(a21, "p21", null);
+        ams.addAccount(a22, "p22", null);
+        ams.addAccount(a31, "p31", null);
+        ams.addAccount(a32, "p32", null);
 
-        assertFalse("duplicate account insertion should fail", ams.addAccount(a32, "p", null));
-
-        Account[] accounts = ams.getAccounts();
+        Account[] accounts = ams.getAccounts(null);
         Arrays.sort(accounts, new AccountSorter());
         assertEquals(6, accounts.length);
         assertEquals(a11, accounts[0]);
@@ -88,7 +85,7 @@
         assertEquals(a21, accounts[1]);
         assertEquals(a31, accounts[2]);
 
-        ams.removeAccount(a21);
+        ams.removeAccount(null, a21);
 
         accounts = ams.getAccountsByType("type1" );
         Arrays.sort(accounts, new AccountSorter());
@@ -101,8 +98,8 @@
         AccountManagerService ams = new AccountManagerService(getContext());
         Account a11 = new Account("account1", "type1");
         Account a12 = new Account("account1", "type2");
-        assertTrue(ams.addAccount(a11, "p11", null));
-        assertTrue(ams.addAccount(a12, "p12", null));
+        ams.addAccount(a11, "p11", null);
+        ams.addAccount(a12, "p12", null);
 
         assertEquals("p11", ams.getPassword(a11));
         assertEquals("p12", ams.getPassword(a12));
@@ -125,8 +122,8 @@
         u12.putString("a", "a_a12");
         u12.putString("b", "b_a12");
         u12.putString("c", "c_a12");
-        assertTrue(ams.addAccount(a11, "p11", u11));
-        assertTrue(ams.addAccount(a12, "p12", u12));
+        ams.addAccount(a11, "p11", u11);
+        ams.addAccount(a12, "p12", u12);
 
         assertEquals("a_a11", ams.getUserData(a11, "a"));
         assertEquals("b_a11", ams.getUserData(a11, "b"));
@@ -149,8 +146,8 @@
         AccountManagerService ams = new AccountManagerService(getContext());
         Account a11 = new Account("account1", "type1");
         Account a12 = new Account("account1", "type2");
-        assertTrue(ams.addAccount(a11, "p11", null));
-        assertTrue(ams.addAccount(a12, "p12", null));
+        ams.addAccount(a11, "p11", null);
+        ams.addAccount(a12, "p12", null);
 
         ams.setAuthToken(a11, "att1", "a11_att1");
         ams.setAuthToken(a11, "att2", "a11_att2");
@@ -167,7 +164,7 @@
         assertEquals("a12_att3", ams.peekAuthToken(a12, "att3"));
 
         ams.setAuthToken(a11, "att3", "a11_att3b");
-        ams.invalidateAuthToken(a12.mType, "a12_att2");
+        ams.invalidateAuthToken(a12.type, "a12_att2");
 
         assertEquals("a11_att1", ams.peekAuthToken(a11, "att1"));
         assertEquals("a11_att2", ams.peekAuthToken(a11, "att2"));
diff --git a/tests/FrameworkTest/tests/src/android/content/AbstractTableMergerTest.java b/tests/FrameworkTest/tests/src/android/content/AbstractTableMergerTest.java
index 42c1e78..a8af7f8 100644
--- a/tests/FrameworkTest/tests/src/android/content/AbstractTableMergerTest.java
+++ b/tests/FrameworkTest/tests/src/android/content/AbstractTableMergerTest.java
@@ -74,8 +74,8 @@
         if (syncVersion != null) values.put("_sync_version", syncVersion);
         if (syncId != null) values.put("_sync_id", syncId);
         if (syncAccount != null) {
-            values.put("_sync_account", syncAccount.mName);
-            values.put("_sync_account_type", syncAccount.mType);
+            values.put("_sync_account", syncAccount.name);
+            values.put("_sync_account_type", syncAccount.type);
         }
         values.put("_sync_local_id", syncLocalId);
         values.put("_sync_dirty", 0);
@@ -88,8 +88,8 @@
         if (syncVersion != null) values.put("_sync_version", syncVersion);
         if (syncId != null) values.put("_sync_id", syncId);
         if (syncAccount != null) {
-            values.put("_sync_account", syncAccount.mName);
-            values.put("_sync_account_type", syncAccount.mType);
+            values.put("_sync_account", syncAccount.name);
+            values.put("_sync_account_type", syncAccount.type);
         }
         if (syncLocalId != null) values.put("_sync_local_id", syncLocalId);
         return values;
diff --git a/tools/aapt/AaptAssets.h b/tools/aapt/AaptAssets.h
index 5724349..32efa4e 100644
--- a/tools/aapt/AaptAssets.h
+++ b/tools/aapt/AaptAssets.h
@@ -482,6 +482,8 @@
                      const sp<AaptFile>& file,
                      const String8& resType);
 
+    void addGroupEntry(const AaptGroupEntry& entry) { mGroupEntries.add(entry); }
+    
     ssize_t slurpFromArgs(Bundle* bundle);
 
     virtual ssize_t slurpFullTree(Bundle* bundle,
diff --git a/tools/aapt/Resource.cpp b/tools/aapt/Resource.cpp
index 9d2ed10..1fa7b18 100644
--- a/tools/aapt/Resource.cpp
+++ b/tools/aapt/Resource.cpp
@@ -472,11 +472,22 @@
                             // didn't find a match fall through and add it..
                         }
                         baseGroup->addFile(overlayFiles.valueAt(overlayGroupIndex));
+                        assets->addGroupEntry(overlayFiles.keyAt(overlayGroupIndex));
                     }
                 } else {
                     // this group doesn't exist (a file that's only in the overlay)
                     baseSet->add(overlaySet->keyAt(overlayIndex),
                             overlaySet->valueAt(overlayIndex));
+                    // make sure all flavors are defined in the resources.
+                    sp<AaptGroup> overlayGroup = overlaySet->valueAt(overlayIndex);
+                    DefaultKeyedVector<AaptGroupEntry, sp<AaptFile> > overlayFiles = 
+                            overlayGroup->getFiles();
+                    size_t overlayGroupSize = overlayFiles.size();
+                    for (size_t overlayGroupIndex = 0; 
+                            overlayGroupIndex<overlayGroupSize; 
+                            overlayGroupIndex++) {
+                        assets->addGroupEntry(overlayFiles.keyAt(overlayGroupIndex));
+                    }
                 }
             }
             // this overlay didn't have resources for this type