Automated import from //branches/master/...@142414,142414
diff --git a/Android.mk b/Android.mk
index 8013c93..b214ddf 100644
--- a/Android.mk
+++ b/Android.mk
@@ -52,7 +52,10 @@
 ##
 ## READ ME: ########################################################
 LOCAL_SRC_FILES += \
-	core/java/android/accounts/IAccountsService.aidl \
+	core/java/android/accounts/IAccountManager.aidl \
+	core/java/android/accounts/IAccountManagerResponse.aidl \
+	core/java/android/accounts/IAccountAuthenticator.aidl \
+	core/java/android/accounts/IAccountAuthenticatorResponse.aidl \
 	core/java/android/app/IActivityPendingResult.aidl \
 	core/java/android/app/IActivityWatcher.aidl \
 	core/java/android/app/IAlarmManager.aidl \
@@ -161,7 +164,10 @@
 # relative to the root of the build tree.
 # ============================================================
 aidl_files := \
-	frameworks/base/core/java/android/accounts/IAccountsService.aidl \
+	frameworks/base/core/java/android/accounts/IAccountManager.aidl \
+	frameworks/base/core/java/android/accounts/IAccountManagerResponse.aidl \
+	frameworks/base/core/java/android/accounts/IAccountAuthenticator.aidl \
+	frameworks/base/core/java/android/accounts/IAccountAuthenticatorResponse.aidl \
 	frameworks/base/core/java/android/app/Notification.aidl \
 	frameworks/base/core/java/android/app/PendingIntent.aidl \
 	frameworks/base/core/java/android/content/ComponentName.aidl \
diff --git a/api/current.xml b/api/current.xml
index 55d160f..848ed83 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -1516,6 +1516,17 @@
  visibility="public"
 >
 </field>
+<field name="accountType"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843376"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="action"
  type="int"
  transient="false"
@@ -12645,6 +12656,2358 @@
 </constructor>
 </class>
 </package>
+<package name="android.accounts"
+>
+<class name="AbstractAccountAuthenticator"
+ extends="java.lang.Object"
+ abstract="true"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<constructor name="AbstractAccountAuthenticator"
+ type="android.accounts.AbstractAccountAuthenticator"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</constructor>
+<method name="addAccount"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="response" type="android.accounts.AccountAuthenticatorResponse">
+</parameter>
+<parameter name="accountType" type="java.lang.String">
+</parameter>
+</method>
+<method name="authenticateAccount"
+ return="void"
+ abstract="true"
+ 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>
+<parameter name="password" type="java.lang.String">
+</parameter>
+</method>
+<method name="checkUsernameExistence"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="response" type="android.accounts.AccountAuthenticatorResponse">
+</parameter>
+<parameter name="accountType" type="java.lang.String">
+</parameter>
+<parameter name="username" type="java.lang.String">
+</parameter>
+</method>
+<method name="editProperties"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="response" type="android.accounts.AccountAuthenticatorResponse">
+</parameter>
+<parameter name="accountType" type="java.lang.String">
+</parameter>
+</method>
+<method name="getAuthToken"
+ return="void"
+ abstract="true"
+ 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>
+<parameter name="authTokenType" type="java.lang.String">
+</parameter>
+</method>
+<method name="getIAccountAuthenticator"
+ return="android.accounts.IAccountAuthenticator"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getPasswordStrength"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="response" type="android.accounts.AccountAuthenticatorResponse">
+</parameter>
+<parameter name="accountType" type="java.lang.String">
+</parameter>
+<parameter name="password" type="java.lang.String">
+</parameter>
+</method>
+<method name="updatePassword"
+ return="void"
+ abstract="true"
+ 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>
+</method>
+</class>
+<class name="Account"
+ extends="java.lang.Object"
+ abstract="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<implements name="android.os.Parcelable">
+</implements>
+<constructor name="Account"
+ type="android.accounts.Account"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="name" type="java.lang.String">
+</parameter>
+<parameter name="type" type="java.lang.String">
+</parameter>
+</constructor>
+<constructor name="Account"
+ type="android.accounts.Account"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="in" type="android.os.Parcel">
+</parameter>
+</constructor>
+<method name="describeContents"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="writeToParcel"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="dest" type="android.os.Parcel">
+</parameter>
+<parameter name="flags" type="int">
+</parameter>
+</method>
+<field name="CREATOR"
+ type="android.os.Parcelable.Creator"
+ transient="false"
+ volatile="false"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="mName"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="mType"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+</class>
+<class name="AccountAuthenticatorCache"
+ extends="java.lang.Object"
+ abstract="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<constructor name="AccountAuthenticatorCache"
+ type="android.accounts.AccountAuthenticatorCache"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="context" type="android.content.Context">
+</parameter>
+</constructor>
+<method name="close"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getAllAuthenticators"
+ return="java.util.Collection&lt;android.accounts.AccountAuthenticatorCache.AuthenticatorInfo&gt;"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getAuthenticatorInfo"
+ return="android.accounts.AccountAuthenticatorCache.AuthenticatorInfo"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="type" type="java.lang.String">
+</parameter>
+</method>
+<method name="parseAuthenticatorInfo"
+ return="android.accounts.AccountAuthenticatorCache.AuthenticatorInfo"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="service" type="android.content.pm.ResolveInfo">
+</parameter>
+<exception name="IOException" type="java.io.IOException">
+</exception>
+<exception name="XmlPullParserException" type="org.xmlpull.v1.XmlPullParserException">
+</exception>
+</method>
+</class>
+<class name="AccountAuthenticatorCache.AuthenticatorInfo"
+ extends="java.lang.Object"
+ abstract="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<field name="mComponentName"
+ type="android.content.ComponentName"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="mComponentShortName"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="mType"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+</class>
+<class name="AccountAuthenticatorResponse"
+ extends="java.lang.Object"
+ abstract="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<constructor name="AccountAuthenticatorResponse"
+ type="android.accounts.AccountAuthenticatorResponse"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="response" type="android.accounts.IAccountAuthenticatorResponse">
+</parameter>
+</constructor>
+<method name="getIAccountAuthenticatorResponse"
+ return="android.accounts.IAccountAuthenticatorResponse"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="onError"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="errorCode" type="int">
+</parameter>
+<parameter name="errorMessage" type="java.lang.String">
+</parameter>
+</method>
+<method name="onFinished"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="result" type="int">
+</parameter>
+</method>
+<method name="onFinished"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="result" type="java.lang.String">
+</parameter>
+</method>
+<method name="onFinished"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="result" type="boolean">
+</parameter>
+</method>
+</class>
+<class name="AccountManager"
+ extends="java.lang.Object"
+ abstract="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<constructor name="AccountManager"
+ type="android.accounts.AccountManager"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="context" type="android.content.Context">
+</parameter>
+<parameter name="service" type="android.accounts.IAccountManager">
+</parameter>
+</constructor>
+<method name="addAccount"
+ 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="addAccountInteractively"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="response" type="android.accounts.AccountManagerResponse">
+</parameter>
+<parameter name="accountType" type="java.lang.String">
+</parameter>
+</method>
+<method name="authenticateAccount"
+ 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>
+</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="checkUsernameExistence"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="response" type="android.accounts.AccountManagerResponse">
+</parameter>
+<parameter name="accountType" type="java.lang.String">
+</parameter>
+<parameter name="username" type="java.lang.String">
+</parameter>
+</method>
+<method name="clearPassword"
+ 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="editProperties"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="response" type="android.accounts.AccountManagerResponse">
+</parameter>
+<parameter name="accountType" type="java.lang.String">
+</parameter>
+</method>
+<method name="getAccounts"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="intent" type="android.app.PendingIntent">
+</parameter>
+<parameter name="code" type="int">
+</parameter>
+</method>
+<method name="getAccountsByType"
+ 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="intent" type="android.app.PendingIntent">
+</parameter>
+<parameter name="code" type="int">
+</parameter>
+</method>
+<method name="getAuthToken"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="response" type="android.accounts.AccountManagerResponse">
+</parameter>
+<parameter name="account" type="android.accounts.Account">
+</parameter>
+<parameter name="authTokenType" type="java.lang.String">
+</parameter>
+<parameter name="notifyAuthFailure" type="boolean">
+</parameter>
+</method>
+<method name="getPassword"
+ 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="getPasswordStrength"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="response" type="android.accounts.AccountManagerResponse">
+</parameter>
+<parameter name="accountType" type="java.lang.String">
+</parameter>
+<parameter name="password" type="java.lang.String">
+</parameter>
+</method>
+<method name="getUserData"
+ 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="invalidateAuthToken"
+ 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="peekAuthToken"
+ 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="removeAccount"
+ 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="setAuthToken"
+ 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="setPassword"
+ 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="setUserData"
+ 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="updatePassword"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="response" type="android.accounts.AccountManagerResponse">
+</parameter>
+<parameter name="account" type="android.accounts.Account">
+</parameter>
+</method>
+</class>
+<class name="AccountManager.AuthenticateAccountThread"
+ extends="java.lang.Thread"
+ abstract="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<constructor name="AccountManager.AuthenticateAccountThread"
+ type="android.accounts.AccountManager.AuthenticateAccountThread"
+ 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>
+</constructor>
+<field name="mCondition"
+ type="java.util.concurrent.locks.Condition"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="mLock"
+ type="java.util.concurrent.locks.Lock"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+</class>
+<class name="AccountManagerResponse"
+ extends="java.lang.Object"
+ abstract="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<constructor name="AccountManagerResponse"
+ type="android.accounts.AccountManagerResponse"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="accountManagerResponse" type="android.accounts.IAccountManagerResponse">
+</parameter>
+</constructor>
+<method name="getIAccountManagerResponse"
+ return="android.accounts.IAccountManagerResponse"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+</class>
+<class name="AccountManagerService"
+ extends="android.accounts.IAccountManager.Stub"
+ abstract="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<constructor name="AccountManagerService"
+ type="android.accounts.AccountManagerService"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="context" type="android.content.Context">
+</parameter>
+</constructor>
+<method name="addAccount"
+ 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>
+<exception name="RemoteException" type="android.os.RemoteException">
+</exception>
+</method>
+<method name="addAccountInteractively"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="response" type="android.accounts.IAccountManagerResponse">
+</parameter>
+<parameter name="accountType" type="java.lang.String">
+</parameter>
+<exception name="RemoteException" type="android.os.RemoteException">
+</exception>
+</method>
+<method name="authenticateAccount"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="response" type="android.accounts.IAccountManagerResponse">
+</parameter>
+<parameter name="account" type="android.accounts.Account">
+</parameter>
+<parameter name="password" type="java.lang.String">
+</parameter>
+<exception name="RemoteException" type="android.os.RemoteException">
+</exception>
+</method>
+<method name="checkUsernameExistence"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="response" type="android.accounts.IAccountManagerResponse">
+</parameter>
+<parameter name="accountType" type="java.lang.String">
+</parameter>
+<parameter name="username" type="java.lang.String">
+</parameter>
+<exception name="RemoteException" type="android.os.RemoteException">
+</exception>
+</method>
+<method name="clearPassword"
+ 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>
+<exception name="RemoteException" type="android.os.RemoteException">
+</exception>
+</method>
+<method name="editProperties"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="response" type="android.accounts.IAccountManagerResponse">
+</parameter>
+<parameter name="accountType" type="java.lang.String">
+</parameter>
+<exception name="RemoteException" type="android.os.RemoteException">
+</exception>
+</method>
+<method name="getAccounts"
+ return="android.accounts.Account[]"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<exception name="RemoteException" type="android.os.RemoteException">
+</exception>
+</method>
+<method name="getAccountsByType"
+ 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>
+<exception name="RemoteException" type="android.os.RemoteException">
+</exception>
+</method>
+<method name="getAuthToken"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="response" type="android.accounts.IAccountManagerResponse">
+</parameter>
+<parameter name="account" type="android.accounts.Account">
+</parameter>
+<parameter name="authTokenType" type="java.lang.String">
+</parameter>
+<parameter name="notifyOnAuthFailure" type="boolean">
+</parameter>
+<exception name="RemoteException" type="android.os.RemoteException">
+</exception>
+</method>
+<method name="getPassword"
+ 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>
+<exception name="RemoteException" type="android.os.RemoteException">
+</exception>
+</method>
+<method name="getPasswordStrength"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="response" type="android.accounts.IAccountManagerResponse">
+</parameter>
+<parameter name="accountType" type="java.lang.String">
+</parameter>
+<parameter name="password" type="java.lang.String">
+</parameter>
+<exception name="RemoteException" type="android.os.RemoteException">
+</exception>
+</method>
+<method name="getUserData"
+ 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>
+<exception name="RemoteException" type="android.os.RemoteException">
+</exception>
+</method>
+<method name="invalidateAuthToken"
+ 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>
+<exception name="RemoteException" type="android.os.RemoteException">
+</exception>
+</method>
+<method name="onBind"
+ return="android.os.IBinder"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="intent" type="android.content.Intent">
+</parameter>
+</method>
+<method name="peekAuthToken"
+ 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>
+<exception name="RemoteException" type="android.os.RemoteException">
+</exception>
+</method>
+<method name="readAuthTokenFromDatabase"
+ 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="removeAccount"
+ 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>
+<exception name="RemoteException" type="android.os.RemoteException">
+</exception>
+</method>
+<method name="setAuthToken"
+ 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>
+<exception name="RemoteException" type="android.os.RemoteException">
+</exception>
+</method>
+<method name="setPassword"
+ 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>
+<exception name="RemoteException" type="android.os.RemoteException">
+</exception>
+</method>
+<method name="setUserData"
+ 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>
+<exception name="RemoteException" type="android.os.RemoteException">
+</exception>
+</method>
+<method name="updatePassword"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="response" type="android.accounts.IAccountManagerResponse">
+</parameter>
+<parameter name="account" type="android.accounts.Account">
+</parameter>
+<exception name="RemoteException" type="android.os.RemoteException">
+</exception>
+</method>
+<field name="mAuthTokenCache"
+ type="java.util.HashMap"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+</class>
+<class name="AccountManagerService.AuthTokenKey"
+ extends="java.lang.Object"
+ abstract="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<constructor name="AccountManagerService.AuthTokenKey"
+ type="android.accounts.AccountManagerService.AuthTokenKey"
+ 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>
+</constructor>
+<field name="mAccount"
+ type="android.accounts.Account"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="mAuthTokenType"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+</class>
+<class name="AccountMonitor"
+ extends="android.content.BroadcastReceiver"
+ abstract="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<constructor name="AccountMonitor"
+ type="android.accounts.AccountMonitor"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="context" type="android.content.Context">
+</parameter>
+<parameter name="listener" type="android.accounts.AccountMonitorListener">
+</parameter>
+</constructor>
+<method name="close"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="true"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="onReceive"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="context" type="android.content.Context">
+</parameter>
+<parameter name="intent" type="android.content.Intent">
+</parameter>
+</method>
+</class>
+<interface name="AccountMonitorListener"
+ abstract="true"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<method name="onAccountsUpdated"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="currentAccounts" type="java.lang.String[]">
+</parameter>
+</method>
+</interface>
+<class name="AccountsServiceConstants"
+ extends="java.lang.Object"
+ abstract="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<method name="isForAccountsService"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="bindIntent" type="android.content.Intent">
+</parameter>
+</method>
+<field name="LOGIN_ACCOUNTS_CHANGED_ACTION"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;android.accounts.LOGIN_ACCOUNTS_CHANGED&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="LOGIN_ACCOUNTS_MISSING_ACTION"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;android.accounts.LOGIN_ACCOUNTS_MISSING&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="SERVICE_INTENT"
+ type="android.content.Intent"
+ transient="false"
+ volatile="false"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+</class>
+<class name="AuthenticatorBindHelper"
+ extends="java.lang.Object"
+ abstract="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<constructor name="AuthenticatorBindHelper"
+ type="android.accounts.AuthenticatorBindHelper"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="context" type="android.content.Context">
+</parameter>
+<parameter name="authenticatorCache" type="android.accounts.AccountAuthenticatorCache">
+</parameter>
+<parameter name="handler" type="android.os.Handler">
+</parameter>
+<parameter name="messageWhatConnected" type="int">
+</parameter>
+<parameter name="messageWhatDisconnected" type="int">
+</parameter>
+</constructor>
+<method name="bind"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="authenticatorType" type="java.lang.String">
+</parameter>
+<parameter name="callback" type="android.accounts.AuthenticatorBindHelper.Callback">
+</parameter>
+</method>
+<method name="unbind"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="callbackToUnbind" type="android.accounts.AuthenticatorBindHelper.Callback">
+</parameter>
+</method>
+</class>
+<interface name="AuthenticatorBindHelper.Callback"
+ abstract="true"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<method name="onConnected"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="service" type="android.os.IBinder">
+</parameter>
+</method>
+<method name="onDisconnected"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+</interface>
+<interface name="IAccountAuthenticator"
+ abstract="true"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<implements name="android.os.IInterface">
+</implements>
+<method name="addAccount"
+ 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="accountType" type="java.lang.String">
+</parameter>
+<exception name="RemoteException" type="android.os.RemoteException">
+</exception>
+</method>
+<method name="authenticateAccount"
+ 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="name" type="java.lang.String">
+</parameter>
+<parameter name="type" type="java.lang.String">
+</parameter>
+<parameter name="password" type="java.lang.String">
+</parameter>
+<exception name="RemoteException" type="android.os.RemoteException">
+</exception>
+</method>
+<method name="checkUsernameExistence"
+ 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="accountType" type="java.lang.String">
+</parameter>
+<parameter name="username" type="java.lang.String">
+</parameter>
+<exception name="RemoteException" type="android.os.RemoteException">
+</exception>
+</method>
+<method name="editProperties"
+ 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="accountType" type="java.lang.String">
+</parameter>
+<exception name="RemoteException" type="android.os.RemoteException">
+</exception>
+</method>
+<method name="getAuthToken"
+ 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="name" type="java.lang.String">
+</parameter>
+<parameter name="type" type="java.lang.String">
+</parameter>
+<parameter name="authTokenType" type="java.lang.String">
+</parameter>
+<exception name="RemoteException" type="android.os.RemoteException">
+</exception>
+</method>
+<method name="getPasswordStrength"
+ 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="accountType" type="java.lang.String">
+</parameter>
+<parameter name="password" type="java.lang.String">
+</parameter>
+<exception name="RemoteException" type="android.os.RemoteException">
+</exception>
+</method>
+<method name="updatePassword"
+ 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="name" type="java.lang.String">
+</parameter>
+<parameter name="type" type="java.lang.String">
+</parameter>
+<exception name="RemoteException" type="android.os.RemoteException">
+</exception>
+</method>
+</interface>
+<class name="IAccountAuthenticator.Stub"
+ extends="android.os.Binder"
+ abstract="true"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<implements name="android.accounts.IAccountAuthenticator">
+</implements>
+<constructor name="IAccountAuthenticator.Stub"
+ type="android.accounts.IAccountAuthenticator.Stub"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</constructor>
+<method name="asBinder"
+ return="android.os.IBinder"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="asInterface"
+ return="android.accounts.IAccountAuthenticator"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="obj" type="android.os.IBinder">
+</parameter>
+</method>
+<method name="onTransact"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="code" type="int">
+</parameter>
+<parameter name="data" type="android.os.Parcel">
+</parameter>
+<parameter name="reply" type="android.os.Parcel">
+</parameter>
+<parameter name="flags" type="int">
+</parameter>
+<exception name="RemoteException" type="android.os.RemoteException">
+</exception>
+</method>
+</class>
+<interface name="IAccountAuthenticatorResponse"
+ abstract="true"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<implements name="android.os.IInterface">
+</implements>
+<method name="onBooleanResult"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="result" type="boolean">
+</parameter>
+<exception name="RemoteException" type="android.os.RemoteException">
+</exception>
+</method>
+<method name="onError"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="errorCode" type="int">
+</parameter>
+<parameter name="errorMessage" type="java.lang.String">
+</parameter>
+<exception name="RemoteException" type="android.os.RemoteException">
+</exception>
+</method>
+<method name="onIntResult"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="result" type="int">
+</parameter>
+<exception name="RemoteException" type="android.os.RemoteException">
+</exception>
+</method>
+<method name="onStringResult"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="result" type="java.lang.String">
+</parameter>
+<exception name="RemoteException" type="android.os.RemoteException">
+</exception>
+</method>
+</interface>
+<class name="IAccountAuthenticatorResponse.Stub"
+ extends="android.os.Binder"
+ abstract="true"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<implements name="android.accounts.IAccountAuthenticatorResponse">
+</implements>
+<constructor name="IAccountAuthenticatorResponse.Stub"
+ type="android.accounts.IAccountAuthenticatorResponse.Stub"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</constructor>
+<method name="asBinder"
+ return="android.os.IBinder"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="asInterface"
+ return="android.accounts.IAccountAuthenticatorResponse"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="obj" type="android.os.IBinder">
+</parameter>
+</method>
+<method name="onTransact"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="code" type="int">
+</parameter>
+<parameter name="data" type="android.os.Parcel">
+</parameter>
+<parameter name="reply" type="android.os.Parcel">
+</parameter>
+<parameter name="flags" type="int">
+</parameter>
+<exception name="RemoteException" type="android.os.RemoteException">
+</exception>
+</method>
+</class>
+<interface name="IAccountManager"
+ abstract="true"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<implements name="android.os.IInterface">
+</implements>
+<method name="addAccount"
+ return="boolean"
+ abstract="true"
+ 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>
+<exception name="RemoteException" type="android.os.RemoteException">
+</exception>
+</method>
+<method name="addAccountInteractively"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="response" type="android.accounts.IAccountManagerResponse">
+</parameter>
+<parameter name="accountType" type="java.lang.String">
+</parameter>
+<exception name="RemoteException" type="android.os.RemoteException">
+</exception>
+</method>
+<method name="authenticateAccount"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="response" type="android.accounts.IAccountManagerResponse">
+</parameter>
+<parameter name="account" type="android.accounts.Account">
+</parameter>
+<parameter name="password" type="java.lang.String">
+</parameter>
+<exception name="RemoteException" type="android.os.RemoteException">
+</exception>
+</method>
+<method name="checkUsernameExistence"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="response" type="android.accounts.IAccountManagerResponse">
+</parameter>
+<parameter name="accountType" type="java.lang.String">
+</parameter>
+<parameter name="username" type="java.lang.String">
+</parameter>
+<exception name="RemoteException" type="android.os.RemoteException">
+</exception>
+</method>
+<method name="clearPassword"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="account" type="android.accounts.Account">
+</parameter>
+<exception name="RemoteException" type="android.os.RemoteException">
+</exception>
+</method>
+<method name="editProperties"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="response" type="android.accounts.IAccountManagerResponse">
+</parameter>
+<parameter name="accountType" type="java.lang.String">
+</parameter>
+<exception name="RemoteException" type="android.os.RemoteException">
+</exception>
+</method>
+<method name="getAccounts"
+ return="android.accounts.Account[]"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<exception name="RemoteException" type="android.os.RemoteException">
+</exception>
+</method>
+<method name="getAccountsByType"
+ return="android.accounts.Account[]"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="accountType" type="java.lang.String">
+</parameter>
+<exception name="RemoteException" type="android.os.RemoteException">
+</exception>
+</method>
+<method name="getAuthToken"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="response" type="android.accounts.IAccountManagerResponse">
+</parameter>
+<parameter name="account" type="android.accounts.Account">
+</parameter>
+<parameter name="authTokenType" type="java.lang.String">
+</parameter>
+<parameter name="notifyOnAuthFailure" type="boolean">
+</parameter>
+<exception name="RemoteException" type="android.os.RemoteException">
+</exception>
+</method>
+<method name="getPassword"
+ return="java.lang.String"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="account" type="android.accounts.Account">
+</parameter>
+<exception name="RemoteException" type="android.os.RemoteException">
+</exception>
+</method>
+<method name="getPasswordStrength"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="response" type="android.accounts.IAccountManagerResponse">
+</parameter>
+<parameter name="accountType" type="java.lang.String">
+</parameter>
+<parameter name="password" type="java.lang.String">
+</parameter>
+<exception name="RemoteException" type="android.os.RemoteException">
+</exception>
+</method>
+<method name="getUserData"
+ return="java.lang.String"
+ abstract="true"
+ 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>
+<exception name="RemoteException" type="android.os.RemoteException">
+</exception>
+</method>
+<method name="invalidateAuthToken"
+ return="void"
+ abstract="true"
+ 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>
+<exception name="RemoteException" type="android.os.RemoteException">
+</exception>
+</method>
+<method name="peekAuthToken"
+ return="java.lang.String"
+ abstract="true"
+ 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>
+<exception name="RemoteException" type="android.os.RemoteException">
+</exception>
+</method>
+<method name="removeAccount"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="account" type="android.accounts.Account">
+</parameter>
+<exception name="RemoteException" type="android.os.RemoteException">
+</exception>
+</method>
+<method name="setAuthToken"
+ return="void"
+ abstract="true"
+ 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>
+<exception name="RemoteException" type="android.os.RemoteException">
+</exception>
+</method>
+<method name="setPassword"
+ return="void"
+ abstract="true"
+ 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>
+<exception name="RemoteException" type="android.os.RemoteException">
+</exception>
+</method>
+<method name="setUserData"
+ return="void"
+ abstract="true"
+ 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>
+<exception name="RemoteException" type="android.os.RemoteException">
+</exception>
+</method>
+<method name="updatePassword"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="response" type="android.accounts.IAccountManagerResponse">
+</parameter>
+<parameter name="account" type="android.accounts.Account">
+</parameter>
+<exception name="RemoteException" type="android.os.RemoteException">
+</exception>
+</method>
+</interface>
+<class name="IAccountManager.Stub"
+ extends="android.os.Binder"
+ abstract="true"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<implements name="android.accounts.IAccountManager">
+</implements>
+<constructor name="IAccountManager.Stub"
+ type="android.accounts.IAccountManager.Stub"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</constructor>
+<method name="asBinder"
+ return="android.os.IBinder"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="asInterface"
+ return="android.accounts.IAccountManager"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="obj" type="android.os.IBinder">
+</parameter>
+</method>
+<method name="onTransact"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="code" type="int">
+</parameter>
+<parameter name="data" type="android.os.Parcel">
+</parameter>
+<parameter name="reply" type="android.os.Parcel">
+</parameter>
+<parameter name="flags" type="int">
+</parameter>
+<exception name="RemoteException" type="android.os.RemoteException">
+</exception>
+</method>
+</class>
+<interface name="IAccountManagerResponse"
+ abstract="true"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<implements name="android.os.IInterface">
+</implements>
+<method name="onBooleanResult"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="value" type="boolean">
+</parameter>
+<exception name="RemoteException" type="android.os.RemoteException">
+</exception>
+</method>
+<method name="onError"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="errorCode" type="int">
+</parameter>
+<parameter name="errorMessage" type="java.lang.String">
+</parameter>
+<exception name="RemoteException" type="android.os.RemoteException">
+</exception>
+</method>
+<method name="onIntResult"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="value" type="int">
+</parameter>
+<exception name="RemoteException" type="android.os.RemoteException">
+</exception>
+</method>
+<method name="onStringResult"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="value" type="java.lang.String">
+</parameter>
+<exception name="RemoteException" type="android.os.RemoteException">
+</exception>
+</method>
+</interface>
+<class name="IAccountManagerResponse.Stub"
+ extends="android.os.Binder"
+ abstract="true"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<implements name="android.accounts.IAccountManagerResponse">
+</implements>
+<constructor name="IAccountManagerResponse.Stub"
+ type="android.accounts.IAccountManagerResponse.Stub"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</constructor>
+<method name="asBinder"
+ return="android.os.IBinder"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="asInterface"
+ return="android.accounts.IAccountManagerResponse"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="obj" type="android.os.IBinder">
+</parameter>
+</method>
+<method name="onTransact"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="code" type="int">
+</parameter>
+<parameter name="data" type="android.os.Parcel">
+</parameter>
+<parameter name="reply" type="android.os.Parcel">
+</parameter>
+<parameter name="flags" type="int">
+</parameter>
+<exception name="RemoteException" type="android.os.RemoteException">
+</exception>
+</method>
+</class>
+</package>
 <package name="android.app"
 >
 <class name="Activity"
@@ -24948,6 +27311,17 @@
 <parameter name="receiver" type="android.content.BroadcastReceiver">
 </parameter>
 </method>
+<field name="ACCOUNT_SERVICE"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;account&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="ACTIVITY_SERVICE"
  type="java.lang.String"
  transient="false"
@@ -58085,7 +60459,7 @@
  type="float"
  transient="false"
  volatile="false"
- value="0.0010f"
+ value="0.001f"
  static="true"
  final="true"
  deprecated="not deprecated"
diff --git a/core/java/android/accounts/AbstractAccountAuthenticator.java b/core/java/android/accounts/AbstractAccountAuthenticator.java
new file mode 100644
index 0000000..ed683d7
--- /dev/null
+++ b/core/java/android/accounts/AbstractAccountAuthenticator.java
@@ -0,0 +1,126 @@
+/*
+ * 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.RemoteException;
+
+/**
+ * Base class for creating AccountAuthenticators. This implements the IAccountAuthenticator
+ * binder interface and also provides helper libraries to simplify the creation of
+ * AccountAuthenticators.
+ */
+public abstract class AbstractAccountAuthenticator {
+    private static final String TAG = "AccountAuthenticator";
+
+    class Transport extends IAccountAuthenticator.Stub {
+        public void addAccount(IAccountAuthenticatorResponse response, String accountType)
+                throws RemoteException {
+            AbstractAccountAuthenticator.this.addAccount(new AccountAuthenticatorResponse(response),
+                    accountType);
+        }
+
+        public void authenticateAccount(IAccountAuthenticatorResponse
+                response, String name, String type, String password)
+                throws RemoteException {
+            AbstractAccountAuthenticator.this.authenticateAccount(
+                    new AccountAuthenticatorResponse(response), new Account(name, type), password);
+        }
+
+        public void getAuthToken(IAccountAuthenticatorResponse response,
+                String name, String type, String authTokenType)
+                throws RemoteException {
+            AbstractAccountAuthenticator.this.getAuthToken(
+                    new AccountAuthenticatorResponse(response),
+                    new Account(name, type), authTokenType);
+        }
+
+        public void getPasswordStrength(IAccountAuthenticatorResponse response,
+                String accountType, String password)
+                throws RemoteException {
+            AbstractAccountAuthenticator.this.getPasswordStrength(
+                    new AccountAuthenticatorResponse(response), accountType, password);
+        }
+
+        public void checkUsernameExistence(IAccountAuthenticatorResponse response,
+                String accountType, String username)
+                throws RemoteException {
+            AbstractAccountAuthenticator.this.checkUsernameExistence(
+                    new AccountAuthenticatorResponse(response), accountType, username);
+        }
+
+        public void updatePassword(IAccountAuthenticatorResponse response, String name, String type)
+                throws RemoteException {
+            AbstractAccountAuthenticator.this.updatePassword(
+                    new AccountAuthenticatorResponse(response), new Account(name, type));
+        }
+
+        public void editProperties(IAccountAuthenticatorResponse response, String accountType)
+                throws RemoteException {
+            AbstractAccountAuthenticator.this.editProperties(
+                    new AccountAuthenticatorResponse(response), accountType);
+        }
+    }
+
+    Transport mTransport = new Transport();
+
+    /**
+     * @return the IAccountAuthenticator binder transport object
+     */
+    public final IAccountAuthenticator getIAccountAuthenticator()
+    {
+        return mTransport;
+    }
+
+    /**
+     * prompts the user for account information and adds the result to the IAccountManager
+     */
+    public abstract void addAccount(AccountAuthenticatorResponse response, String accountType);
+
+    /**
+     * prompts the user for the credentials of the account
+     */
+    public abstract void authenticateAccount(AccountAuthenticatorResponse response,
+            Account account, String password);
+
+    /**
+     * gets the password by either prompting the user or querying the IAccountManager
+     */
+    public abstract void getAuthToken(AccountAuthenticatorResponse response,
+            Account account, String authTokenType);
+
+    /**
+     * does local analysis or uses a service in the cloud
+     */
+    public abstract void getPasswordStrength(AccountAuthenticatorResponse response,
+        String accountType, String password);
+
+    /**
+     * checks with the login service in the cloud
+     */
+    public abstract void checkUsernameExistence(AccountAuthenticatorResponse response,
+        String accountType, String username);
+
+    /**
+     * prompts the user for a new password and writes it to the IAccountManager
+     */
+    public abstract void updatePassword(AccountAuthenticatorResponse response, Account account);
+
+    /**
+     * launches an activity that lets the user edit and set the properties for an authenticator
+     */
+    public abstract void editProperties(AccountAuthenticatorResponse response, String accountType);
+}
diff --git a/core/java/android/accounts/Account.aidl b/core/java/android/accounts/Account.aidl
new file mode 100644
index 0000000..8752d99
--- /dev/null
+++ b/core/java/android/accounts/Account.aidl
@@ -0,0 +1,19 @@
+/*
+ * 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;
+
+parcelable Account;
diff --git a/core/java/android/accounts/Account.java b/core/java/android/accounts/Account.java
new file mode 100644
index 0000000..efcd366
--- /dev/null
+++ b/core/java/android/accounts/Account.java
@@ -0,0 +1,77 @@
+/*
+ * 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.Parcelable;
+import android.os.Parcel;
+
+/**
+ * Value type that represents an Account in the {@link AccountManager}. This object is
+ * {@link Parcelable} and also overrides {@link #equals} and {@link #hashCode}, making it
+ * 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 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);
+    }
+
+    public int hashCode() {
+        int result = 17;
+        result = 31 * result + mName.hashCode();
+        result = 31 * result + mType.hashCode();
+        return result;
+    }
+
+    public Account(String name, String type) {
+        mName = name;
+        mType = type;
+    }
+
+    public Account(Parcel in) {
+        mName = in.readString();
+        mType = in.readString();
+    }
+
+    public int describeContents() {
+        return 0;
+    }
+
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeString(mName);
+        dest.writeString(mType);
+    }
+
+    public static final Creator<Account> CREATOR = new Creator<Account>() {
+        public Account createFromParcel(Parcel source) {
+            return new Account(source);
+        }
+
+        public Account[] newArray(int size) {
+            return new Account[size];
+        }
+    };
+
+    public String toString() {
+        return "Account {name=" + mName + ", type=" + mType + "}";
+    }
+}
diff --git a/core/java/android/accounts/AccountAuthenticatorCache.java b/core/java/android/accounts/AccountAuthenticatorCache.java
new file mode 100644
index 0000000..72b6bde
--- /dev/null
+++ b/core/java/android/accounts/AccountAuthenticatorCache.java
@@ -0,0 +1,197 @@
+/*
+ * 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.content.*;
+import android.content.res.XmlResourceParser;
+import android.content.res.TypedArray;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.content.pm.ServiceInfo;
+import android.util.Log;
+import android.util.AttributeSet;
+import android.util.Xml;
+
+import java.util.*;
+import java.io.IOException;
+
+import com.google.android.collect.Maps;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlPullParser;
+
+/**
+ * A cache of services that export the {@link IAccountAuthenticator} interface. This cache
+ * is built by interrogating the {@link PackageManager} and is updated as packages are added,
+ * removed and changed. The authenticators are referred to by their account type and
+ * are made available via the {@link #getAuthenticatorInfo(String type)} method.
+ */
+public class AccountAuthenticatorCache {
+    private static final String TAG = "Account";
+
+    private static final String SERVICE_INTERFACE = "android.accounts.AccountAuthenticator";
+    private static final String SERVICE_META_DATA = "android.accounts.AccountAuthenticator";
+
+    private volatile Map<String, AuthenticatorInfo> mAuthenticators;
+
+    private final Context mContext;
+    private BroadcastReceiver mReceiver;
+
+    public AccountAuthenticatorCache(Context context) {
+        mContext = context;
+        mReceiver = new BroadcastReceiver() {
+            public void onReceive(Context context, Intent intent) {
+                buildAuthenticatorList();
+            }
+        };
+    }
+
+    private void monitorPackageChanges() {
+        IntentFilter intentFilter = new IntentFilter();
+        intentFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
+        intentFilter.addAction(Intent.ACTION_PACKAGE_CHANGED);
+        intentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
+        mContext.registerReceiver(mReceiver, intentFilter);
+    }
+
+    /**
+     * Value type that describes an AccountAuthenticator. The information within can be used
+     * to bind to its {@link IAccountAuthenticator} interface.
+     */
+    public class AuthenticatorInfo {
+        public final String mType;
+        public final String mComponentShortName;
+        public final ComponentName mComponentName;
+
+        private AuthenticatorInfo(String type, ComponentName componentName) {
+            mType = type;
+            mComponentName = componentName;
+            mComponentShortName = componentName.flattenToShortString();
+        }
+    }
+
+    /**
+     * Accessor for the registered authenticators.
+     * @param type the account type of the authenticator
+     * @return the AuthenticatorInfo that matches the account type or null if none is present
+     */
+    public AuthenticatorInfo getAuthenticatorInfo(String type) {
+        if (mAuthenticators == null) {
+            monitorPackageChanges();
+            buildAuthenticatorList();
+        }
+        return mAuthenticators.get(type);
+    }
+
+    /**
+     * @return a collection of {@link AuthenticatorInfo} objects for all
+     * registered authenticators.
+     */
+    public Collection<AuthenticatorInfo> getAllAuthenticators() {
+        if (mAuthenticators == null) {
+            monitorPackageChanges();
+            buildAuthenticatorList();
+        }
+        return Collections.unmodifiableCollection(mAuthenticators.values());
+    }
+
+    /**
+     * Stops the monitoring of package additions, removals and changes.
+     */
+    public void close() {
+        if (mReceiver != null) {
+            mContext.unregisterReceiver(mReceiver);
+            mReceiver = null;
+        }
+    }
+
+    protected void finalize() throws Throwable {
+        if (mReceiver != null) {
+            Log.e(TAG, "AccountAuthenticatorCache finalized without being closed");
+        }
+        close();
+        super.finalize();
+    }
+
+    private void buildAuthenticatorList() {
+        Map<String, AuthenticatorInfo> authenticators = Maps.newHashMap();
+        PackageManager pm = mContext.getPackageManager();
+
+        List<ResolveInfo> services =
+                pm.queryIntentServices(new Intent(SERVICE_INTERFACE), PackageManager.GET_META_DATA);
+
+        for (ResolveInfo resolveInfo : services) {
+            try {
+                AuthenticatorInfo info = parseAuthenticatorInfo(resolveInfo);
+                if (info != null) {
+                    authenticators.put(info.mType, info);
+                } else {
+                    Log.w(TAG, "Unable to load input method " + resolveInfo.toString());
+                }
+            } catch (XmlPullParserException e) {
+                Log.w(TAG, "Unable to load input method " + resolveInfo.toString(), e);
+            } catch (IOException e) {
+                Log.w(TAG, "Unable to load input method " + resolveInfo.toString(), e);
+            }
+        }
+
+        mAuthenticators = authenticators;
+    }
+
+    public AuthenticatorInfo parseAuthenticatorInfo(ResolveInfo service)
+            throws XmlPullParserException, IOException {
+        ServiceInfo si = service.serviceInfo;
+        ComponentName componentName = new ComponentName(si.packageName, si.name);
+
+        PackageManager pm = mContext.getPackageManager();
+        String authenticatorType = null;
+
+        XmlResourceParser parser = null;
+        try {
+            parser = si.loadXmlMetaData(pm, SERVICE_META_DATA);
+            if (parser == null) {
+                throw new XmlPullParserException("No " + SERVICE_META_DATA + " meta-data");
+            }
+
+            AttributeSet attrs = Xml.asAttributeSet(parser);
+
+            int type;
+            while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
+                    && type != XmlPullParser.START_TAG) {
+            }
+
+            String nodeName = parser.getName();
+            if (!"account-authenticator".equals(nodeName)) {
+                throw new XmlPullParserException(
+                        "Meta-data does not start with account-authenticator tag");
+            }
+
+            TypedArray sa = mContext.getResources().obtainAttributes(attrs,
+                    com.android.internal.R.styleable.AccountAuthenticator);
+            authenticatorType = sa.getString(
+                    com.android.internal.R.styleable.AccountAuthenticator_accountType);
+            sa.recycle();
+        } finally {
+            if (parser != null) parser.close();
+        }
+
+        if (authenticatorType == null) {
+            return null;
+        }
+
+        return new AuthenticatorInfo(authenticatorType, componentName);
+    }
+}
diff --git a/core/java/android/accounts/AccountAuthenticatorResponse.java b/core/java/android/accounts/AccountAuthenticatorResponse.java
new file mode 100644
index 0000000..07cee40
--- /dev/null
+++ b/core/java/android/accounts/AccountAuthenticatorResponse.java
@@ -0,0 +1,67 @@
+/*
+ * 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.RemoteException;
+
+/**
+ * Object that wraps calls to an {@link IAccountAuthenticatorResponse} object.
+ * TODO: this interface is still in flux
+ */
+public class AccountAuthenticatorResponse {
+    private IAccountAuthenticatorResponse mAccountAuthenticatorResponse;
+
+    public AccountAuthenticatorResponse(IAccountAuthenticatorResponse response) {
+        mAccountAuthenticatorResponse = response;
+    }
+
+    public void onFinished(int result) {
+        try {
+            mAccountAuthenticatorResponse.onIntResult(result);
+        } catch (RemoteException e) {
+            // this should never happen
+        }
+    }
+
+    public void onFinished(String result) {
+        try {
+            mAccountAuthenticatorResponse.onStringResult(result);
+        } catch (RemoteException e) {
+            // this should never happen
+        }
+    }
+
+    public void onFinished(boolean result) {
+        try {
+            mAccountAuthenticatorResponse.onBooleanResult(result);
+        } catch (RemoteException e) {
+            // this should never happen
+        }
+    }
+
+    public void onError(int errorCode, String errorMessage) {
+        try {
+            mAccountAuthenticatorResponse.onError(errorCode, errorMessage);
+        } catch (RemoteException e) {
+            // this should never happen
+        }
+    }
+
+    public IAccountAuthenticatorResponse getIAccountAuthenticatorResponse() {
+        return mAccountAuthenticatorResponse;
+    }
+}
diff --git a/core/java/android/accounts/AccountManager.java b/core/java/android/accounts/AccountManager.java
new file mode 100644
index 0000000..d0d4750
--- /dev/null
+++ b/core/java/android/accounts/AccountManager.java
@@ -0,0 +1,306 @@
+/*
+ * 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.RemoteException;
+import android.os.Bundle;
+import android.app.PendingIntent;
+import android.app.Activity;
+import android.content.Intent;
+import android.content.Context;
+
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+import java.util.concurrent.locks.Condition;
+
+/**
+ * A class that helps with interactions with the {@link IAccountManager} interface. It provides
+ * methods to allow for account, password, and authtoken management for all accounts on the
+ * device. Some of these calls are implemented with the help of the corresponding
+ * {@link IAccountAuthenticator} services. One accesses the {@link AccountManager} by calling:
+ *    AccountManager accountManager =
+ *      (AccountManager)context.getSystemService(Context.ACCOUNT_SERVICE)
+ *
+ * <p>
+ * TODO: this interface is still in flux
+ */
+public class AccountManager {
+    private static final String TAG = "AccountManager";
+
+    private final Context mContext;
+    private final IAccountManager mService;
+
+    public AccountManager(Context context, IAccountManager service) {
+        mContext = context;
+        mService = service;
+    }
+
+    public String getPassword(Account account) {
+        try {
+            return mService.getPassword(account);
+        } catch (RemoteException e) {
+            // if this happens the entire runtime will restart
+            throw new RuntimeException(e);
+        }
+    }
+
+    public String getUserData(Account account, String key) {
+        try {
+            return mService.getUserData(account, key);
+        } catch (RemoteException e) {
+            // if this happens the entire runtime will restart
+            throw new RuntimeException(e);
+        }
+    }
+
+    public Account[] blockingGetAccounts() {
+        try {
+            return mService.getAccounts();
+        } catch (RemoteException e) {
+            // if this happens the entire runtime will restart
+            throw new RuntimeException(e);
+        }
+    }
+
+    public void getAccounts(final PendingIntent intent, final int code) {
+        getAccountsByType(null /* all account types */, intent, code);
+    }
+
+    public void getAccountsByType(final String accountType,
+            final PendingIntent intent, final int code) {
+        Thread t = new Thread() {
+            public void run() {
+                try {
+                    Account[] accounts;
+                    if (accountType != null) {
+                        accounts = blockingGetAccountsByType(accountType);
+                    } else {
+                        accounts = blockingGetAccounts();
+                    }
+                    Intent payload = new Intent();
+                    payload.putExtra("accounts", accounts);
+                    intent.send(mContext, code, payload);
+                } catch (PendingIntent.CanceledException e) {
+                    // the pending intent is no longer accepting results, we don't
+                    // need to do anything to handle this
+                }
+            }
+        };
+        t.start();
+    }
+
+    public Account[] blockingGetAccountsByType(String accountType) {
+        try {
+            return mService.getAccountsByType(accountType);
+        } catch (RemoteException e) {
+            // if this happens the entire runtime will restart
+            throw new RuntimeException(e);
+        }
+    }
+
+    public boolean addAccount(Account account, String password, Bundle extras) {
+        try {
+            return mService.addAccount(account, password, extras);
+        } catch (RemoteException e) {
+            // if this happens the entire runtime will restart
+            throw new RuntimeException(e);
+        }
+    }
+
+    public void removeAccount(Account account) {
+        try {
+            mService.removeAccount(account);
+        } catch (RemoteException e) {
+            // if this happens the entire runtime will restart
+        }
+    }
+
+    public void invalidateAuthToken(String accountType, String authToken) {
+        try {
+            mService.invalidateAuthToken(accountType, authToken);
+        } catch (RemoteException e) {
+            // if this happens the entire runtime will restart
+        }
+    }
+
+    public String peekAuthToken(Account account, String authTokenType) {
+        try {
+            return mService.peekAuthToken(account, authTokenType);
+        } catch (RemoteException e) {
+            // if this happens the entire runtime will restart
+            throw new RuntimeException(e);
+        }
+    }
+
+    public void setPassword(Account account, String password) {
+        try {
+            mService.setPassword(account, password);
+        } catch (RemoteException e) {
+            // if this happens the entire runtime will restart
+        }
+    }
+
+    public void clearPassword(Account account) {
+        try {
+            mService.clearPassword(account);
+        } catch (RemoteException e) {
+            // if this happens the entire runtime will restart
+        }
+    }
+
+    public void setUserData(Account account, String key, String value) {
+        try {
+            mService.setUserData(account, key, value);
+        } catch (RemoteException e) {
+            // if this happens the entire runtime will restart
+        }
+    }
+
+    public void getAuthToken(AccountManagerResponse response,
+            Account account, String authTokenType, boolean notifyAuthFailure) {
+        try {
+            mService.getAuthToken(response.getIAccountManagerResponse(), account, authTokenType,
+                    notifyAuthFailure);
+        } catch (RemoteException e) {
+            // if this happens the entire runtime will restart
+        }
+    }
+
+    public void setAuthToken(Account account, String authTokenType, String authToken) {
+        try {
+            mService.setAuthToken(account, authTokenType, authToken);
+        } catch (RemoteException e) {
+            // if this happens the entire runtime will restart
+        }
+    }
+
+    public void addAccountInteractively(AccountManagerResponse response, String accountType) {
+        try {
+            mService.addAccountInteractively(response.getIAccountManagerResponse(), accountType);
+        } catch (RemoteException e) {
+            // if this happens the entire runtime will restart
+        }
+    }
+
+    public class AuthenticateAccountThread extends Thread {
+        public Lock mLock = new ReentrantLock();
+        public Condition mCondition = mLock.newCondition();
+        volatile boolean mSuccess = false;
+        volatile boolean mFailure = false;
+        volatile boolean mResult = false;
+        private final Account mAccount;
+        private final String mPassword;
+        public AuthenticateAccountThread(Account account, String password) {
+            mAccount = account;
+            mPassword = password;
+        }
+        public void run() {
+            try {
+                IAccountManagerResponse response = new IAccountManagerResponse.Stub() {
+                    public void onStringResult(String value) throws RemoteException {
+                    }
+
+                    public void onIntResult(int value) throws RemoteException {
+                    }
+
+                    public void onBooleanResult(boolean value) throws RemoteException {
+                        mLock.lock();
+                        try {
+                            if (!mFailure && !mSuccess) {
+                                mSuccess = true;
+                                mResult = value;
+                                mCondition.signalAll();
+                            }
+                        } finally {
+                            mLock.unlock();
+                        }
+                    }
+
+                    public void onError(int errorCode, String errorMessage) {
+                        mLock.lock();
+                        try {
+                            if (!mFailure && !mSuccess) {
+                                mFailure = true;
+                                mCondition.signalAll();
+                            }
+                        } finally {
+                            mLock.unlock();
+                        }
+                    }
+                };
+
+                mService.authenticateAccount(response, mAccount, mPassword);
+            } catch (RemoteException e) {
+                // if this happens the entire runtime will restart
+            }
+        }
+    }
+
+    public boolean authenticateAccount(Account account, String password) {
+        AuthenticateAccountThread thread = new AuthenticateAccountThread(account, password);
+        thread.mLock.lock();
+        thread.start();
+        try {
+          while (!thread.mSuccess && !thread.mFailure) {
+              try {
+                  thread.mCondition.await();
+              } catch (InterruptedException e) {
+                  // keep waiting
+              }
+          }
+          return thread.mResult;
+        } finally {
+          thread.mLock.unlock();
+        }
+    }
+
+    public void updatePassword(AccountManagerResponse response, Account account) {
+        try {
+            mService.updatePassword(response.getIAccountManagerResponse(), account);
+        } catch (RemoteException e) {
+            // if this happens the entire runtime will restart
+        }
+    }
+
+    public void editProperties(AccountManagerResponse response, String accountType) {
+        try {
+            mService.editProperties(response.getIAccountManagerResponse(), accountType);
+        } catch (RemoteException e) {
+            // if this happens the entire runtime will restart
+        }
+    }
+
+    public void getPasswordStrength(AccountManagerResponse response,
+            String accountType, String password) {
+        try {
+            mService.getPasswordStrength(response.getIAccountManagerResponse(),
+                    accountType, password);
+        } catch (RemoteException e) {
+            // if this happens the entire runtime will restart
+        }
+    }
+
+    public void checkUsernameExistence(AccountManagerResponse response,
+            String accountType, String username) {
+        try {
+            mService.checkUsernameExistence(response.getIAccountManagerResponse(),
+                    accountType, username);
+        } catch (RemoteException e) {
+            // if this happens the entire runtime will restart
+        }
+    }
+}
diff --git a/core/java/android/accounts/AccountManagerResponse.java b/core/java/android/accounts/AccountManagerResponse.java
new file mode 100644
index 0000000..b15fb13
--- /dev/null
+++ b/core/java/android/accounts/AccountManagerResponse.java
@@ -0,0 +1,32 @@
+/*
+ * 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;
+
+/**
+ * Object that wraps calls to an {@link IAccountManagerResponse} object.
+ * TODO: this interface is still in flux
+ */
+public class AccountManagerResponse {
+    private IAccountManagerResponse mResponse;
+
+    public AccountManagerResponse(IAccountManagerResponse accountManagerResponse) {
+        mResponse = accountManagerResponse;
+    }
+
+    public IAccountManagerResponse getIAccountManagerResponse() {
+        return mResponse;
+    }
+}
diff --git a/core/java/android/accounts/AccountManagerService.java b/core/java/android/accounts/AccountManagerService.java
new file mode 100644
index 0000000..78d4535
--- /dev/null
+++ b/core/java/android/accounts/AccountManagerService.java
@@ -0,0 +1,901 @@
+/*
+ * 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.*;
+import android.content.*;
+import android.database.sqlite.*;
+import android.database.Cursor;
+import android.database.DatabaseUtils;
+import android.util.Log;
+import android.text.TextUtils;
+import android.telephony.TelephonyManager;
+
+import java.util.HashMap;
+
+import com.google.android.collect.Maps;
+import com.android.internal.telephony.TelephonyIntents;
+
+/**
+ * A system service that provides  account, password, and authtoken management for all
+ * accounts on the device. Some of these calls are implemented with the help of the corresponding
+ * {@link IAccountAuthenticator} services. This service is not accessed by users directly,
+ * instead one uses an instance of {@link AccountManager}, which can be accessed as follows:
+ *    AccountManager accountManager =
+ *      (AccountManager)context.getSystemService(Context.ACCOUNT_SERVICE)
+ */
+public class AccountManagerService extends IAccountManager.Stub {
+    private static final String TAG = "AccountManagerService";
+
+    private static final int TIMEOUT_DELAY_MS = 1000 * 60;
+    private static final String DATABASE_NAME = "accounts.db";
+    private static final int DATABASE_VERSION = 1;
+
+    private final Context mContext;
+
+    private HandlerThread mMessageThread;
+    private final MessageHandler mMessageHandler;
+
+    // Messages that can be sent on mHandler
+    private static final int MESSAGE_TIMED_OUT = 3;
+    private static final int MESSAGE_CONNECTED = 7;
+    private static final int MESSAGE_DISCONNECTED = 8;
+
+    private final AccountAuthenticatorCache mAuthenticatorCache;
+    private final AuthenticatorBindHelper mBindHelper;
+    public final HashMap<AuthTokenKey, String> mAuthTokenCache = Maps.newHashMap();
+    private final DatabaseHelper mOpenHelper;
+    private final SimWatcher mSimWatcher;
+
+    private static final String TABLE_ACCOUNTS = "accounts";
+    private static final String ACCOUNTS_ID = "_id";
+    private static final String ACCOUNTS_NAME = "name";
+    private static final String ACCOUNTS_TYPE = "type";
+    private static final String ACCOUNTS_PASSWORD = "password";
+
+    private static final String TABLE_AUTHTOKENS = "authtokens";
+    private static final String AUTHTOKENS_ID = "_id";
+    private static final String AUTHTOKENS_ACCOUNTS_ID = "accounts_id";
+    private static final String AUTHTOKENS_TYPE = "type";
+    private static final String AUTHTOKENS_AUTHTOKEN = "authtoken";
+
+    private static final String TABLE_EXTRAS = "extras";
+    private static final String EXTRAS_ID = "_id";
+    private static final String EXTRAS_ACCOUNTS_ID = "accounts_id";
+    private static final String EXTRAS_KEY = "key";
+    private static final String EXTRAS_VALUE = "value";
+
+    private static final String TABLE_META = "meta";
+    private static final String META_KEY = "key";
+    private static final String META_VALUE = "value";
+
+    private static final String[] ACCOUNT_NAME_TYPE_PROJECTION =
+            new String[]{ACCOUNTS_ID, ACCOUNTS_NAME, ACCOUNTS_TYPE};
+    private static final Intent ACCOUNTS_CHANGED_INTENT =
+            new Intent(AccountsServiceConstants.LOGIN_ACCOUNTS_CHANGED_ACTION);
+
+    public class AuthTokenKey {
+        public final Account mAccount;
+        public final String mAuthTokenType;
+        private final int mHashCode;
+
+        public AuthTokenKey(Account account, String authTokenType) {
+            mAccount = account;
+            mAuthTokenType = authTokenType;
+            mHashCode = computeHashCode();
+        }
+
+        public boolean equals(Object o) {
+            if (o == this) {
+                return true;
+            }
+            if (!(o instanceof AuthTokenKey)) {
+                return false;
+            }
+            AuthTokenKey other = (AuthTokenKey)o;
+            if (!mAccount.equals(other.mAccount)) {
+                return false;
+            }
+            return (mAuthTokenType == null)
+                    ? other.mAuthTokenType == null
+                    : mAuthTokenType.equals(other.mAuthTokenType);
+        }
+
+        private int computeHashCode() {
+            int result = 17;
+            result = 31 * result + mAccount.hashCode();
+            result = 31 * result + ((mAuthTokenType == null) ? 0 : mAuthTokenType.hashCode());
+            return result;
+        }
+
+        public int hashCode() {
+            return mHashCode;
+        }
+    }
+
+    public AccountManagerService(Context context) {
+        mContext = context;
+
+        mOpenHelper = new DatabaseHelper(mContext);
+
+        mMessageThread = new HandlerThread("AccountManagerService");
+        mMessageThread.start();
+        mMessageHandler = new MessageHandler(mMessageThread.getLooper());
+
+        mAuthenticatorCache = new AccountAuthenticatorCache(mContext);
+        mBindHelper = new AuthenticatorBindHelper(mContext, mAuthenticatorCache, mMessageHandler,
+                MESSAGE_CONNECTED, MESSAGE_DISCONNECTED);
+
+        mSimWatcher = new SimWatcher(mContext);
+    }
+
+    public String getPassword(Account account) throws RemoteException {
+        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);
+        try {
+            if (cursor.moveToNext()) {
+                return cursor.getString(0);
+            }
+            return null;
+        } finally {
+            cursor.close();
+        }
+    }
+
+    public String getUserData(Account account, String key) throws RemoteException {
+        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.setTransactionSuccessful();
+            db.endTransaction();
+        }
+    }
+
+    public Account[] getAccounts() throws RemoteException {
+        return getAccountsByType(null);
+    }
+
+    public Account[] getAccountsByType(String accountType) throws RemoteException {
+        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();
+        }
+    }
+
+    public boolean addAccount(Account account, String password, Bundle extras)
+            throws RemoteException {
+        // fails if the account already exists
+        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();
+            mContext.sendBroadcast(ACCOUNTS_CHANGED_INTENT);
+            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);
+        values.put(EXTRAS_ACCOUNTS_ID, accountId);
+        values.put(EXTRAS_VALUE, value);
+        return db.insert(TABLE_EXTRAS, EXTRAS_KEY, values);
+    }
+
+    public void removeAccount(Account account) throws RemoteException {
+        // clear out matching authtokens from the cache
+        final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+        db.delete(TABLE_ACCOUNTS, ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE+ "=?",
+                new String[]{account.mName, account.mType});
+        mContext.sendBroadcast(ACCOUNTS_CHANGED_INTENT);
+    }
+
+    public void invalidateAuthToken(String accountType, String authToken) throws RemoteException {
+        SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+        db.beginTransaction();
+        try {
+            invalidateAuthToken(db, accountType, authToken);
+            db.setTransactionSuccessful();
+        } finally {
+            db.endTransaction();
+        }
+    }
+
+    private void invalidateAuthToken(SQLiteDatabase db, String accountType, String authToken) {
+        Cursor cursor = db.rawQuery(
+                "SELECT " + TABLE_AUTHTOKENS + "." + AUTHTOKENS_ID
+                        + ", " + TABLE_ACCOUNTS + "." + ACCOUNTS_NAME
+                        + ", " + TABLE_AUTHTOKENS + "." + AUTHTOKENS_TYPE
+                        + " FROM " + TABLE_ACCOUNTS
+                        + " JOIN " + TABLE_AUTHTOKENS
+                        + " ON " + TABLE_ACCOUNTS + "." + ACCOUNTS_ID
+                        + " = " + AUTHTOKENS_ACCOUNTS_ID
+                        + " WHERE " + AUTHTOKENS_AUTHTOKEN + " = ? AND "
+                        + TABLE_ACCOUNTS + "." + ACCOUNTS_TYPE + " = ?",
+                new String[]{authToken, accountType});
+        try {
+            while (cursor.moveToNext()) {
+                long authTokenId = cursor.getLong(0);
+                String accountName = cursor.getString(1);
+                String authTokenType = cursor.getString(2);
+                AuthTokenKey key = new AuthTokenKey(new Account(accountName, accountType),
+                        authTokenType);
+                mAuthTokenCache.remove(key);
+                db.delete(TABLE_AUTHTOKENS, AUTHTOKENS_ID + "=" + authTokenId, null);
+            }
+        } finally {
+            cursor.close();
+        }
+    }
+
+    private boolean saveAuthTokenToDatabase(Account account, String type, String authToken) {
+        SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+        db.beginTransaction();
+        try {
+            if (saveAuthTokenToDatabase(db, account, type, authToken)) {
+                mContext.sendBroadcast(ACCOUNTS_CHANGED_INTENT);
+                db.setTransactionSuccessful();
+                return true;
+            }
+            return false;
+        } finally {
+            db.endTransaction();
+        }
+    }
+
+    private boolean saveAuthTokenToDatabase(SQLiteDatabase db, Account account, 
+            String type, String authToken) {
+        long accountId = getAccountId(db, account);
+        if (accountId < 0) {
+            return false;
+        }
+        db.delete(TABLE_AUTHTOKENS,
+                AUTHTOKENS_ACCOUNTS_ID + "=" + accountId + " AND " + AUTHTOKENS_TYPE + "=?",
+                new String[]{type});
+        ContentValues values = new ContentValues();
+        values.put(AUTHTOKENS_ACCOUNTS_ID, accountId);
+        values.put(AUTHTOKENS_TYPE, type);
+        values.put(AUTHTOKENS_AUTHTOKEN, authToken);
+        return db.insert(TABLE_AUTHTOKENS, AUTHTOKENS_AUTHTOKEN, values) >= 0;
+    }
+
+    public String readAuthTokenFromDatabase(Account account, String authTokenType) {
+        SQLiteDatabase db = mOpenHelper.getReadableDatabase();
+        db.beginTransaction();
+        try {
+            long accountId = getAccountId(db, account);
+            if (accountId < 0) {
+                return null;
+            }
+            return getAuthToken(db, accountId, authTokenType);
+        } finally {
+            db.setTransactionSuccessful();
+            db.endTransaction();
+        }
+    }
+
+    public String peekAuthToken(Account account, String authTokenType) throws RemoteException {
+        AuthTokenKey key = new AuthTokenKey(account, authTokenType);
+        if (mAuthTokenCache.containsKey(key)) {
+            return mAuthTokenCache.get(key);
+        }
+        return readAuthTokenFromDatabase(account, authTokenType);
+    }
+
+    public void setAuthToken(Account account, String authTokenType, String authToken)
+            throws RemoteException {
+        cacheAuthToken(account, authTokenType, authToken);
+    }
+
+    public void setPassword(Account account, String password) throws RemoteException {
+        ContentValues values = new ContentValues();
+        values.put(ACCOUNTS_PASSWORD, password);
+        mOpenHelper.getWritableDatabase().update(TABLE_ACCOUNTS, values,
+                ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE+ "=?",
+                new String[]{account.mName, account.mType});
+        mContext.sendBroadcast(ACCOUNTS_CHANGED_INTENT);
+    }
+
+    public void clearPassword(Account account) throws RemoteException {
+        setPassword(account, null);
+    }
+
+    public void setUserData(Account account, String key, String value) throws RemoteException {
+        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();
+        }
+    }
+
+    public void getAuthToken(IAccountManagerResponse response, Account account,
+            String authTokenType, boolean notifyOnAuthFailure) throws RemoteException {
+        // create a new Session
+        Session session = new GetAuthTokenSession(response, account, authTokenType,
+                notifyOnAuthFailure);
+
+        String authToken = getCachedAuthToken(account, authTokenType);
+        if (authToken != null) {
+            session.onStringResult(authToken);
+            return;
+        }
+
+        session.bind();
+    }
+
+    public void addAccountInteractively(IAccountManagerResponse response, String accountType)
+            throws RemoteException {
+        new AddAccountInteractivelySession(response, accountType).bind();
+    }
+
+    public void authenticateAccount(IAccountManagerResponse response, Account account,
+            String password)
+            throws RemoteException {
+        new AuthenticateAccountSession(response, account, password).bind();
+    }
+
+    public void updatePassword(IAccountManagerResponse response, Account account)
+            throws RemoteException {
+        new UpdatePasswordSession(response, account).bind();
+    }
+
+    public void editProperties(IAccountManagerResponse response, String accountType)
+            throws RemoteException {
+        new EditPropertiesSession(response, accountType).bind();
+    }
+
+    public void getPasswordStrength(IAccountManagerResponse response,
+            String accountType, String password) throws RemoteException {
+        new GetPasswordStrengthSession(response, accountType, password).bind();
+    }
+
+    public void checkUsernameExistence(IAccountManagerResponse response,
+            String accountType, String username) throws RemoteException {
+        new CheckUsernameExistenceSession(response, username, accountType).bind();
+    }
+
+    private boolean cacheAuthToken(Account account, String authTokenType, String authToken) {
+        if (saveAuthTokenToDatabase(account, authTokenType, authToken)) {
+            final AuthTokenKey key = new AuthTokenKey(account, authTokenType);
+            mAuthTokenCache.put(key, authToken);
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    private String getCachedAuthToken(Account account, String authTokenType) {
+        final AuthTokenKey key = new AuthTokenKey(account, authTokenType);
+        if (!mAuthTokenCache.containsKey(key)) return null;
+        return mAuthTokenCache.get(key);
+    }
+
+    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);
+        try {
+            if (cursor.moveToNext()) {
+                return cursor.getLong(0);
+            }
+            return -1;
+        } finally {
+            cursor.close();
+        }
+    }
+
+    private long getExtrasId(SQLiteDatabase db, long accountId, String key) {
+        Cursor cursor = db.query(TABLE_EXTRAS, new String[]{EXTRAS_ID},
+                EXTRAS_ACCOUNTS_ID + "=" + accountId + " AND " + EXTRAS_KEY + "=?",
+                new String[]{key}, null, null, null);
+        try {
+            if (cursor.moveToNext()) {
+                return cursor.getLong(0);
+            }
+            return -1;
+        } finally {
+            cursor.close();
+        }
+    }
+
+    private String getAuthToken(SQLiteDatabase db, long accountId, String authTokenType) {
+        Cursor cursor = db.query(TABLE_AUTHTOKENS, new String[]{AUTHTOKENS_AUTHTOKEN},
+                AUTHTOKENS_ACCOUNTS_ID + "=" + accountId + " AND " + AUTHTOKENS_TYPE + "=?",
+                new String[]{authTokenType},
+                null, null, null);
+        try {
+            if (cursor.moveToNext()) {
+                return cursor.getString(0);
+            }
+            return null;
+        } finally {
+            cursor.close();
+        }
+    }
+
+    private class Session extends IAccountAuthenticatorResponse.Stub
+            implements AuthenticatorBindHelper.Callback {
+        IAccountManagerResponse mResponse;
+        final String mAccountType;
+
+        IAccountAuthenticator mAuthenticator = null;
+
+        public Session(IAccountManagerResponse response, String accountType) {
+            super();
+            mResponse = response;
+            mAccountType = accountType;
+        }
+
+        IAccountManagerResponse close() {
+            if (mResponse == null) {
+                // this session has already been closed
+                return null;
+            }
+            cancelTimeout();
+            unbind();
+            IAccountManagerResponse response = mResponse;
+            mResponse = null;
+            return response;
+        }
+
+        void bind() {
+            if (!mBindHelper.bind(mAccountType, this)) {
+                onError(6, "bind failure");
+            }
+        }
+
+        private void unbind() {
+            if (mAuthenticator != null) {
+                mAuthenticator = null;
+                mBindHelper.unbind(this);
+            }
+        }
+
+        public void scheduleTimeout() {
+            mMessageHandler.sendMessageDelayed(
+                    mMessageHandler.obtainMessage(MESSAGE_TIMED_OUT, this), TIMEOUT_DELAY_MS);
+        }
+
+        public void cancelTimeout() {
+            mMessageHandler.removeMessages(MESSAGE_TIMED_OUT, this);
+        }
+
+        public void onConnected(IBinder service) {
+            mAuthenticator = IAccountAuthenticator.Stub.asInterface(service);
+            // do the next step
+        }
+
+        public void onDisconnected() {
+            IAccountManagerResponse response = close();
+            if (response != null) {
+                onError(3, "disconnected");
+            }
+        }
+
+        public void onTimedOut() {
+            IAccountManagerResponse response = close();
+            if (response != null) {
+                onError(4, "timeout");
+            }
+        }
+
+        public void onIntResult(int result) throws RemoteException {
+            IAccountManagerResponse response = close();
+            if (response != null) {
+                response.onIntResult(result);
+            }
+        }
+
+        public void onBooleanResult(boolean result) throws RemoteException {
+            IAccountManagerResponse response = close();
+            if (response != null) {
+                response.onBooleanResult(result);
+            }
+        }
+
+        public void onStringResult(String result) throws RemoteException {
+            IAccountManagerResponse response = close();
+            if (response != null) {
+                response.onStringResult(result);
+            }
+        }
+
+        public void onError(int errorCode, String errorMessage) {
+            IAccountManagerResponse response = close();
+            if (response != null) {
+                try {
+                    response.onError(errorCode, errorMessage);
+                } catch (RemoteException e) {
+                    // error while trying to notify user of an error
+                }
+            }
+        }
+    }
+
+    private class GetAuthTokenSession extends Session {
+        final Account mAccount;
+        final String mAuthTokenType;
+        final boolean mNotifyOnAuthFailure;
+
+        public GetAuthTokenSession(IAccountManagerResponse response,
+                Account account, String authTokenType, boolean interactive) {
+            super(response, account.mType);
+            mAccount = account;
+            mAuthTokenType = authTokenType;
+            mNotifyOnAuthFailure = interactive;
+        }
+
+        public void onConnected(IBinder service) {
+            super.onConnected(service);
+
+            try {
+                mAuthenticator.getAuthToken(this, mAccount.mName, mAccount.mType, mAuthTokenType);
+            } catch (RemoteException e) {
+                onError(4, "remote exception");
+            }
+        }
+
+        public void onStringResult(String result) throws RemoteException {
+            IAccountManagerResponse response = close();
+            if (response != null) {
+                cacheAuthToken(mAccount, mAccountType, result);
+                response.onStringResult(result);
+            }
+        }
+
+        public void onError(int errorCode, String errorMessage) {
+            if (mNotifyOnAuthFailure && errorCode == 0 /* TODO: put the real value here */) {
+                // TODO: authentication failed, pop up the notification
+            }
+            super.onError(errorCode, errorMessage);
+        }
+    }
+
+    private class CheckUsernameExistenceSession extends Session {
+        final String mUsername;
+
+        public CheckUsernameExistenceSession(IAccountManagerResponse response,
+                String username, String accountType) {
+            super(response, accountType);
+            mUsername = username;
+        }
+
+        public void onConnected(IBinder service) {
+            super.onConnected(service);
+
+            try {
+                mAuthenticator.checkUsernameExistence(this, mAccountType, mUsername);
+            } catch (RemoteException e) {
+                onError(4, "remote exception");
+            }
+        }
+    }
+
+    private class AddAccountInteractivelySession extends Session {
+
+        public AddAccountInteractivelySession(IAccountManagerResponse response,
+                String accountType) {
+            super(response, accountType);
+        }
+
+        public void onConnected(IBinder service) {
+            super.onConnected(service);
+
+            try {
+                mAuthenticator.addAccount(this, mAccountType);
+            } catch (RemoteException e) {
+                onError(4, "remote exception");
+            }
+        }
+    }
+
+    private class AuthenticateAccountSession extends Session {
+        final String mUsername;
+        final String mPassword;
+
+        public AuthenticateAccountSession(IAccountManagerResponse response, Account account,
+                String password) {
+            super(response, account.mType);
+            mUsername = account.mName;
+            mPassword = password;
+        }
+
+        public void onConnected(IBinder service) {
+            super.onConnected(service);
+
+            try {
+                mAuthenticator.authenticateAccount(this, mUsername, mAccountType, mPassword);
+            } catch (RemoteException e) {
+                onError(4, "remote exception");
+            }
+        }
+    }
+
+    private class UpdatePasswordSession extends Session {
+        final String mUsername;
+
+        public UpdatePasswordSession(IAccountManagerResponse response, Account account) {
+            super(response, account.mType);
+            mUsername = account.mName;
+        }
+
+        public void onConnected(IBinder service) {
+            super.onConnected(service);
+
+            try {
+                mAuthenticator.updatePassword(this, mUsername, mAccountType);
+            } catch (RemoteException e) {
+                onError(4, "remote exception");
+            }
+        }
+    }
+
+    private class EditPropertiesSession extends Session {
+        public EditPropertiesSession(IAccountManagerResponse response, String accountType) {
+            super(response, accountType);
+        }
+
+        public void onConnected(IBinder service) {
+            super.onConnected(service);
+
+            try {
+                mAuthenticator.editProperties(this, mAccountType);
+            } catch (RemoteException e) {
+                onError(4, "remote exception");
+            }
+        }
+    }
+
+    private class GetPasswordStrengthSession extends Session {
+        final String mPassword;
+
+        public GetPasswordStrengthSession(IAccountManagerResponse response,
+                String accountType, String password) {
+            super(response, accountType);
+            mPassword = password;
+        }
+
+        public void onConnected(IBinder service) {
+            super.onConnected(service);
+
+            try {
+                mAuthenticator.getPasswordStrength(this, mAccountType, mPassword);
+            } catch (RemoteException e) {
+                onError(4, "remote exception");
+            }
+        }
+    }
+
+    private class MessageHandler extends Handler {
+        MessageHandler(Looper looper) {
+            super(looper);
+        }
+        
+        public void handleMessage(Message msg) {
+            if (mBindHelper.handleMessage(msg)) {
+                return;
+            }
+            switch (msg.what) {
+                case MESSAGE_TIMED_OUT:
+                    Session session = (Session)msg.obj;
+                    session.onTimedOut();
+                    break;
+
+                default:
+                    throw new IllegalStateException("unhandled message: " + msg.what);
+            }
+        }
+    }
+
+    private class DatabaseHelper extends SQLiteOpenHelper {
+        public DatabaseHelper(Context context) {
+            super(context, DATABASE_NAME, null, DATABASE_VERSION);
+        }
+
+        @Override
+        public void onCreate(SQLiteDatabase db) {
+            db.execSQL("CREATE TABLE " + TABLE_ACCOUNTS + " ( "
+                    + ACCOUNTS_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
+                    + ACCOUNTS_NAME + " TEXT NOT NULL, "
+                    + ACCOUNTS_TYPE + " TEXT NOT NULL, "
+                    + ACCOUNTS_PASSWORD + " TEXT, "
+                    + "UNIQUE(" + ACCOUNTS_NAME + "," + ACCOUNTS_TYPE + "))");
+
+            db.execSQL("CREATE TABLE " + TABLE_AUTHTOKENS + " (  "
+                    + AUTHTOKENS_ID + " INTEGER PRIMARY KEY AUTOINCREMENT,  "
+                    + AUTHTOKENS_ACCOUNTS_ID + " INTEGER NOT NULL, "
+                    + AUTHTOKENS_TYPE + " TEXT NOT NULL,  "
+                    + AUTHTOKENS_AUTHTOKEN + " TEXT,  "
+                    + "UNIQUE (" + AUTHTOKENS_ACCOUNTS_ID + "," + AUTHTOKENS_TYPE + "))");
+
+            db.execSQL("CREATE TABLE " + TABLE_EXTRAS + " ( "
+                    + EXTRAS_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
+                    + EXTRAS_ACCOUNTS_ID + " INTEGER, "
+                    + EXTRAS_KEY + " TEXT NOT NULL, "
+                    + EXTRAS_VALUE + " TEXT, "
+                    + "UNIQUE(" + EXTRAS_ACCOUNTS_ID + "," + EXTRAS_KEY + "))");
+
+            db.execSQL("CREATE TABLE " + TABLE_META + " ( "
+                    + META_KEY + " TEXT PRIMARY KEY NOT NULL, "
+                    + META_VALUE + " TEXT)");
+        }
+
+        @Override
+        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+            Log.e(TAG, "GLS upgrade from version " + oldVersion + " to version " +
+                  newVersion + " not supported");
+
+            db.execSQL("DROP TABLE " + TABLE_ACCOUNTS);
+            db.execSQL("DROP TABLE " + TABLE_AUTHTOKENS);
+            db.execSQL("DROP TABLE " + TABLE_EXTRAS);
+            db.execSQL("DROP TABLE " + TABLE_META);
+            onCreate(db);
+        }
+
+        @Override
+        public void onOpen(SQLiteDatabase db) {
+            if (Log.isLoggable(TAG, Log.VERBOSE)) Log.v(TAG, "opened database " + DATABASE_NAME);
+        }
+    }
+
+    private void setMetaValue(String key, String value) {
+        ContentValues values = new ContentValues();
+        values.put(META_KEY, key);
+        values.put(META_VALUE, value);
+        mOpenHelper.getWritableDatabase().replace(TABLE_META, META_KEY, values);
+    }
+
+    private String getMetaValue(String key) {
+        Cursor c = mOpenHelper.getReadableDatabase().query(TABLE_META,
+                new String[]{META_VALUE}, META_KEY + "=?", new String[]{key}, null, null, null);
+        try {
+            if (c.moveToNext()) {
+                return c.getString(0);
+            }
+            return null;
+        } finally {
+            c.close();
+        }
+    }
+
+    private class SimWatcher extends BroadcastReceiver {
+        public SimWatcher(Context context) {
+            // Re-scan the SIM card when the SIM state changes, and also if
+            // the disk recovers from a full state (we may have failed to handle
+            // things properly while the disk was full).
+            final IntentFilter filter = new IntentFilter();
+            filter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
+            filter.addAction(Intent.ACTION_DEVICE_STORAGE_OK);
+            context.registerReceiver(this, filter);
+        }
+        
+        /**
+         * Compare the IMSI to the one stored in the login service's
+         * database.  If they differ, erase all passwords and
+         * authtokens (and store the new IMSI).
+         */
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            // Check IMSI on every update; nothing happens if the IMSI is missing or unchanged.
+            String imsi = ((TelephonyManager) context.getSystemService(
+                    Context.TELEPHONY_SERVICE)).getSubscriberId();
+            if (TextUtils.isEmpty(imsi)) return;
+
+            String storedImsi = getMetaValue("imsi");
+
+            if (Log.isLoggable(TAG, Log.VERBOSE)) {
+                Log.v(TAG, "current IMSI=" + imsi + "; stored IMSI=" + storedImsi);
+            }
+
+            if (!imsi.equals(storedImsi) && !"initial".equals(storedImsi)) {
+                if (Log.isLoggable(TAG, Log.VERBOSE)) {
+                    Log.v(TAG, "wiping all passwords and authtokens");
+                }
+                SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+                db.beginTransaction();
+                try {
+                    db.execSQL("DELETE from " + TABLE_AUTHTOKENS);
+                    db.execSQL("UPDATE " + TABLE_ACCOUNTS + " SET " + ACCOUNTS_PASSWORD + " = ''");
+                    mContext.sendBroadcast(ACCOUNTS_CHANGED_INTENT);
+                    db.setTransactionSuccessful();
+                } finally {
+                    db.endTransaction();
+                }
+            }
+            setMetaValue("imsi", imsi);
+        }
+    }
+
+    public IBinder onBind(Intent intent) {
+        return asBinder();
+    }
+}
diff --git a/core/java/android/accounts/AccountMonitor.java b/core/java/android/accounts/AccountMonitor.java
index f21385e..4ad06d4 100644
--- a/core/java/android/accounts/AccountMonitor.java
+++ b/core/java/android/accounts/AccountMonitor.java
@@ -17,16 +17,10 @@
 package android.accounts;
 
 import android.content.BroadcastReceiver;
-import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
-import android.content.ServiceConnection;
-import android.database.SQLException;
-import android.os.IBinder;
-import android.os.Process;
-import android.os.RemoteException;
-import android.util.Log;
+import android.os.*;
 
 /**
  * A helper class that calls back on the provided
@@ -38,55 +32,15 @@
  * fetch the current list of accounts (that is, when the
  * AccountMonitor is first created, and when the intent is received).
  */
-public class AccountMonitor extends BroadcastReceiver implements ServiceConnection {
+public class AccountMonitor extends BroadcastReceiver {
+    private static final String TAG = "AccountMonitor";
+
     private final Context mContext;
     private final AccountMonitorListener mListener;
     private boolean mClosed = false;
-    private int pending = 0;
 
-    // This thread runs in the background and runs the code to update accounts
-    // in the listener.
-    private class AccountUpdater extends Thread {
-        private IBinder mService;
-
-        public AccountUpdater(IBinder service) {
-            mService = service;
-        }
-
-        @Override
-        public void run() {
-            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
-            IAccountsService accountsService = IAccountsService.Stub.asInterface(mService);
-            String[] accounts = null;
-            do {
-                try {
-                    accounts = accountsService.getAccounts();
-                } catch (RemoteException e) {
-                    // if the service was killed then the system will restart it and when it does we
-                    // will get another onServiceConnected, at which point we will do a notify.
-                    Log.w("AccountMonitor", "Remote exception when getting accounts", e);
-                    return;
-                }
-
-                synchronized (AccountMonitor.this) {
-                    --pending;
-                    if (pending == 0) {
-                        break;
-                    }
-                }
-            } while (true);
-
-            mContext.unbindService(AccountMonitor.this);
-
-            try {
-                mListener.onAccountsUpdated(accounts);
-            } catch (SQLException e) {
-                // Better luck next time.  If the problem was disk-full,
-                // the STORAGE_OK intent will re-trigger the update.
-                Log.e("AccountMonitor", "Can't update accounts", e);
-            }
-        }
-    }
+    private volatile Looper mServiceLooper;
+    private volatile NotifierHandler mServiceHandler;
 
     /**
      * Initializes the AccountMonitor and initiates a bind to the
@@ -110,8 +64,12 @@
         intentFilter.addAction(Intent.ACTION_DEVICE_STORAGE_OK);  // To recover from disk-full.
         mContext.registerReceiver(this, intentFilter);
 
-        // Send the listener the initial state now.
-        notifyListener();
+        HandlerThread thread = new HandlerThread("AccountMonitorHandlerThread");
+        thread.start();
+        mServiceLooper = thread.getLooper();
+        mServiceHandler = new NotifierHandler(mServiceLooper);
+
+        mServiceHandler.sendEmptyMessage(0);
     }
 
     @Override
@@ -119,45 +77,15 @@
         notifyListener();
     }
 
-    public void onServiceConnected(ComponentName className, IBinder service) {
-        // Create a background thread to update the accounts.
-        new AccountUpdater(service).start();
-    }
-
-    public void onServiceDisconnected(ComponentName className) {
-    }
-
     private synchronized void notifyListener() {
-        if (pending == 0) {
-            // initiate the bind
-            if (!mContext.bindService(AccountsServiceConstants.SERVICE_INTENT,
-                                      this, Context.BIND_AUTO_CREATE)) {
-                // This is normal if GLS isn't part of this build.
-                Log.w("AccountMonitor",
-                      "Couldn't connect to "  +
-                      AccountsServiceConstants.SERVICE_INTENT +
-                      " (Missing service?)");
-            }
-        } else {
-            // already bound.  bindService will not trigger another
-            // call to onServiceConnected, so instead we make sure
-            // that the existing background thread will call
-            // getAccounts() after this function returns, by
-            // incrementing pending.
-            //
-            // Yes, this else clause contains only a comment.
+        AccountManager accountManager =
+                (AccountManager)mContext.getSystemService(Context.ACCOUNT_SERVICE);
+        Account[] accounts = accountManager.blockingGetAccounts();
+        String[] accountNames = new String[accounts.length];
+        for (int i = 0; i < accounts.length; i++) {
+            accountNames[i] = accounts[i].mName;
         }
-        ++pending;
-    }
-
-    /**
-     * calls close()
-     * @throws Throwable
-     */
-    @Override
-    protected void finalize() throws Throwable {
-        close();
-        super.finalize();
+        mListener.onAccountsUpdated(accountNames);
     }
 
     /**
@@ -171,4 +99,14 @@
             mClosed = true;
         }
     }
+
+    private final class NotifierHandler extends Handler {
+        public NotifierHandler(Looper looper) {
+            super(looper);
+        }
+
+        public void handleMessage(Message msg) {
+            notifyListener();
+        }
+    }
 }
diff --git a/core/java/android/accounts/AuthenticatorBindHelper.java b/core/java/android/accounts/AuthenticatorBindHelper.java
new file mode 100644
index 0000000..ec41810
--- /dev/null
+++ b/core/java/android/accounts/AuthenticatorBindHelper.java
@@ -0,0 +1,172 @@
+/*
+ * 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.Handler;
+import android.os.IBinder;
+import android.os.Message;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.ServiceConnection;
+import android.content.Intent;
+
+import java.util.Map;
+import java.util.ArrayList;
+
+import com.google.android.collect.Maps;
+import com.google.android.collect.Lists;
+
+/**
+ * A helper object that simplifies binding to Account Authenticators. It uses the
+ * {@link AccountAuthenticatorCache} to find the component name of the authenticators,
+ * allowing the user to bind by account name. It also allows multiple, simultaneous binds
+ * to the same authenticator, with each bind call guaranteed to return either
+ * {@link Callback#onConnected} or {@link Callback#onDisconnected} if the bind() call
+ * itself succeeds, even if the authenticator is already bound internally.
+ */
+public class AuthenticatorBindHelper {
+    final private Handler mHandler;
+    final private Context mContext;
+    final private int mMessageWhatConnected;
+    final private int mMessageWhatDisconnected;
+    final private Map<String, MyServiceConnection> mServiceConnections = Maps.newHashMap();
+    final private Map<String, ArrayList<Callback>> mServiceUsers = Maps.newHashMap();
+    final private AccountAuthenticatorCache mAuthenticatorCache;
+
+    public AuthenticatorBindHelper(Context context,
+            AccountAuthenticatorCache authenticatorCache, Handler handler,
+            int messageWhatConnected, int messageWhatDisconnected) {
+        mContext = context;
+        mHandler = handler;
+        mAuthenticatorCache = authenticatorCache;
+        mMessageWhatConnected = messageWhatConnected;
+        mMessageWhatDisconnected = messageWhatDisconnected;
+    }
+
+    public interface Callback {
+        void onConnected(IBinder service);
+        void onDisconnected();
+    }
+
+    public boolean bind(String authenticatorType, Callback callback) {
+        // if the authenticator is connecting or connected then return true
+        synchronized (mServiceConnections) {
+            if (mServiceConnections.containsKey(authenticatorType)) {
+                mServiceUsers.get(authenticatorType).add(callback);
+                return true;
+            }
+
+            // otherwise find the component name for the authenticator and initiate a bind
+            // if no authenticator or the bind fails then return false, otherwise return true
+            AccountAuthenticatorCache.AuthenticatorInfo authenticatorInfo =
+                    mAuthenticatorCache.getAuthenticatorInfo(authenticatorType);
+            if (authenticatorInfo == null) {
+                return false;
+            }
+
+            MyServiceConnection connection = new MyServiceConnection(authenticatorType);
+
+            Intent intent = new Intent();
+            intent.setAction("android.accounts.AccountAuthenticator");
+            intent.setComponent(authenticatorInfo.mComponentName);
+            if (!mContext.bindService(intent, connection, Context.BIND_AUTO_CREATE)) {
+                return false;
+            }
+
+            mServiceConnections.put(authenticatorType, connection);
+            mServiceUsers.put(authenticatorType, Lists.newArrayList(callback));
+            return true;
+        }
+    }
+
+    public void unbind(Callback callbackToUnbind) {
+        synchronized (mServiceConnections) {
+            for (Map.Entry<String, ArrayList<Callback>> entry : mServiceUsers.entrySet()) {
+                final String authenticatorType = entry.getKey();
+                final ArrayList<Callback> serviceUsers = entry.getValue();
+                for (Callback callback : serviceUsers) {
+                    if (callback == callbackToUnbind) {
+                        serviceUsers.remove(callbackToUnbind);
+                        if (serviceUsers.isEmpty()) {
+                            unbindFromService(authenticatorType);
+                        }
+                        return;
+                    }
+                }
+            }
+        }
+    }
+
+    private void unbindFromService(String authenticatorType) {
+        mContext.unbindService(mServiceConnections.get(authenticatorType));
+        mServiceUsers.remove(authenticatorType);
+        mServiceConnections.remove(authenticatorType);
+    }
+
+    private class ConnectedMessagePayload {
+        public final IBinder mService;
+        public final Callback mCallback;
+        public ConnectedMessagePayload(IBinder service, Callback callback) {
+            mService = service;
+            mCallback = callback;
+        }
+    }
+
+    private class MyServiceConnection implements ServiceConnection {
+        final private String mAuthenticatorType;
+
+        public MyServiceConnection(String authenticatorType) {
+            mAuthenticatorType = authenticatorType;
+        }
+
+        public void onServiceConnected(ComponentName name, IBinder service) {
+            // post a message for each service user to tell them that the service is connected
+            synchronized (mServiceConnections) {
+                for (Callback callback : mServiceUsers.get(mAuthenticatorType)) {
+                    final ConnectedMessagePayload payload =
+                            new ConnectedMessagePayload(service, callback);
+                    mHandler.obtainMessage(mMessageWhatConnected, payload).sendToTarget();
+                }
+            }
+        }
+
+        public void onServiceDisconnected(ComponentName name) {
+            // post a message for each service user to tell them that the service is disconnected,
+            // and unbind from the service.
+            synchronized (mServiceConnections) {
+                for (Callback callback : mServiceUsers.get(mAuthenticatorType)) {
+                    mHandler.obtainMessage(mMessageWhatDisconnected, callback).sendToTarget();
+                }
+                unbindFromService(mAuthenticatorType);
+            }
+        }
+    }
+
+    boolean handleMessage(Message message) {
+        if (message.what == mMessageWhatConnected) {
+            ConnectedMessagePayload payload = (ConnectedMessagePayload)message.obj;
+            payload.mCallback.onConnected(payload.mService);
+            return true;
+        } else if (message.what == mMessageWhatDisconnected) {
+            Callback callback = (Callback)message.obj;
+            callback.onDisconnected();
+            return true;
+        } else {
+            return false;
+        }
+    }
+}
diff --git a/core/java/android/accounts/IAccountAuthenticator.aidl b/core/java/android/accounts/IAccountAuthenticator.aidl
new file mode 100644
index 0000000..b2c2223
--- /dev/null
+++ b/core/java/android/accounts/IAccountAuthenticator.aidl
@@ -0,0 +1,63 @@
+/*
+ * 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.accounts.IAccountAuthenticatorResponse;
+
+/**
+ * Service that allows the interaction with an authentication server.
+ */
+oneway interface IAccountAuthenticator {
+    /**
+     * prompts the user for account information and adds the result to the IAccountManager
+     */
+    void addAccount(in IAccountAuthenticatorResponse response, String accountType);
+
+    /**
+     * prompts the user for the credentials of the account
+     */
+    void authenticateAccount(in IAccountAuthenticatorResponse response, String name,
+        String type, String password);
+
+    /**
+     * gets the password by either prompting the user or querying the IAccountManager
+     */
+    void getAuthToken(in IAccountAuthenticatorResponse response,
+        String name, String type, String authTokenType);
+
+    /**
+     * does local analysis or uses a service in the cloud
+     */
+    void getPasswordStrength(in IAccountAuthenticatorResponse response,
+        String accountType, String password);
+
+    /**
+     * checks with the login service in the cloud
+     */
+    void checkUsernameExistence(in IAccountAuthenticatorResponse response,
+        String accountType, String username);
+
+    /**
+     * prompts the user for a new password and writes it to the IAccountManager
+     */
+    void updatePassword(in IAccountAuthenticatorResponse response, String name, String type);
+
+    /**
+     * launches an activity that lets the user edit and set the properties for an authenticator
+     */
+    void editProperties(in IAccountAuthenticatorResponse response, String accountType);
+}
diff --git a/core/java/android/accounts/IAccountAuthenticatorResponse.aidl b/core/java/android/accounts/IAccountAuthenticatorResponse.aidl
new file mode 100644
index 0000000..83504d3
--- /dev/null
+++ b/core/java/android/accounts/IAccountAuthenticatorResponse.aidl
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.accounts;
+import android.os.Parcelable;
+
+/**
+ * The interface used to return responses from an {@link IAccountAuthenticator}
+ */
+oneway interface IAccountAuthenticatorResponse {
+    void onIntResult(int result);
+    void onBooleanResult(boolean result);
+    void onStringResult(String result);
+    void onError(int errorCode, String errorMessage);
+}
diff --git a/core/java/android/accounts/IAccountManager.aidl b/core/java/android/accounts/IAccountManager.aidl
new file mode 100644
index 0000000..8a0d1c4
--- /dev/null
+++ b/core/java/android/accounts/IAccountManager.aidl
@@ -0,0 +1,55 @@
+/*
+ * 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.accounts.IAccountManagerResponse;
+import android.accounts.Account;
+import android.os.Bundle;
+
+/**
+ * Central application service that provides account management.
+ */
+interface IAccountManager {
+    String getPassword(in Account account);
+    String getUserData(in Account account, String key);
+    Account[] getAccounts();
+    Account[] getAccountsByType(String accountType);
+    boolean addAccount(in Account account, String password, in Bundle extras);
+    void removeAccount(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);
+    void setPassword(in Account account, String password);
+    void clearPassword(in Account account);
+    void setUserData(in Account account, String key, String value);
+
+    // interactive
+
+    void getAuthToken(in IAccountManagerResponse response, in Account account, String authTokenType,
+        boolean notifyOnAuthFailure);
+    void addAccountInteractively(in IAccountManagerResponse response, String accountType);
+    void authenticateAccount(in IAccountManagerResponse response, in Account account,
+        String password);
+    void updatePassword(in IAccountManagerResponse response, in Account account);
+    void editProperties(in IAccountManagerResponse response, String accountType);
+
+    // not interactive
+    void getPasswordStrength(in IAccountManagerResponse response, String accountType,
+        String password);
+    void checkUsernameExistence(in IAccountManagerResponse response, String accountType,
+        String username);
+}
diff --git a/core/java/android/accounts/IAccountManagerResponse.aidl b/core/java/android/accounts/IAccountManagerResponse.aidl
new file mode 100644
index 0000000..7bbaa8b
--- /dev/null
+++ b/core/java/android/accounts/IAccountManagerResponse.aidl
@@ -0,0 +1,27 @@
+/*
+ * 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;
+
+/**
+ * The interface used to return responses for asynchronous calls to the {@link IAccountManager}
+ */
+oneway interface IAccountManagerResponse {
+        void onStringResult(String value);
+        void onIntResult(int value);
+        void onBooleanResult(boolean value);
+        void onError(int errorCode, String errorMessage);
+}
diff --git a/core/java/android/accounts/IAccountsService.aidl b/core/java/android/accounts/IAccountsService.aidl
deleted file mode 100644
index dda513c..0000000
--- a/core/java/android/accounts/IAccountsService.aidl
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.accounts;
-
-/**
- * Central application service that allows querying the list of accounts.
- */
-interface IAccountsService {
-    /**
-     * Gets the list of Accounts the user has previously logged
-     * in to.  Accounts are of the form "username@domain".
-     * <p>
-     * This method will return an empty array if the device doesn't
-     * know about any accounts (yet).
-     *
-     * @return The accounts.  The array will be zero-length if the
-     *         AccountsService doesn't know about any accounts yet.
-     */
-    String[] getAccounts();
-
-    /**
-     * This is an interim solution for bypassing a forgotten gesture on the
-     * unlock screen (it is hidden, please make sure it stays this way!). This
-     * will be *removed* when the unlock screen design supports additional
-     * authenticators.
-     * <p>
-     * The user will be presented with username and password fields that are
-     * called as parameters to this method. If true is returned, the user is
-     * able to define a new gesture and get back into the system. If false, the
-     * user can try again.
-     * 
-     * @param username The username entered.
-     * @param password The password entered.
-     * @return Whether to allow the user to bypass the lock screen and define a
-     *         new gesture.
-     * @hide (The package is already hidden, but just in case someone
-     *       unhides that, this should not be revealed.)
-     */
-    boolean shouldUnlock(String username, String password);
-}
diff --git a/core/java/android/accounts/package.html b/core/java/android/accounts/package.html
deleted file mode 100755
index c9f96a6..0000000
--- a/core/java/android/accounts/package.html
+++ /dev/null
@@ -1,5 +0,0 @@
-<body>
-
-{@hide}
-
-</body>
diff --git a/core/java/android/app/ApplicationContext.java b/core/java/android/app/ApplicationContext.java
index 55fce49..94f3373 100644
--- a/core/java/android/app/ApplicationContext.java
+++ b/core/java/android/app/ApplicationContext.java
@@ -88,6 +88,8 @@
 import android.view.LayoutInflater;
 import android.view.WindowManagerImpl;
 import android.view.inputmethod.InputMethodManager;
+import android.accounts.AccountManager;
+import android.accounts.IAccountManager;
 
 import com.android.internal.policy.PolicyManager;
 
@@ -150,6 +152,7 @@
     private final static boolean DEBUG_ICONS = false;
 
     private static final Object sSync = new Object();
+    private static AccountManager sAccountManager;
     private static AlarmManager sAlarmManager;
     private static PowerManager sPowerManager;
     private static ConnectivityManager sConnectivityManager;
@@ -881,6 +884,8 @@
             return getActivityManager();
         } else if (ALARM_SERVICE.equals(name)) {
             return getAlarmManager();
+        } else if (ACCOUNT_SERVICE.equals(name)) {
+            return getAccountManager();
         } else if (POWER_SERVICE.equals(name)) {
             return getPowerManager();
         } else if (CONNECTIVITY_SERVICE.equals(name)) {
@@ -921,6 +926,17 @@
         return null;
     }
 
+    private AccountManager getAccountManager() {
+        synchronized (sSync) {
+            if (sAccountManager == null) {
+                IBinder b = ServiceManager.getService(ACCOUNT_SERVICE);
+                IAccountManager service = IAccountManager.Stub.asInterface(b);
+                sAccountManager = new AccountManager(this, service);
+            }
+        }
+        return sAccountManager;
+    }
+
     private ActivityManager getActivityManager() {
         synchronized (mSync) {
             if (mActivityManager == null) {
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 9a0dc9f..abcc1ea 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -1097,6 +1097,16 @@
     public static final String LAYOUT_INFLATER_SERVICE = "layout_inflater";
     /**
      * Use with {@link #getSystemService} to retrieve a
+     * {@link android.accounts.AccountManager} for receiving intents at a
+     * time of your choosing.
+     * TODO STOPSHIP perform a final review of the the account apis before shipping
+     *
+     * @see #getSystemService
+     * @see android.accounts.AccountManager
+     */
+    public static final String ACCOUNT_SERVICE = "account";
+    /**
+     * Use with {@link #getSystemService} to retrieve a
      * {@link android.app.ActivityManager} for interacting with the global
      * system state.
      *
diff --git a/core/java/android/content/SyncManager.java b/core/java/android/content/SyncManager.java
index 96470c3..01b07eb 100644
--- a/core/java/android/content/SyncManager.java
+++ b/core/java/android/content/SyncManager.java
@@ -181,6 +181,47 @@
                 }
             };
 
+    private BroadcastReceiver mBootCompletedReceiver = new BroadcastReceiver() {
+        public void onReceive(Context context, Intent intent) {
+            if (!mFactoryTest) {
+                AccountMonitorListener listener = new AccountMonitorListener() {
+                    public void onAccountsUpdated(String[] accounts) {
+                        final boolean hadAccountsAlready = mAccounts != null;
+                        // copy the accounts into a new array and change mAccounts to point to it
+                        String[] newAccounts = new String[accounts.length];
+                        System.arraycopy(accounts, 0, newAccounts, 0, accounts.length);
+                        mAccounts = newAccounts;
+
+                        // if a sync is in progress yet it is no longer in the accounts list,
+                        // cancel it
+                        ActiveSyncContext activeSyncContext = mActiveSyncContext;
+                        if (activeSyncContext != null) {
+                            if (!ArrayUtils.contains(newAccounts,
+                                    activeSyncContext.mSyncOperation.account)) {
+                                Log.d(TAG, "canceling sync since the account has been removed");
+                                sendSyncFinishedOrCanceledMessage(activeSyncContext,
+                                        null /* no result since this is a cancel */);
+                            }
+                        }
+
+                        // we must do this since we don't bother scheduling alarms when
+                        // the accounts are not set yet
+                        sendCheckAlarmsMessage();
+
+                        mSyncStorageEngine.doDatabaseCleanup(accounts);
+
+                        if (hadAccountsAlready && mAccounts.length > 0) {
+                            // request a sync so that if the password was changed we will
+                            // retry any sync that failed when it was wrong
+                            startSync(null /* all providers */, null /* no extras */);
+                        }
+                    }
+                };
+                mAccountMonitor = new AccountMonitor(context, listener);
+            }
+        }
+    };
+
     private BroadcastReceiver mConnectivityIntentReceiver =
             new BroadcastReceiver() {
         public void onReceive(Context context, Intent intent) {
@@ -241,7 +282,11 @@
 
     private static final String SYNCMANAGER_PREFS_FILENAME = "/data/system/syncmanager.prefs";
 
+    private final boolean mFactoryTest;
+
     public SyncManager(Context context, boolean factoryTest) {
+        mFactoryTest = factoryTest;
+
         // Initialize the SyncStorageEngine first, before registering observers
         // and creating threads and so on; it may fail if the disk is full.
         SyncStorageEngine.init(context);
@@ -265,6 +310,9 @@
         IntentFilter intentFilter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
         context.registerReceiver(mConnectivityIntentReceiver, intentFilter);
 
+        intentFilter = new IntentFilter(Intent.ACTION_BOOT_COMPLETED);
+        context.registerReceiver(mBootCompletedReceiver, intentFilter);
+
         intentFilter = new IntentFilter(Intent.ACTION_DEVICE_STORAGE_LOW);
         intentFilter.addAction(Intent.ACTION_DEVICE_STORAGE_OK);
         context.registerReceiver(mStorageIntentReceiver, intentFilter);
@@ -288,42 +336,6 @@
         mHandleAlarmWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
                 HANDLE_SYNC_ALARM_WAKE_LOCK);
         mHandleAlarmWakeLock.setReferenceCounted(false);
-
-        if (!factoryTest) {
-            AccountMonitorListener listener = new AccountMonitorListener() {
-                public void onAccountsUpdated(String[] accounts) {
-                    final boolean hadAccountsAlready = mAccounts != null;
-                    // copy the accounts into a new array and change mAccounts to point to it
-                    String[] newAccounts = new String[accounts.length];
-                    System.arraycopy(accounts, 0, newAccounts, 0, accounts.length);
-                    mAccounts = newAccounts;
-
-                    // if a sync is in progress yet it is no longer in the accounts list, cancel it
-                    ActiveSyncContext activeSyncContext = mActiveSyncContext;
-                    if (activeSyncContext != null) {
-                        if (!ArrayUtils.contains(newAccounts,
-                                activeSyncContext.mSyncOperation.account)) {
-                            Log.d(TAG, "canceling sync since the account has been removed");
-                            sendSyncFinishedOrCanceledMessage(activeSyncContext,
-                                    null /* no result since this is a cancel */);
-                        }
-                    }
-
-                    // we must do this since we don't bother scheduling alarms when
-                    // the accounts are not set yet
-                    sendCheckAlarmsMessage();
-
-                    mSyncStorageEngine.doDatabaseCleanup(accounts);
-
-                    if (hadAccountsAlready && mAccounts.length > 0) {
-                        // request a sync so that if the password was changed we will retry any sync
-                        // that failed when it was wrong
-                        startSync(null /* all providers */, null /* no extras */);
-                    }
-                }
-            };
-            mAccountMonitor = new AccountMonitor(context, listener);
-        }
     }
 
     private synchronized void initializeSyncPoll() {
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 9a569a1..b2a17da 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -25,7 +25,7 @@
     <!-- Permissions for things that cost money -->
     <!-- ====================================== -->
     <eat-comment />
-    
+
     <!-- Used for permissions that can be used to make the user spend money
          without their direct involvement.  For example, this is the group
          for permissions that allow you to directly place phone calls,
@@ -54,7 +54,7 @@
     <!-- Permissions for accessing messages -->
     <!-- ================================== -->
     <eat-comment />
-    
+
     <!-- Used for permissions that allow an application to send messages
          on behalf of the user or intercept messages being received by the
          user.  This is primarily intended for SMS/MMS messaging, such as
@@ -104,7 +104,7 @@
     <!-- Permissions for accessing personal info (contacts and calendar) -->
     <!-- =============================================================== -->
     <eat-comment />
-    
+
     <!-- Used for permissions that provide access to the user's private data,
          such as contacts, calendar events, e-mail messages, etc.  This includes
          both reading and writing of this data (which should generally be
@@ -158,8 +158,8 @@
         android:description="@string/permdesc_writeCalendar" />
 
     <!-- Allows an application to read the user dictionary. This should
-         really only be required by an IME, or a dictionary editor like 
-         the Settings app. 
+         really only be required by an IME, or a dictionary editor like
+         the Settings app.
          @hide Pending API council approval -->
     <permission android:name="android.permission.READ_USER_DICTIONARY"
         android:permissionGroup="android.permission-group.PERSONAL_INFO"
@@ -179,7 +179,7 @@
     <!-- Permissions for accessing location info -->
     <!-- ======================================= -->
     <eat-comment />
-    
+
     <!-- Used for permissions that allow access to the user's current
          location. -->
     <permission-group android:name="android.permission-group.LOCATION"
@@ -216,7 +216,7 @@
     <!-- Permissions for accessing networks -->
     <!-- ======================================= -->
     <eat-comment />
-    
+
     <!-- Used for permissions that provide access to networking services.  The
          main permission here is internet access, but this is also an
          appropriate group for accessing or modifying any network configuration
@@ -257,7 +257,7 @@
     <!-- Permissions for accessing accounts -->
     <!-- ================================== -->
     <eat-comment />
-    
+
     <!-- Permissions for direct access to Google accounts.
          Note that while right now this is only used for Google accounts,
          we expect in the future to have a more general account management
@@ -278,7 +278,7 @@
     <!-- Permissions for accessing hardware -->
     <!-- ================================== -->
     <eat-comment />
-    
+
     <!-- Used for permissions that provide direct access to the hardware on
          the device.  This includes audio, the camera, vibrator, etc. -->
     <permission-group android:name="android.permission-group.HARDWARE_CONTROLS"
@@ -331,7 +331,7 @@
     <!-- Permissions associated with telephony state -->
     <!-- =========================================== -->
     <eat-comment />
-    
+
     <!-- Used for permissions that are associated with accessing and modifyign
          telephony state: intercepting outgoing calls, reading
          and modifying the phone state.  Note that
@@ -368,7 +368,7 @@
     <!-- Permissions for low-level system interaction -->
     <!-- ============================================ -->
     <eat-comment />
-    
+
     <!-- Group of permissions that are related to system APIs.  Many
          of these are not permissions the user will be expected to understand,
          and such permissions should generally be marked as "normal" protection
@@ -592,7 +592,7 @@
                 android:description="@string/permdesc_writeApnSettings"
                 android:label="@string/permlab_writeApnSettings" />
 
-    <!-- Allows an application to allow access the subscribed feeds 
+    <!-- Allows an application to allow access the subscribed feeds
          ContentProvider. -->
     <permission android:name="android.permission.SUBSCRIBED_FEEDS_READ"
         android:permissionGroup="android.permission-group.SYSTEM_TOOLS"
@@ -604,7 +604,7 @@
         android:label="@string/permlab_subscribedFeedsWrite"
         android:description="@string/permdesc_subscribedFeedsWrite"
         android:protectionLevel="dangerous" />
-        
+
     <!-- Allows applications to change network connectivity state -->
     <permission android:name="android.permission.CHANGE_NETWORK_STATE"
         android:permissionGroup="android.permission-group.SYSTEM_TOOLS"
@@ -648,7 +648,7 @@
     <!-- Permissions for special development tools -->
     <!-- ========================================= -->
     <eat-comment />
-    
+
     <!-- Group of permissions that are related to development features.  These
          are not permissions that should appear in normal applications; they
          protect APIs that are intended only to be used for development
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 485edca..9d041f9 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -4,9 +4,9 @@
      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.
@@ -64,7 +64,7 @@
 
         <!-- Inverse hint text color -->
         <attr name="textColorHintInverse" format="reference|color" />
-        
+
         <!-- Bright text color. Only differentiates based on the disabled state. -->
         <attr name="textColorPrimaryDisableOnly" format="reference|color" />
 
@@ -96,20 +96,20 @@
 
         <!-- Text color, typeface, size, and style for the text inside of a button. -->
         <attr name="textAppearanceButton" format="reference" />
-        
+
         <!-- A styled string, specifying the style to be used for showing
              inline candidate text when composing with an input method.  The
              text itself will be ignored, but the style spans will be applied
              to the candidate text as it is edited. -->
         <attr name="candidatesTextStyleSpans" format="reference|string" />
-        
+
         <!-- Drawable to use for check marks -->
         <attr name="textCheckMark" format="reference" />
         <attr name="textCheckMarkInverse" format="reference" />
 
         <!-- Drawable to use for multiple choice indicators-->
         <attr name="listChoiceIndicatorMultiple" format="reference" />
-        
+
         <!-- Drawable to use for single choice indicators-->
         <attr name="listChoiceIndicatorSingle" format="reference" />
 
@@ -134,7 +134,7 @@
         <!-- Gallery styles -->
         <!-- ============== -->
         <eat-comment />
-        
+
         <!-- The preferred background for gallery items. This should be set
              as the background of any Views you provide from the Adapter. -->
         <attr name="galleryItemBackground" format="reference" />
@@ -152,20 +152,20 @@
         <attr name="listSeparatorTextViewStyle" format="reference" />
         <!-- The preferred left padding for an expandable list item (for child-specific layouts,
              use expandableListPreferredChildPaddingLeft). This takes into account
-             the indicator that will be shown to next to the item. --> 
+             the indicator that will be shown to next to the item. -->
         <attr name="expandableListPreferredItemPaddingLeft" format="dimension" />
         <!-- The preferred left padding for an expandable list item that is a child.
-             If this is not provided, it defaults to the expandableListPreferredItemPaddingLeft. --> 
+             If this is not provided, it defaults to the expandableListPreferredItemPaddingLeft. -->
         <attr name="expandableListPreferredChildPaddingLeft" format="dimension" />
         <!-- The preferred left bound for an expandable list item's indicator. For a child-specific
-             indicator, use expandableListPreferredChildIndicatorLeft. --> 
+             indicator, use expandableListPreferredChildIndicatorLeft. -->
         <attr name="expandableListPreferredItemIndicatorLeft" format="dimension" />
         <!-- The preferred right bound for an expandable list item's indicator. For a child-specific
-             indicator, use expandableListPreferredChildIndicatorRight. --> 
+             indicator, use expandableListPreferredChildIndicatorRight. -->
         <attr name="expandableListPreferredItemIndicatorRight" format="dimension" />
-        <!-- The preferred left bound for an expandable list child's indicator. --> 
+        <!-- The preferred left bound for an expandable list child's indicator. -->
         <attr name="expandableListPreferredChildIndicatorLeft" format="dimension" />
-        <!-- The preferred right bound for an expandable list child's indicator. --> 
+        <!-- The preferred right bound for an expandable list child's indicator. -->
         <attr name="expandableListPreferredChildIndicatorRight" format="dimension" />
 
         <!-- ============= -->
@@ -214,7 +214,7 @@
              any of the attributes defined by
              {@link android.R.styleable#WindowAnimation}. -->
         <attr name="windowAnimationStyle" format="reference" />
-    
+
         <!-- Defines the default soft input state that this window would
              like when it is displayed. -->
         <attr name="windowSoftInputMode">
@@ -236,7 +236,7 @@
             <!-- Always make the soft input area visible when this window
                  has input focus. -->
             <flag name="stateAlwaysVisible" value="5" />
-            
+
             <!-- The window resize/pan adjustment has not been specified,
                  the system will automatically select between resize and pan
                  modes, depending
@@ -263,7 +263,7 @@
              use the window's theme to show a preview of it before your
              actual instance is shown to the user. -->
         <attr name="windowDisablePreview" format="boolean" />
-        
+
         <!-- Flag indicating that this window should not be displayed at all.
              The default value is false; if set to true, and this window is
              the main window of an Activity, then it will never actually
@@ -271,13 +271,13 @@
              must immediately quit without waiting for user interaction,
              because there will be no such interaction coming. -->
         <attr name="windowNoDisplay" format="boolean" />
-        
+
         <!-- ============ -->
         <!-- Alert Dialog styles -->
         <!-- ============ -->
         <eat-comment />
         <attr name="alertDialogStyle" format="reference" />
-        
+
         <!-- ============ -->
         <!-- Panel styles -->
         <!-- ============ -->
@@ -376,7 +376,7 @@
         <!-- Preference styles   -->
         <!-- =================== -->
         <eat-comment />
-        
+
         <!-- Default style for PreferenceScreen. -->
         <attr name="preferenceScreenStyle" format="reference" />
         <!-- Default style for PreferenceCategory. -->
@@ -397,7 +397,7 @@
         <attr name="ringtonePreferenceStyle" format="reference" />
         <!-- The preference layout that has the child/tabbed effect. -->
         <attr name="preferenceLayoutChild" format="reference" />
-        
+
     </declare-styleable>
 
     <!-- **************************************************************** -->
@@ -415,7 +415,7 @@
     </ul>
         -->
     <attr name="textSize" format="dimension" />
-    
+
     <!-- Default text typeface. -->
     <attr name="typeface">
         <enum name="normal" value="0" />
@@ -423,26 +423,26 @@
         <enum name="serif" value="2" />
         <enum name="monospace" value="3" />
     </attr>
-    
+
     <!-- Default text typeface style. -->
     <attr name="textStyle">
         <flag name="normal" value="0" />
         <flag name="bold" value="1" />
         <flag name="italic" value="2" />
     </attr>
-    
+
     <!-- Color of text (usually same as colorForeground). -->
     <attr name="textColor" format="reference|color" />
-    
+
     <!-- Color of highlighted text. -->
     <attr name="textColorHighlight" format="reference|color" />
-    
+
     <!-- Color of hint text (displayed when the field is empty). -->
     <attr name="textColorHint" format="reference|color" />
-    
+
     <!-- Color of link text (URLs). -->
     <attr name="textColorLink" format="reference|color" />
-    
+
     <!-- Where to ellipsize text. -->
     <attr name="ellipsize">
         <enum name="none" value="0" />
@@ -451,7 +451,7 @@
         <enum name="end" value="3" />
         <enum name="marquee" value="4" />
     </attr>
-    
+
     <!-- The type of data being placed in a text field, used to help an
          input method decide how to let the user enter text.  The constants
          here correspond to those defined by
@@ -658,7 +658,7 @@
     <attr name="x" format="dimension" />
     <!-- A coordinate in the Y dimension. -->
     <attr name="y" format="dimension" />
-          
+
     <!-- Specifies how to place an object, both
          its x and y axis, within a larger containing object. -->
     <attr name="gravity">
@@ -764,11 +764,11 @@
     <!-- ========================== -->
     <eat-comment />
 
-    <!-- This enum provides the same keycode values as can be found in 
+    <!-- This enum provides the same keycode values as can be found in
         {@link android.view.KeyEvent} -->
     <attr name="keycode">
         <enum name="KEYCODE_UNKNOWN" value="0" />
-        <enum name="KEYCODE_SOFT_LEFT" value="1" />    
+        <enum name="KEYCODE_SOFT_LEFT" value="1" />
         <enum name="KEYCODE_SOFT_RIGHT" value="2" />
         <enum name="KEYCODE_HOME" value="3" />
         <enum name="KEYCODE_BACK" value="4" />
@@ -901,7 +901,7 @@
         <attr name="bottomMedium" format="reference|color" />
         <attr name="centerMedium" format="reference|color" />
     </declare-styleable>
-    
+
     <!-- Window animation class attributes. -->
     <declare-styleable name="WindowAnimation">
         <!-- The animation used when a window is being added. -->
@@ -945,7 +945,7 @@
              allows you to later retrieve the view
              with <code>findViewById(R.id.my_id)</code>. -->
         <attr name="id" format="reference" />
-        
+
         <!-- Supply a tag for this view containing a String, to be retrieved
              later with {@link android.view.View#getTag View.getTag()} or
              searched for with {@link android.view.View#findViewWithTag
@@ -953,7 +953,7 @@
              IDs (through the android:id attribute) instead of tags because
              they are faster and allow for compile-time type checking. -->
         <attr name="tag" format="string" />
-        
+
         <!-- The initial horizontal scroll offset, in pixels.-->
         <attr name="scrollX" format="dimension" />
 
@@ -967,7 +967,7 @@
         <attr name="background" format="reference|color" />
 
         <!-- Sets the padding, in pixels, of all four edges.  Padding is defined as
-             space between the edges of the view and the view's content. A views size 
+             space between the edges of the view and the view's content. A views size
              will include it's padding.  If a {@link android.R.attr#background}
              is provided, the padding will initially be set to that (0 if the
              drawable does not have padding).  Explicitly setting a padding value
@@ -1022,12 +1022,12 @@
         </attr>
 
         <!-- Controls the scrollbar style and position. The scrollbars can be overlaid or
-             inset. When inset, they add to the padding of the view. And the 
-             scrollbars can be drawn inside the padding area or on the edge of 
-             the view. For example, if a view has a background drawable and you 
-             want to draw the scrollbars inside the padding specified by the 
-             drawable, you can use insideOverlay or insideInset. If you want them 
-             to appear at the edge of the view, ignoring the padding, then you can 
+             inset. When inset, they add to the padding of the view. And the
+             scrollbars can be drawn inside the padding area or on the edge of
+             the view. For example, if a view has a background drawable and you
+             want to draw the scrollbars inside the padding specified by the
+             drawable, you can use insideOverlay or insideInset. If you want them
+             to appear at the edge of the view, ignoring the padding, then you can
              use outsideOverlay or outsideInset.-->
         <attr name="scrollbarStyle">
             <!-- Inside the padding and overlaid -->
@@ -1039,14 +1039,14 @@
             <!-- Edge of the view and inset -->
             <enum name="outsideInset" value="0x03000000" />
         </attr>
-        
+
         <!-- Set this if the view will serve as a scrolling container, meaing
              that it can be resized to shrink its overall window so that there
              will be space for an input method.  If not set, the default
              value will be true if "scrollbars" has the vertical scrollbar
              set, else it will be false. -->
         <attr name="isScrollContainer" format="boolean" />
-        
+
         <!-- Sets the width of vertical scrollbars and height of horizontal scrollbars. -->
         <attr name="scrollbarSize" format="dimension" />
         <!-- Defines the horizontal scrollbar thumb drawable. -->
@@ -1108,10 +1108,10 @@
 
         <!-- Defines whether this view reacts to click events. -->
         <attr name="clickable" format="boolean" />
-        
+
         <!-- Defines whether this view reacts to long click events. -->
         <attr name="longClickable" format="boolean" />
-        
+
         <!-- If unset, no state will be saved for this view when it is being
              frozen. The default is true, allowing the view to be saved
              (however it also must have an ID assigned to it for its
@@ -1119,7 +1119,7 @@
              state for this view, not for its children which may still
              be saved. -->
         <attr name="saveEnabled" format="boolean" />
-        
+
         <!-- Defines the quality of translucent drawing caches. This property is used
              only when the drawing cache is enabled and translucent. The default value is auto. -->
         <attr name="drawingCacheQuality">
@@ -1137,16 +1137,16 @@
         <!-- Controls whether the view's window should keep the screen on
              while visible. -->
         <attr name="keepScreenOn" format="boolean" />
-        
+
         <!-- When this attribute is set to true, the view gets its drawable state
              (focused, pressed, etc.) from its direct parent rather than from itself. -->
         <attr name="duplicateParentState" format="boolean" />
-        
+
         <!-- Defines the minimum height of the view. It is not guaranteed
              the view will be able to achieve this minimum height (for example,
              if its parent layout constrains it with less available height). -->
         <attr name="minHeight" />
-        
+
         <!-- Defines the minimum width of the view. It is not guaranteed
              the view will be able to achieve this minimum width (for example,
              if its parent layout constrains it with less available width). -->
@@ -1196,7 +1196,7 @@
             <flag name="animation" value="0x1" />
             <!-- The drawing cache is persisted after a scroll. -->
             <flag name="scrolling" value="0x2" />
-            <!-- The drawing cache is always persisted. -->            
+            <!-- The drawing cache is always persisted. -->
             <flag name="all" value="0x3" />
         </attr>
         <!-- Defines whether the ViewGroup should always draw its children using their
@@ -1308,7 +1308,7 @@
              method should be considered an option as the default. -->
         <attr name="isDefault" format="boolean" />
     </declare-styleable>
-    
+
     <!-- =============================== -->
     <!-- Widget package class attributes -->
     <!-- =============================== -->
@@ -1317,7 +1317,7 @@
     <declare-styleable name="AbsListView">
          <!-- Drawable used to indicate the currently selected item in the list. -->
         <attr name="listSelector" format="color|reference" />
-        <!-- When set to true, the selector will be drawn over the selected item. 
+        <!-- When set to true, the selector will be drawn over the selected item.
              Otherwise the selector is drawn behind the selected item. The default
              value is false. -->
         <attr name="drawSelectorOnTop" format="boolean" />
@@ -1340,13 +1340,13 @@
                  already visible on screen. -->
             <enum name="normal" value="1" />
             <!-- The list will automatically scroll to the bottom, no matter what items
-                 are currently visible. --> 
+                 are currently visible. -->
             <enum name="alwaysScroll" value="2" />
         </attr>
         <!-- Indicates that this list will always be drawn on top of solid, single-color
              opaque background. This allows the list to optimize drawing. -->
         <attr name="cacheColorHint" format="color" />
-        <!-- Enables the fast scroll thumb that can be dragged to quickly scroll through 
+        <!-- Enables the fast scroll thumb that can be dragged to quickly scroll through
              the list. -->
         <attr name="fastScrollEnabled" format="boolean" />
         <!-- When set to true, the list will use a more refined calculation
@@ -1435,7 +1435,7 @@
         <!-- Defines whether the foreground drawable should be drawn inside the padding.
              This property is turned on by default. -->
         <attr name="foregroundInsidePadding" format="boolean" />
-        <!-- Determines whether to measure all children or just those in 
+        <!-- Determines whether to measure all children or just those in
              the VISIBLE or INVISIBLE state when measuring. Defaults to false. -->
         <attr name="measureAllChildren" format="boolean" />
     </declare-styleable>
@@ -1445,14 +1445,14 @@
         <!-- Indicator shown beside the child View. This can be a stateful Drawable. -->
         <attr name="childIndicator" format="reference" />
         <!-- The left bound for an item's indicator. To specify a left bound specific to children,
-             use childIndicatorLeft. --> 
+             use childIndicatorLeft. -->
         <attr name="indicatorLeft" format="dimension" />
         <!-- The right bound for an item's indicator. To specify a right bound specific to children,
-             use childIndicatorRight. --> 
+             use childIndicatorRight. -->
         <attr name="indicatorRight" format="dimension" />
-        <!-- The left bound for a child's indicator. --> 
+        <!-- The left bound for a child's indicator. -->
         <attr name="childIndicatorLeft" format="dimension" />
-        <!-- The right bound for a child's indicator. --> 
+        <!-- The right bound for a child's indicator. -->
         <attr name="childIndicatorRight" format="dimension" />
         <!-- Drawable or color that is used as a divider for children. (It will drawn
              below and above child items.) The height of this will be the same as
@@ -1503,10 +1503,10 @@
         <!-- Set this to true if you want the ImageView to adjust its bounds
              to preserve the aspect ratio of its drawable. -->
         <attr name="adjustViewBounds" format="boolean" />
-        <!-- An optional argument to supply a maximum width for this view. 
+        <!-- An optional argument to supply a maximum width for this view.
              See {see android.widget.ImageView#setMaxWidth} for details. -->
         <attr name="maxWidth" format="dimension" />
-        <!-- An optional argument to supply a maximum height for this view. 
+        <!-- An optional argument to supply a maximum height for this view.
              See {see android.widget.ImageView#setMaxHeight} for details. -->
         <attr name="maxHeight" format="dimension" />
         <!-- Set a tinting color for the image -->
@@ -1560,9 +1560,9 @@
         <!-- Height of the divider. Will use the intrinsic height of the divider if this
              is not specified. -->
         <attr name="dividerHeight" format="dimension" />
-        <!-- Defines the choice behavior for the List. By default, Lists do not have 
+        <!-- Defines the choice behavior for the List. By default, Lists do not have
              any choice behavior. By setting the choiceMode to singleChoice, the List
-             allows up to one item to be in a chosen state. By setting the choiceMode to 
+             allows up to one item to be in a chosen state. By setting the choiceMode to
              multipleChoice, the list allows any number of items to be chosen. -->
         <attr name="choiceMode">
             <!-- Normal list that does not indicate choices -->
@@ -1607,7 +1607,7 @@
         <!-- 'More' icon -->
         <attr name="moreIcon" format="reference" />
     </declare-styleable>
-    
+
     <declare-styleable name="ProgressBar">
         <!-- Defines the maximum value the progress can take. -->
         <attr name="max" format="integer" />
@@ -1640,27 +1640,27 @@
         <attr name="maxWidth" />
         <attr name="minHeight" format="dimension" />
         <attr name="maxHeight" />
-        <attr name="interpolator" format="reference" />        
+        <attr name="interpolator" format="reference" />
     </declare-styleable>
-    
+
     <declare-styleable name="SeekBar">
-        <!-- Draws the thumb on a seekbar -->    
+        <!-- Draws the thumb on a seekbar -->
         <attr name="thumb" format="reference" />
         <!-- An offset for the thumb that allows it to extend out of the range of the track. -->
-        <attr name="thumbOffset" format="dimension" /> 
+        <attr name="thumbOffset" format="dimension" />
     </declare-styleable>
-    
+
     <declare-styleable name="RatingBar">
-        <!-- The number of stars (or rating items) to show. -->    
-        <attr name="numStars" format="integer" /> 
-        <!-- The rating to set by default. -->    
-        <attr name="rating" format="float" /> 
-        <!-- The step size of the rating. -->    
-        <attr name="stepSize" format="float" /> 
-        <!-- Whether this rating bar is an indicator (and non-changeable by the user). -->    
-        <attr name="isIndicator" format="boolean" /> 
+        <!-- The number of stars (or rating items) to show. -->
+        <attr name="numStars" format="integer" />
+        <!-- The rating to set by default. -->
+        <attr name="rating" format="float" />
+        <!-- The step size of the rating. -->
+        <attr name="stepSize" format="float" />
+        <!-- Whether this rating bar is an indicator (and non-changeable by the user). -->
+        <attr name="isIndicator" format="boolean" />
     </declare-styleable>
-    
+
     <declare-styleable name="RadioGroup">
         <!-- The id of the child radio button that should be checked by default
              within this radio group. -->
@@ -1682,7 +1682,7 @@
              indices are ignored. You can shrink all columns by using the
              value "*" instead. Note that a column can be marked stretchable
              and shrinkable at the same time. -->
-        <attr name="shrinkColumns" format="string" /> 
+        <attr name="shrinkColumns" format="string" />
         <!-- The 0 based index of the columns to collapse. The column indices
              must be separated by a comma: 1, 2, 5. Illegal and duplicate
              indices are ignored. -->
@@ -1783,7 +1783,7 @@
         <attr name="minEms" format="integer" min="0" />
         <!-- Makes the TextView be at least this many pixels wide -->
         <attr name="minWidth" />
-        <!-- Specifies how to align the text by the view's x and/or y axis 
+        <!-- Specifies how to align the text by the view's x and/or y axis
              when the text is smaller than the view. -->
         <attr name="gravity" />
         <!-- Whether the text is allowed to be wider than the view (and
@@ -1801,10 +1801,10 @@
              attribute.  (If both singleLine and inputType are supplied,
              the inputType flags will override the value of singleLine.)
              {@deprecated This attribute is deprecated and is replaced by the textMultiLine flag
-             in the inputType attribute.  Use caution when altering existing layouts, as the 
-             default value of singeLine is false (multi-line mode), but if you specify any 
-             value for inputType, the default is single-line mode.  (If both singleLine and 
-             inputType attributes are found,  the inputType flags will override the value of 
+             in the inputType attribute.  Use caution when altering existing layouts, as the
+             default value of singeLine is false (multi-line mode), but if you specify any
+             value for inputType, the default is single-line mode.  (If both singleLine and
+             inputType attributes are found,  the inputType flags will override the value of
              singleLine.) } -->
         <attr name="singleLine" format="boolean" />
         <!-- {@deprecated Use state_enabled instead.} -->
@@ -1908,7 +1908,7 @@
         <attr name="lineSpacingExtra" format="dimension" />
         <!-- Extra spacing between lines of text, as a multiplier. -->
         <attr name="lineSpacingMultiplier" format="float" />
-        <!-- The number of times to repeat the marquee animation. Only applied if the 
+        <!-- The number of times to repeat the marquee animation. Only applied if the
              TextView has marquee enabled. -->
         <attr name="marqueeRepeatLimit" format="integer">
             <!-- Indicates that marquee should repeat indefinitely  -->
@@ -1999,7 +1999,7 @@
         <!-- The prompt to display when the spinner's dialog is shown. -->
         <attr name="prompt" format="reference" />
     </declare-styleable>
-    <declare-styleable name="DatePicker">  
+    <declare-styleable name="DatePicker">
         <!-- The first year (inclusive) i.e. 1940 -->
         <attr name="startYear" format="integer" />
         <!-- The last year (inclusive) i.e. 2010 -->
@@ -2123,7 +2123,7 @@
              {@link android.graphics.drawable.Drawable#setVisible} -->
         <attr name="visible" format="boolean" />
     </declare-styleable>
-    
+
     <declare-styleable name="StateListDrawable">
         <attr name="visible" />
         <!-- If true, allows the drawable's padding to change based on the
@@ -2139,7 +2139,7 @@
              current state. -->
         <attr name="constantSize" format="boolean" />
     </declare-styleable>
-    
+
     <declare-styleable name="AnimationDrawable">
         <attr name="visible" />
         <attr name="variablePadding" />
@@ -2148,15 +2148,15 @@
              restarting at the first frame after the last has finished. -->
         <attr name="oneshot" format="boolean" />
     </declare-styleable>
-    
+
     <declare-styleable name="AnimationDrawableItem">
         <!-- Amount of time (in milliseconds) to display this frame. -->
-        <attr name="duration" format="integer" /> 
+        <attr name="duration" format="integer" />
         <!-- Reference to a drawable resource to use for the frame.  If not
              given, the drawable must be defined by the first child tag. -->
         <attr name="drawable" format="reference" />
     </declare-styleable>
-    
+
     <declare-styleable name="GradientDrawable">
         <attr name="visible" />
         <attr name="shape">
@@ -2179,18 +2179,18 @@
         <attr name="thickness" format="dimension" />
         <attr name="useLevel" />
     </declare-styleable>
-    
+
     <declare-styleable name="GradientDrawableSize">
         <attr name="width" />
         <attr name="height" />
     </declare-styleable>
-    
+
     <declare-styleable name="GradientDrawableGradient">
         <attr name="startColor" format="color" />
         <!-- Optional center color. For linear gradients, use centerX or centerY to place the center color. -->
         <attr name="centerColor" format="color" />
         <attr name="endColor" format="color" />
-        <attr name="useLevel" format="boolean" />        
+        <attr name="useLevel" format="boolean" />
         <attr name="angle" format="float" />
         <attr name="type">
             <enum name="linear" value="0" />
@@ -2201,18 +2201,18 @@
         <attr name="centerY" format="float|fraction" />
         <attr name="gradientRadius" format="float|fraction" />
     </declare-styleable>
-    
+
     <declare-styleable name="GradientDrawableSolid">
         <attr name="color" format="color" />
     </declare-styleable>
-    
+
     <declare-styleable name="GradientDrawableStroke">
         <attr name="width" />
         <attr name="color" />
         <attr name="dashWidth" format="dimension" />
         <attr name="dashGap" format="dimension" />
     </declare-styleable>
-    
+
     <declare-styleable name="DrawableCorners">
         <attr name="radius" format="dimension" />
         <attr name="topLeftRadius" format="dimension" />
@@ -2220,14 +2220,14 @@
         <attr name="bottomLeftRadius" format="dimension" />
         <attr name="bottomRightRadius" format="dimension" />
     </declare-styleable>
-    
+
     <declare-styleable name="GradientDrawablePadding">
         <attr name="left" format="dimension" />
         <attr name="top" format="dimension" />
         <attr name="right" format="dimension" />
         <attr name="bottom" format="dimension" />
     </declare-styleable>
-    
+
     <declare-styleable name="LayerDrawableItem">
         <attr name="left" />
         <attr name="top" />
@@ -2236,7 +2236,7 @@
         <attr name="drawable" />
         <attr name="id" />
     </declare-styleable>
-    
+
     <declare-styleable name="LevelListDrawableItem">
         <!-- The minimum level allowed for this item. -->
         <attr name="minLevel" format="integer" />
@@ -2244,7 +2244,7 @@
         <attr name="maxLevel" format="integer" />
         <attr name="drawable" />
     </declare-styleable>
-    
+
     <declare-styleable name="RotateDrawable">
         <attr name="visible" />
         <attr name="fromDegrees" format="float" />
@@ -2400,7 +2400,7 @@
     <declare-styleable name="AnimationSet">
         <attr name="shareInterpolator" format="boolean" />
     </declare-styleable>
-    
+
     <declare-styleable name="Animation">
         <!-- Defines the interpolator used to smooth the animation movement in time. -->
         <attr name="interpolator" />
@@ -2443,14 +2443,14 @@
             <enum name="bottom" value="-1" />
         </attr>
     </declare-styleable>
-    
+
     <declare-styleable name="RotateAnimation">
         <attr name="fromDegrees" />
         <attr name="toDegrees" />
         <attr name="pivotX" />
         <attr name="pivotY" />
     </declare-styleable>
-    
+
     <declare-styleable name="ScaleAnimation">
         <attr name="fromXScale" format="float" />
         <attr name="toXScale" format="float" />
@@ -2459,14 +2459,14 @@
         <attr name="pivotX" />
         <attr name="pivotY" />
     </declare-styleable>
-    
+
     <declare-styleable name="TranslateAnimation">
         <attr name="fromXDelta" format="float|fraction" />
         <attr name="toXDelta" format="float|fraction" />
         <attr name="fromYDelta" format="float|fraction" />
         <attr name="toYDelta" format="float|fraction" />
     </declare-styleable>
-    
+
     <declare-styleable name="AlphaAnimation">
         <attr name="fromAlpha" format="float" />
         <attr name="toAlpha" format="float" />
@@ -2528,12 +2528,12 @@
         <!-- This is the amount of deceleration to ad when easing in. -->
         <attr name="factor" format="float" />
     </declare-styleable>
-    
+
     <declare-styleable name="DecelerateInterpolator">
         <!-- This is the amount of acceleration to ad when easing out. -->
         <attr name="factor" />
     </declare-styleable>
-    
+
     <declare-styleable name="CycleInterpolator">
         <attr name="cycles" format="float" />
     </declare-styleable>
@@ -2626,18 +2626,18 @@
     </declare-styleable>
     <!-- State array representing an expandable list child's indicator. -->
     <declare-styleable name="ExpandableListChildIndicatorState">
-        <!-- State identifier indicating the child is the last child within its group. --> 
+        <!-- State identifier indicating the child is the last child within its group. -->
         <attr name="state_last" />
     </declare-styleable>
     <!-- State array representing an expandable list group's indicator. -->
     <declare-styleable name="ExpandableListGroupIndicatorState">
-        <!-- State identifier indicating the group is expanded. --> 
+        <!-- State identifier indicating the group is expanded. -->
         <attr name="state_expanded" format="boolean" />
-        <!-- State identifier indicating the group is empty (has no children). --> 
+        <!-- State identifier indicating the group is empty (has no children). -->
         <attr name="state_empty" format="boolean" />
     </declare-styleable>
     <declare-styleable name="PopupWindowBackgroundState">
-        <!-- State identifier indicating the popup will be above the anchor. --> 
+        <!-- State identifier indicating the popup will be above the anchor. -->
         <attr name="state_above_anchor" format="boolean" />
     </declare-styleable>
 
@@ -2647,7 +2647,7 @@
     <eat-comment />
 
     <!-- Searchable activities and applications must provide search configuration information
-        in an XML file, typically called searchable.xml.  This file is referenced in your manifest. 
+        in an XML file, typically called searchable.xml.  This file is referenced in your manifest.
         For a more in-depth discussion of search configuration, please refer to
         {@link android.app.SearchManager}. -->
     <declare-styleable name="Searchable">
@@ -2656,29 +2656,29 @@
              plain text.  This is a reference to a drawable (icon) resource.
              <i>Optional attribute.</i> -->
         <attr name="icon" />
-        <!-- This is the user-displayed name of the searchable activity.  <i>Required 
+        <!-- This is the user-displayed name of the searchable activity.  <i>Required
             attribute.</i> -->
         <attr name="label" />
-        <!-- If supplied, this string will be displayed as a hint to the user.  <i>Optional 
+        <!-- If supplied, this string will be displayed as a hint to the user.  <i>Optional
             attribute.</i> -->
         <attr name="hint" />
         <!-- If supplied, this string will be displayed as the text of the "Search" button.
-          <i>Optional attribute.</i> 
+          <i>Optional attribute.</i>
           {@deprecated This will create a non-standard UI appearance, because the search bar UI is
                        changing to use only icons for its buttons.}-->
         <attr name="searchButtonText" format="string" />
         <attr name="inputType" />
         <attr name="imeOptions" />
-        
+
         <!-- Additional features are controlled by mode bits in this field.  Omitting
-            this field, or setting to zero, provides default behavior.  <i>Optional attribute.</i> 
+            this field, or setting to zero, provides default behavior.  <i>Optional attribute.</i>
         -->
         <attr name="searchMode">
           <!-- If set, this flag enables the display of the search target (label) within the
                search bar.  If neither bad mode is selected, no badge will be shown. -->
           <flag name="showSearchLabelAsBadge" value="0x04" />
           <!-- If set, this flag enables the display of the search target (icon) within the
-               search bar.  (Note, overrides showSearchLabel)  If neither bad mode is selected, 
+               search bar.  (Note, overrides showSearchLabel)  If neither bad mode is selected,
                no badge will be shown.-->
           <flag name="showSearchIconAsBadge" value="0x08" />
           <!-- If set, this flag causes the suggestion column SUGGEST_COLUMN_INTENT_DATA to
@@ -2692,11 +2692,11 @@
                values are not suitable for user inspection and editing. -->
           <flag name="queryRewriteFromText" value="0x20" />
         </attr>
-        
+
         <!-- Voice search features are controlled by mode bits in this field.  Omitting
             this field, or setting to zero, provides default behavior.
             If showVoiceSearchButton is set, then launchWebSearch or launchRecognizer must
-            also be set.  <i>Optional attribute.</i> 
+            also be set.  <i>Optional attribute.</i>
         -->
         <attr name="voiceSearchMode">
           <!-- If set, display a voice search button.  This only takes effect if voice search is
@@ -2714,9 +2714,9 @@
         </attr>
 
         <!-- If provided, this specifies the language model that should be used by the
-             voice recognition system.  See 
-             {@link android.speech.RecognizerIntent#EXTRA_LANGUAGE_MODEL } for more information. 
-             If not provided, the default value 
+             voice recognition system.  See
+             {@link android.speech.RecognizerIntent#EXTRA_LANGUAGE_MODEL } for more information.
+             If not provided, the default value
              {@link android.speech.RecognizerIntent#LANGUAGE_MODEL_FREE_FORM } will be used. -->
         <attr name="voiceLanguageModel" format="string" />
         <!-- If provided, this specifies a prompt that will be displayed during voice input. -->
@@ -2726,14 +2726,14 @@
         <attr name="voiceLanguage" format="string" />
         <!-- If provided, enforces the maximum number of results to return, including the "best"
              result which will always be provided as the SEARCH intent's primary query.  Must be one
-             or greater.  If not provided, the recognizer will choose how many results to return. 
+             or greater.  If not provided, the recognizer will choose how many results to return.
              -->
         <attr name="voiceMaxResults" format="integer" />
 
         <!-- If provided, this is the trigger indicating that the searchable activity
             provides suggestions as well.  The value must be a fully-qualified content provider
-            authority (e.g. "com.example.android.apis.SuggestionProvider") and should match the 
-            "android:authorities" tag in your content provider's manifest entry.  <i>Optional 
+            authority (e.g. "com.example.android.apis.SuggestionProvider") and should match the
+            "android:authorities" tag in your content provider's manifest entry.  <i>Optional
             attribute.</i> -->
         <attr name="searchSuggestAuthority" format="string" />
         <!-- If provided, this will be inserted in the suggestions query Uri, after the authority
@@ -2741,22 +2741,22 @@
             -->
         <attr name="searchSuggestPath" format="string" />
         <!-- If provided, suggestion queries will be passed into your query function
-            as the <i>selection</i> parameter.  Typically this will be a WHERE clause for your 
-            database, and will contain a single question mark, which represents the actual query 
+            as the <i>selection</i> parameter.  Typically this will be a WHERE clause for your
+            database, and will contain a single question mark, which represents the actual query
             string that has been typed by the user.  If not provided, then the user query text
-            will be appended to the query Uri (after an additional "/".)  <i>Optional 
+            will be appended to the query Uri (after an additional "/".)  <i>Optional
             attribute.</i> -->
         <attr name="searchSuggestSelection" format="string" />
 
-        <!-- If provided, and not overridden by an action in the selected suggestion, this 
+        <!-- If provided, and not overridden by an action in the selected suggestion, this
             string will be placed in the action field of the {@link android.content.Intent Intent}
             when the user clicks a suggestion.  <i>Optional attribute.</i> -->
         <attr name="searchSuggestIntentAction" format="string" />
-        <!-- If provided, and not overridden by an action in the selected suggestion, this 
-            string will be placed in the data field of the {@link android.content.Intent Intent} 
+        <!-- If provided, and not overridden by an action in the selected suggestion, this
+            string will be placed in the data field of the {@link android.content.Intent Intent}
             when the user clicks a suggestion.  <i>Optional attribute.</i> -->
         <attr name="searchSuggestIntentData" format="string" />
-        
+
     </declare-styleable>
 
     <!-- In order to process special action keys during search, you must define them using
@@ -2766,70 +2766,70 @@
     <declare-styleable name="SearchableActionKey">
         <!-- This attribute denotes the action key you wish to respond to.  Note that not
             all action keys are actually supported using this mechanism, as many of them are
-            used for typing, navigation, or system functions.  This will be added to the 
+            used for typing, navigation, or system functions.  This will be added to the
             {@link android.content.Intent#ACTION_SEARCH ACTION_SEARCH} intent that is passed to your
-            searchable activity.  To examine the key code, use 
+            searchable activity.  To examine the key code, use
             {@link android.content.Intent#getIntExtra getIntExtra(SearchManager.ACTION_KEY)}.
-            <p>Note, in addition to the keycode, you must also provide one or more of the action 
+            <p>Note, in addition to the keycode, you must also provide one or more of the action
             specifier attributes.  <i>Required attribute.</i> -->
         <attr name="keycode" />
-        
+
         <!-- If you wish to handle an action key during normal search query entry, you
-            must define an action string here.  This will be added to the 
+            must define an action string here.  This will be added to the
             {@link android.content.Intent#ACTION_SEARCH ACTION_SEARCH} intent that is passed to your
-            searchable activity.  To examine the string, use 
+            searchable activity.  To examine the string, use
             {@link android.content.Intent#getStringExtra getStringExtra(SearchManager.ACTION_MSG)}.
             <i>Optional attribute.</i> -->
         <attr name="queryActionMsg"  format="string" />
-        
+
         <!-- If you wish to handle an action key while a suggestion is being displayed <i>and
             selected</i>, there are two ways to handle this.  If <i>all</i> of your suggestions
-            can handle the action key, you can simply define the action message using this 
-            attribute.  This will be added to the 
+            can handle the action key, you can simply define the action message using this
+            attribute.  This will be added to the
             {@link android.content.Intent#ACTION_SEARCH ACTION_SEARCH} intent that is passed to your
-            searchable activity.  To examine the string, use 
+            searchable activity.  To examine the string, use
             {@link android.content.Intent#getStringExtra getStringExtra(SearchManager.ACTION_MSG)}.
             <i>Optional attribute.</i> -->
         <attr name="suggestActionMsg"  format="string" />
-        
+
         <!-- If you wish to handle an action key while a suggestion is being displayed <i>and
-            selected</i>, but you do not wish to enable this action key for every suggestion, 
+            selected</i>, but you do not wish to enable this action key for every suggestion,
             then you can use this attribute to control it on a suggestion-by-suggestion basis.
-            First, you must define a column (and name it here) where your suggestions will include 
+            First, you must define a column (and name it here) where your suggestions will include
             the action string.  Then, in your content provider, you must provide this column, and
             when desired, provide data in this column.
-            The search manager will look at your suggestion cursor, using the string 
-            provided here in order to select a column, and will use that to select a string from 
-            the cursor.  That string will be added to the 
-            {@link android.content.Intent#ACTION_SEARCH ACTION_SEARCH} intent that is passed to 
-            your searchable activity.  To examine the string, use 
-            {@link android.content.Intent#getStringExtra 
+            The search manager will look at your suggestion cursor, using the string
+            provided here in order to select a column, and will use that to select a string from
+            the cursor.  That string will be added to the
+            {@link android.content.Intent#ACTION_SEARCH ACTION_SEARCH} intent that is passed to
+            your searchable activity.  To examine the string, use
+            {@link android.content.Intent#getStringExtra
             getStringExtra(SearchManager.ACTION_MSG)}.  <i>If the data does not exist for the
             selection suggestion, the action key will be ignored.</i><i>Optional attribute.</i> -->
         <attr name="suggestActionMsgColumn" format="string" />
 
     </declare-styleable>
-    
+
     <!-- ***************************************************************** -->
     <!-- Support for MapView. -->
     <!-- ***************************************************************** -->
     <eat-comment />
-    
+
     <!-- The set of attributes for a MapView. -->
     <declare-styleable name="MapView">
         <!-- Value is a string that specifies the Maps API Key to use. -->
         <attr name="apiKey" format="string" />
     </declare-styleable>
-    
+
     <!-- **************************************************************** -->
     <!-- Menu XML inflation. -->
     <!-- **************************************************************** -->
     <eat-comment />
-    
+
     <!-- Base attributes that are available to all Menu objects. -->
     <declare-styleable name="Menu">
     </declare-styleable>
-    
+
     <!-- Base attributes that are available to all groups. -->
     <declare-styleable name="MenuGroup">
 
@@ -2848,11 +2848,11 @@
             <!-- Items are alternative actions. -->
             <enum name="alternative" value="0x00040000" />
         </attr>
-        
+
         <!-- The order within the category applied to all items within this group.
              (This will be or'ed with the category attribute.) -->
         <attr name="orderInCategory" format="integer" />
-        
+
         <!-- Whether the items are capable of displaying a check mark. -->
         <attr name="checkableBehavior">
             <!-- The items are not checkable. -->
@@ -2863,7 +2863,7 @@
                  this group. -->
             <enum name="single" value="2" />
         </attr>
-                
+
         <!-- Whether the items are shown/visible. -->
         <attr name="visible" />
 
@@ -2877,7 +2877,7 @@
 
         <!-- The ID of the item. -->
         <attr name="id" />
-        
+
         <!-- The category applied to the item.
              (This will be or'ed with the orderInCategory attribute.) -->
         <attr name="menuCategory" />
@@ -2888,15 +2888,15 @@
 
         <!-- The title associated with the item. -->
         <attr name="title" format="string" />
-        
+
         <!-- The condensed title associated with the item.  This is used in situations where the
              normal title may be too long to be displayed. -->
         <attr name="titleCondensed" format="string" />
 
         <!-- The icon associated with this item.  This icon will not always be shown, so
-             the title should be sufficient in describing this item. -->        
+             the title should be sufficient in describing this item. -->
         <attr name="icon" />
-        
+
         <!-- The alphabetic shortcut key.  This is the shortcut when using a keyboard
              with alphabetic keys. -->
         <attr name="alphabeticShortcut" format="string" />
@@ -2904,14 +2904,14 @@
         <!-- The numeric shortcut key.  This is the shortcut when using a numeric (e.g., 12-key)
              keyboard. -->
         <attr name="numericShortcut" format="string" />
-        
+
         <!-- Whether the item is capable of displaying a check mark. -->
         <attr name="checkable" format="boolean" />
-        
-        <!-- Whether the item is checked.  Note that you must first have enabled checking with 
+
+        <!-- Whether the item is checked.  Note that you must first have enabled checking with
              the checkable attribute or else the check mark will not appear. -->
         <attr name="checked" />
-        
+
         <!-- Whether the item is shown/visible. -->
         <attr name="visible" />
 
@@ -2937,7 +2937,7 @@
                    with a View's attributes.  Some subclasses (e.g., EditTextPreference)
                    proxy all attributes to its EditText widget. -->
     <eat-comment />
-    
+
     <!-- Base attributes available to Preference. -->
     <declare-styleable name="Preference">
         <!-- The key to store the Preference value. -->
@@ -3066,7 +3066,7 @@
              it had previously been shown. -->
         <attr name="imeExtractExitAnimation" format="reference" />
     </declare-styleable>
-    
+
     <declare-styleable name="KeyboardView">
         <!-- Default KeyboardView style. -->
         <attr name="keyboardViewStyle" format="reference" />
@@ -3099,13 +3099,13 @@
 
         <!-- Layout resource for popup keyboards -->
         <attr name="popupLayout" format="reference" />
-        
+
         <attr name="shadowColor" />
         <attr name="shadowRadius" />
     </declare-styleable>
-    
+
     <declare-styleable name="KeyboardViewPreviewState">
-        <!-- State for {@link android.inputmethodservice.KeyboardView KeyboardView} 
+        <!-- State for {@link android.inputmethodservice.KeyboardView KeyboardView}
                 key preview background -->
         <attr name="state_long_pressable" format="boolean" />
     </declare-styleable>
@@ -3188,7 +3188,20 @@
              If not supplied, then no activity will be launched. -->
         <attr name="configure" format="string" />
     </declare-styleable>
-    
-    
+
+
+    <!-- =============================== -->
+    <!-- Accounts package class attributes -->
+    <!-- =============================== -->
+
+    <!-- Use <code>account-authenticator</code> as the root tag of the XML resource that
+         describes an account authenticator.
+     -->
+    <declare-styleable name="AccountAuthenticator">
+        <!-- the account type this authenticator handles. -->
+        <attr name="accountType" format="string"/>
+    </declare-styleable>
+
+
 </resources>
 
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index ed35986..66a2cb8 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -5,16 +5,16 @@
      ***************************************************************
      IMPORTANT NOTE FOR ANYONE MODIFYING THIS FILE
      READ THIS BEFORE YOU MAKE ANY CHANGES
-     
+
      This file defines the binary compatibility for resources.  As such,
      you must be very careful when making changes here, or you will
      completely break backwards compatibility with old applications.
-     
+
      To avoid breaking compatibility, all new resources must be placed
      at the end of the list of resources of the same type.  Placing a resource
      in the middle of type will cause all following resources to be
      assigned new resource numbers, breaking compatibility.
-     
+
      ***************************************************************
      *************************************************************** -->
 <resources>
@@ -22,7 +22,7 @@
   <!-- We don't want to publish private symbols in android.R as part of the
        SDK.  Instead, put them here. -->
   <private-symbols package="com.android.internal" />
-    
+
   <!-- AndroidManifest.xml attributes. -->
   <eat-comment />
 
@@ -569,10 +569,10 @@
   <public type="attr" name="lineSpacingExtra" id="0x01010217" />
   <public type="attr" name="lineSpacingMultiplier" id="0x01010218" />
   <public type="attr" name="listChoiceIndicatorSingle" id="0x01010219" />
-  <public type="attr" name="listChoiceIndicatorMultiple" id="0x0101021a" />    
+  <public type="attr" name="listChoiceIndicatorMultiple" id="0x0101021a" />
   <public type="attr" name="versionCode" id="0x0101021b" />
   <public type="attr" name="versionName" id="0x0101021c" />
-  
+
   <public type="id" name="background" id="0x01020000" />
   <public type="id" name="checkbox" id="0x01020001" />
   <public type="id" name="content" id="0x01020002" />
@@ -601,7 +601,7 @@
   <public type="id" name="button1" id="0x01020019" />
   <public type="id" name="button2" id="0x0102001a" />
   <public type="id" name="button3" id="0x0102001b" />
-  
+
   <public type="style" name="Animation" id="0x01030000" />
   <public type="style" name="Animation.Activity" id="0x01030001" />
   <public type="style" name="Animation.Dialog" id="0x01030002" />
@@ -748,7 +748,7 @@
   <public type="drawable" name="btn_plus" id="0x01080008" />
   <public type="drawable" name="btn_radio" id="0x01080009" />
   <public type="drawable" name="btn_star" id="0x0108000a" />
-  <public type="drawable" name="btn_star_big_off" id="0x0108000b" /> 
+  <public type="drawable" name="btn_star_big_off" id="0x0108000b" />
   <public type="drawable" name="btn_star_big_on" id="0x0108000c" />
   <public type="drawable" name="button_onoff_indicator_on" id="0x0108000d" />
   <public type="drawable" name="button_onoff_indicator_off" id="0x0108000e" />
@@ -916,7 +916,7 @@
   <public type="layout" name="select_dialog_item" id="0x01090011" />
   <public type="layout" name="select_dialog_singlechoice" id="0x01090012" />
   <public type="layout" name="select_dialog_multichoice" id="0x01090013" />
-  
+
   <public type="anim" name="fade_in" id="0x010a0000" />
   <public type="anim" name="fade_out" id="0x010a0001" />
   <public type="anim" name="slide_in_left" id="0x010a0002" />
@@ -929,9 +929,9 @@
      Resources added in version 2 of the platform.
      =============================================================== -->
   <eat-comment />
-  
+
   <public type="attr" name="marqueeRepeatLimit" id="0x0101021d" />
-  
+
 <!-- ===============================================================
      Resources added in version 3 of the platform.
      =============================================================== -->
@@ -1063,7 +1063,7 @@
   <public type="id" name="stopSelectingText" id="0x01020029" />
   <!-- Menu ID to perform a "add to dictionary" operation. -->
   <public type="id" name="addToDictionary" id="0x0102002a" />
-  
+
   <public type="style" name="Theme.InputMethod" id="0x01030054" />
   <public type="style" name="Theme.NoDisplay" id="0x01030055" />
   <public type="style" name="Animation.InputMethod" id="0x01030056" />
@@ -1071,7 +1071,7 @@
   <public type="style" name="ButtonBar" id="0x01030058" />
   <public type="style" name="Theme.Panel" id="0x01030059" />
   <public type="style" name="Theme.Light.Panel" id="0x0103005a" />
-  
+
   <public type="string" name="dialog_alert_title" id="0x01040014" />
   <public type="string" name="VideoView_error_text_invalid_progressive_playback" id="0x01040015" />
 
@@ -1092,7 +1092,7 @@
   <public type="drawable" name="emo_im_winking"             id="0x010800b2" />
   <public type="drawable" name="emo_im_wtf"                 id="0x010800b3" />
   <public type="drawable" name="emo_im_yelling"             id="0x010800b4" />
-  
+
   <public type="drawable" name="ic_btn_speak_now" id="0x010800b5" />
 
   <!--  Drawable to use as a background for separators on a list with a dark background -->
@@ -1100,8 +1100,14 @@
 
   <!--  Drawable to use as a background for a taller version of the titlebar -->
   <public type="drawable" name="title_bar_tall" id="0x010800b7" />
-  
   <public type="integer" name="config_shortAnimTime" id="0x010e0000" />
   <public type="integer" name="config_mediumAnimTime" id="0x010e0001" />
   <public type="integer" name="config_longAnimTime" id="0x010e0002" />
+
+<!-- ===============================================================
+     Resources added in version 4 of the platform.
+     =============================================================== -->
+  <eat-comment />
+
+  <public type="attr" name="accountType" id="0x01010270" />
 </resources>
diff --git a/preloaded-classes b/preloaded-classes
index e3197b41..7b060b1 100644
--- a/preloaded-classes
+++ b/preloaded-classes
@@ -1,7 +1,6 @@
 # Classes which are preloaded by com.android.internal.os.ZygoteInit.
 android.R$styleable
 android.accounts.AccountMonitor
-android.accounts.AccountMonitor$AccountUpdater
 android.app.Activity
 android.app.ActivityGroup
 android.app.ActivityManager$MemoryInfo$1
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 1f508a6..efca2cb 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -32,12 +32,7 @@
 import android.database.ContentObserver;
 import android.database.Cursor;
 import android.media.AudioService;
-import android.os.IBinder;
-import android.os.Looper;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.os.SystemClock;
-import android.os.SystemProperties;
+import android.os.*;
 import android.provider.Contacts.People;
 import android.provider.Settings;
 import android.server.BluetoothA2dpService;
@@ -45,6 +40,7 @@
 import android.server.search.SearchManagerService;
 import android.util.EventLog;
 import android.util.Log;
+import android.accounts.AccountManagerService;
 
 import java.lang.reflect.Constructor;
 import java.lang.reflect.InvocationTargetException;
@@ -117,6 +113,14 @@
 
             mContentResolver = context.getContentResolver();
 
+            try {
+                Log.i(TAG, "Starting Account Manager.");
+                ServiceManager.addService(Context.ACCOUNT_SERVICE,
+                        new AccountManagerService(context));
+            } catch (Throwable e) {
+                Log.e(TAG, "Failure starting Account Manager", e);
+            }
+
             Log.i(TAG, "Starting Content Manager.");
             ContentService.main(context,
                     factoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL);
diff --git a/tests/AndroidTests/run_test.sh b/tests/AndroidTests/run_test.sh
index 0cdf63f..6c3710a 100755
--- a/tests/AndroidTests/run_test.sh
+++ b/tests/AndroidTests/run_test.sh
@@ -1,4 +1,4 @@
 framework=/system/framework
 bpath=$framework/core.jar:$framework/ext.jar:$framework/framework.jar:$framework/android.test.runner.jar
-adb shell exec dalvikvm  -Xbootclasspath:$bpath -cp system/app/AndroidTests.apk \
+adb shell exec dalvikvm  -Xbootclasspath:$bpath -cp system/app/AndroidTests.apk:data/app/AndroidTests.apk \
       com.android.internal.util.WithFramework junit.textui.TestRunner $*
diff --git a/tests/AndroidTests/src/com/android/unit_tests/accounts/AccountManagerServiceTest.java b/tests/AndroidTests/src/com/android/unit_tests/accounts/AccountManagerServiceTest.java
new file mode 100644
index 0000000..90c0ec0
--- /dev/null
+++ b/tests/AndroidTests/src/com/android/unit_tests/accounts/AccountManagerServiceTest.java
@@ -0,0 +1,188 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.unit_tests.accounts;
+
+import android.test.AndroidTestCase;
+import android.test.RenamingDelegatingContext;
+import android.test.IsolatedContext;
+import android.test.mock.MockContext;
+import android.test.mock.MockContentResolver;
+import android.content.*;
+import android.accounts.Account;
+import android.accounts.AccountManagerService;
+import android.os.Bundle;
+
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.Map;
+
+public class AccountManagerServiceTest extends AndroidTestCase {
+    @Override
+    protected void setUp() throws Exception {
+        final String filenamePrefix = "test.";
+        MockContentResolver resolver = new MockContentResolver();
+        RenamingDelegatingContext targetContextWrapper = new RenamingDelegatingContext(
+                new MockContext(), // The context that most methods are delegated to
+                getContext(), // The context that file methods are delegated to
+                filenamePrefix);
+        Context context = new IsolatedContext(resolver, targetContextWrapper);
+        setContext(context);
+    }
+
+    public class AccountSorter implements Comparator<Account> {
+        public int compare(Account object1, Account object2) {
+            if (object1 == object2) return 0;
+            if (object1 == null) return 1;
+            if (object2 == null) return -1;
+            int result = object1.mType.compareTo(object2.mType);
+            if (result != 0) return result;
+            return object1.mName.compareTo(object2.mName);
+        }
+    }
+
+    public void testCheckAddAccount() throws Exception {
+        AccountManagerService ams = new AccountManagerService(getContext());
+        Account a11 = new Account("account1", "type1");
+        Account a21 = new Account("account2", "type1");
+        Account a31 = new Account("account3", "type1");
+        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));
+
+        assertFalse("duplicate account insertion should fail", ams.addAccount(a32, "p", null));
+
+        Account[] accounts = ams.getAccounts();
+        Arrays.sort(accounts, new AccountSorter());
+        assertEquals(6, accounts.length);
+        assertEquals(a11, accounts[0]);
+        assertEquals(a21, accounts[1]);
+        assertEquals(a31, accounts[2]);
+        assertEquals(a12, accounts[3]);
+        assertEquals(a22, accounts[4]);
+        assertEquals(a32, accounts[5]);
+
+        accounts = ams.getAccountsByType("type1");
+        Arrays.sort(accounts, new AccountSorter());
+        assertEquals(3, accounts.length);
+        assertEquals(a11, accounts[0]);
+        assertEquals(a21, accounts[1]);
+        assertEquals(a31, accounts[2]);
+
+        ams.removeAccount(a21);
+
+        accounts = ams.getAccountsByType("type1");
+        Arrays.sort(accounts, new AccountSorter());
+        assertEquals(2, accounts.length);
+        assertEquals(a11, accounts[0]);
+        assertEquals(a31, accounts[1]);
+    }
+
+    public void testPasswords() throws Exception {
+        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));
+
+        assertEquals("p11", ams.getPassword(a11));
+        assertEquals("p12", ams.getPassword(a12));
+
+        ams.setPassword(a11, "p11b");
+
+        assertEquals("p11b", ams.getPassword(a11));
+        assertEquals("p12", ams.getPassword(a12));
+    }
+
+    public void testUserdata() throws Exception {
+        AccountManagerService ams = new AccountManagerService(getContext());
+        Account a11 = new Account("account1", "type1");
+        Bundle u11 = new Bundle();
+        u11.putString("a", "a_a11");
+        u11.putString("b", "b_a11");
+        u11.putString("c", "c_a11");
+        Account a12 = new Account("account1", "type2");
+        Bundle u12 = new Bundle();
+        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));
+
+        assertEquals("a_a11", ams.getUserData(a11, "a"));
+        assertEquals("b_a11", ams.getUserData(a11, "b"));
+        assertEquals("c_a11", ams.getUserData(a11, "c"));
+        assertEquals("a_a12", ams.getUserData(a12, "a"));
+        assertEquals("b_a12", ams.getUserData(a12, "b"));
+        assertEquals("c_a12", ams.getUserData(a12, "c"));
+
+        ams.setUserData(a11, "b", "b_a11b");
+
+        assertEquals("a_a11", ams.getUserData(a11, "a"));
+        assertEquals("b_a11b", ams.getUserData(a11, "b"));
+        assertEquals("c_a11", ams.getUserData(a11, "c"));
+        assertEquals("a_a12", ams.getUserData(a12, "a"));
+        assertEquals("b_a12", ams.getUserData(a12, "b"));
+        assertEquals("c_a12", ams.getUserData(a12, "c"));
+    }
+
+    public void testAuthtokens() throws Exception {
+        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.setAuthToken(a11, "att1", "a11_att1");
+        ams.setAuthToken(a11, "att2", "a11_att2");
+        ams.setAuthToken(a11, "att3", "a11_att3");
+        ams.setAuthToken(a12, "att1", "a12_att1");
+        ams.setAuthToken(a12, "att2", "a12_att2");
+        ams.setAuthToken(a12, "att3", "a12_att3");
+
+        assertEquals("a11_att1", ams.peekAuthToken(a11, "att1"));
+        assertEquals("a11_att2", ams.peekAuthToken(a11, "att2"));
+        assertEquals("a11_att3", ams.peekAuthToken(a11, "att3"));
+        assertEquals("a12_att1", ams.peekAuthToken(a12, "att1"));
+        assertEquals("a12_att2", ams.peekAuthToken(a12, "att2"));
+        assertEquals("a12_att3", ams.peekAuthToken(a12, "att3"));
+
+        ams.setAuthToken(a11, "att3", "a11_att3b");
+        ams.invalidateAuthToken(a12.mType, "a12_att2");
+
+        assertEquals("a11_att1", ams.peekAuthToken(a11, "att1"));
+        assertEquals("a11_att2", ams.peekAuthToken(a11, "att2"));
+        assertEquals("a11_att3b", ams.peekAuthToken(a11, "att3"));
+        assertEquals("a12_att1", ams.peekAuthToken(a12, "att1"));
+        assertNull(ams.peekAuthToken(a12, "att2"));
+        assertEquals("a12_att3", ams.peekAuthToken(a12, "att3"));
+
+        // check that the authtoken cache is consistent with the database
+        assertEquals(5, ams.mAuthTokenCache.size());
+        for (Map.Entry<AccountManagerService.AuthTokenKey, String> entry
+                : ams.mAuthTokenCache.entrySet()) {
+            assertEquals(entry.getValue(), ams.readAuthTokenFromDatabase(
+                    entry.getKey().mAccount, entry.getKey().mAuthTokenType));
+        }
+        assertNull(ams.readAuthTokenFromDatabase(a12, "att2"));
+    }
+}
\ No newline at end of file