diff --git a/src/com/android/contacts/SimImportService.java b/src/com/android/contacts/SimImportService.java
index 7a4997e..4fa3695 100644
--- a/src/com/android/contacts/SimImportService.java
+++ b/src/com/android/contacts/SimImportService.java
@@ -32,6 +32,7 @@
 
 import com.android.contacts.activities.PeopleActivity;
 import com.android.contacts.common.database.SimContactDao;
+import com.android.contacts.common.database.SimContactDaoImpl;
 import com.android.contacts.common.model.SimCard;
 import com.android.contacts.common.model.SimContact;
 import com.android.contacts.common.model.account.AccountWithDataSet;
@@ -49,6 +50,26 @@
 
     private static final String TAG = "SimImportService";
 
+    /**
+     * Wrapper around the service state for testability
+     */
+    public interface StatusProvider {
+
+        /**
+         * Returns whether there is any imports still pending
+         *
+         * <p>This should be called from the UI thread</p>
+         */
+        boolean isRunning();
+
+        /**
+         * Returns whether an import for sim has been requested
+         *
+         * <p>This should be called from the UI thread</p>
+         */
+        boolean isImporting(SimCard sim);
+    }
+
     public static final String EXTRA_ACCOUNT = "account";
     public static final String EXTRA_SIM_CONTACTS = "simContacts";
     public static final String EXTRA_SIM_SUBSCRIPTION_ID = "simSubscriptionId";
@@ -74,12 +95,24 @@
     // Keeps track of current tasks. This is only modified from the UI thread.
     private static List<ImportTask> sPending = new ArrayList<>();
 
+    private static StatusProvider sStatusProvider = new StatusProvider() {
+        @Override
+        public boolean isRunning() {
+            return !sPending.isEmpty();
+        }
+
+        @Override
+        public boolean isImporting(SimCard sim) {
+            return SimImportService.isImporting(sim);
+        }
+    };
+
     /**
      * Returns whether an import for sim has been requested
      *
      * <p>This should be called from the UI thread</p>
      */
-    public static boolean isImporting(SimCard sim) {
+    private static boolean isImporting(SimCard sim) {
         for (ImportTask task : sPending) {
             if (task.getSim().equals(sim)) {
                 return true;
@@ -88,13 +121,8 @@
         return false;
     }
 
-    /**
-     * Returns whether there is any imports still pending
-     *
-     * <p>This should be called from the UI thread</p>
-     */
-    public static boolean isRunning() {
-        return !sPending.isEmpty();
+    public static StatusProvider getStatusProvider() {
+        return sStatusProvider;
     }
 
     /**
diff --git a/src/com/android/contacts/common/database/SimContactDao.java b/src/com/android/contacts/common/database/SimContactDao.java
index b5b6626..b7b3ae4 100644
--- a/src/com/android/contacts/common/database/SimContactDao.java
+++ b/src/com/android/contacts/common/database/SimContactDao.java
@@ -15,46 +15,19 @@
  */
 package com.android.contacts.common.database;
 
-import android.annotation.TargetApi;
-import android.content.ContentProviderOperation;
 import android.content.ContentProviderResult;
-import android.content.ContentResolver;
 import android.content.Context;
 import android.content.OperationApplicationException;
-import android.content.pm.PackageManager;
-import android.database.Cursor;
-import android.net.Uri;
-import android.os.Build;
 import android.os.RemoteException;
-import android.provider.BaseColumns;
-import android.provider.ContactsContract;
-import android.provider.ContactsContract.CommonDataKinds.Phone;
-import android.provider.ContactsContract.CommonDataKinds.StructuredName;
-import android.provider.ContactsContract.Data;
-import android.provider.ContactsContract.RawContacts;
-import android.support.annotation.VisibleForTesting;
-import android.support.v4.util.ArrayMap;
-import android.support.v4.util.ArraySet;
-import android.telephony.SubscriptionInfo;
-import android.telephony.SubscriptionManager;
-import android.telephony.TelephonyManager;
-import android.text.TextUtils;
 import android.util.SparseArray;
 
-import com.android.contacts.R;
-import com.android.contacts.common.compat.CompatUtils;
 import com.android.contacts.common.model.SimCard;
 import com.android.contacts.common.model.SimContact;
 import com.android.contacts.common.model.account.AccountWithDataSet;
-import com.android.contacts.common.util.PermissionsUtil;
 import com.android.contacts.util.SharedPreferenceUtil;
-import com.google.common.base.Joiner;
 
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -63,349 +36,15 @@
  * Provides data access methods for loading contacts from a SIM card and and migrating these
  * SIM contacts to a CP2 account.
  */
-public class SimContactDao {
-    private static final String TAG = "SimContactDao";
-
-    // Maximum number of SIM contacts to import in a single ContentResolver.applyBatch call.
-    // This is necessary to avoid TransactionTooLargeException when there are a large number of
-    // contacts. This has been tested on Nexus 6 NME70B and is probably be conservative enough
-    // to work on any phone.
-    private static final int IMPORT_MAX_BATCH_SIZE = 300;
-
-    // How many SIM contacts to consider in a single query. This prevents hitting the SQLite
-    // query parameter limit.
-    static final int QUERY_MAX_BATCH_SIZE = 100;
+public abstract class SimContactDao {
 
     // Set to true for manual testing on an emulator or phone without a SIM card
     // DO NOT SUBMIT if set to true
     private static final boolean USE_FAKE_INSTANCE = false;
 
-    @VisibleForTesting
-    public static final Uri ICC_CONTENT_URI = Uri.parse("content://icc/adn");
-
-    public static String _ID = BaseColumns._ID;
-    public static String NAME = "name";
-    public static String NUMBER = "number";
-    public static String EMAILS = "emails";
-
-    private final Context mContext;
-    private final ContentResolver mResolver;
-    private final TelephonyManager mTelephonyManager;
-
-    private SimContactDao(Context context) {
-        mContext = context;
-        mResolver = context.getContentResolver();
-        mTelephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
-    }
-
-
-    public Context getContext() {
-        return mContext;
-    }
-
-    public boolean canReadSimContacts() {
-        // Require SIM_STATE_READY because the TelephonyManager methods related to SIM require
-        // this state
-        return hasTelephony() && hasPermissions() &&
-                mTelephonyManager.getSimState() == TelephonyManager.SIM_STATE_READY;
-    }
-
-    public List<SimCard> getSimCards() {
-        if (!canReadSimContacts()) {
-            return Collections.emptyList();
-        }
-        final List<SimCard> sims = CompatUtils.isMSIMCompatible() ?
-                getSimCardsFromSubscriptions() :
-                Collections.singletonList(SimCard.create(mTelephonyManager,
-                        mContext.getString(R.string.single_sim_display_label)));
-        return SharedPreferenceUtil.restoreSimStates(mContext, sims);
-    }
-
-    public List<SimCard> getSimCardsWithContacts() {
-        final List<SimCard> result = new ArrayList<>();
-        for (SimCard sim : getSimCards()) {
-            result.add(sim.withContacts(loadContactsForSim(sim)));
-        }
-        return result;
-    }
-
-    public ArrayList<SimContact> loadContactsForSim(SimCard sim) {
-        if (sim.hasValidSubscriptionId()) {
-            return loadSimContacts(sim.getSubscriptionId());
-        }
-        return loadSimContacts();
-    }
-
-    public ArrayList<SimContact> loadSimContacts(int subscriptionId) {
-        return loadFrom(ICC_CONTENT_URI.buildUpon()
-                .appendPath("subId")
-                .appendPath(String.valueOf(subscriptionId))
-                .build());
-    }
-
-    public ArrayList<SimContact> loadSimContacts() {
-        return loadFrom(ICC_CONTENT_URI);
-    }
-
-    public ContentProviderResult[] importContacts(List<SimContact> contacts,
-            AccountWithDataSet targetAccount)
-            throws RemoteException, OperationApplicationException {
-        if (contacts.size() < IMPORT_MAX_BATCH_SIZE) {
-            return importBatch(contacts, targetAccount);
-        }
-        final List<ContentProviderResult> results = new ArrayList<>();
-        for (int i = 0; i < contacts.size(); i += IMPORT_MAX_BATCH_SIZE) {
-            results.addAll(Arrays.asList(importBatch(
-                    contacts.subList(i, Math.min(contacts.size(), i + IMPORT_MAX_BATCH_SIZE)),
-                    targetAccount)));
-        }
-        return results.toArray(new ContentProviderResult[results.size()]);
-    }
-
-    public void persistSimState(SimCard sim) {
-        SharedPreferenceUtil.persistSimStates(mContext, Collections.singletonList(sim));
-    }
-
-    public void persistSimStates(List<SimCard> simCards) {
-        SharedPreferenceUtil.persistSimStates(mContext, simCards);
-    }
-
-    public SimCard getFirstSimCard() {
-        return getSimBySubscriptionId(SimCard.NO_SUBSCRIPTION_ID);
-    }
-
-    public SimCard getSimBySubscriptionId(int subscriptionId) {
-        final List<SimCard> sims = SharedPreferenceUtil.restoreSimStates(mContext, getSimCards());
-        if (subscriptionId == SimCard.NO_SUBSCRIPTION_ID && !sims.isEmpty()) {
-            return sims.get(0);
-        }
-        for (SimCard sim : getSimCards()) {
-            if (sim.getSubscriptionId() == subscriptionId) {
-                return sim;
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Finds SIM contacts that exist in CP2 and associates the account of the CP2 contact with
-     * the SIM contact
-     */
-    public Map<AccountWithDataSet, Set<SimContact>> findAccountsOfExistingSimContacts(
-            List<SimContact> contacts) {
-        final Map<AccountWithDataSet, Set<SimContact>> result = new ArrayMap<>();
-        for (int i = 0; i < contacts.size(); i += QUERY_MAX_BATCH_SIZE) {
-            findAccountsOfExistingSimContacts(
-                    contacts.subList(i, Math.min(contacts.size(), i + QUERY_MAX_BATCH_SIZE)),
-                    result);
-        }
-        return result;
-    }
-
-    private void findAccountsOfExistingSimContacts(List<SimContact> contacts,
-            Map<AccountWithDataSet, Set<SimContact>> result) {
-        final Map<Long, List<SimContact>> rawContactToSimContact = new HashMap<>();
-        Collections.sort(contacts, SimContact.compareByPhoneThenName());
-
-        final Cursor dataCursor = queryRawContactsForSimContacts(contacts);
-
-        try {
-            while (dataCursor.moveToNext()) {
-                final String number = DataQuery.getPhoneNumber(dataCursor);
-                final String name = DataQuery.getDisplayName(dataCursor);
-
-                final int index = SimContact.findByPhoneAndName(contacts, number, name);
-                if (index < 0) {
-                    continue;
-                }
-                final SimContact contact = contacts.get(index);
-                final long id = DataQuery.getRawContactId(dataCursor);
-                if (!rawContactToSimContact.containsKey(id)) {
-                    rawContactToSimContact.put(id, new ArrayList<SimContact>());
-                }
-                rawContactToSimContact.get(id).add(contact);
-            }
-        } finally {
-            dataCursor.close();
-        }
-
-        final Cursor accountsCursor = queryAccountsOfRawContacts(rawContactToSimContact.keySet());
-        try {
-            while (accountsCursor.moveToNext()) {
-                final AccountWithDataSet account = AccountQuery.getAccount(accountsCursor);
-                final long id = AccountQuery.getId(accountsCursor);
-                if (!result.containsKey(account)) {
-                    result.put(account, new ArraySet<SimContact>());
-                }
-                for (SimContact contact : rawContactToSimContact.get(id)) {
-                    result.get(account).add(contact);
-                }
-            }
-        } finally {
-            accountsCursor.close();
-        }
-    }
-
-    private ContentProviderResult[] importBatch(List<SimContact> contacts,
-            AccountWithDataSet targetAccount)
-            throws RemoteException, OperationApplicationException {
-        final ArrayList<ContentProviderOperation> ops =
-                createImportOperations(contacts, targetAccount);
-        return mResolver.applyBatch(ContactsContract.AUTHORITY, ops);
-    }
-
-    @TargetApi(Build.VERSION_CODES.LOLLIPOP_MR1)
-    private List<SimCard> getSimCardsFromSubscriptions() {
-        final SubscriptionManager subscriptionManager = (SubscriptionManager)
-                mContext.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
-        final List<SubscriptionInfo> subscriptions = subscriptionManager
-                .getActiveSubscriptionInfoList();
-        final ArrayList<SimCard> result = new ArrayList<>();
-        for (SubscriptionInfo subscriptionInfo : subscriptions) {
-            result.add(SimCard.create(subscriptionInfo));
-        }
-        return result;
-    }
-
-    private List<SimContact> getContactsForSim(SimCard sim) {
-        final List<SimContact> contacts = sim.getContacts();
-        return contacts != null ? contacts : loadContactsForSim(sim);
-    }
-
-    // See b/32831092
-    // Sometimes the SIM contacts provider seems to get stuck if read from multiple threads
-    // concurrently. So we just have a global lock around it to prevent potential issues.
-    private static final Object SIM_READ_LOCK = new Object();
-    private ArrayList<SimContact> loadFrom(Uri uri) {
-        synchronized (SIM_READ_LOCK) {
-            final Cursor cursor = mResolver.query(uri, null, null, null, null);
-
-            try {
-                return loadFromCursor(cursor);
-            } finally {
-                cursor.close();
-            }
-        }
-    }
-
-    private ArrayList<SimContact> loadFromCursor(Cursor cursor) {
-        final int colId = cursor.getColumnIndex(_ID);
-        final int colName = cursor.getColumnIndex(NAME);
-        final int colNumber = cursor.getColumnIndex(NUMBER);
-        final int colEmails = cursor.getColumnIndex(EMAILS);
-
-        final ArrayList<SimContact> result = new ArrayList<>();
-
-        while (cursor.moveToNext()) {
-            final long id = cursor.getLong(colId);
-            final String name = cursor.getString(colName);
-            final String number = cursor.getString(colNumber);
-            final String emails = cursor.getString(colEmails);
-
-            final SimContact contact = new SimContact(id, name, number, parseEmails(emails));
-            result.add(contact);
-        }
-        return result;
-    }
-
-    private Cursor queryRawContactsForSimContacts(List<SimContact> contacts) {
-        final StringBuilder selectionBuilder = new StringBuilder();
-
-        int phoneCount = 0;
-        int nameCount = 0;
-        for (SimContact contact : contacts) {
-            if (contact.hasPhone()) {
-                phoneCount++;
-            } else if (contact.hasName()) {
-                nameCount++;
-            }
-        }
-        List<String> selectionArgs = new ArrayList<>(phoneCount + 1);
-
-        selectionBuilder.append('(');
-        selectionBuilder.append(Data.MIMETYPE).append("=? AND ");
-        selectionArgs.add(Phone.CONTENT_ITEM_TYPE);
-
-        selectionBuilder.append(Phone.NUMBER).append(" IN (")
-                .append(Joiner.on(',').join(Collections.nCopies(phoneCount, '?')))
-                .append(')');
-        for (SimContact contact : contacts) {
-            if (contact.hasPhone()) {
-                selectionArgs.add(contact.getPhone());
-            }
-        }
-        selectionBuilder.append(')');
-
-        if (nameCount > 0) {
-            selectionBuilder.append(" OR (");
-
-            selectionBuilder.append(Data.MIMETYPE).append("=? AND ");
-            selectionArgs.add(StructuredName.CONTENT_ITEM_TYPE);
-
-            selectionBuilder.append(Data.DISPLAY_NAME).append(" IN (")
-                    .append(Joiner.on(',').join(Collections.nCopies(nameCount, '?')))
-                    .append(')');
-            for (SimContact contact : contacts) {
-                if (!contact.hasPhone() && contact.hasName()) {
-                    selectionArgs.add(contact.getName());
-                }
-            }
-            selectionBuilder.append(')');
-        }
-
-        return mResolver.query(Data.CONTENT_URI.buildUpon()
-                        .appendQueryParameter(Data.VISIBLE_CONTACTS_ONLY, "true")
-                        .build(),
-                DataQuery.PROJECTION,
-                selectionBuilder.toString(),
-                selectionArgs.toArray(new String[selectionArgs.size()]),
-                null);
-    }
-
-    private Cursor queryAccountsOfRawContacts(Set<Long> ids) {
-        final StringBuilder selectionBuilder = new StringBuilder();
-
-        final String[] args = new String[ids.size()];
-
-        selectionBuilder.append(RawContacts._ID).append(" IN (")
-                .append(Joiner.on(',').join(Collections.nCopies(args.length, '?')))
-                .append(")");
-        int i = 0;
-        for (long id : ids) {
-            args[i++] = String.valueOf(id);
-        }
-        return mResolver.query(RawContacts.CONTENT_URI,
-                AccountQuery.PROJECTION,
-                selectionBuilder.toString(),
-                args,
-                null);
-    }
-
-    private ArrayList<ContentProviderOperation> createImportOperations(List<SimContact> contacts,
-            AccountWithDataSet targetAccount) {
-        final ArrayList<ContentProviderOperation> ops = new ArrayList<>();
-        for (SimContact contact : contacts) {
-            contact.appendCreateContactOperations(ops, targetAccount);
-        }
-        return ops;
-    }
-
-    private String[] parseEmails(String emails) {
-        return emails != null ? emails.split(",") : null;
-    }
-
-    private boolean hasTelephony() {
-        return mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEPHONY);
-    }
-
-    private boolean hasPermissions() {
-        return PermissionsUtil.hasContactsPermissions(mContext) &&
-                PermissionsUtil.hasPhonePermissions(mContext);
-    }
-
     public static SimContactDao create(Context context) {
         if (USE_FAKE_INSTANCE) {
-            return new DebugImpl(context)
+            return new SimContactDaoImpl.DebugImpl(context)
                     .addSimCard(new SimCard("fake-sim-id1", 1, "Fake Carrier",
                             "Card 1", "15095550101", "us").withContacts(
                             new SimContact(1, "Sim One", "15095550111", null),
@@ -423,89 +62,27 @@
                             new SimContact(5, "Sim Duplicate", "15095550121", null)
                     ));
         }
-        return new SimContactDao(context);
+        return new SimContactDaoImpl(context);
     }
 
-    // TODO remove this class and the USE_FAKE_INSTANCE flag once this code is not under
-    // active development or anytime after 3/1/2017
-    public static class DebugImpl extends SimContactDao {
+    public abstract boolean canReadSimContacts();
 
-        private List<SimCard> mSimCards = new ArrayList<>();
-        private SparseArray<SimCard> mCardsBySubscription = new SparseArray<>();
+    public abstract List<SimCard> getSimCards();
 
-        public DebugImpl(Context context) {
-            super(context);
-        }
+    public abstract ArrayList<SimContact> loadContactsForSim(SimCard sim);
 
-        public DebugImpl addSimCard(SimCard sim) {
-            mSimCards.add(sim);
-            mCardsBySubscription.put(sim.getSubscriptionId(), sim);
-            return this;
-        }
+    public abstract ContentProviderResult[] importContacts(List<SimContact> contacts,
+            AccountWithDataSet targetAccount)
+            throws RemoteException, OperationApplicationException;
 
-        @Override
-        public List<SimCard> getSimCards() {
-            return SharedPreferenceUtil.restoreSimStates(getContext(), mSimCards);
-        }
+    public abstract void persistSimStates(List<SimCard> simCards);
 
-        @Override
-        public ArrayList<SimContact> loadSimContacts() {
-            return new ArrayList<>(mSimCards.get(0).getContacts());
-        }
+    public abstract SimCard getSimBySubscriptionId(int subscriptionId);
 
-        @Override
-        public ArrayList<SimContact> loadSimContacts(int subscriptionId) {
-            return new ArrayList<>(mCardsBySubscription.get(subscriptionId).getContacts());
-        }
+    public abstract Map<AccountWithDataSet, Set<SimContact>> findAccountsOfExistingSimContacts(
+            List<SimContact> contacts);
 
-        @Override
-        public boolean canReadSimContacts() {
-            return true;
-        }
-    }
-
-    // Query used for detecting existing contacts that may match a SimContact.
-    private static final class DataQuery {
-
-        public static final String[] PROJECTION = new String[] {
-                Data.RAW_CONTACT_ID, Phone.NUMBER, Data.DISPLAY_NAME, Data.MIMETYPE
-        };
-
-        public static final int RAW_CONTACT_ID = 0;
-        public static final int PHONE_NUMBER = 1;
-        public static final int DISPLAY_NAME = 2;
-        public static final int MIMETYPE = 3;
-
-        public static long getRawContactId(Cursor cursor) {
-            return cursor.getLong(RAW_CONTACT_ID);
-        }
-
-        public static String getPhoneNumber(Cursor cursor) {
-            return isPhoneNumber(cursor) ? cursor.getString(PHONE_NUMBER) : null;
-        }
-
-        public static String getDisplayName(Cursor cursor) {
-            return cursor.getString(DISPLAY_NAME);
-        }
-
-        public static boolean isPhoneNumber(Cursor cursor) {
-            return Phone.CONTENT_ITEM_TYPE.equals(cursor.getString(MIMETYPE));
-        }
-    }
-
-    private static final class AccountQuery {
-        public static final String[] PROJECTION = new String[] {
-                RawContacts._ID, RawContacts.ACCOUNT_NAME, RawContacts.ACCOUNT_TYPE,
-                RawContacts.DATA_SET
-        };
-
-        public static long getId(Cursor cursor) {
-            return cursor.getLong(0);
-        }
-
-        public static AccountWithDataSet getAccount(Cursor cursor) {
-            return new AccountWithDataSet(cursor.getString(1), cursor.getString(2),
-                    cursor.getString(3));
-        }
+    public void persistSimState(SimCard sim) {
+        persistSimStates(Collections.singletonList(sim));
     }
 }
diff --git a/src/com/android/contacts/common/database/SimContactDaoImpl.java b/src/com/android/contacts/common/database/SimContactDaoImpl.java
new file mode 100644
index 0000000..a6824bb
--- /dev/null
+++ b/src/com/android/contacts/common/database/SimContactDaoImpl.java
@@ -0,0 +1,473 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.contacts.common.database;
+
+import android.annotation.TargetApi;
+import android.content.ContentProviderOperation;
+import android.content.ContentProviderResult;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.OperationApplicationException;
+import android.content.pm.PackageManager;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Build;
+import android.os.RemoteException;
+import android.provider.BaseColumns;
+import android.provider.ContactsContract;
+import android.provider.ContactsContract.CommonDataKinds.Phone;
+import android.provider.ContactsContract.CommonDataKinds.StructuredName;
+import android.provider.ContactsContract.Data;
+import android.provider.ContactsContract.RawContacts;
+import android.support.annotation.VisibleForTesting;
+import android.support.v4.util.ArrayMap;
+import android.support.v4.util.ArraySet;
+import android.telephony.SubscriptionInfo;
+import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
+import android.text.TextUtils;
+import android.util.SparseArray;
+
+import com.android.contacts.R;
+import com.android.contacts.common.compat.CompatUtils;
+import com.android.contacts.common.model.SimCard;
+import com.android.contacts.common.model.SimContact;
+import com.android.contacts.common.model.account.AccountWithDataSet;
+import com.android.contacts.common.util.PermissionsUtil;
+import com.android.contacts.util.SharedPreferenceUtil;
+import com.google.common.base.Joiner;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Provides data access methods for loading contacts from a SIM card and and migrating these
+ * SIM contacts to a CP2 account.
+ */
+public class SimContactDaoImpl extends SimContactDao {
+    private static final String TAG = "SimContactDao";
+
+    // Maximum number of SIM contacts to import in a single ContentResolver.applyBatch call.
+    // This is necessary to avoid TransactionTooLargeException when there are a large number of
+    // contacts. This has been tested on Nexus 6 NME70B and is probably be conservative enough
+    // to work on any phone.
+    private static final int IMPORT_MAX_BATCH_SIZE = 300;
+
+    // How many SIM contacts to consider in a single query. This prevents hitting the SQLite
+    // query parameter limit.
+    static final int QUERY_MAX_BATCH_SIZE = 100;
+
+    @VisibleForTesting
+    public static final Uri ICC_CONTENT_URI = Uri.parse("content://icc/adn");
+
+    public static String _ID = BaseColumns._ID;
+    public static String NAME = "name";
+    public static String NUMBER = "number";
+    public static String EMAILS = "emails";
+
+    private final Context mContext;
+    private final ContentResolver mResolver;
+    private final TelephonyManager mTelephonyManager;
+
+    public SimContactDaoImpl(Context context) {
+        mContext = context;
+        mResolver = context.getContentResolver();
+        mTelephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
+    }
+
+    public Context getContext() {
+        return mContext;
+    }
+
+    @Override
+    public boolean canReadSimContacts() {
+        // Require SIM_STATE_READY because the TelephonyManager methods related to SIM require
+        // this state
+        return hasTelephony() && hasPermissions() &&
+                mTelephonyManager.getSimState() == TelephonyManager.SIM_STATE_READY;
+    }
+
+    @Override
+    public List<SimCard> getSimCards() {
+        if (!canReadSimContacts()) {
+            return Collections.emptyList();
+        }
+        final List<SimCard> sims = CompatUtils.isMSIMCompatible() ?
+                getSimCardsFromSubscriptions() :
+                Collections.singletonList(SimCard.create(mTelephonyManager,
+                        mContext.getString(R.string.single_sim_display_label)));
+        return SharedPreferenceUtil.restoreSimStates(mContext, sims);
+    }
+
+    @Override
+    public ArrayList<SimContact> loadContactsForSim(SimCard sim) {
+        if (sim.hasValidSubscriptionId()) {
+            return loadSimContacts(sim.getSubscriptionId());
+        }
+        return loadSimContacts();
+    }
+
+    public ArrayList<SimContact> loadSimContacts(int subscriptionId) {
+        return loadFrom(ICC_CONTENT_URI.buildUpon()
+                .appendPath("subId")
+                .appendPath(String.valueOf(subscriptionId))
+                .build());
+    }
+
+    public ArrayList<SimContact> loadSimContacts() {
+        return loadFrom(ICC_CONTENT_URI);
+    }
+
+    @Override
+    public ContentProviderResult[] importContacts(List<SimContact> contacts,
+            AccountWithDataSet targetAccount)
+            throws RemoteException, OperationApplicationException {
+        if (contacts.size() < IMPORT_MAX_BATCH_SIZE) {
+            return importBatch(contacts, targetAccount);
+        }
+        final List<ContentProviderResult> results = new ArrayList<>();
+        for (int i = 0; i < contacts.size(); i += IMPORT_MAX_BATCH_SIZE) {
+            results.addAll(Arrays.asList(importBatch(
+                    contacts.subList(i, Math.min(contacts.size(), i + IMPORT_MAX_BATCH_SIZE)),
+                    targetAccount)));
+        }
+        return results.toArray(new ContentProviderResult[results.size()]);
+    }
+
+    public void persistSimState(SimCard sim) {
+        SharedPreferenceUtil.persistSimStates(mContext, Collections.singletonList(sim));
+    }
+
+    @Override
+    public void persistSimStates(List<SimCard> simCards) {
+        SharedPreferenceUtil.persistSimStates(mContext, simCards);
+    }
+
+    @Override
+    public SimCard getSimBySubscriptionId(int subscriptionId) {
+        final List<SimCard> sims = SharedPreferenceUtil.restoreSimStates(mContext, getSimCards());
+        if (subscriptionId == SimCard.NO_SUBSCRIPTION_ID && !sims.isEmpty()) {
+            return sims.get(0);
+        }
+        for (SimCard sim : getSimCards()) {
+            if (sim.getSubscriptionId() == subscriptionId) {
+                return sim;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Finds SIM contacts that exist in CP2 and associates the account of the CP2 contact with
+     * the SIM contact
+     */
+    public Map<AccountWithDataSet, Set<SimContact>> findAccountsOfExistingSimContacts(
+            List<SimContact> contacts) {
+        final Map<AccountWithDataSet, Set<SimContact>> result = new ArrayMap<>();
+        for (int i = 0; i < contacts.size(); i += QUERY_MAX_BATCH_SIZE) {
+            findAccountsOfExistingSimContacts(
+                    contacts.subList(i, Math.min(contacts.size(), i + QUERY_MAX_BATCH_SIZE)),
+                    result);
+        }
+        return result;
+    }
+
+    private void findAccountsOfExistingSimContacts(List<SimContact> contacts,
+            Map<AccountWithDataSet, Set<SimContact>> result) {
+        final Map<Long, List<SimContact>> rawContactToSimContact = new HashMap<>();
+        Collections.sort(contacts, SimContact.compareByPhoneThenName());
+
+        final Cursor dataCursor = queryRawContactsForSimContacts(contacts);
+
+        try {
+            while (dataCursor.moveToNext()) {
+                final String number = DataQuery.getPhoneNumber(dataCursor);
+                final String name = DataQuery.getDisplayName(dataCursor);
+
+                final int index = SimContact.findByPhoneAndName(contacts, number, name);
+                if (index < 0) {
+                    continue;
+                }
+                final SimContact contact = contacts.get(index);
+                final long id = DataQuery.getRawContactId(dataCursor);
+                if (!rawContactToSimContact.containsKey(id)) {
+                    rawContactToSimContact.put(id, new ArrayList<SimContact>());
+                }
+                rawContactToSimContact.get(id).add(contact);
+            }
+        } finally {
+            dataCursor.close();
+        }
+
+        final Cursor accountsCursor = queryAccountsOfRawContacts(rawContactToSimContact.keySet());
+        try {
+            while (accountsCursor.moveToNext()) {
+                final AccountWithDataSet account = AccountQuery.getAccount(accountsCursor);
+                final long id = AccountQuery.getId(accountsCursor);
+                if (!result.containsKey(account)) {
+                    result.put(account, new ArraySet<SimContact>());
+                }
+                for (SimContact contact : rawContactToSimContact.get(id)) {
+                    result.get(account).add(contact);
+                }
+            }
+        } finally {
+            accountsCursor.close();
+        }
+    }
+
+
+    private ContentProviderResult[] importBatch(List<SimContact> contacts,
+            AccountWithDataSet targetAccount)
+            throws RemoteException, OperationApplicationException {
+        final ArrayList<ContentProviderOperation> ops =
+                createImportOperations(contacts, targetAccount);
+        return mResolver.applyBatch(ContactsContract.AUTHORITY, ops);
+    }
+
+    @TargetApi(Build.VERSION_CODES.LOLLIPOP_MR1)
+    private List<SimCard> getSimCardsFromSubscriptions() {
+        final SubscriptionManager subscriptionManager = (SubscriptionManager)
+                mContext.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
+        final List<SubscriptionInfo> subscriptions = subscriptionManager
+                .getActiveSubscriptionInfoList();
+        final ArrayList<SimCard> result = new ArrayList<>();
+        for (SubscriptionInfo subscriptionInfo : subscriptions) {
+            result.add(SimCard.create(subscriptionInfo));
+        }
+        return result;
+    }
+
+    private List<SimContact> getContactsForSim(SimCard sim) {
+        final List<SimContact> contacts = sim.getContacts();
+        return contacts != null ? contacts : loadContactsForSim(sim);
+    }
+
+    // See b/32831092
+    // Sometimes the SIM contacts provider seems to get stuck if read from multiple threads
+    // concurrently. So we just have a global lock around it to prevent potential issues.
+    private static final Object SIM_READ_LOCK = new Object();
+    private ArrayList<SimContact> loadFrom(Uri uri) {
+        synchronized (SIM_READ_LOCK) {
+            final Cursor cursor = mResolver.query(uri, null, null, null, null);
+
+            try {
+                return loadFromCursor(cursor);
+            } finally {
+                cursor.close();
+            }
+        }
+    }
+
+    private ArrayList<SimContact> loadFromCursor(Cursor cursor) {
+        final int colId = cursor.getColumnIndex(_ID);
+        final int colName = cursor.getColumnIndex(NAME);
+        final int colNumber = cursor.getColumnIndex(NUMBER);
+        final int colEmails = cursor.getColumnIndex(EMAILS);
+
+        final ArrayList<SimContact> result = new ArrayList<>();
+
+        while (cursor.moveToNext()) {
+            final long id = cursor.getLong(colId);
+            final String name = cursor.getString(colName);
+            final String number = cursor.getString(colNumber);
+            final String emails = cursor.getString(colEmails);
+
+            final SimContact contact = new SimContact(id, name, number, parseEmails(emails));
+            result.add(contact);
+        }
+        return result;
+    }
+
+    private Cursor queryRawContactsForSimContacts(List<SimContact> contacts) {
+        final StringBuilder selectionBuilder = new StringBuilder();
+
+        int phoneCount = 0;
+        int nameCount = 0;
+        for (SimContact contact : contacts) {
+            if (contact.hasPhone()) {
+                phoneCount++;
+            } else if (contact.hasName()) {
+                nameCount++;
+            }
+        }
+        List<String> selectionArgs = new ArrayList<>(phoneCount + 1);
+
+        selectionBuilder.append('(');
+        selectionBuilder.append(Data.MIMETYPE).append("=? AND ");
+        selectionArgs.add(Phone.CONTENT_ITEM_TYPE);
+
+        selectionBuilder.append(Phone.NUMBER).append(" IN (")
+                .append(Joiner.on(',').join(Collections.nCopies(phoneCount, '?')))
+                .append(')');
+        for (SimContact contact : contacts) {
+            if (contact.hasPhone()) {
+                selectionArgs.add(contact.getPhone());
+            }
+        }
+        selectionBuilder.append(')');
+
+        if (nameCount > 0) {
+            selectionBuilder.append(" OR (");
+
+            selectionBuilder.append(Data.MIMETYPE).append("=? AND ");
+            selectionArgs.add(StructuredName.CONTENT_ITEM_TYPE);
+
+            selectionBuilder.append(Data.DISPLAY_NAME).append(" IN (")
+                    .append(Joiner.on(',').join(Collections.nCopies(nameCount, '?')))
+                    .append(')');
+            for (SimContact contact : contacts) {
+                if (!contact.hasPhone() && contact.hasName()) {
+                    selectionArgs.add(contact.getName());
+                }
+            }
+            selectionBuilder.append(')');
+        }
+
+        return mResolver.query(Data.CONTENT_URI.buildUpon()
+                        .appendQueryParameter(Data.VISIBLE_CONTACTS_ONLY, "true")
+                        .build(),
+                DataQuery.PROJECTION,
+                selectionBuilder.toString(),
+                selectionArgs.toArray(new String[selectionArgs.size()]),
+                null);
+    }
+
+    private Cursor queryAccountsOfRawContacts(Set<Long> ids) {
+        final StringBuilder selectionBuilder = new StringBuilder();
+
+        final String[] args = new String[ids.size()];
+
+        selectionBuilder.append(RawContacts._ID).append(" IN (")
+                .append(Joiner.on(',').join(Collections.nCopies(args.length, '?')))
+                .append(")");
+        int i = 0;
+        for (long id : ids) {
+            args[i++] = String.valueOf(id);
+        }
+        return mResolver.query(RawContacts.CONTENT_URI,
+                AccountQuery.PROJECTION,
+                selectionBuilder.toString(),
+                args,
+                null);
+    }
+
+    private ArrayList<ContentProviderOperation> createImportOperations(List<SimContact> contacts,
+            AccountWithDataSet targetAccount) {
+        final ArrayList<ContentProviderOperation> ops = new ArrayList<>();
+        for (SimContact contact : contacts) {
+            contact.appendCreateContactOperations(ops, targetAccount);
+        }
+        return ops;
+    }
+
+    private String[] parseEmails(String emails) {
+        return emails != null ? emails.split(",") : null;
+    }
+
+    private boolean hasTelephony() {
+        return mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEPHONY);
+    }
+
+    private boolean hasPermissions() {
+        return PermissionsUtil.hasContactsPermissions(mContext) &&
+                PermissionsUtil.hasPhonePermissions(mContext);
+    }
+
+    // TODO remove this class and the USE_FAKE_INSTANCE flag once this code is not under
+    // active development or anytime after 3/1/2017
+    public static class DebugImpl extends SimContactDaoImpl {
+
+        private List<SimCard> mSimCards = new ArrayList<>();
+        private SparseArray<SimCard> mCardsBySubscription = new SparseArray<>();
+
+        public DebugImpl(Context context) {
+            super(context);
+        }
+
+        public DebugImpl addSimCard(SimCard sim) {
+            mSimCards.add(sim);
+            mCardsBySubscription.put(sim.getSubscriptionId(), sim);
+            return this;
+        }
+
+        @Override
+        public List<SimCard> getSimCards() {
+            return SharedPreferenceUtil.restoreSimStates(getContext(), mSimCards);
+        }
+
+        @Override
+        public ArrayList<SimContact> loadContactsForSim(SimCard card) {
+            return new ArrayList<>(card.getContacts());
+        }
+
+        @Override
+        public boolean canReadSimContacts() {
+            return true;
+        }
+    }
+
+    // Query used for detecting existing contacts that may match a SimContact.
+    private static final class DataQuery {
+
+        public static final String[] PROJECTION = new String[] {
+                Data.RAW_CONTACT_ID, Phone.NUMBER, Data.DISPLAY_NAME, Data.MIMETYPE
+        };
+
+        public static final int RAW_CONTACT_ID = 0;
+        public static final int PHONE_NUMBER = 1;
+        public static final int DISPLAY_NAME = 2;
+        public static final int MIMETYPE = 3;
+
+        public static long getRawContactId(Cursor cursor) {
+            return cursor.getLong(RAW_CONTACT_ID);
+        }
+
+        public static String getPhoneNumber(Cursor cursor) {
+            return isPhoneNumber(cursor) ? cursor.getString(PHONE_NUMBER) : null;
+        }
+
+        public static String getDisplayName(Cursor cursor) {
+            return cursor.getString(DISPLAY_NAME);
+        }
+
+        public static boolean isPhoneNumber(Cursor cursor) {
+            return Phone.CONTENT_ITEM_TYPE.equals(cursor.getString(MIMETYPE));
+        }
+    }
+
+    private static final class AccountQuery {
+        public static final String[] PROJECTION = new String[] {
+                RawContacts._ID, RawContacts.ACCOUNT_NAME, RawContacts.ACCOUNT_TYPE,
+                RawContacts.DATA_SET
+        };
+
+        public static long getId(Cursor cursor) {
+            return cursor.getLong(0);
+        }
+
+        public static AccountWithDataSet getAccount(Cursor cursor) {
+            return new AccountWithDataSet(cursor.getString(1), cursor.getString(2),
+                    cursor.getString(3));
+        }
+    }
+}
diff --git a/src/com/android/contacts/common/model/SimCard.java b/src/com/android/contacts/common/model/SimCard.java
index 7b13096..3e826dd 100644
--- a/src/com/android/contacts/common/model/SimCard.java
+++ b/src/com/android/contacts/common/model/SimCard.java
@@ -221,6 +221,20 @@
         return result;
     }
 
+    @Override
+    public String toString() {
+        return "SimCard{" +
+                "mSimId='" + mSimId + '\'' +
+                ", mSubscriptionId=" + mSubscriptionId +
+                ", mCarrierName=" + mCarrierName +
+                ", mDisplayName=" + mDisplayName +
+                ", mPhoneNumber='" + mPhoneNumber + '\'' +
+                ", mCountryCode='" + mCountryCode + '\'' +
+                ", mDismissed=" + mDismissed +
+                ", mImported=" + mImported +
+                ", mContacts=" + mContacts +
+                '}';
+    }
 
     @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP_MR1)
     public static SimCard create(SubscriptionInfo info) {
diff --git a/tests/src/com/android/contacts/common/database/SimContactDaoTests.java b/tests/src/com/android/contacts/common/database/SimContactDaoTests.java
index ec03f0f..e180ca2 100644
--- a/tests/src/com/android/contacts/common/database/SimContactDaoTests.java
+++ b/tests/src/com/android/contacts/common/database/SimContactDaoTests.java
@@ -30,6 +30,7 @@
 import android.support.test.filters.Suppress;
 import android.support.test.runner.AndroidJUnit4;
 
+import com.android.contacts.common.model.SimCard;
 import com.android.contacts.common.model.SimContact;
 import com.android.contacts.common.model.account.AccountWithDataSet;
 import com.android.contacts.tests.AccountsTestHelper;
@@ -281,7 +282,8 @@
             mSimTestHelper.addSimContact("Test Simthree", "15095550103");
 
             final SimContactDao sut = SimContactDao.create(getContext());
-            final ArrayList<SimContact> contacts = sut.loadSimContacts();
+            final SimCard sim = sut.getSimCards().get(0);
+            final ArrayList<SimContact> contacts = sut.loadContactsForSim(sim);
 
             assertThat(contacts.get(0), isSimContactWithNameAndPhone("Test Simone", "15095550101"));
             assertThat(contacts.get(1), isSimContactWithNameAndPhone("Test Simtwo", "15095550102"));
diff --git a/tests/src/com/android/contacts/tests/FakeSimContactDao.java b/tests/src/com/android/contacts/tests/FakeSimContactDao.java
new file mode 100644
index 0000000..ba091ca
--- /dev/null
+++ b/tests/src/com/android/contacts/tests/FakeSimContactDao.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.contacts.tests;
+
+import android.content.ContentProviderResult;
+import android.content.OperationApplicationException;
+import android.os.RemoteException;
+
+import com.android.contacts.common.database.SimContactDao;
+import com.android.contacts.common.model.SimCard;
+import com.android.contacts.common.model.SimContact;
+import com.android.contacts.common.model.account.AccountWithDataSet;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Fake implementation of SimContactDao for testing
+ */
+public class FakeSimContactDao extends SimContactDao {
+
+    public boolean canReadSimContacts = true;
+    public List<SimCard> simCards;
+    public Map<SimCard, ArrayList<SimContact>> simContacts;
+    public ContentProviderResult[] importResult;
+    public Map<AccountWithDataSet, Set<SimContact>> existingSimContacts;
+
+    public FakeSimContactDao() {
+        simCards = new ArrayList<>();
+        simContacts = new HashMap<>();
+        importResult = new ContentProviderResult[0];
+        existingSimContacts = new HashMap<>();
+    }
+
+    @Override
+    public boolean canReadSimContacts() {
+        return canReadSimContacts;
+    }
+
+    @Override
+    public List<SimCard> getSimCards() {
+        return simCards;
+    }
+
+    @Override
+    public ArrayList<SimContact> loadContactsForSim(SimCard sim) {
+        return simContacts.get(sim);
+    }
+
+    @Override
+    public ContentProviderResult[] importContacts(List<SimContact> contacts,
+            AccountWithDataSet targetAccount)
+            throws RemoteException, OperationApplicationException {
+        return importResult;
+    }
+
+    @Override
+    public void persistSimStates(List<SimCard> simCards) {
+        this.simCards = simCards;
+    }
+
+    @Override
+    public SimCard getSimBySubscriptionId(int subscriptionId) {
+        for (SimCard sim : simCards) {
+            if (sim.getSubscriptionId() == subscriptionId) {
+                return sim;
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public Map<AccountWithDataSet, Set<SimContact>> findAccountsOfExistingSimContacts(
+            List<SimContact> contacts) {
+        return existingSimContacts;
+    }
+
+    public FakeSimContactDao addSim(SimCard sim, SimContact... contacts) {
+        simCards.add(sim);
+        simContacts.put(sim, new ArrayList<>(Arrays.asList(contacts)));
+        return this;
+    }
+
+    public static FakeSimContactDao singleSimWithContacts(SimCard sim, SimContact... contacts) {
+        return new FakeSimContactDao().addSim(sim, contacts);
+    }
+
+    public static FakeSimContactDao noSim() {
+        FakeSimContactDao result = new FakeSimContactDao();
+        result.canReadSimContacts = false;
+        return result;
+    }
+
+}
diff --git a/tests/src/com/android/contacts/tests/SimContactsTestHelper.java b/tests/src/com/android/contacts/tests/SimContactsTestHelper.java
index c2ffead..552d790 100644
--- a/tests/src/com/android/contacts/tests/SimContactsTestHelper.java
+++ b/tests/src/com/android/contacts/tests/SimContactsTestHelper.java
@@ -15,7 +15,6 @@
  */
 package com.android.contacts.tests;
 
-import android.content.ContentProvider;
 import android.content.ContentProviderOperation;
 import android.content.ContentProviderResult;
 import android.content.ContentResolver;
@@ -29,9 +28,10 @@
 import android.support.test.InstrumentationRegistry;
 import android.telephony.TelephonyManager;
 
+import com.android.contacts.common.database.SimContactDaoImpl;
+import com.android.contacts.common.model.SimCard;
 import com.android.contacts.common.model.SimContact;
 import com.android.contacts.common.database.SimContactDao;
-import com.android.contacts.common.test.mocks.MockContentProvider;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -59,7 +59,7 @@
     }
 
     public int getSimContactCount() {
-        Cursor cursor = mContext.getContentResolver().query(SimContactDao.ICC_CONTENT_URI,
+        Cursor cursor = mContext.getContentResolver().query(SimContactDaoImpl.ICC_CONTENT_URI,
                 null, null, null, null);
         try {
             return cursor.getCount();
@@ -68,32 +68,6 @@
         }
     }
 
-    public ContentValues iccRow(long id, String name, String number, String emails) {
-        ContentValues values = new ContentValues();
-        values.put(SimContactDao._ID, id);
-        values.put(SimContactDao.NAME, name);
-        values.put(SimContactDao.NUMBER, number);
-        values.put(SimContactDao.EMAILS, emails);
-        return values;
-    }
-
-    public ContentProvider iccProviderExpectingNoQueries() {
-        return new MockContentProvider();
-    }
-
-    public ContentProvider emptyIccProvider() {
-        final MockContentProvider provider = new MockContentProvider();
-        provider.expectQuery(SimContactDao.ICC_CONTENT_URI)
-                .withDefaultProjection(
-                        SimContactDao._ID, SimContactDao.NAME,
-                        SimContactDao.NUMBER, SimContactDao.EMAILS)
-                .withAnyProjection()
-                .withAnySelection()
-                .withAnySortOrder()
-                .returnEmptyCursor();
-        return provider;
-    }
-
     public Uri addSimContact(String name, String number) {
         ContentValues values = new ContentValues();
         // Oddly even though it's called name when querying we have to use "tag" for it to work
@@ -102,23 +76,26 @@
             values.put("tag", name);
         }
         if (number != null) {
-            values.put(SimContactDao.NUMBER, number);
+            values.put(SimContactDaoImpl.NUMBER, number);
         }
-        return mResolver.insert(SimContactDao.ICC_CONTENT_URI, values);
+        return mResolver.insert(SimContactDaoImpl.ICC_CONTENT_URI, values);
     }
 
     public ContentProviderResult[] deleteAllSimContacts()
             throws RemoteException, OperationApplicationException {
-        SimContactDao dao = SimContactDao.create(mContext);
-        List<SimContact> contacts = dao.loadSimContacts();
+        final List<SimCard> sims = mSimDao.getSimCards();
+        if (sims.isEmpty()) {
+            throw new IllegalStateException("Expected SIM card");
+        }
+        final List<SimContact> contacts = mSimDao.loadContactsForSim(sims.get(0));
         ArrayList<ContentProviderOperation> ops = new ArrayList<>();
         for (SimContact contact : contacts) {
             ops.add(ContentProviderOperation
-                    .newDelete(SimContactDao.ICC_CONTENT_URI)
+                    .newDelete(SimContactDaoImpl.ICC_CONTENT_URI)
                     .withSelection(getWriteSelection(contact), null)
                     .build());
         }
-        return mResolver.applyBatch(SimContactDao.ICC_CONTENT_URI.getAuthority(), ops);
+        return mResolver.applyBatch(SimContactDaoImpl.ICC_CONTENT_URI.getAuthority(), ops);
     }
 
     public ContentProviderResult[] restore(ArrayList<ContentProviderOperation> restoreOps)
@@ -128,13 +105,17 @@
         // Remove SIM contacts because we assume that caller wants the data to be in the exact
         // state as when the restore ops were captured.
         deleteAllSimContacts();
-        return mResolver.applyBatch(SimContactDao.ICC_CONTENT_URI.getAuthority(), restoreOps);
+        return mResolver.applyBatch(SimContactDaoImpl.ICC_CONTENT_URI.getAuthority(), restoreOps);
     }
 
     public ArrayList<ContentProviderOperation> captureRestoreSnapshot() {
-        ArrayList<SimContact> contacts = mSimDao.loadSimContacts();
+        final List<SimCard> sims = mSimDao.getSimCards();
+        if (sims.isEmpty()) {
+            throw new IllegalStateException("Expected SIM card");
+        }
+        final ArrayList<SimContact> contacts = mSimDao.loadContactsForSim(sims.get(0));
 
-        ArrayList<ContentProviderOperation> ops = new ArrayList<>();
+        final ArrayList<ContentProviderOperation> ops = new ArrayList<>();
         for (SimContact contact : contacts) {
             final String[] emails = contact.getEmails();
             if (emails != null && emails.length > 0) {
@@ -142,7 +123,7 @@
                         " Please manually remove SIM contacts with emails.");
             }
             ops.add(ContentProviderOperation
-                    .newInsert(SimContactDao.ICC_CONTENT_URI)
+                    .newInsert(SimContactDaoImpl.ICC_CONTENT_URI)
                     .withValue("tag", contact.getName())
                     .withValue("number", contact.getPhone())
                     .build());
@@ -151,15 +132,15 @@
     }
 
     public String getWriteSelection(SimContact simContact) {
-        return "tag='" + simContact.getName() + "' AND " + SimContactDao.NUMBER + "='" +
+        return "tag='" + simContact.getName() + "' AND " + SimContactDaoImpl.NUMBER + "='" +
                 simContact.getPhone() + "'";
     }
 
     public int deleteSimContact(@NonNull  String name, @NonNull  String number) {
         // IccProvider doesn't use the selection args.
         final String selection = "tag='" + name + "' AND " +
-                SimContactDao.NUMBER + "='" + number + "'";
-        return mResolver.delete(SimContactDao.ICC_CONTENT_URI, selection, null);
+                SimContactDaoImpl.NUMBER + "='" + number + "'";
+        return mResolver.delete(SimContactDaoImpl.ICC_CONTENT_URI, selection, null);
     }
 
     public boolean isSimReady() {
