diff --git a/services/core/java/com/android/server/accounts/AccountManagerBackupHelper.java b/services/core/java/com/android/server/accounts/AccountManagerBackupHelper.java
index 63afccc..c3b7e15 100644
--- a/services/core/java/com/android/server/accounts/AccountManagerBackupHelper.java
+++ b/services/core/java/com/android/server/accounts/AccountManagerBackupHelper.java
@@ -142,9 +142,8 @@
         final AccountManagerService.UserAccounts accounts = mAccountManagerService
                 .getUserAccounts(userId);
         synchronized (accounts.cacheLock) {
-            SQLiteDatabase db = accounts.openHelper.getReadableDatabase();
-            List<Pair<String, Integer>> allAccountGrants = DeDatabaseHelper.findAllAccountGrants(
-                    db);
+            List<Pair<String, Integer>> allAccountGrants = accounts.accountsDb
+                    .findAllAccountGrants();
             if (allAccountGrants.isEmpty()) {
                 return null;
             }
diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java
index 575018d..7802576 100644
--- a/services/core/java/com/android/server/accounts/AccountManagerService.java
+++ b/services/core/java/com/android/server/accounts/AccountManagerService.java
@@ -98,9 +98,6 @@
 import com.android.server.LocalServices;
 import com.android.server.ServiceThread;
 import com.android.server.SystemService;
-import com.android.server.accounts.AccountsDb.CeDatabaseHelper;
-import com.android.server.accounts.AccountsDb.DeDatabaseHelper;
-import com.android.server.accounts.AccountsDb.DebugDbHelper;
 
 import com.google.android.collect.Lists;
 import com.google.android.collect.Sets;
@@ -161,8 +158,6 @@
         }
     }
 
-    private static final int MAX_DEBUG_DB_SIZE = 64;
-
     final Context mContext;
 
     private final PackageManager mPackageManager;
@@ -193,7 +188,7 @@
 
     static class UserAccounts {
         private final int userId;
-        final DeDatabaseHelper openHelper;
+        final AccountsDb accountsDb;
         private final HashMap<Pair<Pair<Account, String>, Integer>, Integer>
                 credentialsPermissionNotificationIds =
                 new HashMap<Pair<Pair<Account, String>, Integer>, Integer>();
@@ -242,12 +237,12 @@
                 new HashMap<Account, AtomicReference<String>>();
 
         private int debugDbInsertionPoint = -1;
-        private SQLiteStatement statementForLogging;
+        private SQLiteStatement statementForLogging; // TODO Move to AccountsDb
 
         UserAccounts(Context context, int userId, File preNDbFile, File deDbFile) {
             this.userId = userId;
             synchronized (cacheLock) {
-                openHelper = DeDatabaseHelper.create(context, userId, preNDbFile, deDbFile);
+                accountsDb = AccountsDb.create(context, userId, preNDbFile, deDbFile);
             }
         }
     }
@@ -993,7 +988,7 @@
             UserAccounts accounts, boolean invalidateAuthenticatorCache) {
         if (Log.isLoggable(TAG, Log.DEBUG)) {
             Log.d(TAG, "validateAccountsInternal " + accounts.userId
-                    + " isCeDatabaseAttached=" + accounts.openHelper.isCeDatabaseAttached()
+                    + " isCeDatabaseAttached=" + accounts.accountsDb.isCeDatabaseAttached()
                     + " userLocked=" + mLocalUnlockedUsers.get(accounts.userId));
         }
 
@@ -1006,11 +1001,11 @@
         boolean userUnlocked = isLocalUnlockedUser(accounts.userId);
 
         synchronized (accounts.cacheLock) {
-            final SQLiteDatabase db = accounts.openHelper.getWritableDatabase();
             boolean accountDeleted = false;
 
             // Get a map of stored authenticator types to UID
-            Map<String, Integer> metaAuthUid = DeDatabaseHelper.findMetaAuthUid(db);
+            final AccountsDb accountsDb = accounts.accountsDb;
+            Map<String, Integer> metaAuthUid = accountsDb.findMetaAuthUid();
             // Create a list of authenticator type whose previous uid no longer exists
             HashSet<String> obsoleteAuthType = Sets.newHashSet();
             SparseBooleanArray knownUids = null;
@@ -1047,7 +1042,7 @@
                         // So purge its data from the account databases.
                         obsoleteAuthType.add(type);
                         // And delete it from the TABLE_META
-                        DeDatabaseHelper.deleteMetaByAuthTypeAndUid(db, type, uid);
+                        accountsDb.deleteMetaByAuthTypeAndUid(type, uid);
                     }
                 }
             }
@@ -1056,11 +1051,10 @@
             // been re-enabled (after being updated for example), then we just overwrite the old
             // values.
             for (Entry<String, Integer> entry : knownAuth.entrySet()) {
-                DeDatabaseHelper.insertOrReplaceMetaAuthTypeAndUid(db, entry.getKey(),
-                        entry.getValue());
+                accountsDb.insertOrReplaceMetaAuthTypeAndUid(entry.getKey(), entry.getValue());
             }
 
-            final Map<Long, Account> accountsMap = DeDatabaseHelper.findAllAccounts(db);
+            final Map<Long, Account> accountsMap = accountsDb.findAllDeAccounts();
             try {
                 accounts.accountCache.clear();
                 final HashMap<String, ArrayList<String>> accountNamesByType = new LinkedHashMap<>();
@@ -1070,17 +1064,17 @@
                     if (obsoleteAuthType.contains(account.type)) {
                         Slog.w(TAG, "deleting account " + account.name + " because type "
                                 + account.type + "'s registered authenticator no longer exist.");
-                        db.beginTransaction();
+                        accountsDb.beginTransaction();
                         try {
-                            DeDatabaseHelper.deleteAccount(db, accountId);
+                            accountsDb.deleteDeAccount(accountId);
                             // Also delete from CE table if user is unlocked; if user is currently
                             // locked the account will be removed later by syncDeCeAccountsLocked
                             if (userUnlocked) {
-                                AccountsDb.deleteCeAccount(db, accountId);
+                                accountsDb.deleteCeAccount(accountId);
                             }
-                            db.setTransactionSuccessful();
+                            accountsDb.setTransactionSuccessful();
                         } finally {
-                            db.endTransaction();
+                            accountsDb.endTransaction();
                         }
                         accountDeleted = true;
 
@@ -1163,20 +1157,17 @@
                 File preNDbFile = new File(mInjector.getPreNDatabaseName(userId));
                 File deDbFile = new File(mInjector.getDeDatabaseName(userId));
                 accounts = new UserAccounts(mContext, userId, preNDbFile, deDbFile);
-                initializeDebugDbSizeAndCompileSqlStatementForLogging(
-                        accounts.openHelper.getWritableDatabase(), accounts);
+                initializeDebugDbSizeAndCompileSqlStatementForLogging(accounts);
                 mUsers.append(userId, accounts);
                 purgeOldGrants(accounts);
                 validateAccounts = true;
             }
             // open CE database if necessary
-            if (!accounts.openHelper.isCeDatabaseAttached() && mLocalUnlockedUsers.get(userId)) {
+            if (!accounts.accountsDb.isCeDatabaseAttached() && mLocalUnlockedUsers.get(userId)) {
                 Log.i(TAG, "User " + userId + " is unlocked - opening CE database");
                 synchronized (accounts.cacheLock) {
-                    File preNDatabaseFile = new File(mInjector.getPreNDatabaseName(userId));
                     File ceDatabaseFile = new File(mInjector.getCeDatabaseName(userId));
-                    CeDatabaseHelper.create(mContext, userId, preNDatabaseFile, ceDatabaseFile);
-                    accounts.openHelper.attachCeDatabase(ceDatabaseFile);
+                    accounts.accountsDb.attachCeDatabase(ceDatabaseFile);
                 }
                 syncDeCeAccountsLocked(accounts);
             }
@@ -1189,8 +1180,7 @@
 
     private void syncDeCeAccountsLocked(UserAccounts accounts) {
         Preconditions.checkState(Thread.holdsLock(mUsers), "mUsers lock must be held");
-        final SQLiteDatabase db = accounts.openHelper.getReadableDatabaseUserIsUnlocked();
-        List<Account> accountsToRemove = AccountsDb.findCeAccountsNotInDe(db);
+        List<Account> accountsToRemove = accounts.accountsDb.findCeAccountsNotInDe();
         if (!accountsToRemove.isEmpty()) {
             Slog.i(TAG, "Accounts " + accountsToRemove + " were previously deleted while user "
                     + accounts.userId + " was locked. Removing accounts from CE tables");
@@ -1213,8 +1203,7 @@
 
     private void purgeOldGrants(UserAccounts accounts) {
         synchronized (accounts.cacheLock) {
-            final SQLiteDatabase db = accounts.openHelper.getWritableDatabase();
-            List<Integer> uids = DeDatabaseHelper.findAllUidGrants(db);
+            List<Integer> uids = accounts.accountsDb.findAllUidGrants();
             for (int uid : uids) {
                 final boolean packageExists = mPackageManager.getPackagesForUid(uid) != null;
                 if (packageExists) {
@@ -1222,7 +1211,7 @@
                 }
                 Log.d(TAG, "deleting grants for UID " + uid
                         + " because its package is no longer installed");
-                DeDatabaseHelper.deleteGrantsByUid(db, uid);
+                accounts.accountsDb.deleteGrantsByUid(uid);
             }
         }
     }
@@ -1241,7 +1230,7 @@
         }
         if (accounts != null) {
             synchronized (accounts.cacheLock) {
-                accounts.openHelper.close();
+                accounts.accountsDb.close();
             }
         }
         Log.i(TAG, "Removing database files for user " + userId);
@@ -1334,9 +1323,7 @@
         }
 
         synchronized (accounts.cacheLock) {
-            final SQLiteDatabase db = accounts.openHelper.getReadableDatabaseUserIsUnlocked();
-            return CeDatabaseHelper.findAccountPasswordByNameAndType(db, account.name,
-                    account.type);
+            return accounts.accountsDb.findAccountPasswordByNameAndType(account.name, account.type);
         }
     }
 
@@ -1365,8 +1352,7 @@
         synchronized (accounts.cacheLock) {
             AtomicReference<String> previousNameRef = accounts.previousNameCache.get(account);
             if (previousNameRef == null) {
-                final SQLiteDatabase db = accounts.openHelper.getReadableDatabase();
-                String previousName = DeDatabaseHelper.findAccountPreviousName(db, account);
+                String previousName = accounts.accountsDb.findDeAccountPreviousName(account);
                 previousNameRef = new AtomicReference<>(previousName);
                 accounts.previousNameCache.put(account, previousNameRef);
                 return previousName;
@@ -1602,8 +1588,7 @@
     private boolean updateLastAuthenticatedTime(Account account) {
         final UserAccounts accounts = getUserAccountsForCaller();
         synchronized (accounts.cacheLock) {
-            return DeDatabaseHelper.updateAccountLastAuthenticatedTime(
-                    accounts.openHelper.getWritableDatabase(), account);
+            return accounts.accountsDb.updateAccountLastAuthenticatedTime(account);
         }
     }
 
@@ -1672,22 +1657,21 @@
             return false;
         }
         synchronized (accounts.cacheLock) {
-            final SQLiteDatabase db = accounts.openHelper.getWritableDatabaseUserIsUnlocked();
-            db.beginTransaction();
+            accounts.accountsDb.beginTransaction();
             try {
-                if (CeDatabaseHelper.findAccountId(db, account) >= 0) {
+                if (accounts.accountsDb.findCeAccountId(account) >= 0) {
                     Log.w(TAG, "insertAccountIntoDatabase: " + account
                             + ", skipping since the account already exists");
                     return false;
                 }
-                long accountId = CeDatabaseHelper.insertAccount(db, account, password);
+                long accountId = accounts.accountsDb.insertCeAccount(account, password);
                 if (accountId < 0) {
                     Log.w(TAG, "insertAccountIntoDatabase: " + account
                             + ", skipping the DB insert failed");
                     return false;
                 }
                 // Insert into DE table
-                if (DeDatabaseHelper.insertAccount(db, account, accountId) < 0) {
+                if (accounts.accountsDb.insertDeAccount(account, accountId) < 0) {
                     Log.w(TAG, "insertAccountIntoDatabase: " + account
                             + ", skipping the DB insert failed");
                     return false;
@@ -1695,21 +1679,21 @@
                 if (extras != null) {
                     for (String key : extras.keySet()) {
                         final String value = extras.getString(key);
-                        if (CeDatabaseHelper.insertExtra(db, accountId, key, value) < 0) {
+                        if (accounts.accountsDb.insertExtra(accountId, key, value) < 0) {
                             Log.w(TAG, "insertAccountIntoDatabase: " + account
                                     + ", skipping since insertExtra failed for key " + key);
                             return false;
                         }
                     }
                 }
-                db.setTransactionSuccessful();
+                accounts.accountsDb.setTransactionSuccessful();
 
                 logRecord(AccountsDb.DEBUG_ACTION_ACCOUNT_ADD, AccountsDb.TABLE_ACCOUNTS,
                         accountId, accounts, callingUid);
 
                 insertAccountIntoCacheLocked(accounts, account);
             } finally {
-                db.endTransaction();
+                accounts.accountsDb.endTransaction();
             }
         }
         if (getUserManager().getUserInfo(accounts.userId).canHaveProfile()) {
@@ -1892,17 +1876,16 @@
             }
         }
         synchronized (accounts.cacheLock) {
-            final SQLiteDatabase db = accounts.openHelper.getWritableDatabaseUserIsUnlocked();
-            db.beginTransaction();
+            accounts.accountsDb.beginTransaction();
             Account renamedAccount = new Account(newName, accountToRename.type);
             try {
-                final long accountId = DeDatabaseHelper.findAccountId(db, accountToRename);
+                final long accountId = accounts.accountsDb.findDeAccountId(accountToRename);
                 if (accountId >= 0) {
-                    CeDatabaseHelper.renameAccount(db, accountId, newName);
-                    DeDatabaseHelper.renameAccount(db, accountId, newName, accountToRename.name);
+                    accounts.accountsDb.renameCeAccount(accountId, newName);
+                    accounts.accountsDb.renameDeAccount(accountId, newName, accountToRename.name);
                 }
             } finally {
-                db.endTransaction();
+                accounts.accountsDb.endTransaction();
             }
             /*
              * Database transaction was successful. Clean up cached
@@ -2025,8 +2008,7 @@
                 }
             }
         }
-        SQLiteDatabase db = accounts.openHelper.getReadableDatabase();
-        final long accountId = DeDatabaseHelper.findAccountId(db, account);
+        final long accountId = accounts.accountsDb.findDeAccountId(account);
         logRecord(
                 AccountsDb.DEBUG_ACTION_CALLED_ACCOUNT_REMOVE,
                 AccountsDb.TABLE_ACCOUNTS,
@@ -2065,8 +2047,7 @@
         }
         removeVisibleListFunctionality(account, getUserAccounts(UserHandle.getUserId(callingUid)));
         UserAccounts accounts = getUserAccountsForCaller();
-        SQLiteDatabase db = accounts.openHelper.getReadableDatabase();
-        final long accountId = DeDatabaseHelper.findAccountId(db, account);
+        final long accountId = accounts.accountsDb.findDeAccountId(account);
         logRecord(
                 AccountsDb.DEBUG_ACTION_CALLED_ACCOUNT_REMOVE,
                 AccountsDb.TABLE_ACCOUNTS,
@@ -2143,26 +2124,23 @@
                     + " is still locked. CE data will be removed later");
         }
         synchronized (accounts.cacheLock) {
-            final SQLiteDatabase db = userUnlocked
-                    ? accounts.openHelper.getWritableDatabaseUserIsUnlocked()
-                    : accounts.openHelper.getWritableDatabase();
-            db.beginTransaction();
+            accounts.accountsDb.beginTransaction();
             // Set to a dummy value, this will only be used if the database
             // transaction succeeds.
             long accountId = -1;
             try {
-                accountId = DeDatabaseHelper.findAccountId(db, account);
+                accountId = accounts.accountsDb.findDeAccountId(account);
                 if (accountId >= 0) {
-                    DeDatabaseHelper.deleteAccount(db, accountId);
+                    accounts.accountsDb.deleteDeAccount(accountId);
                     if (userUnlocked) {
                         // Delete from CE table
-                        AccountsDb.deleteCeAccount(db, accountId);
+                        accounts.accountsDb.deleteCeAccount(accountId);
                     }
-                    db.setTransactionSuccessful();
+                    accounts.accountsDb.setTransactionSuccessful();
                     isChanged = true;
                 }
             } finally {
-                db.endTransaction();
+                accounts.accountsDb.endTransaction();
             }
             if (isChanged) {
                 removeAccountFromCacheLocked(accounts, account);
@@ -2221,14 +2199,13 @@
         try {
             UserAccounts accounts = getUserAccounts(userId);
             synchronized (accounts.cacheLock) {
-                final SQLiteDatabase db = accounts.openHelper.getWritableDatabaseUserIsUnlocked();
-                db.beginTransaction();
+                accounts.accountsDb.beginTransaction();
                 try {
-                    invalidateAuthTokenLocked(accounts, db, accountType, authToken);
+                    invalidateAuthTokenLocked(accounts, accountType, authToken);
                     invalidateCustomTokenLocked(accounts, accountType, authToken);
-                    db.setTransactionSuccessful();
+                    accounts.accountsDb.setTransactionSuccessful();
                 } finally {
-                    db.endTransaction();
+                    accounts.accountsDb.endTransaction();
                 }
             }
         } finally {
@@ -2247,21 +2224,20 @@
         accounts.accountTokenCaches.remove(accountType, authToken);
     }
 
-    private void invalidateAuthTokenLocked(UserAccounts accounts, SQLiteDatabase db,
-            String accountType, String authToken) {
+    private void invalidateAuthTokenLocked(UserAccounts accounts, String accountType,
+            String authToken) {
         if (authToken == null || accountType == null) {
             return;
         }
-        Cursor cursor = CeDatabaseHelper.findAuthtokenForAllAccounts(db, accountType, authToken);
+        Cursor cursor = accounts.accountsDb.findAuthtokenForAllAccounts(accountType, authToken);
         try {
             while (cursor.moveToNext()) {
                 String authTokenId = cursor.getString(0);
                 String accountName = cursor.getString(1);
                 String authTokenType = cursor.getString(2);
-                CeDatabaseHelper.deleteAuthToken(db, authTokenId);
+                accounts.accountsDb.deleteAuthToken(authTokenId);
                 writeAuthTokenIntoCacheLocked(
                         accounts,
-                        db,
                         new Account(accountName, accountType),
                         authTokenType,
                         null);
@@ -2299,22 +2275,21 @@
         cancelNotification(getSigninRequiredNotificationId(accounts, account),
                 UserHandle.of(accounts.userId));
         synchronized (accounts.cacheLock) {
-            final SQLiteDatabase db = accounts.openHelper.getWritableDatabaseUserIsUnlocked();
-            db.beginTransaction();
+            accounts.accountsDb.beginTransaction();
             try {
-                long accountId = DeDatabaseHelper.findAccountId(db, account);
+                long accountId = accounts.accountsDb.findDeAccountId(account);
                 if (accountId < 0) {
                     return false;
                 }
-                CeDatabaseHelper.deleteAuthtokensByAccountIdAndType(db, accountId, type);
-                if (CeDatabaseHelper.insertAuthToken(db, accountId, type, authToken) >= 0) {
-                    db.setTransactionSuccessful();
-                    writeAuthTokenIntoCacheLocked(accounts, db, account, type, authToken);
+                accounts.accountsDb.deleteAuthtokensByAccountIdAndType(accountId, type);
+                if (accounts.accountsDb.insertAuthToken(accountId, type, authToken) >= 0) {
+                    accounts.accountsDb.setTransactionSuccessful();
+                    writeAuthTokenIntoCacheLocked(accounts, account, type, authToken);
                     return true;
                 }
                 return false;
             } finally {
-                db.endTransaction();
+                accounts.accountsDb.endTransaction();
             }
         }
     }
@@ -2413,16 +2388,15 @@
         }
         boolean isChanged = false;
         synchronized (accounts.cacheLock) {
-            final SQLiteDatabase db = accounts.openHelper.getWritableDatabaseUserIsUnlocked();
-            db.beginTransaction();
+            accounts.accountsDb.beginTransaction();
             try {
-                final long accountId = DeDatabaseHelper.findAccountId(db, account);
+                final long accountId = accounts.accountsDb.findDeAccountId(account);
                 if (accountId >= 0) {
-                    CeDatabaseHelper.updateAccountPassword(db, accountId, password);
-                    CeDatabaseHelper.deleteAuthTokensByAccountId(db, accountId);
+                    accounts.accountsDb.updateCeAccountPassword(accountId, password);
+                    accounts.accountsDb.deleteAuthTokensByAccountId(accountId);
                     accounts.authTokenCache.remove(account);
                     accounts.accountTokenCaches.remove(account);
-                    db.setTransactionSuccessful();
+                    accounts.accountsDb.setTransactionSuccessful();
                     // If there is an account whose password will be updated and the database
                     // transactions succeed, then we say that a change has occured. Even if the
                     // new password is the same as the old and there were no authtokens to delete.
@@ -2433,7 +2407,7 @@
                     logRecord(action, AccountsDb.TABLE_ACCOUNTS, accountId, accounts, callingUid);
                 }
             } finally {
-                db.endTransaction();
+                accounts.accountsDb.endTransaction();
                 if (isChanged) {
                     // Send LOGIN_ACCOUNTS_CHANGED only if the something changed.
                     sendAccountsChangedBroadcast(accounts.userId);
@@ -2523,26 +2497,25 @@
         if (account == null || key == null) {
             return;
         }
-        final SQLiteDatabase db = accounts.openHelper.getWritableDatabase();
-        db.beginTransaction();
+        accounts.accountsDb.beginTransaction();
         try {
-            long accountId = DeDatabaseHelper.findAccountId(db, account);
+            long accountId = accounts.accountsDb.findDeAccountId(account);
             if (accountId < 0) {
                 return;
             }
-            long extrasId = CeDatabaseHelper.findExtrasIdByAccountId(db, accountId, key);
+            long extrasId = accounts.accountsDb.findExtrasIdByAccountId(accountId, key);
             if (extrasId < 0) {
-                extrasId = CeDatabaseHelper.insertExtra(db, accountId, key, value);
+                extrasId = accounts.accountsDb.insertExtra(accountId, key, value);
                 if (extrasId < 0) {
                     return;
                 }
-            } else if (!CeDatabaseHelper.updateExtra(db, extrasId, value)) {
+            } else if (!accounts.accountsDb.updateExtra(extrasId, value)) {
                 return;
             }
-            writeUserDataIntoCacheLocked(accounts, db, account, key, value);
-            db.setTransactionSuccessful();
+            writeUserDataIntoCacheLocked(accounts, account, key, value);
+            accounts.accountsDb.setTransactionSuccessful();
         } finally {
-            db.endTransaction();
+            accounts.accountsDb.endTransaction();
         }
     }
 
@@ -4171,9 +4144,8 @@
     private boolean addSharedAccountAsUser(Account account, int userId) {
         userId = handleIncomingUser(userId);
         UserAccounts accounts = getUserAccounts(userId);
-        SQLiteDatabase db = accounts.openHelper.getWritableDatabase();
-        DeDatabaseHelper.deleteSharedAccount(db, account);
-        long accountId = DeDatabaseHelper.insertSharedAccount(db, account);
+        accounts.accountsDb.deleteSharedAccount(account);
+        long accountId = accounts.accountsDb.insertSharedAccount(account);
         if (accountId < 0) {
             Log.w(TAG, "insertAccountIntoDatabase: " + account
                     + ", skipping the DB insert failed");
@@ -4188,9 +4160,8 @@
     public boolean renameSharedAccountAsUser(Account account, String newName, int userId) {
         userId = handleIncomingUser(userId);
         UserAccounts accounts = getUserAccounts(userId);
-        SQLiteDatabase db = accounts.openHelper.getWritableDatabase();
-        long sharedTableAccountId = DeDatabaseHelper.findSharedAccountId(db, account);
-        int r = DeDatabaseHelper.renameSharedAccount(db, account, newName);
+        long sharedTableAccountId = accounts.accountsDb.findSharedAccountId(account);
+        int r = accounts.accountsDb.renameSharedAccount(account, newName);
         if (r > 0) {
             int callingUid = getCallingUid();
             logRecord(AccountsDb.DEBUG_ACTION_ACCOUNT_RENAME, AccountsDb.TABLE_SHARED_ACCOUNTS,
@@ -4209,9 +4180,8 @@
     private boolean removeSharedAccountAsUser(Account account, int userId, int callingUid) {
         userId = handleIncomingUser(userId);
         UserAccounts accounts = getUserAccounts(userId);
-        SQLiteDatabase db = accounts.openHelper.getWritableDatabase();
-        long sharedTableAccountId = DeDatabaseHelper.findSharedAccountId(db, account);
-        boolean deleted = DeDatabaseHelper.deleteSharedAccount(db, account);
+        long sharedTableAccountId = accounts.accountsDb.findSharedAccountId(account);
+        boolean deleted = accounts.accountsDb.deleteSharedAccount(account);
         if (deleted) {
             logRecord(AccountsDb.DEBUG_ACTION_ACCOUNT_REMOVE, AccountsDb.TABLE_SHARED_ACCOUNTS,
                     sharedTableAccountId, accounts, callingUid);
@@ -4223,8 +4193,8 @@
     @Override
     public Account[] getSharedAccountsAsUser(int userId) {
         userId = handleIncomingUser(userId);
-        SQLiteDatabase db = getUserAccounts(userId).openHelper.getReadableDatabase();
-        List<Account> accountList = DeDatabaseHelper.getSharedAccounts(db);
+        UserAccounts accounts = getUserAccounts(userId);
+        List<Account> accountList = accounts.accountsDb.getSharedAccounts();
         Account[] accountArray = new Account[accountList.size()];
         accountList.toArray(accountArray);
         return accountArray;
@@ -4575,9 +4545,8 @@
                     if (mAuthDetailsRequired) {
                         long lastAuthenticatedTime = -1;
                         if (accountPresent) {
-                            lastAuthenticatedTime = DeDatabaseHelper
+                            lastAuthenticatedTime = mAccounts.accountsDb
                                     .findAccountLastAuthenticatedTime(
-                                            mAccounts.openHelper.getReadableDatabase(),
                                             new Account(mAccountName, mAccountType));
                         }
                         result.putLong(AccountManager.KEY_LAST_AUTHENTICATED_TIME,
@@ -4795,7 +4764,7 @@
         LogRecordTask logTask = new LogRecordTask(action, tableName, accountId, userAccount,
                 callingUid, userAccount.debugDbInsertionPoint);
         userAccount.debugDbInsertionPoint = (userAccount.debugDbInsertionPoint + 1)
-                % MAX_DEBUG_DB_SIZE;
+                % AccountsDb.MAX_DEBUG_DB_SIZE;
         mHandler.post(logTask);
     }
 
@@ -4803,17 +4772,10 @@
      * This should only be called once to compile the sql statement for logging
      * and to find the insertion point.
      */
-    private void initializeDebugDbSizeAndCompileSqlStatementForLogging(SQLiteDatabase db,
-            UserAccounts userAccount) {
-        // Initialize the count if not done earlier.
-        int size = DebugDbHelper.getDebugTableRowCount(db);
-        if (size >= MAX_DEBUG_DB_SIZE) {
-            // Table is full, and we need to find the point where to insert.
-            userAccount.debugDbInsertionPoint = DebugDbHelper.getDebugTableInsertionPoint(db);
-        } else {
-            userAccount.debugDbInsertionPoint = size;
-        }
-        userAccount.statementForLogging = DebugDbHelper.compileSqlStatementForLogging(db);
+    private void initializeDebugDbSizeAndCompileSqlStatementForLogging(UserAccounts userAccount) {
+        userAccount.debugDbInsertionPoint = userAccount.accountsDb
+                .calculateDebugTableInsertionPoint();
+        userAccount.statementForLogging = userAccount.accountsDb.compileSqlStatementForLogging();
     }
 
     public IBinder onBind(@SuppressWarnings("unused") Intent intent) {
@@ -4862,11 +4824,9 @@
     private void dumpUser(UserAccounts userAccounts, FileDescriptor fd, PrintWriter fout,
             String[] args, boolean isCheckinRequest) {
         synchronized (userAccounts.cacheLock) {
-            final SQLiteDatabase db = userAccounts.openHelper.getReadableDatabase();
-
             if (isCheckinRequest) {
                 // This is a checkin request. *Only* upload the account types and the count of each.
-                DeDatabaseHelper.dumpAccountsTable(db, fout);
+                userAccounts.accountsDb.dumpDeAccountsTable(fout);
             } else {
                 Account[] accounts = getAccountsFromCacheLocked(userAccounts, null /* type */,
                         Process.myUid(), null);
@@ -4877,7 +4837,7 @@
 
                 // Add debug information.
                 fout.println();
-                DebugDbHelper.dumpDebugTable(db, fout);
+                userAccounts.accountsDb.dumpDebugTable(fout);
                 fout.println();
                 synchronized (mSessions) {
                     final long now = SystemClock.elapsedRealtime();
@@ -5139,13 +5099,12 @@
         }
         UserAccounts accounts = getUserAccounts(UserHandle.getUserId(callerUid));
         synchronized (accounts.cacheLock) {
-            final SQLiteDatabase db = accounts.openHelper.getReadableDatabase();
             long grantsCount;
             if (authTokenType != null) {
-                grantsCount = DeDatabaseHelper.findMatchingGrantsCount(db, callerUid, authTokenType,
+                grantsCount = accounts.accountsDb.findMatchingGrantsCount(callerUid, authTokenType,
                         account);
             } else {
-                grantsCount = DeDatabaseHelper.findMatchingGrantsCountAnyToken(db, callerUid,
+                grantsCount = accounts.accountsDb.findMatchingGrantsCountAnyToken(callerUid,
                         account);
             }
             final boolean permissionGranted = grantsCount > 0;
@@ -5273,10 +5232,9 @@
         }
         UserAccounts accounts = getUserAccounts(UserHandle.getUserId(uid));
         synchronized (accounts.cacheLock) {
-            final SQLiteDatabase db = accounts.openHelper.getWritableDatabase();
-            long accountId = DeDatabaseHelper.findAccountId(db, account);
+            long accountId = accounts.accountsDb.findDeAccountId(account);
             if (accountId >= 0) {
-                DeDatabaseHelper.insertGrant(db, accountId, authTokenType, uid);
+                accounts.accountsDb.insertGrant(accountId, authTokenType, uid);
             }
             cancelNotification(getCredentialPermissionNotificationId(account, authTokenType, uid),
                     UserHandle.of(accounts.userId));
@@ -5306,17 +5264,16 @@
         }
         UserAccounts accounts = getUserAccounts(UserHandle.getUserId(uid));
         synchronized (accounts.cacheLock) {
-            final SQLiteDatabase db = accounts.openHelper.getWritableDatabase();
-            db.beginTransaction();
+            accounts.accountsDb.beginTransaction();
             try {
-                long accountId = DeDatabaseHelper.findAccountId(db, account);
+                long accountId = accounts.accountsDb.findDeAccountId(account);
                 if (accountId >= 0) {
-                    DeDatabaseHelper.deleteGrantsByAccountIdAuthTokenTypeAndUid(
-                            db, accountId, authTokenType, uid);
-                    db.setTransactionSuccessful();
+                    accounts.accountsDb.deleteGrantsByAccountIdAuthTokenTypeAndUid(
+                            accountId, authTokenType, uid);
+                    accounts.accountsDb.setTransactionSuccessful();
                 }
             } finally {
-                db.endTransaction();
+                accounts.accountsDb.endTransaction();
             }
 
             cancelNotification(getCredentialPermissionNotificationId(account, authTokenType, uid),
@@ -5472,11 +5429,11 @@
         }
     }
 
-    protected void writeUserDataIntoCacheLocked(UserAccounts accounts, final SQLiteDatabase db,
+    protected void writeUserDataIntoCacheLocked(UserAccounts accounts,
             Account account, String key, String value) {
         Map<String, String> userDataForAccount = accounts.userDataCache.get(account);
         if (userDataForAccount == null) {
-            userDataForAccount = CeDatabaseHelper.findUserExtrasForAccount(db, account);
+            userDataForAccount = accounts.accountsDb.findUserExtrasForAccount(account);
             accounts.userDataCache.put(account, userDataForAccount);
         }
         if (value == null) {
@@ -5498,11 +5455,11 @@
         }
     }
 
-    protected void writeAuthTokenIntoCacheLocked(UserAccounts accounts, final SQLiteDatabase db,
+    protected void writeAuthTokenIntoCacheLocked(UserAccounts accounts,
             Account account, String key, String value) {
         Map<String, String> authTokensForAccount = accounts.authTokenCache.get(account);
         if (authTokensForAccount == null) {
-            authTokensForAccount = CeDatabaseHelper.findAuthTokensByAccount(db, account);
+            authTokensForAccount = accounts.accountsDb.findAuthTokensByAccount(account);
             accounts.authTokenCache.put(account, authTokensForAccount);
         }
         if (value == null) {
@@ -5518,8 +5475,7 @@
             Map<String, String> authTokensForAccount = accounts.authTokenCache.get(account);
             if (authTokensForAccount == null) {
                 // need to populate the cache for this account
-                final SQLiteDatabase db = accounts.openHelper.getReadableDatabaseUserIsUnlocked();
-                authTokensForAccount = CeDatabaseHelper.findAuthTokensByAccount(db, account);
+                authTokensForAccount = accounts.accountsDb.findAuthTokensByAccount(account);
                 accounts.authTokenCache.put(account, authTokensForAccount);
             }
             return authTokensForAccount.get(authTokenType);
@@ -5531,8 +5487,7 @@
         Map<String, String> userDataForAccount = accounts.userDataCache.get(account);
         if (userDataForAccount == null) {
             // need to populate the cache for this account
-            final SQLiteDatabase db = accounts.openHelper.getReadableDatabaseUserIsUnlocked();
-            userDataForAccount = CeDatabaseHelper.findUserExtrasForAccount(db, account);
+            userDataForAccount = accounts.accountsDb.findUserExtrasForAccount(account);
             accounts.userDataCache.put(account, userDataForAccount);
         }
         return userDataForAccount.get(key);
diff --git a/services/core/java/com/android/server/accounts/AccountsDb.java b/services/core/java/com/android/server/accounts/AccountsDb.java
index 6ef521e..1adcf34 100644
--- a/services/core/java/com/android/server/accounts/AccountsDb.java
+++ b/services/core/java/com/android/server/accounts/AccountsDb.java
@@ -42,8 +42,13 @@
 
 /**
  * Persistence layer abstraction for accessing accounts_ce/accounts_de databases.
+ *
+ * <p>At first, CE database needs to be {@link #attachCeDatabase(File) attached to DE},
+ * in order for the tables to be available. All operations with CE database are done through the
+ * connection to the DE database, to which it is attached. This approach allows atomic
+ * transactions across two databases</p>
  */
-class AccountsDb {
+class AccountsDb implements AutoCloseable {
     private static final String TAG = "AccountsDb";
 
     private static final String DATABASE_NAME = "accounts.db";
@@ -128,6 +133,8 @@
     private static final String CE_TABLE_AUTHTOKENS = CE_DB_PREFIX + TABLE_AUTHTOKENS;
     private static final String CE_TABLE_EXTRAS = CE_DB_PREFIX + TABLE_EXTRAS;
 
+    static final int MAX_DEBUG_DB_SIZE = 64;
+
     private static final String[] ACCOUNT_TYPE_COUNT_PROJECTION =
             new String[] { ACCOUNTS_TYPE, ACCOUNTS_TYPE_COUNT};
 
@@ -169,7 +176,17 @@
     private static final String META_KEY_DELIMITER = ":";
     private static final String SELECTION_META_BY_AUTHENTICATOR_TYPE = META_KEY + " LIKE ?";
 
-    static class CeDatabaseHelper extends SQLiteOpenHelper {
+    private final DeDatabaseHelper mDeDatabase;
+    private final Context mContext;
+    private final File mPreNDatabaseFile;
+
+    AccountsDb(DeDatabaseHelper deDatabase, Context context, File preNDatabaseFile) {
+        mDeDatabase = deDatabase;
+        mContext = context;
+        mPreNDatabaseFile = preNDatabaseFile;
+    }
+
+    private static class CeDatabaseHelper extends SQLiteOpenHelper {
 
         CeDatabaseHelper(Context context, String ceDatabaseName) {
             super(context, ceDatabaseName, null, CE_DATABASE_VERSION);
@@ -249,17 +266,16 @@
         /**
          * Creates a new {@code CeDatabaseHelper}. If pre-N db file is present at the old location,
          * it also performs migration to the new CE database.
-         * @param userId id of the user where the database is located
          */
         static CeDatabaseHelper create(
                 Context context,
-                int userId,
                 File preNDatabaseFile,
                 File ceDatabaseFile) {
             boolean newDbExists = ceDatabaseFile.exists();
             if (Log.isLoggable(TAG, Log.VERBOSE)) {
-                Log.v(TAG, "CeDatabaseHelper.create userId=" + userId + " oldDbExists="
-                        + preNDatabaseFile.exists() + " newDbExists=" + newDbExists);
+                Log.v(TAG, "CeDatabaseHelper.create ceDatabaseFile=" + ceDatabaseFile
+                        + " oldDbExists=" + preNDatabaseFile.exists()
+                        + " newDbExists=" + newDbExists);
             }
             boolean removeOldDb = false;
             if (!newDbExists && preNDatabaseFile.exists()) {
@@ -290,187 +306,189 @@
             }
             return true;
         }
-
-        /**
-         * Returns information about auth tokens and their account for the specified query
-         * parameters.
-         * Output is in the format:
-         * <pre><code> | AUTHTOKEN_ID |  ACCOUNT_NAME | AUTH_TOKEN_TYPE |</code></pre>
-         */
-        static Cursor findAuthtokenForAllAccounts(SQLiteDatabase db, String accountType,
-                String authToken) {
-            return db.rawQuery(
-                    "SELECT " + CE_TABLE_AUTHTOKENS + "." + AUTHTOKENS_ID
-                            + ", " + CE_TABLE_ACCOUNTS + "." + ACCOUNTS_NAME
-                            + ", " + CE_TABLE_AUTHTOKENS + "." + AUTHTOKENS_TYPE
-                            + " FROM " + CE_TABLE_ACCOUNTS
-                            + " JOIN " + CE_TABLE_AUTHTOKENS
-                            + " ON " + CE_TABLE_ACCOUNTS + "." + ACCOUNTS_ID
-                            + " = " + CE_TABLE_AUTHTOKENS + "." + AUTHTOKENS_ACCOUNTS_ID
-                            + " WHERE " + CE_TABLE_AUTHTOKENS + "." + AUTHTOKENS_AUTHTOKEN
-                            + " = ? AND " + CE_TABLE_ACCOUNTS + "." + ACCOUNTS_TYPE + " = ?",
-                    new String[]{authToken, accountType});
-        }
-
-        static boolean deleteAuthtokensByAccountIdAndType(SQLiteDatabase db, long accountId,
-                String authtokenType) {
-            return db.delete(CE_TABLE_AUTHTOKENS,
-                    AUTHTOKENS_ACCOUNTS_ID + "=?" + accountId + " AND " + AUTHTOKENS_TYPE + "=?",
-                    new String[]{String.valueOf(accountId), authtokenType}) > 0;
-        }
-
-        static boolean deleteAuthToken(SQLiteDatabase db, String authTokenId) {
-            return db.delete(
-                    CE_TABLE_AUTHTOKENS, AUTHTOKENS_ID + "= ?",
-                    new String[]{authTokenId}) > 0;
-        }
-
-        static long insertAuthToken(SQLiteDatabase db, long accountId, String authTokenType,
-                String authToken) {
-            ContentValues values = new ContentValues();
-            values.put(AUTHTOKENS_ACCOUNTS_ID, accountId);
-            values.put(AUTHTOKENS_TYPE, authTokenType);
-            values.put(AUTHTOKENS_AUTHTOKEN, authToken);
-            return db.insert(
-                    CE_TABLE_AUTHTOKENS, AUTHTOKENS_AUTHTOKEN, values);
-        }
-
-        static Map<String, String> findAuthTokensByAccount(final SQLiteDatabase db,
-                Account account) {
-            HashMap<String, String> authTokensForAccount = new HashMap<>();
-            Cursor cursor = db.query(CE_TABLE_AUTHTOKENS,
-                    COLUMNS_AUTHTOKENS_TYPE_AND_AUTHTOKEN,
-                    SELECTION_AUTHTOKENS_BY_ACCOUNT,
-                    new String[]{account.name, account.type},
-                    null, null, null);
-            try {
-                while (cursor.moveToNext()) {
-                    final String type = cursor.getString(0);
-                    final String authToken = cursor.getString(1);
-                    authTokensForAccount.put(type, authToken);
-                }
-            } finally {
-                cursor.close();
-            }
-            return authTokensForAccount;
-        }
-
-        static int updateAccountPassword(SQLiteDatabase db, long accountId, String password) {
-            final ContentValues values = new ContentValues();
-            values.put(ACCOUNTS_PASSWORD, password);
-            return db.update(
-                    CE_TABLE_ACCOUNTS, values, ACCOUNTS_ID + "=?",
-                    new String[]{String.valueOf(accountId)});
-        }
-
-        static boolean renameAccount(SQLiteDatabase db, long accountId, String newName) {
-            final ContentValues values = new ContentValues();
-            values.put(ACCOUNTS_NAME, newName);
-            final String[] argsAccountId = {String.valueOf(accountId)};
-            return db.update(
-                    CE_TABLE_ACCOUNTS, values, ACCOUNTS_ID + "=?", argsAccountId) > 0;
-        }
-
-        static boolean deleteAuthTokensByAccountId(SQLiteDatabase db, long accountId) {
-            return db.delete(
-                    CE_TABLE_AUTHTOKENS, AUTHTOKENS_ACCOUNTS_ID + "=?",
-                    new String[]{String.valueOf(accountId)}) > 0;
-        }
-
-        static long findExtrasIdByAccountId(SQLiteDatabase db, long accountId, String key) {
-            Cursor cursor = db.query(
-                    CE_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();
-            }
-        }
-
-        static boolean updateExtra(SQLiteDatabase db, long extrasId, String value) {
-            ContentValues values = new ContentValues();
-            values.put(EXTRAS_VALUE, value);
-            int rows = db.update(
-                    TABLE_EXTRAS, values, EXTRAS_ID + "=?",
-                    new String[]{String.valueOf(extrasId)});
-            return rows == 1;
-        }
-
-        static 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(CE_TABLE_EXTRAS, EXTRAS_KEY, values);
-        }
-
-        static Map<String, String> findUserExtrasForAccount(SQLiteDatabase db, Account account) {
-            Map<String, String> userExtrasForAccount = new HashMap<>();
-            Cursor cursor = db.query(CE_TABLE_EXTRAS,
-                    COLUMNS_EXTRAS_KEY_AND_VALUE,
-                    SELECTION_USERDATA_BY_ACCOUNT,
-                    new String[]{account.name, account.type},
-                    null, null, null);
-            try {
-                while (cursor.moveToNext()) {
-                    final String tmpkey = cursor.getString(0);
-                    final String value = cursor.getString(1);
-                    userExtrasForAccount.put(tmpkey, value);
-                }
-            } finally {
-                cursor.close();
-            }
-            return userExtrasForAccount;
-        }
-
-        static long findAccountId(SQLiteDatabase db, Account account) {
-            Cursor cursor = db.query(
-                    CE_TABLE_ACCOUNTS, new String[]{
-                            ACCOUNTS_ID},
-                    "name=? AND type=?", new String[]{account.name, account.type}, null, null,
-                    null);
-            try {
-                if (cursor.moveToNext()) {
-                    return cursor.getLong(0);
-                }
-                return -1;
-            } finally {
-                cursor.close();
-            }
-        }
-
-        static String findAccountPasswordByNameAndType(SQLiteDatabase db, String name,
-                String type) {
-            Cursor cursor = db.query(CE_TABLE_ACCOUNTS, new String[]{
-                            ACCOUNTS_PASSWORD},
-                    ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE + "=?",
-                    new String[]{name, type}, null, null, null);
-            try {
-                if (cursor.moveToNext()) {
-                    return cursor.getString(0);
-                }
-                return null;
-            } finally {
-                cursor.close();
-            }
-        }
-
-        static long insertAccount(SQLiteDatabase db, Account account, String password) {
-            ContentValues values = new ContentValues();
-            values.put(ACCOUNTS_NAME, account.name);
-            values.put(ACCOUNTS_TYPE, account.type);
-            values.put(ACCOUNTS_PASSWORD, password);
-            return db.insert(
-                    CE_TABLE_ACCOUNTS, ACCOUNTS_NAME, values);
-        }
-
     }
 
+    /**
+     * Returns information about auth tokens and their account for the specified query
+     * parameters.
+     * Output is in the format:
+     * <pre><code> | AUTHTOKEN_ID |  ACCOUNT_NAME | AUTH_TOKEN_TYPE |</code></pre>
+     */
+    Cursor findAuthtokenForAllAccounts(String accountType, String authToken) {
+        SQLiteDatabase db = mDeDatabase.getReadableDatabaseUserIsUnlocked();
+        return db.rawQuery(
+                "SELECT " + CE_TABLE_AUTHTOKENS + "." + AUTHTOKENS_ID
+                        + ", " + CE_TABLE_ACCOUNTS + "." + ACCOUNTS_NAME
+                        + ", " + CE_TABLE_AUTHTOKENS + "." + AUTHTOKENS_TYPE
+                        + " FROM " + CE_TABLE_ACCOUNTS
+                        + " JOIN " + CE_TABLE_AUTHTOKENS
+                        + " ON " + CE_TABLE_ACCOUNTS + "." + ACCOUNTS_ID
+                        + " = " + CE_TABLE_AUTHTOKENS + "." + AUTHTOKENS_ACCOUNTS_ID
+                        + " WHERE " + CE_TABLE_AUTHTOKENS + "." + AUTHTOKENS_AUTHTOKEN
+                        + " = ? AND " + CE_TABLE_ACCOUNTS + "." + ACCOUNTS_TYPE + " = ?",
+                new String[]{authToken, accountType});
+    }
+
+    Map<String, String> findAuthTokensByAccount(Account account) {
+        SQLiteDatabase db = mDeDatabase.getReadableDatabaseUserIsUnlocked();
+        HashMap<String, String> authTokensForAccount = new HashMap<>();
+        Cursor cursor = db.query(CE_TABLE_AUTHTOKENS,
+                COLUMNS_AUTHTOKENS_TYPE_AND_AUTHTOKEN,
+                SELECTION_AUTHTOKENS_BY_ACCOUNT,
+                new String[] {account.name, account.type},
+                null, null, null);
+        try {
+            while (cursor.moveToNext()) {
+                final String type = cursor.getString(0);
+                final String authToken = cursor.getString(1);
+                authTokensForAccount.put(type, authToken);
+            }
+        } finally {
+            cursor.close();
+        }
+        return authTokensForAccount;
+    }
+
+    boolean deleteAuthtokensByAccountIdAndType(long accountId, String authtokenType) {
+        SQLiteDatabase db = mDeDatabase.getWritableDatabaseUserIsUnlocked();
+        return db.delete(CE_TABLE_AUTHTOKENS,
+                AUTHTOKENS_ACCOUNTS_ID + "=?" + accountId + " AND " + AUTHTOKENS_TYPE + "=?",
+                new String[]{String.valueOf(accountId), authtokenType}) > 0;
+    }
+
+    boolean deleteAuthToken(String authTokenId) {
+        SQLiteDatabase db = mDeDatabase.getWritableDatabaseUserIsUnlocked();
+        return db.delete(
+                CE_TABLE_AUTHTOKENS, AUTHTOKENS_ID + "= ?",
+                new String[]{authTokenId}) > 0;
+    }
+
+    long insertAuthToken(long accountId, String authTokenType, String authToken) {
+        SQLiteDatabase db = mDeDatabase.getWritableDatabaseUserIsUnlocked();
+        ContentValues values = new ContentValues();
+        values.put(AUTHTOKENS_ACCOUNTS_ID, accountId);
+        values.put(AUTHTOKENS_TYPE, authTokenType);
+        values.put(AUTHTOKENS_AUTHTOKEN, authToken);
+        return db.insert(
+                CE_TABLE_AUTHTOKENS, AUTHTOKENS_AUTHTOKEN, values);
+    }
+
+    int updateCeAccountPassword(long accountId, String password) {
+        SQLiteDatabase db = mDeDatabase.getWritableDatabaseUserIsUnlocked();
+        final ContentValues values = new ContentValues();
+        values.put(ACCOUNTS_PASSWORD, password);
+        return db.update(
+                CE_TABLE_ACCOUNTS, values, ACCOUNTS_ID + "=?",
+                new String[] {String.valueOf(accountId)});
+    }
+
+    boolean renameCeAccount(long accountId, String newName) {
+        SQLiteDatabase db = mDeDatabase.getWritableDatabaseUserIsUnlocked();
+        final ContentValues values = new ContentValues();
+        values.put(ACCOUNTS_NAME, newName);
+        final String[] argsAccountId = {String.valueOf(accountId)};
+        return db.update(
+                CE_TABLE_ACCOUNTS, values, ACCOUNTS_ID + "=?", argsAccountId) > 0;
+    }
+
+    boolean deleteAuthTokensByAccountId(long accountId) {
+        SQLiteDatabase db = mDeDatabase.getWritableDatabaseUserIsUnlocked();
+        return db.delete(CE_TABLE_AUTHTOKENS, AUTHTOKENS_ACCOUNTS_ID + "=?",
+                new String[] {String.valueOf(accountId)}) > 0;
+    }
+
+    long findExtrasIdByAccountId(long accountId, String key) {
+        SQLiteDatabase db = mDeDatabase.getReadableDatabaseUserIsUnlocked();
+        Cursor cursor = db.query(
+                CE_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();
+        }
+    }
+
+    boolean updateExtra(long extrasId, String value) {
+        SQLiteDatabase db = mDeDatabase.getWritableDatabaseUserIsUnlocked();
+        ContentValues values = new ContentValues();
+        values.put(EXTRAS_VALUE, value);
+        int rows = db.update(
+                TABLE_EXTRAS, values, EXTRAS_ID + "=?",
+                new String[]{String.valueOf(extrasId)});
+        return rows == 1;
+    }
+
+    long insertExtra(long accountId, String key, String value) {
+        SQLiteDatabase db = mDeDatabase.getWritableDatabaseUserIsUnlocked();
+        ContentValues values = new ContentValues();
+        values.put(EXTRAS_KEY, key);
+        values.put(EXTRAS_ACCOUNTS_ID, accountId);
+        values.put(EXTRAS_VALUE, value);
+        return db.insert(CE_TABLE_EXTRAS, EXTRAS_KEY, values);
+    }
+
+    Map<String, String> findUserExtrasForAccount(Account account) {
+        SQLiteDatabase db = mDeDatabase.getReadableDatabaseUserIsUnlocked();
+        Map<String, String> userExtrasForAccount = new HashMap<>();
+        String[] selectionArgs = {account.name, account.type};
+        try (Cursor cursor = db.query(CE_TABLE_EXTRAS,
+                COLUMNS_EXTRAS_KEY_AND_VALUE,
+                SELECTION_USERDATA_BY_ACCOUNT,
+                selectionArgs,
+                null, null, null)) {
+            while (cursor.moveToNext()) {
+                final String tmpkey = cursor.getString(0);
+                final String value = cursor.getString(1);
+                userExtrasForAccount.put(tmpkey, value);
+            }
+        }
+        return userExtrasForAccount;
+    }
+
+    long findCeAccountId(Account account) {
+        SQLiteDatabase db = mDeDatabase.getReadableDatabaseUserIsUnlocked();
+        String[] columns = { ACCOUNTS_ID };
+        String selection = "name=? AND type=?";
+        String[] selectionArgs = {account.name, account.type};
+        try (Cursor cursor = db.query(CE_TABLE_ACCOUNTS, columns, selection, selectionArgs,
+                null, null, null)) {
+            if (cursor.moveToNext()) {
+                return cursor.getLong(0);
+            }
+            return -1;
+        }
+    }
+
+    String findAccountPasswordByNameAndType(String name, String type) {
+        SQLiteDatabase db = mDeDatabase.getReadableDatabaseUserIsUnlocked();
+        String selection = ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE + "=?";
+        String[] selectionArgs = {name, type};
+        String[] columns = {ACCOUNTS_PASSWORD};
+        try (Cursor cursor = db.query(CE_TABLE_ACCOUNTS, columns, selection, selectionArgs,
+                null, null, null)) {
+            if (cursor.moveToNext()) {
+                return cursor.getString(0);
+            }
+            return null;
+        }
+    }
+
+    long insertCeAccount(Account account, String password) {
+        SQLiteDatabase db = mDeDatabase.getWritableDatabaseUserIsUnlocked();
+        ContentValues values = new ContentValues();
+        values.put(ACCOUNTS_NAME, account.name);
+        values.put(ACCOUNTS_TYPE, account.type);
+        values.put(ACCOUNTS_PASSWORD, password);
+        return db.insert(
+                CE_TABLE_ACCOUNTS, ACCOUNTS_NAME, values);
+    }
+
+
     static class DeDatabaseHelper extends SQLiteOpenHelper {
 
         private final int mUserId;
@@ -504,7 +522,7 @@
             createGrantsTable(db);
             createSharedAccountsTable(db);
             createAccountsDeletionTrigger(db);
-            DebugDbHelper.createDebugTable(db);
+            createDebugTable(db);
         }
 
         private void createSharedAccountsTable(SQLiteDatabase db) {
@@ -533,6 +551,18 @@
                     +   "," + GRANTS_GRANTEE_UID + "))");
         }
 
+        static void createDebugTable(SQLiteDatabase db) {
+            db.execSQL("CREATE TABLE " + TABLE_DEBUG + " ( "
+                    + ACCOUNTS_ID + " INTEGER,"
+                    + DEBUG_TABLE_ACTION_TYPE + " TEXT NOT NULL, "
+                    + DEBUG_TABLE_TIMESTAMP + " DATETIME,"
+                    + DEBUG_TABLE_CALLER_UID + " INTEGER NOT NULL,"
+                    + DEBUG_TABLE_TABLE_NAME + " TEXT NOT NULL,"
+                    + DEBUG_TABLE_KEY + " INTEGER PRIMARY KEY)");
+            db.execSQL("CREATE INDEX timestamp_index ON " + TABLE_DEBUG + " ("
+                    + DEBUG_TABLE_TIMESTAMP + ")");
+        }
+
         @Override
         public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
             Log.i(TAG, "upgrade from version " + oldVersion + " to version " + newVersion);
@@ -542,17 +572,6 @@
             }
         }
 
-        public void attachCeDatabase(File ceDbFile) {
-            SQLiteDatabase db = getWritableDatabase();
-            db.execSQL("ATTACH DATABASE '" +  ceDbFile.getPath()+ "' AS ceDb");
-            mCeAttached = true;
-        }
-
-        public boolean isCeDatabaseAttached() {
-            return mCeAttached;
-        }
-
-
         public SQLiteDatabase getReadableDatabaseUserIsUnlocked() {
             if(!mCeAttached) {
                 Log.wtf(TAG, "getReadableDatabaseUserIsUnlocked called while user " + mUserId
@@ -616,343 +635,305 @@
 
             db.execSQL("DETACH DATABASE preNDb");
         }
+    }
 
-        static boolean deleteAccount(SQLiteDatabase db, long accountId) {
-            return db.delete(TABLE_ACCOUNTS, ACCOUNTS_ID + "=" + accountId, null) > 0;
-        }
+    boolean deleteDeAccount(long accountId) {
+        SQLiteDatabase db = mDeDatabase.getWritableDatabase();
+        return db.delete(TABLE_ACCOUNTS, ACCOUNTS_ID + "=" + accountId, null) > 0;
+    }
 
-        static long insertSharedAccount(SQLiteDatabase db, Account account) {
-            ContentValues values = new ContentValues();
-            values.put(ACCOUNTS_NAME, account.name);
-            values.put(ACCOUNTS_TYPE, account.type);
-            return db.insert(
-                    TABLE_SHARED_ACCOUNTS, ACCOUNTS_NAME, values);
-        }
+    long insertSharedAccount(Account account) {
+        SQLiteDatabase db = mDeDatabase.getWritableDatabase();
+        ContentValues values = new ContentValues();
+        values.put(ACCOUNTS_NAME, account.name);
+        values.put(ACCOUNTS_TYPE, account.type);
+        return db.insert(
+                TABLE_SHARED_ACCOUNTS, ACCOUNTS_NAME, values);
+    }
 
-        static boolean deleteSharedAccount(SQLiteDatabase db, Account account) {
-            return db
-                    .delete(TABLE_SHARED_ACCOUNTS, ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE + "=?",
-                            new String[]{account.name, account.type}) > 0;
-        }
+    boolean deleteSharedAccount(Account account) {
+        SQLiteDatabase db = mDeDatabase.getWritableDatabase();
+        return db.delete(TABLE_SHARED_ACCOUNTS, ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE + "=?",
+                new String[]{account.name, account.type}) > 0;
+    }
 
-        static int renameSharedAccount(SQLiteDatabase db, Account account, String newName) {
-            final ContentValues values = new ContentValues();
-            values.put(ACCOUNTS_NAME, newName);
-            return db.update(TABLE_SHARED_ACCOUNTS,
-                    values,
-                    ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE
-                            + "=?",
-                    new String[]{account.name, account.type});
-        }
+    int renameSharedAccount(Account account, String newName) {
+        SQLiteDatabase db = mDeDatabase.getWritableDatabase();
+        final ContentValues values = new ContentValues();
+        values.put(ACCOUNTS_NAME, newName);
+        return db.update(TABLE_SHARED_ACCOUNTS,
+                values,
+                ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE + "=?",
+                new String[] {account.name, account.type});
+    }
 
-        static List<Account> getSharedAccounts(SQLiteDatabase db) {
-            ArrayList<Account> accountList = new ArrayList<>();
-            Cursor cursor = null;
-            try {
-                cursor = db.query(TABLE_SHARED_ACCOUNTS, new String[]{
-                                ACCOUNTS_NAME, ACCOUNTS_TYPE},
-                        null, null, null, null, null);
-                if (cursor != null && cursor.moveToFirst()) {
-                    int nameIndex = cursor.getColumnIndex(ACCOUNTS_NAME);
-                    int typeIndex = cursor.getColumnIndex(ACCOUNTS_TYPE);
-                    do {
-                        accountList.add(new Account(cursor.getString(nameIndex),
-                                cursor.getString(typeIndex)));
-                    } while (cursor.moveToNext());
-                }
-            } finally {
-                if (cursor != null) {
-                    cursor.close();
-                }
-            }
-            return accountList;
-        }
-
-        static long findSharedAccountId(SQLiteDatabase db, Account account) {
-            Cursor cursor = db.query(TABLE_SHARED_ACCOUNTS, new String[]{
-                            ACCOUNTS_ID},
-                    "name=? AND type=?", new String[]{account.name, account.type}, null, null,
-                    null);
-            try {
-                if (cursor.moveToNext()) {
-                    return cursor.getLong(0);
-                }
-                return -1;
-            } finally {
-                cursor.close();
-            }
-        }
-
-        static long findAccountLastAuthenticatedTime(SQLiteDatabase db, Account account) {
-            return DatabaseUtils.longForQuery(
-                    db,
-                    "SELECT " + AccountsDb.ACCOUNTS_LAST_AUTHENTICATE_TIME_EPOCH_MILLIS
-                            + " FROM " +
-                            TABLE_ACCOUNTS + " WHERE " + ACCOUNTS_NAME + "=? AND "
-                            + ACCOUNTS_TYPE + "=?",
-                    new String[] {account.name, account.type});
-        }
-
-        static boolean updateAccountLastAuthenticatedTime(SQLiteDatabase db, Account account) {
-            final ContentValues values = new ContentValues();
-            values.put(ACCOUNTS_LAST_AUTHENTICATE_TIME_EPOCH_MILLIS, System.currentTimeMillis());
-            int rowCount = db.update(
-                    TABLE_ACCOUNTS,
-                    values,
-                    ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE + "=?",
-                    new String[] {
-                            account.name, account.type
-                    });
-            return rowCount > 0;
-        }
-
-
-        static void dumpAccountsTable(SQLiteDatabase db, PrintWriter pw) {
-            Cursor cursor = db.query(
-                    TABLE_ACCOUNTS, ACCOUNT_TYPE_COUNT_PROJECTION,
-                    null, null, ACCOUNTS_TYPE, null, null);
-            try {
-                while (cursor.moveToNext()) {
-                    // print type,count
-                    pw.println(cursor.getString(0) + "," + cursor.getString(1));
-                }
-            } finally {
-                if (cursor != null) {
-                    cursor.close();
-                }
-            }
-        }
-
-        static long findAccountId(SQLiteDatabase db, Account account) {
-            Cursor cursor = db.query(
-                    TABLE_ACCOUNTS, new String[]{ACCOUNTS_ID},
-                    "name=? AND type=?", new String[]{account.name, account.type}, null, null,
-                    null);
-            try {
-                if (cursor.moveToNext()) {
-                    return cursor.getLong(0);
-                }
-                return -1;
-            } finally {
-                cursor.close();
-            }
-        }
-
-        static Map<Long, Account> findAllAccounts(SQLiteDatabase db) {
-            LinkedHashMap<Long, Account> map = new LinkedHashMap<>();
-            Cursor cursor = db.query(TABLE_ACCOUNTS,
-                    new String[]{ACCOUNTS_ID, ACCOUNTS_TYPE, ACCOUNTS_NAME},
-                    null, null, null, null, ACCOUNTS_ID);
-            try {
-                while (cursor.moveToNext()) {
-                    final long accountId = cursor.getLong(0);
-                    final String accountType = cursor.getString(1);
-                    final String accountName = cursor.getString(2);
-
-                    final Account account = new Account(accountName, accountType);
-                    map.put(accountId, account);
-                }
-            } finally {
-                cursor.close();
-            }
-            return map;
-        }
-
-        static String findAccountPreviousName(SQLiteDatabase db, Account account) {
-            Cursor cursor = db.query(
-                    TABLE_ACCOUNTS,
-                    new String[]{ACCOUNTS_PREVIOUS_NAME},
-                    ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE
-                            + "=?",
-                    new String[]{account.name, account.type},
-                    null,
-                    null,
-                    null);
-            try {
-                if (cursor.moveToNext()) {
-                    return cursor.getString(0);
-                }
-            } finally {
-                cursor.close();
-            }
-            return null;
-        }
-
-        static long insertAccount(SQLiteDatabase db, Account account, long accountId) {
-            ContentValues values = new ContentValues();
-            values.put(ACCOUNTS_ID, accountId);
-            values.put(ACCOUNTS_NAME, account.name);
-            values.put(ACCOUNTS_TYPE, account.type);
-            values.put(ACCOUNTS_LAST_AUTHENTICATE_TIME_EPOCH_MILLIS, System.currentTimeMillis());
-            return db.insert(TABLE_ACCOUNTS, ACCOUNTS_NAME, values);
-        }
-
-        static boolean renameAccount(SQLiteDatabase db, long accountId, String newName,
-                String previousName) {
-            final ContentValues values = new ContentValues();
-            values.put(ACCOUNTS_NAME, newName);
-            values.put(ACCOUNTS_PREVIOUS_NAME, previousName);
-            final String[] argsAccountId = {String.valueOf(accountId)};
-            return db.update(
-                    TABLE_ACCOUNTS, values, ACCOUNTS_ID + "=?", argsAccountId) > 0;
-        }
-
-        static boolean deleteGrantsByAccountIdAuthTokenTypeAndUid(SQLiteDatabase db, long accountId,
-                String authTokenType, long uid) {
-            return db.delete(TABLE_GRANTS,
-                    GRANTS_ACCOUNTS_ID + "=? AND " + GRANTS_AUTH_TOKEN_TYPE + "=? AND "
-                            + GRANTS_GRANTEE_UID + "=?",
-                    new String[]{String.valueOf(accountId), authTokenType, String.valueOf(uid)})
-                    > 0;
-        }
-
-        static List<Integer> findAllUidGrants(SQLiteDatabase db) {
-            List<Integer> result = new ArrayList<>();
-            final Cursor cursor = db.query(TABLE_GRANTS,
-                    new String[]{GRANTS_GRANTEE_UID},
-                    null, null, GRANTS_GRANTEE_UID, null, null);
-            try {
-                while (cursor.moveToNext()) {
-                    final int uid = cursor.getInt(0);
-                    result.add(uid);
-                }
-            } finally {
-                cursor.close();
-            }
-            return result;
-        }
-
-        static long findMatchingGrantsCount(SQLiteDatabase db,
-                int uid, String authTokenType, Account account) {
-            String[] args = {String.valueOf(uid), authTokenType,
-                    account.name, account.type};
-            return DatabaseUtils
-                    .longForQuery(db, COUNT_OF_MATCHING_GRANTS, args);
-        }
-
-        static long findMatchingGrantsCountAnyToken(SQLiteDatabase db,
-                int uid, Account account) {
-            String[] args = {String.valueOf(uid), account.name, account.type};
-            return DatabaseUtils.longForQuery(db, COUNT_OF_MATCHING_GRANTS_ANY_TOKEN, args);
-        }
-
-        static long insertGrant(SQLiteDatabase db, long accountId, String authTokenType, int uid) {
-            ContentValues values = new ContentValues();
-            values.put(GRANTS_ACCOUNTS_ID, accountId);
-            values.put(GRANTS_AUTH_TOKEN_TYPE, authTokenType);
-            values.put(GRANTS_GRANTEE_UID, uid);
-            return db.insert(
-                    TABLE_GRANTS, GRANTS_ACCOUNTS_ID, values);
-        }
-
-        static boolean deleteGrantsByUid(SQLiteDatabase db, int uid) {
-            return db.delete(
-                    TABLE_GRANTS, GRANTS_GRANTEE_UID + "=?",
-                    new String[]{Integer.toString(uid)}) > 0;
-        }
-
-        static long insertMetaAuthTypeAndUid(SQLiteDatabase db, String authenticatorType, int uid) {
-            ContentValues values = new ContentValues();
-            values.put(META_KEY,
-                    META_KEY_FOR_AUTHENTICATOR_UID_FOR_TYPE_PREFIX + authenticatorType);
-            values.put(META_VALUE, uid);
-            return db.insert(TABLE_META, null, values);
-        }
-
-        static long insertOrReplaceMetaAuthTypeAndUid(SQLiteDatabase db, String authenticatorType,
-                int uid) {
-            ContentValues values = new ContentValues();
-            values.put(META_KEY,
-                    META_KEY_FOR_AUTHENTICATOR_UID_FOR_TYPE_PREFIX + authenticatorType);
-            values.put(META_VALUE, uid);
-            return db.insertWithOnConflict(TABLE_META, null, values,
-                    SQLiteDatabase.CONFLICT_REPLACE);
-        }
-
-        static Map<String, Integer> findMetaAuthUid(SQLiteDatabase db) {
-            Cursor metaCursor = db.query(
-                    TABLE_META,
-                    new String[]{META_KEY, META_VALUE},
-                    SELECTION_META_BY_AUTHENTICATOR_TYPE,
-                    new String[]{META_KEY_FOR_AUTHENTICATOR_UID_FOR_TYPE_PREFIX + "%"},
-                    null /* groupBy */,
-                    null /* having */,
-                    META_KEY);
-            Map<String, Integer> map = new LinkedHashMap<>();
-            try {
-                while (metaCursor.moveToNext()) {
-                    String type = TextUtils
-                            .split(metaCursor.getString(0), META_KEY_DELIMITER)[1];
-                    String uidStr = metaCursor.getString(1);
-                    if (TextUtils.isEmpty(type) || TextUtils.isEmpty(uidStr)) {
-                        // Should never happen.
-                        Slog.e(TAG, "Auth type empty: " + TextUtils.isEmpty(type)
-                                + ", uid empty: " + TextUtils.isEmpty(uidStr));
-                        continue;
-                    }
-                    int uid = Integer.parseInt(metaCursor.getString(1));
-                    map.put(type, uid);
-                }
-            } finally {
-                metaCursor.close();
-            }
-            return map;
-        }
-
-        static boolean deleteMetaByAuthTypeAndUid(SQLiteDatabase db, String type, int uid) {
-            return db.delete(
-                    TABLE_META,
-                    META_KEY + "=? AND " + META_VALUE + "=?",
-                    new String[]{
-                            META_KEY_FOR_AUTHENTICATOR_UID_FOR_TYPE_PREFIX + type,
-                            String.valueOf(uid)}
-            ) > 0;
-        }
-
-        static List<Pair<String, Integer>> findAllAccountGrants(SQLiteDatabase db) {
-            try (Cursor cursor = db.rawQuery(ACCOUNT_ACCESS_GRANTS, null)) {
-                if (cursor == null || !cursor.moveToFirst()) {
-                    return Collections.emptyList();
-                }
-                List<Pair<String, Integer>> results = new ArrayList<>();
+    List<Account> getSharedAccounts() {
+        SQLiteDatabase db = mDeDatabase.getReadableDatabase();
+        ArrayList<Account> accountList = new ArrayList<>();
+        Cursor cursor = null;
+        try {
+            cursor = db.query(TABLE_SHARED_ACCOUNTS, new String[] {ACCOUNTS_NAME, ACCOUNTS_TYPE},
+                    null, null, null, null, null);
+            if (cursor != null && cursor.moveToFirst()) {
+                int nameIndex = cursor.getColumnIndex(ACCOUNTS_NAME);
+                int typeIndex = cursor.getColumnIndex(ACCOUNTS_TYPE);
                 do {
-                    final String accountName = cursor.getString(0);
-                    final int uid = cursor.getInt(1);
-                    results.add(Pair.create(accountName, uid));
+                    accountList.add(new Account(cursor.getString(nameIndex),
+                            cursor.getString(typeIndex)));
                 } while (cursor.moveToNext());
-                return results;
+            }
+        } finally {
+            if (cursor != null) {
+                cursor.close();
             }
         }
+        return accountList;
+    }
 
-        static DeDatabaseHelper create(
-                Context context,
-                int userId,
-                File preNDatabaseFile,
-                File deDatabaseFile) {
-            boolean newDbExists = deDatabaseFile.exists();
-            DeDatabaseHelper deDatabaseHelper = new DeDatabaseHelper(context, userId,
-                    deDatabaseFile.getPath());
-            // If the db just created, and there is a legacy db, migrate it
-            if (!newDbExists && preNDatabaseFile.exists()) {
-                // Migrate legacy db to the latest version -  PRE_N_DATABASE_VERSION
-                PreNDatabaseHelper
-                        preNDatabaseHelper = new PreNDatabaseHelper(context, userId,
-                        preNDatabaseFile.getPath());
-                // Open the database to force upgrade if required
-                preNDatabaseHelper.getWritableDatabase();
-                preNDatabaseHelper.close();
-                // Move data without SPII to DE
-                deDatabaseHelper.migratePreNDbToDe(preNDatabaseFile);
+    long findSharedAccountId(Account account) {
+        SQLiteDatabase db = mDeDatabase.getReadableDatabase();
+        Cursor cursor = db.query(TABLE_SHARED_ACCOUNTS, new String[]{
+                        ACCOUNTS_ID},
+                "name=? AND type=?", new String[]{account.name, account.type}, null, null,
+                null);
+        try {
+            if (cursor.moveToNext()) {
+                return cursor.getLong(0);
             }
-            return deDatabaseHelper;
+            return -1;
+        } finally {
+            cursor.close();
         }
     }
 
-    static class PreNDatabaseHelper extends SQLiteOpenHelper {
+    long findAccountLastAuthenticatedTime(Account account) {
+        SQLiteDatabase db = mDeDatabase.getReadableDatabase();
+        return DatabaseUtils.longForQuery(db,
+                "SELECT " + AccountsDb.ACCOUNTS_LAST_AUTHENTICATE_TIME_EPOCH_MILLIS
+                        + " FROM " + TABLE_ACCOUNTS + " WHERE " + ACCOUNTS_NAME + "=? AND "
+                        + ACCOUNTS_TYPE + "=?",
+                new String[] {account.name, account.type});
+    }
+
+    boolean updateAccountLastAuthenticatedTime(Account account) {
+        SQLiteDatabase db = mDeDatabase.getWritableDatabase();
+        final ContentValues values = new ContentValues();
+        values.put(ACCOUNTS_LAST_AUTHENTICATE_TIME_EPOCH_MILLIS, System.currentTimeMillis());
+        int rowCount = db.update(TABLE_ACCOUNTS,
+                values,
+                ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE + "=?",
+                new String[] { account.name, account.type });
+        return rowCount > 0;
+    }
+
+    void dumpDeAccountsTable(PrintWriter pw) {
+        SQLiteDatabase db = mDeDatabase.getReadableDatabase();
+        Cursor cursor = db.query(
+                TABLE_ACCOUNTS, ACCOUNT_TYPE_COUNT_PROJECTION,
+                null, null, ACCOUNTS_TYPE, null, null);
+        try {
+            while (cursor.moveToNext()) {
+                // print type,count
+                pw.println(cursor.getString(0) + "," + cursor.getString(1));
+            }
+        } finally {
+            if (cursor != null) {
+                cursor.close();
+            }
+        }
+    }
+
+    long findDeAccountId(Account account) {
+        SQLiteDatabase db = mDeDatabase.getReadableDatabase();
+        String[] columns = {ACCOUNTS_ID};
+        String selection = "name=? AND type=?";
+        String[] selectionArgs = {account.name, account.type};
+        try (Cursor cursor = db.query(TABLE_ACCOUNTS, columns, selection, selectionArgs,
+                null, null, null)) {
+            if (cursor.moveToNext()) {
+                return cursor.getLong(0);
+            }
+            return -1;
+        }
+    }
+
+    Map<Long, Account> findAllDeAccounts() {
+        SQLiteDatabase db = mDeDatabase.getReadableDatabase();
+        LinkedHashMap<Long, Account> map = new LinkedHashMap<>();
+        String[] columns = {ACCOUNTS_ID, ACCOUNTS_TYPE, ACCOUNTS_NAME};
+        try (Cursor cursor = db.query(TABLE_ACCOUNTS, columns,
+                null, null, null, null, ACCOUNTS_ID)) {
+            while (cursor.moveToNext()) {
+                final long accountId = cursor.getLong(0);
+                final String accountType = cursor.getString(1);
+                final String accountName = cursor.getString(2);
+
+                final Account account = new Account(accountName, accountType);
+                map.put(accountId, account);
+            }
+        }
+        return map;
+    }
+
+    String findDeAccountPreviousName(Account account) {
+        SQLiteDatabase db = mDeDatabase.getReadableDatabase();
+        String[] columns = {ACCOUNTS_PREVIOUS_NAME};
+        String selection = ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE + "=?";
+        String[] selectionArgs = {account.name, account.type};
+        try (Cursor cursor = db.query(TABLE_ACCOUNTS, columns, selection, selectionArgs,
+                null, null, null)) {
+            if (cursor.moveToNext()) {
+                return cursor.getString(0);
+            }
+        }
+        return null;
+    }
+
+    long insertDeAccount(Account account, long accountId) {
+        SQLiteDatabase db = mDeDatabase.getWritableDatabase();
+        ContentValues values = new ContentValues();
+        values.put(ACCOUNTS_ID, accountId);
+        values.put(ACCOUNTS_NAME, account.name);
+        values.put(ACCOUNTS_TYPE, account.type);
+        values.put(ACCOUNTS_LAST_AUTHENTICATE_TIME_EPOCH_MILLIS, System.currentTimeMillis());
+        return db.insert(TABLE_ACCOUNTS, ACCOUNTS_NAME, values);
+    }
+
+    boolean renameDeAccount(long accountId, String newName, String previousName) {
+        SQLiteDatabase db = mDeDatabase.getWritableDatabase();
+        final ContentValues values = new ContentValues();
+        values.put(ACCOUNTS_NAME, newName);
+        values.put(ACCOUNTS_PREVIOUS_NAME, previousName);
+        final String[] argsAccountId = {String.valueOf(accountId)};
+        return db.update(TABLE_ACCOUNTS, values, ACCOUNTS_ID + "=?", argsAccountId) > 0;
+    }
+
+    boolean deleteGrantsByAccountIdAuthTokenTypeAndUid(long accountId,
+            String authTokenType, long uid) {
+        SQLiteDatabase db = mDeDatabase.getWritableDatabase();
+        return db.delete(TABLE_GRANTS,
+                GRANTS_ACCOUNTS_ID + "=? AND " + GRANTS_AUTH_TOKEN_TYPE + "=? AND "
+                        + GRANTS_GRANTEE_UID + "=?",
+                new String[] {String.valueOf(accountId), authTokenType, String.valueOf(uid)}) > 0;
+    }
+
+    List<Integer> findAllUidGrants() {
+        SQLiteDatabase db = mDeDatabase.getReadableDatabase();
+        List<Integer> result = new ArrayList<>();
+        final Cursor cursor = db.query(TABLE_GRANTS,
+                new String[]{GRANTS_GRANTEE_UID},
+                null, null, GRANTS_GRANTEE_UID, null, null);
+        try {
+            while (cursor.moveToNext()) {
+                final int uid = cursor.getInt(0);
+                result.add(uid);
+            }
+        } finally {
+            cursor.close();
+        }
+        return result;
+    }
+
+    long findMatchingGrantsCount(int uid, String authTokenType, Account account) {
+        SQLiteDatabase db = mDeDatabase.getReadableDatabase();
+        String[] args = {String.valueOf(uid), authTokenType, account.name, account.type};
+        return DatabaseUtils.longForQuery(db, COUNT_OF_MATCHING_GRANTS, args);
+    }
+
+    long findMatchingGrantsCountAnyToken(int uid, Account account) {
+        SQLiteDatabase db = mDeDatabase.getReadableDatabase();
+        String[] args = {String.valueOf(uid), account.name, account.type};
+        return DatabaseUtils.longForQuery(db, COUNT_OF_MATCHING_GRANTS_ANY_TOKEN, args);
+    }
+
+    long insertGrant(long accountId, String authTokenType, int uid) {
+        SQLiteDatabase db = mDeDatabase.getWritableDatabase();
+        ContentValues values = new ContentValues();
+        values.put(GRANTS_ACCOUNTS_ID, accountId);
+        values.put(GRANTS_AUTH_TOKEN_TYPE, authTokenType);
+        values.put(GRANTS_GRANTEE_UID, uid);
+        return db.insert(TABLE_GRANTS, GRANTS_ACCOUNTS_ID, values);
+    }
+
+    boolean deleteGrantsByUid(int uid) {
+        SQLiteDatabase db = mDeDatabase.getWritableDatabase();
+        return db.delete(TABLE_GRANTS, GRANTS_GRANTEE_UID + "=?",
+                new String[] {Integer.toString(uid)}) > 0;
+    }
+
+    long insertOrReplaceMetaAuthTypeAndUid(String authenticatorType, int uid) {
+        SQLiteDatabase db = mDeDatabase.getWritableDatabase();
+        ContentValues values = new ContentValues();
+        values.put(META_KEY,
+                META_KEY_FOR_AUTHENTICATOR_UID_FOR_TYPE_PREFIX + authenticatorType);
+        values.put(META_VALUE, uid);
+        return db.insertWithOnConflict(TABLE_META, null, values,
+                SQLiteDatabase.CONFLICT_REPLACE);
+    }
+
+    Map<String, Integer> findMetaAuthUid() {
+        SQLiteDatabase db = mDeDatabase.getReadableDatabase();
+        Cursor metaCursor = db.query(
+                TABLE_META,
+                new String[]{META_KEY, META_VALUE},
+                SELECTION_META_BY_AUTHENTICATOR_TYPE,
+                new String[]{META_KEY_FOR_AUTHENTICATOR_UID_FOR_TYPE_PREFIX + "%"},
+                null /* groupBy */,
+                null /* having */,
+                META_KEY);
+        Map<String, Integer> map = new LinkedHashMap<>();
+        try {
+            while (metaCursor.moveToNext()) {
+                String type = TextUtils
+                        .split(metaCursor.getString(0), META_KEY_DELIMITER)[1];
+                String uidStr = metaCursor.getString(1);
+                if (TextUtils.isEmpty(type) || TextUtils.isEmpty(uidStr)) {
+                    // Should never happen.
+                    Slog.e(TAG, "Auth type empty: " + TextUtils.isEmpty(type)
+                            + ", uid empty: " + TextUtils.isEmpty(uidStr));
+                    continue;
+                }
+                int uid = Integer.parseInt(metaCursor.getString(1));
+                map.put(type, uid);
+            }
+        } finally {
+            metaCursor.close();
+        }
+        return map;
+    }
+
+    boolean deleteMetaByAuthTypeAndUid(String type, int uid) {
+        SQLiteDatabase db = mDeDatabase.getWritableDatabase();
+        return db.delete(
+                TABLE_META,
+                META_KEY + "=? AND " + META_VALUE + "=?",
+                new String[]{
+                        META_KEY_FOR_AUTHENTICATOR_UID_FOR_TYPE_PREFIX + type,
+                        String.valueOf(uid)}
+        ) > 0;
+    }
+
+    List<Pair<String, Integer>> findAllAccountGrants() {
+        SQLiteDatabase db = mDeDatabase.getReadableDatabase();
+        try (Cursor cursor = db.rawQuery(ACCOUNT_ACCESS_GRANTS, null)) {
+            if (cursor == null || !cursor.moveToFirst()) {
+                return Collections.emptyList();
+            }
+            List<Pair<String, Integer>> results = new ArrayList<>();
+            do {
+                final String accountName = cursor.getString(0);
+                final int uid = cursor.getInt(1);
+                results.add(Pair.create(accountName, uid));
+            } while (cursor.moveToNext());
+            return results;
+        }
+    }
+
+    private static class PreNDatabaseHelper extends SQLiteOpenHelper {
         private final Context mContext;
         private final int mUserId;
 
-        public PreNDatabaseHelper(Context context, int userId, String preNDatabaseName) {
+        PreNDatabaseHelper(Context context, int userId, String preNDatabaseName) {
             super(context, preNDatabaseName, null, PRE_N_DATABASE_VERSION);
             mContext = context;
             mUserId = userId;
@@ -982,7 +963,7 @@
         }
 
         private void addDebugTable(SQLiteDatabase db) {
-            DebugDbHelper.createDebugTable(db);
+            DeDatabaseHelper.createDebugTable(db);
         }
 
         private void createAccountsDeletionTrigger(SQLiteDatabase db) {
@@ -1007,10 +988,18 @@
                     +   "," + GRANTS_GRANTEE_UID + "))");
         }
 
+        static long insertMetaAuthTypeAndUid(SQLiteDatabase db, String authenticatorType, int uid) {
+            ContentValues values = new ContentValues();
+            values.put(META_KEY,
+                    META_KEY_FOR_AUTHENTICATOR_UID_FOR_TYPE_PREFIX + authenticatorType);
+            values.put(META_VALUE, uid);
+            return db.insert(TABLE_META, null, values);
+        }
+
         private void populateMetaTableWithAuthTypeAndUID(SQLiteDatabase db,
                 Map<String, Integer> authTypeAndUIDMap) {
             for (Map.Entry<String, Integer> entry : authTypeAndUIDMap.entrySet()) {
-                DeDatabaseHelper.insertMetaAuthTypeAndUid(db, entry.getKey(), entry.getValue());
+                insertMetaAuthTypeAndUid(db, entry.getKey(), entry.getValue());
             }
         }
 
@@ -1078,68 +1067,8 @@
         }
     }
 
-    static class DebugDbHelper{
-        private DebugDbHelper() {
-        }
-
-
-        private static void createDebugTable(SQLiteDatabase db) {
-            db.execSQL("CREATE TABLE " + TABLE_DEBUG + " ( "
-                    + ACCOUNTS_ID + " INTEGER,"
-                    + DEBUG_TABLE_ACTION_TYPE + " TEXT NOT NULL, "
-                    + DEBUG_TABLE_TIMESTAMP + " DATETIME,"
-                    + DEBUG_TABLE_CALLER_UID + " INTEGER NOT NULL,"
-                    + DEBUG_TABLE_TABLE_NAME + " TEXT NOT NULL,"
-                    + DEBUG_TABLE_KEY + " INTEGER PRIMARY KEY)");
-            db.execSQL("CREATE INDEX timestamp_index ON " + TABLE_DEBUG + " ("
-                    + DEBUG_TABLE_TIMESTAMP + ")");
-        }
-
-        static SQLiteStatement compileSqlStatementForLogging(SQLiteDatabase db) {
-            String sql = "INSERT OR REPLACE INTO " + AccountsDb.TABLE_DEBUG
-                    + " VALUES (?,?,?,?,?,?)";
-            return db.compileStatement(sql);
-        }
-
-        static int getDebugTableRowCount(SQLiteDatabase db) {
-            String queryCountDebugDbRows = "SELECT COUNT(*) FROM " + TABLE_DEBUG;
-            return (int) DatabaseUtils.longForQuery(db, queryCountDebugDbRows, null);
-        }
-
-        /*
-         * Finds the row key where the next insertion should take place. This should
-         * be invoked only if the table has reached its full capacity.
-         */
-        static int getDebugTableInsertionPoint(SQLiteDatabase db) {
-            // This query finds the smallest timestamp value (and if 2 records have
-            // same timestamp, the choose the lower id).
-            String queryCountDebugDbRows = "SELECT " + DEBUG_TABLE_KEY +
-                    " FROM " + TABLE_DEBUG +
-                    " ORDER BY "  + DEBUG_TABLE_TIMESTAMP + "," + DEBUG_TABLE_KEY +
-                    " LIMIT 1";
-            return (int) DatabaseUtils.longForQuery(db, queryCountDebugDbRows, null);
-        }
-
-        static void dumpDebugTable(SQLiteDatabase db, PrintWriter pw) {
-            Cursor cursor = db.query(TABLE_DEBUG, null,
-                    null, null, null, null, DEBUG_TABLE_TIMESTAMP);
-            pw.println("AccountId, Action_Type, timestamp, UID, TableName, Key");
-            pw.println("Accounts History");
-            try {
-                while (cursor.moveToNext()) {
-                    // print type,count
-                    pw.println(cursor.getString(0) + "," + cursor.getString(1) + "," +
-                            cursor.getString(2) + "," + cursor.getString(3) + ","
-                            + cursor.getString(4) + "," + cursor.getString(5));
-                }
-            } finally {
-                cursor.close();
-            }
-        }
-
-    }
-
-    static List<Account> findCeAccountsNotInDe(SQLiteDatabase db) {
+    List<Account> findCeAccountsNotInDe() {
+        SQLiteDatabase db = mDeDatabase.getReadableDatabaseUserIsUnlocked();
         // Select accounts from CE that do not exist in DE
         Cursor cursor = db.rawQuery(
                 "SELECT " + ACCOUNTS_NAME + "," + ACCOUNTS_TYPE
@@ -1161,14 +1090,110 @@
         }
     }
 
-    static boolean deleteCeAccount(SQLiteDatabase db, long accountId) {
+    boolean deleteCeAccount(long accountId) {
+        SQLiteDatabase db = mDeDatabase.getReadableDatabaseUserIsUnlocked();
         return db.delete(
                 CE_TABLE_ACCOUNTS, ACCOUNTS_ID + "=" + accountId, null) > 0;
     }
 
+    boolean isCeDatabaseAttached() {
+        return mDeDatabase.mCeAttached;
+    }
+
+    void beginTransaction() {
+        mDeDatabase.getWritableDatabase().beginTransaction();
+    }
+
+    void setTransactionSuccessful() {
+        mDeDatabase.getWritableDatabase().setTransactionSuccessful();
+    }
+
+    void endTransaction() {
+        mDeDatabase.getWritableDatabase().endTransaction();
+    }
+
+    void attachCeDatabase(File ceDbFile) {
+        CeDatabaseHelper.create(mContext, mPreNDatabaseFile, ceDbFile);
+        SQLiteDatabase db = mDeDatabase.getWritableDatabase();
+        db.execSQL("ATTACH DATABASE '" +  ceDbFile.getPath()+ "' AS ceDb");
+        mDeDatabase.mCeAttached = true;
+    }
+
+    /*
+     * Finds the row key where the next insertion should take place. Returns number of rows
+     * if it is less {@link #MAX_DEBUG_DB_SIZE}, otherwise finds the lowest number available.
+     */
+    int calculateDebugTableInsertionPoint() {
+        SQLiteDatabase db = mDeDatabase.getReadableDatabase();
+        String queryCountDebugDbRows = "SELECT COUNT(*) FROM " + TABLE_DEBUG;
+        int size = (int) DatabaseUtils.longForQuery(db, queryCountDebugDbRows, null);
+        if (size < MAX_DEBUG_DB_SIZE) {
+            return size;
+        }
+
+        // This query finds the smallest timestamp value (and if 2 records have
+        // same timestamp, the choose the lower id).
+        queryCountDebugDbRows = "SELECT " + DEBUG_TABLE_KEY +
+                " FROM " + TABLE_DEBUG +
+                " ORDER BY "  + DEBUG_TABLE_TIMESTAMP + "," + DEBUG_TABLE_KEY +
+                " LIMIT 1";
+        return (int) DatabaseUtils.longForQuery(db, queryCountDebugDbRows, null);
+    }
+
+    SQLiteStatement compileSqlStatementForLogging() {
+        // TODO b/31708085 Fix debug logging - it eagerly opens database for write without a need
+        SQLiteDatabase db = mDeDatabase.getWritableDatabase();
+        String sql = "INSERT OR REPLACE INTO " + AccountsDb.TABLE_DEBUG
+                + " VALUES (?,?,?,?,?,?)";
+        return db.compileStatement(sql);
+    }
+
+    void dumpDebugTable(PrintWriter pw) {
+        SQLiteDatabase db = mDeDatabase.getReadableDatabase();
+        Cursor cursor = db.query(TABLE_DEBUG, null,
+                null, null, null, null, DEBUG_TABLE_TIMESTAMP);
+        pw.println("AccountId, Action_Type, timestamp, UID, TableName, Key");
+        pw.println("Accounts History");
+        try {
+            while (cursor.moveToNext()) {
+                // print type,count
+                pw.println(cursor.getString(0) + "," + cursor.getString(1) + "," +
+                        cursor.getString(2) + "," + cursor.getString(3) + ","
+                        + cursor.getString(4) + "," + cursor.getString(5));
+            }
+        } finally {
+            cursor.close();
+        }
+    }
+
+    public void close() {
+        mDeDatabase.close();
+    }
+
     static void deleteDbFileWarnIfFailed(File dbFile) {
         if (!SQLiteDatabase.deleteDatabase(dbFile)) {
             Log.w(TAG, "Database at " + dbFile + " was not deleted successfully");
         }
     }
+
+    public static AccountsDb create(Context context, int userId, File preNDatabaseFile,
+            File deDatabaseFile) {
+        boolean newDbExists = deDatabaseFile.exists();
+        DeDatabaseHelper deDatabaseHelper = new DeDatabaseHelper(context, userId,
+                deDatabaseFile.getPath());
+        // If the db just created, and there is a legacy db, migrate it
+        if (!newDbExists && preNDatabaseFile.exists()) {
+            // Migrate legacy db to the latest version -  PRE_N_DATABASE_VERSION
+            PreNDatabaseHelper
+                    preNDatabaseHelper = new PreNDatabaseHelper(context, userId,
+                    preNDatabaseFile.getPath());
+            // Open the database to force upgrade if required
+            preNDatabaseHelper.getWritableDatabase();
+            preNDatabaseHelper.close();
+            // Move data without SPII to DE
+            deDatabaseHelper.migratePreNDbToDe(preNDatabaseFile);
+        }
+        return new AccountsDb(deDatabaseHelper, context, preNDatabaseFile);
+    }
+
 }
