do not merge: cherrypicked a83a03bbf0a7480c856d102a2b3a7f823ac4566b and a076d0dbd1d1afa7695150fddc8f9aae414f4c5d from master branch
diff --git a/apps/Development/res/layout/accounts_tester.xml b/apps/Development/res/layout/accounts_tester.xml
index 0a5b0d8..e69f505 100644
--- a/apps/Development/res/layout/accounts_tester.xml
+++ b/apps/Development/res/layout/accounts_tester.xml
@@ -25,6 +25,9 @@
        android:layout_width="fill_parent"
        android:layout_height="wrap_content">
 
+        <ListView android:id="@+id/accounts_tester_authenticators_list"
+           android:layout_width="fill_parent" android:layout_height="fill_parent"/>
+
       <LinearLayout
          android:orientation="horizontal"
          android:layout_width="fill_parent"
@@ -40,13 +43,14 @@
                    android:layout_height="wrap_content"/>
       </LinearLayout>
 
-      <ListView android:id="@+id/accounts_tester_authenticators_list"
-         android:layout_width="fill_parent" android:layout_height="fill_parent"/>
-
       <LinearLayout
          android:orientation="vertical"
          android:layout_width="fill_parent"
          android:layout_height="wrap_content">
+          <LinearLayout
+             android:orientation="horizontal"
+             android:layout_width="fill_parent"
+             android:layout_height="wrap_content">
          <Button
             android:id="@+id/accounts_tester_get_accounts_by_type"
             android:layout_width="wrap_content"
@@ -58,16 +62,45 @@
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:text="@string/accounts_tester_get_all_accounts"/>
+              <Button android:id="@+id/accounts_tester_add_account"
+                 android:layout_width="wrap_content"
+                 android:layout_height="wrap_content"
+                 android:text="@string/accounts_tester_add_account"/>
 
-         <Button android:id="@+id/accounts_tester_add_account"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:text="@string/accounts_tester_add_account"/>
+              <Button android:id="@+id/accounts_tester_edit_properties"
+                 android:layout_width="wrap_content"
+                 android:layout_height="wrap_content"
+                 android:text="@string/accounts_tester_edit_properties"/>
+          </LinearLayout>
 
-         <Button android:id="@+id/accounts_tester_edit_properties"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:text="@string/accounts_tester_edit_properties"/>
+          <LinearLayout
+             android:orientation="horizontal"
+             android:layout_width="fill_parent"
+             android:layout_height="wrap_content">
+              <TextView android:id="@+id/accounts_tester_desiredFeatures"
+                       android:layout_width="wrap_content"
+                       android:layout_height="wrap_content"
+                       android:text="@string/accounts_tester_desired_features_label"/>
+
+          <EditText android:id="@+id/accounts_tester_desired_features"
+                   android:layout_width="wrap_content"
+                   android:layout_height="wrap_content"
+                   android:minEms="15"/>
+          </LinearLayout>
+          <LinearLayout
+             android:orientation="horizontal"
+             android:layout_width="fill_parent"
+             android:layout_height="wrap_content">
+              <TextView android:id="@+id/accounts_tester_desiredFeatures"
+                       android:layout_width="wrap_content"
+                       android:layout_height="wrap_content"
+                       android:text="@string/accounts_tester_desired_authtokentype_label"/>
+
+          <EditText android:id="@+id/accounts_tester_desired_authtokentype"
+                   android:layout_width="wrap_content"
+                   android:layout_height="wrap_content"
+                   android:minEms="15"/>
+          </LinearLayout>
        </LinearLayout>
     </LinearLayout>
 
diff --git a/apps/Development/res/values/strings.xml b/apps/Development/res/values/strings.xml
index d3f6aa3..21f15f6 100644
--- a/apps/Development/res/values/strings.xml
+++ b/apps/Development/res/values/strings.xml
@@ -136,9 +136,9 @@
 
     <!-- AccountsTester -->
     <string name="accounts_tester_app_name">Accounts Tester</string>
-    <string name="accounts_tester_get_accounts_by_type">Get Accounts By Type</string>
-    <string name="accounts_tester_get_all_accounts">Get All Accounts</string>
-    <string name="accounts_tester_add_account">Add Account</string>
+    <string name="accounts_tester_get_accounts_by_type">Get By Type</string>
+    <string name="accounts_tester_get_all_accounts">Get All</string>
+    <string name="accounts_tester_add_account">Add</string>
     <string name="accounts_tester_select_account_type">Select Account Type</string>
     <string name="accounts_tester_process_name_header">Process Name:</string>
     <string name="accounts_tester_remove_account">remove</string>
@@ -149,5 +149,7 @@
     <string name="accounts_tester_enter_auth_token_type">Enter the authtoken type:</string>
     <string name="accounts_tester_update_credentials">Update Credentials</string>
     <string name="accounts_tester_confirm_credentials">Confirm Credentials</string>
-    <string name="accounts_tester_edit_properties">Edit Properties</string>
+    <string name="accounts_tester_edit_properties">Properties</string>
+    <string name="accounts_tester_desired_authtokentype_label">authtoken type:</string>
+    <string name="accounts_tester_desired_features_label">features:</string>
 </resources>
diff --git a/apps/Development/src/com/android/development/AccountsTester.java b/apps/Development/src/com/android/development/AccountsTester.java
index e326c4c..2525f4a 100644
--- a/apps/Development/src/com/android/development/AccountsTester.java
+++ b/apps/Development/src/com/android/development/AccountsTester.java
@@ -40,13 +40,14 @@
     private ListView mAuthenticatorsListView;
     private AccountManager mAccountManager;
     private String mLongPressedAccount = null;
-    private Future1Callback<Account[]> mGetAccountsCallback;
     private static final String COM_GOOGLE_GAIA = "com.google.GAIA";
     private AuthenticatorDescription[] mAuthenticatorDescs;
 
     private static final int GET_AUTH_TOKEN_DIALOG_ID = 1;
     private static final int UPDATE_CREDENTIALS_DIALOG_ID = 2;
     private static final int INVALIDATE_AUTH_TOKEN_DIALOG_ID = 3;
+    private EditText mDesiredAuthTokenTypeEditText;
+    private EditText mDesiredFeaturesEditText;
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
@@ -54,29 +55,20 @@
         mAccountManager = AccountManager.get(this);
         setContentView(R.layout.accounts_tester);
         ButtonClickListener buttonClickListener = new ButtonClickListener();
-        mGetAccountsCallback = new Future1Callback<Account[]>() {
-            public void run(Future1<Account[]> future) {
-                Log.d(TAG, "mGetAccountsCallback: starting");
-                try {
-                    Account[] accounts = future.getResult();
-                    onAccountsUpdated(accounts);
-                } catch (OperationCanceledException e) {
-                    // the request was canceled
-                    Log.d(TAG, "mGetAccountsCallback: request was canceled", e);
-                }
-            }
-        };
 
         mAccountTypesSpinner = (Spinner) findViewById(R.id.accounts_tester_account_types_spinner);
         mAccountsListView = (ListView) findViewById(R.id.accounts_tester_accounts_list);
         mAuthenticatorsListView = (ListView) findViewById(R.id.accounts_tester_authenticators_list);
         registerForContextMenu(mAccountsListView);
-        asyncGetAuthenticatorTypes();
+        getAuthenticatorTypes();
         findViewById(R.id.accounts_tester_get_all_accounts).setOnClickListener(buttonClickListener);
         findViewById(R.id.accounts_tester_get_accounts_by_type).setOnClickListener(
                 buttonClickListener);
         findViewById(R.id.accounts_tester_add_account).setOnClickListener(buttonClickListener);
         findViewById(R.id.accounts_tester_edit_properties).setOnClickListener(buttonClickListener);
+        mDesiredAuthTokenTypeEditText =
+                (EditText) findViewById(R.id.accounts_tester_desired_authtokentype);
+        mDesiredFeaturesEditText = (EditText) findViewById(R.id.accounts_tester_desired_features);
     }
 
     private static class AuthenticatorsArrayAdapter extends ArrayAdapter<AuthenticatorDescription> {
@@ -138,15 +130,33 @@
         }
     }
 
-    private void asyncGetAuthenticatorTypes() {
-        mAccountManager.getAuthenticatorTypes(new GetAuthenticatorsCallback(), null /* handler */);
+    private void getAuthenticatorTypes() {
+        mAuthenticatorDescs = mAccountManager.getAuthenticatorTypes();
+        String[] names = new String[mAuthenticatorDescs.length];
+        for (int i = 0; i < mAuthenticatorDescs.length; i++) {
+            Context authContext;
+            try {
+                authContext = createPackageContext(mAuthenticatorDescs[i].packageName, 0);
+            } catch (PackageManager.NameNotFoundException e) {
+                continue;
+            }
+            names[i] = authContext.getString(mAuthenticatorDescs[i].labelId);
+        }
+
+        ArrayAdapter<String> adapter =
+                new ArrayAdapter<String>(AccountsTester.this,
+                android.R.layout.simple_spinner_item, names);
+        mAccountTypesSpinner.setAdapter(adapter);
+
+        mAuthenticatorsListView.setAdapter(new AuthenticatorsArrayAdapter(
+                AccountsTester.this, mAuthenticatorDescs));
     }
 
     public void onAccountsUpdated(Account[] accounts) {
         Log.d(TAG, "onAccountsUpdated: \n  " + TextUtils.join("\n  ", accounts));
         String[] accountNames = new String[accounts.length];
         for (int i = 0; i < accounts.length; i++) {
-            accountNames[i] = accounts[i].mName;
+            accountNames[i] = accounts[i].name;
         }
         ArrayAdapter<String> adapter =
                 new ArrayAdapter<String>(AccountsTester.this,
@@ -169,14 +179,13 @@
     class ButtonClickListener implements View.OnClickListener {
         public void onClick(View v) {
             if (R.id.accounts_tester_get_all_accounts == v.getId()) {
-                mAccountManager.getAccounts(mGetAccountsCallback, null /* handler */);
+                onAccountsUpdated(mAccountManager.getAccounts());
             } else if (R.id.accounts_tester_get_accounts_by_type == v.getId()) {
                 String type = getSelectedAuthenticator().type;
-                mAccountManager.getAccountsByType(mGetAccountsCallback, type,
-                        null /* handler */);
+                onAccountsUpdated(mAccountManager.getAccountsByType(type));
             } else if (R.id.accounts_tester_add_account == v.getId()) {
-                Future2Callback callback = new Future2Callback() {
-                    public void run(Future2 future) {
+                AccountManagerCallback<Bundle> callback = new AccountManagerCallback<Bundle>() {
+                    public void run(AccountManagerFuture<Bundle> future) {
                         try {
                             Bundle bundle = future.getResult();
                             bundle.keySet();
@@ -190,9 +199,17 @@
                         }
                     }
                 };
+                String authTokenType = mDesiredAuthTokenTypeEditText.getText().toString();
+                if (TextUtils.isEmpty(authTokenType)) {
+                    authTokenType = null;
+                }
+                String featureString = mDesiredFeaturesEditText.getText().toString();
+                String[] requiredFeatures = TextUtils.split(featureString, " ");
+                if (requiredFeatures.length == 0) {
+                    requiredFeatures = null;
+                }
                 mAccountManager.addAccount(getSelectedAuthenticator().type,
-                        null /* authTokenType */,
-                        null /* requiredFeatures */, null /* options */,
+                        authTokenType, requiredFeatures, null /* options */,
                         AccountsTester.this, callback, null /* handler */);
             } else if (R.id.accounts_tester_edit_properties == v.getId()) {
                 mAccountManager.editProperties(getSelectedAuthenticator().type,
@@ -202,8 +219,8 @@
             }
         }
 
-        private class EditPropertiesCallback implements Future2Callback {
-            public void run(Future2 future) {
+        private class EditPropertiesCallback implements AccountManagerCallback<Bundle> {
+            public void run(AccountManagerFuture<Bundle> future) {
                 try {
                     Bundle bundle = future.getResult();
                     bundle.keySet();
@@ -238,8 +255,17 @@
     @Override
     public boolean onContextItemSelected(MenuItem item) {
         if (item.getItemId() == R.id.accounts_tester_remove_account) {
-            mAccountManager.removeAccount(null /* callback */, new Account(mLongPressedAccount,
-                    COM_GOOGLE_GAIA), null /* handler */);
+            final Account account = new Account(mLongPressedAccount, COM_GOOGLE_GAIA);
+            mAccountManager.removeAccount(account, new AccountManagerCallback<Boolean>() {
+                public void run(AccountManagerFuture<Boolean> future) {
+                    try {
+                        Log.d(TAG, "removeAccount(" + account + ") = " + future.getResult());
+                    } catch (OperationCanceledException e) {
+                    } catch (IOException e) {
+                    } catch (AuthenticatorException e) {
+                    }
+                }
+            }, null /* handler */);
         } else if (item.getItemId() == R.id.accounts_tester_get_auth_token) {
             showDialog(GET_AUTH_TOKEN_DIALOG_ID);
         } else if (item.getItemId() == R.id.accounts_tester_invalidate_auth_token) {
@@ -266,8 +292,8 @@
                                     R.id.accounts_tester_auth_token_type);
 
                             String authTokenType = value.getText().toString();
-                            Future2Callback callback = new Future2Callback() {
-                                public void run(Future2 future) {
+                            AccountManagerCallback<Bundle> callback = new AccountManagerCallback<Bundle>() {
+                                public void run(AccountManagerFuture<Bundle> future) {
                                     try {
                                         Bundle bundle = future.getResult();
                                         bundle.keySet();
@@ -304,11 +330,11 @@
         return super.onCreateDialog(id);
     }
 
-    Future2Callback newAccountsCallback(String type, String[] features) {
+    AccountManagerCallback<Bundle> newAccountsCallback(String type, String[] features) {
         return new GetAccountsCallback(type, features);
     }
 
-    class GetAccountsCallback implements Future2Callback {
+    class GetAccountsCallback implements AccountManagerCallback<Bundle> {
         final String[] mFeatures;
         final String mAccountType;
 
@@ -317,7 +343,7 @@
             mAccountType = type;
         }
 
-        public void run(Future2 future) {
+        public void run(AccountManagerFuture<Bundle> future) {
             Log.d(TAG, "GetAccountsCallback: type " + mAccountType
                     + ", features "
                     + (mFeatures == null ? "none" : TextUtils.join(",", mFeatures)));
@@ -338,11 +364,11 @@
         }
     }
 
-    Future2Callback newAuthTokensCallback(String type, String authTokenType, String[] features) {
+    AccountManagerCallback<Bundle> newAuthTokensCallback(String type, String authTokenType, String[] features) {
         return new GetAuthTokenCallback(type, authTokenType, features);
     }
 
-    class GetAuthTokenCallback implements Future2Callback {
+    class GetAuthTokenCallback implements AccountManagerCallback<Bundle> {
         final String[] mFeatures;
         final String mAccountType;
         final String mAuthTokenType;
@@ -353,7 +379,7 @@
             mAuthTokenType = authTokenType;
         }
 
-        public void run(Future2 future) {
+        public void run(AccountManagerFuture<Bundle> future) {
             Log.d(TAG, "GetAuthTokenCallback: type " + mAccountType
                     + ", features "
                     + (mFeatures == null ? "none" : TextUtils.join(",", mFeatures)));
@@ -371,20 +397,12 @@
         }
     }
 
-    private class GetAndInvalidateAuthTokenCallback implements Future2Callback {
-        public void run(Future2 future) {
+    private class GetAndInvalidateAuthTokenCallback implements AccountManagerCallback<Bundle> {
+        public void run(AccountManagerFuture<Bundle> future) {
             try {
                 Bundle bundle = future.getResult();
                 String authToken = bundle.getString(Constants.AUTHTOKEN_KEY);
-                mAccountManager.invalidateAuthToken(new Future1Callback<Void>() {
-                    public void run(Future1<Void> future) {
-                        try {
-                            future.getResult();
-                        } catch (OperationCanceledException e) {
-                            // the request was canceled
-                        }
-                    }
-                }, COM_GOOGLE_GAIA, authToken, null);
+                mAccountManager.invalidateAuthToken(COM_GOOGLE_GAIA, authToken);
             } catch (OperationCanceledException e) {
                 Log.d(TAG, "invalidate: interrupted while getting authToken");
             } catch (IOException e) {
@@ -395,8 +413,8 @@
         }
     }
 
-    private static class ConfirmCredentialsCallback implements Future2Callback {
-        public void run(Future2 future) {
+    private static class ConfirmCredentialsCallback implements AccountManagerCallback<Bundle> {
+        public void run(AccountManagerFuture<Bundle> future) {
             try {
                 Bundle bundle = future.getResult();
                 bundle.keySet();
@@ -410,33 +428,4 @@
             }
         }
     }
-
-    private class GetAuthenticatorsCallback implements Future1Callback<AuthenticatorDescription[]> {
-        public void run(Future1<AuthenticatorDescription[]> future) {
-            if (isFinishing()) return;
-            try {
-                mAuthenticatorDescs = future.getResult();
-                String[] names = new String[mAuthenticatorDescs.length];
-                for (int i = 0; i < mAuthenticatorDescs.length; i++) {
-                    Context authContext;
-                    try {
-                        authContext = createPackageContext(mAuthenticatorDescs[i].packageName, 0);
-                    } catch (PackageManager.NameNotFoundException e) {
-                        continue;
-                    }
-                    names[i] = authContext.getString(mAuthenticatorDescs[i].labelId);
-                }
-
-                ArrayAdapter<String> adapter =
-                        new ArrayAdapter<String>(AccountsTester.this,
-                        android.R.layout.simple_spinner_item, names);
-                mAccountTypesSpinner.setAdapter(adapter);
-
-                mAuthenticatorsListView.setAdapter(new AuthenticatorsArrayAdapter(
-                        AccountsTester.this, mAuthenticatorDescs));
-            } catch (OperationCanceledException e) {
-                // the request was canceled
-            }
-        }
-    }
 }