diff --git a/tests/src/com/android/contacts/GroupsDaoIntegrationTests.java b/tests/src/com/android/contacts/GroupsDaoIntegrationTests.java
index d2e4283..f6925ad 100644
--- a/tests/src/com/android/contacts/GroupsDaoIntegrationTests.java
+++ b/tests/src/com/android/contacts/GroupsDaoIntegrationTests.java
@@ -16,15 +16,16 @@
 
 package com.android.contacts;
 
-import android.accounts.Account;
-import android.accounts.AccountManager;
+import android.content.ContentProviderOperation;
 import android.content.ContentResolver;
 import android.content.ContentUris;
 import android.content.ContentValues;
 import android.content.Context;
+import android.content.OperationApplicationException;
 import android.database.Cursor;
 import android.net.Uri;
 import android.os.Bundle;
+import android.os.RemoteException;
 import android.provider.ContactsContract;
 import android.provider.ContactsContract.CommonDataKinds.GroupMembership;
 import android.provider.ContactsContract.Data;
@@ -32,24 +33,23 @@
 
 import com.android.contacts.common.model.account.AccountWithDataSet;
 
+import java.util.ArrayList;
+import java.util.List;
+
 /**
  * Tests of GroupsDaoImpl that perform DB operations directly against CP2
  */
 public class GroupsDaoIntegrationTests extends InstrumentationTestCase {
 
-    private Account mAccount;
-    private ContentResolver cr;
+    private ContentResolver mResolver;
+    private List<Uri> mTestRecords;
 
     @Override
     protected void setUp() throws Exception {
         super.setUp();
 
-        mAccount = new Account(getClass().getSimpleName() + "_t" +
-                System.currentTimeMillis(), "com.android.contacts.tests.authtest.basic");
-        AccountManager accountManager = (AccountManager) getContext()
-                .getSystemService(Context.ACCOUNT_SERVICE);
-        accountManager.addAccountExplicitly(mAccount, null, null);
-        cr = getContext().getContentResolver();
+        mTestRecords = new ArrayList<>();
+        mResolver = getContext().getContentResolver();
     }
 
     @Override
@@ -57,63 +57,50 @@
         super.tearDown();
 
         // Cleanup anything leftover by the tests.
-        // the ACCOUNT_NAME should be unique because it contains a timestamp
-        final Uri groupsUri = ContactsContract.Groups.CONTENT_URI.buildUpon()
-                .appendQueryParameter(ContactsContract.CALLER_IS_SYNCADAPTER, "true").build();
-        final Uri rawContactsUri = ContactsContract.RawContacts.CONTENT_URI.buildUpon()
-                .appendQueryParameter(ContactsContract.CALLER_IS_SYNCADAPTER, "true").build();
-        getContext().getContentResolver().delete(groupsUri,
-                ContactsContract.Groups.ACCOUNT_NAME + "=?", new String[] { mAccount.name });
-        getContext().getContentResolver().delete(rawContactsUri,
-                ContactsContract.RawContacts.ACCOUNT_NAME + "=?", new String[] { mAccount.name });
-
-        if (mAccount != null) {
-            AccountManager accountManager = (AccountManager) getContext()
-                    .getSystemService(Context.ACCOUNT_SERVICE);
-            accountManager.removeAccountExplicitly(mAccount);
-            mAccount = null;
-        }
+        cleanupTestRecords();
+        mTestRecords.clear();
     }
 
     public void test_createGroup_createsGroupWithCorrectTitle() throws Exception {
-        ContactSaveService.GroupsDaoImpl sut = createDao();
-        Uri uri = sut.create("Test Create Group", getTestAccount());
+        final ContactSaveService.GroupsDao sut = createDao();
+        final Uri uri = sut.create("Test Create Group", getLocalAccount());
 
         assertNotNull(uri);
         assertGroupHasTitle(uri, "Test Create Group");
     }
 
     public void test_deleteEmptyGroup_marksRowDeleted() throws Exception {
-        ContactSaveService.GroupsDaoImpl sut = createDao();
-        Uri uri = sut.create("Test Delete Group", getTestAccount());
+        final ContactSaveService.GroupsDao sut = createDao();
+        final Uri uri = sut.create("Test Delete Group", getLocalAccount());
 
         assertEquals(1, sut.delete(uri));
 
-        Cursor cursor = cr.query(uri, null, null, null, null, null);
+        final Cursor cursor = mResolver.query(uri, null, null, null, null, null);
         try {
             cursor.moveToFirst();
-            assertEquals(1, cursor.getInt(cursor.getColumnIndexOrThrow(ContactsContract.Groups.DELETED)));
+            assertEquals(1, cursor.getInt(cursor.getColumnIndexOrThrow(
+                    ContactsContract.Groups.DELETED)));
         } finally {
             cursor.close();
         }
     }
 
     public void test_undoDeleteEmptyGroup_createsGroupWithMatchingTitle() throws Exception {
-        ContactSaveService.GroupsDaoImpl sut = createDao();
-        Uri uri = sut.create("Test Undo Delete Empty Group", getTestAccount());
+        final ContactSaveService.GroupsDao sut = createDao();
+        final Uri uri = sut.create("Test Undo Delete Empty Group", getLocalAccount());
 
-        Bundle undoData = sut.captureDeletionUndoData(uri);
+        final Bundle undoData = sut.captureDeletionUndoData(uri);
 
         assertEquals(1, sut.delete(uri));
 
-        Uri groupUri = sut.undoDeletion(undoData);
+        final Uri groupUri = sut.undoDeletion(undoData);
 
         assertGroupHasTitle(groupUri, "Test Undo Delete Empty Group");
     }
 
     public void test_deleteNonEmptyGroup_removesGroupAndMembers() throws Exception {
-        final ContactSaveService.GroupsDaoImpl sut = createDao();
-        final Uri groupUri = sut.create("Test delete non-empty group", getTestAccount());
+        final ContactSaveService.GroupsDao sut = createDao();
+        final Uri groupUri = sut.create("Test delete non-empty group", getLocalAccount());
 
         final long groupId = ContentUris.parseId(groupUri);
         addMemberToGroup(ContentUris.parseId(createRawContact()), groupId);
@@ -121,7 +108,7 @@
 
         assertEquals(1, sut.delete(groupUri));
 
-        final Cursor cursor = cr.query(Data.CONTENT_URI, null,
+        final Cursor cursor = mResolver.query(Data.CONTENT_URI, null,
                 Data.MIMETYPE + "=? AND " + GroupMembership.GROUP_ROW_ID + "=?",
                 new String[] { GroupMembership.CONTENT_ITEM_TYPE, String.valueOf(groupId) },
                 null, null);
@@ -138,14 +125,14 @@
     }
 
     public void test_undoDeleteNonEmptyGroup_restoresGroupAndMembers() throws Exception {
-        final ContactSaveService.GroupsDaoImpl sut = createDao();
-        final Uri groupUri = sut.create("Test undo delete non-empty group", getTestAccount());
+        final ContactSaveService.GroupsDao sut = createDao();
+        final Uri groupUri = sut.create("Test undo delete non-empty group", getLocalAccount());
 
         final long groupId = ContentUris.parseId(groupUri);
         addMemberToGroup(ContentUris.parseId(createRawContact()), groupId);
         addMemberToGroup(ContentUris.parseId(createRawContact()), groupId);
 
-        Bundle undoData = sut.captureDeletionUndoData(groupUri);
+        final Bundle undoData = sut.captureDeletionUndoData(groupUri);
 
         sut.delete(groupUri);
 
@@ -153,7 +140,7 @@
 
         final long newGroupId = ContentUris.parseId(recreatedGroup);
 
-        final Cursor cursor = cr.query(Data.CONTENT_URI, null,
+        final Cursor cursor = mResolver.query(Data.CONTENT_URI, null,
                 Data.MIMETYPE + "=? AND " + GroupMembership.GROUP_ROW_ID + "=?",
                 new String[] { GroupMembership.CONTENT_ITEM_TYPE, String.valueOf(newGroupId) },
                 null, null);
@@ -166,56 +153,45 @@
     }
 
     public void test_captureUndoDataForDeletedGroup_returnsEmptyBundle() {
-        final ContactSaveService.GroupsDaoImpl sut = createDao();
+        final ContactSaveService.GroupsDao sut = createDao();
 
-        Uri uri = sut.create("a deleted group", getTestAccount());
+        final Uri uri = sut.create("a deleted group", getLocalAccount());
         sut.delete(uri);
 
-        Bundle undoData = sut.captureDeletionUndoData(uri);
+        final Bundle undoData = sut.captureDeletionUndoData(uri);
 
         assertTrue(undoData.isEmpty());
     }
 
     public void test_captureUndoDataForNonExistentGroup_returnsEmptyBundle() {
-        final ContactSaveService.GroupsDaoImpl sut = createDao();
+        final ContactSaveService.GroupsDao sut = createDao();
 
         // This test could potentially be flaky if this ID exists for some reason. 10 is subtracted
         // to reduce the likelihood of this happening; some other test may use Integer.MAX_VALUE
         // or nearby values  to cover some special case or boundary condition.
         final long nonExistentId = Integer.MAX_VALUE - 10;
 
-        Bundle undoData = sut.captureDeletionUndoData(ContentUris
+        final Bundle undoData = sut.captureDeletionUndoData(ContentUris
                 .withAppendedId(ContactsContract.Groups.CONTENT_URI, nonExistentId));
 
         assertTrue(undoData.isEmpty());
     }
 
     public void test_undoWithEmptyBundle_doesNothing() {
-        final ContactSaveService.GroupsDaoImpl sut = createDao();
+        final ContactSaveService.GroupsDao sut = createDao();
 
-        Cursor cursor = queryGroupsForTestAccount();
-        try {
-            assertEquals(0, cursor.getCount());
-        } finally {
-            cursor.close();
-        }
+        final Uri uri = sut.undoDeletion(new Bundle());
 
-        sut.undoDeletion(new Bundle());
-
-        cursor = queryGroupsForTestAccount();
-        try {
-            assertEquals(0, cursor.getCount());
-        } finally {
-            cursor.close();
-        }
+        assertNull(uri);
     }
 
     public void test_undoDeleteEmptyGroupWithMissingMembersKey_shouldRecreateGroup() {
-        final ContactSaveService.GroupsDaoImpl sut = createDao();
-        final Uri groupUri = sut.create("Test undo delete null memberIds", getTestAccount());
+        final ContactSaveService.GroupsDao sut = createDao();
+        final Uri groupUri = sut.create("Test undo delete null memberIds", getLocalAccount());
 
-        Bundle undoData = sut.captureDeletionUndoData(groupUri);
+        final Bundle undoData = sut.captureDeletionUndoData(groupUri);
         undoData.remove(ContactSaveService.GroupsDaoImpl.KEY_GROUP_MEMBERS);
+        sut.delete(groupUri);
 
         sut.undoDeletion(undoData);
 
@@ -223,7 +199,8 @@
     }
 
     private void assertGroupHasTitle(Uri groupUri, String title) {
-        final Cursor cursor = cr.query(groupUri, new String[] { ContactsContract.Groups.TITLE },
+        final Cursor cursor = mResolver.query(groupUri,
+                new String[] { ContactsContract.Groups.TITLE },
                 ContactsContract.Groups.DELETED + "=?",
                 new String[] { "0" }, null, null);
         try {
@@ -236,11 +213,10 @@
     }
 
     private void assertGroupWithTitleExists(String title) {
-        final Cursor cursor = cr.query(ContactsContract.Groups.CONTENT_URI, null,
+        final Cursor cursor = mResolver.query(ContactsContract.Groups.CONTENT_URI, null,
                 ContactsContract.Groups.TITLE + "=? AND " +
-                        ContactsContract.Groups.DELETED + "=? AND " +
-                        ContactsContract.Groups.ACCOUNT_NAME + "=?",
-                new String[] { title, "0", mAccount.name }, null, null);
+                        ContactsContract.Groups.DELETED + "=?",
+                new String[] { title, "0" }, null, null);
         try {
             assertTrue("No group exists with title \"" + title + "\"", cursor.getCount() > 0);
         } finally {
@@ -248,36 +224,81 @@
         }
     }
 
-    private Cursor queryGroupsForTestAccount() {
-        return cr.query(ContactsContract.Groups.CONTENT_URI, null,
-                ContactsContract.Groups.ACCOUNT_NAME + "=?", new String[] { mAccount.name }, null);
-    }
-
-    public ContactSaveService.GroupsDaoImpl createDao() {
-        return new ContactSaveService.GroupsDaoImpl(getContext());
+    public ContactSaveService.GroupsDao createDao() {
+        return new GroupsDaoWrapper(new ContactSaveService.GroupsDaoImpl(getContext()));
     }
 
     private Uri createRawContact() {
-        ContentValues values = new ContentValues();
-        values.put(ContactsContract.RawContacts.ACCOUNT_NAME, mAccount.name);
-        values.put(ContactsContract.RawContacts.ACCOUNT_TYPE, mAccount.type);
-        return cr.insert(ContactsContract.RawContacts.CONTENT_URI, values);
+        final ContentValues values = new ContentValues();
+        values.putNull(ContactsContract.RawContacts.ACCOUNT_NAME);
+        values.putNull(ContactsContract.RawContacts.ACCOUNT_TYPE);
+        final Uri result = mResolver.insert(ContactsContract.RawContacts.CONTENT_URI, values);
+        mTestRecords.add(result);
+        return result;
     }
 
     private Uri addMemberToGroup(long rawContactId, long groupId) {
-        ContentValues values = new ContentValues();
+        final ContentValues values = new ContentValues();
         values.put(Data.RAW_CONTACT_ID, rawContactId);
         values.put(Data.MIMETYPE,
                 GroupMembership.CONTENT_ITEM_TYPE);
         values.put(GroupMembership.GROUP_ROW_ID, groupId);
-        return cr.insert(Data.CONTENT_URI, values);
-    }
 
-    private AccountWithDataSet getTestAccount() {
-        return new AccountWithDataSet(mAccount.name, mAccount.type, null);
+        // Dont' need to add to testRecords because it will be cleaned up when parent raw_contact
+        // is deleted.
+        return mResolver.insert(Data.CONTENT_URI, values);
     }
 
     private Context getContext() {
         return getInstrumentation().getTargetContext();
     }
+
+    private AccountWithDataSet getLocalAccount() {
+        return new AccountWithDataSet(null, null, null);
+    }
+
+    private void cleanupTestRecords() throws RemoteException, OperationApplicationException {
+        final ArrayList<ContentProviderOperation> ops = new ArrayList<>();
+        for (Uri uri : mTestRecords) {
+            if (uri == null) continue;
+            ops.add(ContentProviderOperation
+                    .newDelete(uri.buildUpon()
+                            .appendQueryParameter(ContactsContract.CALLER_IS_SYNCADAPTER, "true")
+                            .build())
+                    .build());
+        }
+        mResolver.applyBatch(ContactsContract.AUTHORITY, ops);
+    }
+
+    private class GroupsDaoWrapper implements ContactSaveService.GroupsDao {
+        private final ContactSaveService.GroupsDao mDelegate;
+
+        public GroupsDaoWrapper(ContactSaveService.GroupsDao delegate) {
+            mDelegate = delegate;
+        }
+
+        @Override
+        public Uri create(String title, AccountWithDataSet account) {
+            final Uri result = mDelegate.create(title, account);
+            mTestRecords.add(result);
+            return result;
+        }
+
+        @Override
+        public int delete(Uri groupUri) {
+            return mDelegate.delete(groupUri);
+        }
+
+        @Override
+        public Bundle captureDeletionUndoData(Uri groupUri) {
+            return mDelegate.captureDeletionUndoData(groupUri);
+        }
+
+        @Override
+        public Uri undoDeletion(Bundle undoData) {
+            final Uri result = mDelegate.undoDeletion(undoData);
+            mTestRecords.add(result);
+            return result;
+        }
+    }
 }
