diff --git a/src/com/android/providers/contacts/aggregation/AbstractContactAggregator.java b/src/com/android/providers/contacts/aggregation/AbstractContactAggregator.java
new file mode 100644
index 0000000..5b407a6
--- /dev/null
+++ b/src/com/android/providers/contacts/aggregation/AbstractContactAggregator.java
@@ -0,0 +1,2805 @@
+/*
+ * Copyright (C) 2015 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.providers.contacts.aggregation;
+
+import android.database.Cursor;
+import android.database.DatabaseUtils;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteQueryBuilder;
+import android.database.sqlite.SQLiteStatement;
+import android.net.Uri;
+import android.provider.ContactsContract.AggregationExceptions;
+import android.provider.ContactsContract.CommonDataKinds.Email;
+import android.provider.ContactsContract.CommonDataKinds.Identity;
+import android.provider.ContactsContract.CommonDataKinds.Phone;
+import android.provider.ContactsContract.CommonDataKinds.Photo;
+import android.provider.ContactsContract.Contacts;
+import android.provider.ContactsContract.Contacts.AggregationSuggestions;
+import android.provider.ContactsContract.Data;
+import android.provider.ContactsContract.DisplayNameSources;
+import android.provider.ContactsContract.FullNameStyle;
+import android.provider.ContactsContract.PhotoFiles;
+import android.provider.ContactsContract.PinnedPositions;
+import android.provider.ContactsContract.RawContacts;
+import android.provider.ContactsContract.StatusUpdates;
+import android.text.TextUtils;
+import android.util.EventLog;
+import android.util.Log;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.providers.contacts.ContactLookupKey;
+import com.android.providers.contacts.ContactsDatabaseHelper;
+import com.android.providers.contacts.ContactsDatabaseHelper.AccountsColumns;
+import com.android.providers.contacts.ContactsDatabaseHelper.AggregatedPresenceColumns;
+import com.android.providers.contacts.ContactsDatabaseHelper.ContactsColumns;
+import com.android.providers.contacts.ContactsDatabaseHelper.DataColumns;
+import com.android.providers.contacts.ContactsDatabaseHelper.NameLookupColumns;
+import com.android.providers.contacts.ContactsDatabaseHelper.NameLookupType;
+import com.android.providers.contacts.ContactsDatabaseHelper.PhoneLookupColumns;
+import com.android.providers.contacts.ContactsDatabaseHelper.PresenceColumns;
+import com.android.providers.contacts.ContactsDatabaseHelper.RawContactsColumns;
+import com.android.providers.contacts.ContactsDatabaseHelper.StatusUpdatesColumns;
+import com.android.providers.contacts.ContactsDatabaseHelper.Tables;
+import com.android.providers.contacts.ContactsDatabaseHelper.Views;
+import com.android.providers.contacts.ContactsProvider2;
+import com.android.providers.contacts.NameLookupBuilder;
+import com.android.providers.contacts.NameNormalizer;
+import com.android.providers.contacts.NameSplitter;
+import com.android.providers.contacts.PhotoPriorityResolver;
+import com.android.providers.contacts.ReorderingCursorWrapper;
+import com.android.providers.contacts.TransactionContext;
+import com.android.providers.contacts.aggregation.util.CommonNicknameCache;
+import com.android.providers.contacts.aggregation.util.ContactAggregatorHelper;
+import com.android.providers.contacts.aggregation.util.ContactMatcher;
+import com.android.providers.contacts.aggregation.util.ContactMatcher.MatchScore;
+import com.android.providers.contacts.database.ContactsTableUtil;
+import com.android.providers.contacts.util.Clock;
+
+import com.google.android.collect.Maps;
+import com.google.android.collect.Sets;
+import com.google.common.collect.Multimap;
+import com.google.common.collect.HashMultimap;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+import java.util.Set;
+
+/**
+ * ContactAggregator deals with aggregating contact information coming from different sources.
+ * Two John Doe contacts from two disjoint sources are presumed to be the same
+ * person unless the user declares otherwise.
+ */
+public class AbstractContactAggregator {
+
+    private static final String TAG = "ContactAggregator";
+
+    private static final boolean DEBUG_LOGGING = Log.isLoggable(TAG, Log.DEBUG);
+    private static final boolean VERBOSE_LOGGING = Log.isLoggable(TAG, Log.VERBOSE);
+
+    private static final String STRUCTURED_NAME_BASED_LOOKUP_SQL =
+            NameLookupColumns.NAME_TYPE + " IN ("
+                    + NameLookupType.NAME_EXACT + ","
+                    + NameLookupType.NAME_VARIANT + ","
+                    + NameLookupType.NAME_COLLATION_KEY + ")";
+
+
+    /**
+     * SQL statement that sets the {@link ContactsColumns#LAST_STATUS_UPDATE_ID} column
+     * on the contact to point to the latest social status update.
+     */
+    private static final String UPDATE_LAST_STATUS_UPDATE_ID_SQL =
+            "UPDATE " + Tables.CONTACTS +
+            " SET " + ContactsColumns.LAST_STATUS_UPDATE_ID + "=" +
+                    "(SELECT " + DataColumns.CONCRETE_ID +
+                    " FROM " + Tables.STATUS_UPDATES +
+                    " JOIN " + Tables.DATA +
+                    "   ON (" + StatusUpdatesColumns.DATA_ID + "="
+                            + DataColumns.CONCRETE_ID + ")" +
+                    " JOIN " + Tables.RAW_CONTACTS +
+                    "   ON (" + DataColumns.CONCRETE_RAW_CONTACT_ID + "="
+                            + RawContactsColumns.CONCRETE_ID + ")" +
+                    " WHERE " + RawContacts.CONTACT_ID + "=?" +
+                    " ORDER BY " + StatusUpdates.STATUS_TIMESTAMP + " DESC,"
+                            + StatusUpdates.STATUS +
+                    " LIMIT 1)" +
+            " WHERE " + ContactsColumns.CONCRETE_ID + "=?";
+
+    // From system/core/logcat/event-log-tags
+    // aggregator [time, count] will be logged for each aggregator cycle.
+    // For the query (as opposed to the merge), count will be negative
+    public static final int LOG_SYNC_CONTACTS_AGGREGATION = 2747;
+
+    // If we encounter more than this many contacts with matching names, aggregate only this many
+    private static final int PRIMARY_HIT_LIMIT = 15;
+    private static final String PRIMARY_HIT_LIMIT_STRING = String.valueOf(PRIMARY_HIT_LIMIT);
+
+    // If we encounter more than this many contacts with matching phone number or email,
+    // don't attempt to aggregate - this is likely an error or a shared corporate data element.
+    private static final int SECONDARY_HIT_LIMIT = 20;
+    private static final String SECONDARY_HIT_LIMIT_STRING = String.valueOf(SECONDARY_HIT_LIMIT);
+
+    // If we encounter no less than this many raw contacts in the best matching contact during
+    // aggregation, don't attempt to aggregate - this is likely an error or a shared corporate
+    // data element.
+    @VisibleForTesting
+    static final int AGGREGATION_CONTACT_SIZE_LIMIT = 50;
+
+    // If we encounter more than this many contacts with matching name during aggregation
+    // suggestion lookup, ignore the remaining results.
+    private static final int FIRST_LETTER_SUGGESTION_HIT_LIMIT = 100;
+
+    // Return code for the canJoinIntoContact method.
+    private static final int JOIN = 1;
+    private static final int KEEP_SEPARATE = 0;
+    private static final int RE_AGGREGATE = -1;
+
+    private final ContactsProvider2 mContactsProvider;
+    private final ContactsDatabaseHelper mDbHelper;
+    private PhotoPriorityResolver mPhotoPriorityResolver;
+    private final NameSplitter mNameSplitter;
+    private final CommonNicknameCache mCommonNicknameCache;
+
+    private boolean mEnabled = true;
+
+    /** Precompiled sql statement for setting an aggregated presence */
+    private SQLiteStatement mAggregatedPresenceReplace;
+    private SQLiteStatement mPresenceContactIdUpdate;
+    private SQLiteStatement mRawContactCountQuery;
+    private SQLiteStatement mAggregatedPresenceDelete;
+    private SQLiteStatement mMarkForAggregation;
+    private SQLiteStatement mPhotoIdUpdate;
+    private SQLiteStatement mDisplayNameUpdate;
+    private SQLiteStatement mLookupKeyUpdate;
+    private SQLiteStatement mStarredUpdate;
+    private SQLiteStatement mPinnedUpdate;
+    private SQLiteStatement mContactIdAndMarkAggregatedUpdate;
+    private SQLiteStatement mContactIdUpdate;
+    private SQLiteStatement mMarkAggregatedUpdate;
+    private SQLiteStatement mContactUpdate;
+    private SQLiteStatement mContactInsert;
+    private SQLiteStatement mResetPinnedForRawContact;
+
+    private HashMap<Long, Integer> mRawContactsMarkedForAggregation = Maps.newHashMap();
+
+    private String[] mSelectionArgs1 = new String[1];
+    private String[] mSelectionArgs2 = new String[2];
+
+    private long mMimeTypeIdIdentity;
+    private long mMimeTypeIdEmail;
+    private long mMimeTypeIdPhoto;
+    private long mMimeTypeIdPhone;
+    private String mRawContactsQueryByRawContactId;
+    private String mRawContactsQueryByContactId;
+    private StringBuilder mSb = new StringBuilder();
+    private MatchCandidateList mCandidates = new MatchCandidateList();
+    private ContactMatcher mMatcher = new ContactMatcher();
+    private DisplayNameCandidate mDisplayNameCandidate = new DisplayNameCandidate();
+
+    /**
+     * Parameter for the suggestion lookup query.
+     */
+    public static final class AggregationSuggestionParameter {
+        public final String kind;
+        public final String value;
+
+        public AggregationSuggestionParameter(String kind, String value) {
+            this.kind = kind;
+            this.value = value;
+        }
+    }
+
+    /**
+     * Captures a potential match for a given name. The matching algorithm
+     * constructs a bunch of NameMatchCandidate objects for various potential matches
+     * and then executes the search in bulk.
+     */
+    private static class NameMatchCandidate {
+        String mName;
+        int mLookupType;
+
+        public NameMatchCandidate(String name, int nameLookupType) {
+            mName = name;
+            mLookupType = nameLookupType;
+        }
+    }
+
+    /**
+     * A list of {@link NameMatchCandidate} that keeps its elements even when the list is
+     * truncated. This is done for optimization purposes to avoid excessive object allocation.
+     */
+    private static class MatchCandidateList {
+        private final ArrayList<NameMatchCandidate> mList = new ArrayList<NameMatchCandidate>();
+        private int mCount;
+
+        /**
+         * Adds a {@link NameMatchCandidate} element or updates the next one if it already exists.
+         */
+        public void add(String name, int nameLookupType) {
+            if (mCount >= mList.size()) {
+                mList.add(new NameMatchCandidate(name, nameLookupType));
+            } else {
+                NameMatchCandidate candidate = mList.get(mCount);
+                candidate.mName = name;
+                candidate.mLookupType = nameLookupType;
+            }
+            mCount++;
+        }
+
+        public void clear() {
+            mCount = 0;
+        }
+
+        public boolean isEmpty() {
+            return mCount == 0;
+        }
+    }
+
+    /**
+     * A convenience class used in the algorithm that figures out which of available
+     * display names to use for an aggregate contact.
+     */
+    private static class DisplayNameCandidate {
+        long rawContactId;
+        String displayName;
+        int displayNameSource;
+        boolean isNameSuperPrimary;
+        boolean writableAccount;
+
+        public DisplayNameCandidate() {
+            clear();
+        }
+
+        public void clear() {
+            rawContactId = -1;
+            displayName = null;
+            displayNameSource = DisplayNameSources.UNDEFINED;
+            isNameSuperPrimary = false;
+            writableAccount = false;
+        }
+    }
+
+    /**
+     * Constructor.
+     */
+    public ContactAggregator(ContactsProvider2 contactsProvider,
+            ContactsDatabaseHelper contactsDatabaseHelper,
+            PhotoPriorityResolver photoPriorityResolver, NameSplitter nameSplitter,
+            CommonNicknameCache commonNicknameCache) {
+        mContactsProvider = contactsProvider;
+        mDbHelper = contactsDatabaseHelper;
+        mPhotoPriorityResolver = photoPriorityResolver;
+        mNameSplitter = nameSplitter;
+        mCommonNicknameCache = commonNicknameCache;
+
+        SQLiteDatabase db = mDbHelper.getReadableDatabase();
+
+        // Since we have no way of determining which custom status was set last,
+        // we'll just pick one randomly.  We are using MAX as an approximation of randomness
+        final String replaceAggregatePresenceSql =
+                "INSERT OR REPLACE INTO " + Tables.AGGREGATED_PRESENCE + "("
+                + AggregatedPresenceColumns.CONTACT_ID + ", "
+                + StatusUpdates.PRESENCE + ", "
+                + StatusUpdates.CHAT_CAPABILITY + ")"
+                + " SELECT " + PresenceColumns.CONTACT_ID + ","
+                + StatusUpdates.PRESENCE + ","
+                + StatusUpdates.CHAT_CAPABILITY
+                + " FROM " + Tables.PRESENCE
+                + " WHERE "
+                + " (" + StatusUpdates.PRESENCE
+                +       " * 10 + " + StatusUpdates.CHAT_CAPABILITY + ")"
+                + " = (SELECT "
+                + "MAX (" + StatusUpdates.PRESENCE
+                +       " * 10 + " + StatusUpdates.CHAT_CAPABILITY + ")"
+                + " FROM " + Tables.PRESENCE
+                + " WHERE " + PresenceColumns.CONTACT_ID
+                + "=?)"
+                + " AND " + PresenceColumns.CONTACT_ID
+                + "=?;";
+        mAggregatedPresenceReplace = db.compileStatement(replaceAggregatePresenceSql);
+
+        mRawContactCountQuery = db.compileStatement(
+                "SELECT COUNT(" + RawContacts._ID + ")" +
+                " FROM " + Tables.RAW_CONTACTS +
+                " WHERE " + RawContacts.CONTACT_ID + "=?"
+                        + " AND " + RawContacts._ID + "<>?");
+
+        mAggregatedPresenceDelete = db.compileStatement(
+                "DELETE FROM " + Tables.AGGREGATED_PRESENCE +
+                " WHERE " + AggregatedPresenceColumns.CONTACT_ID + "=?");
+
+        mMarkForAggregation = db.compileStatement(
+                "UPDATE " + Tables.RAW_CONTACTS +
+                " SET " + RawContactsColumns.AGGREGATION_NEEDED + "=1" +
+                " WHERE " + RawContacts._ID + "=?"
+                        + " AND " + RawContactsColumns.AGGREGATION_NEEDED + "=0");
+
+        mPhotoIdUpdate = db.compileStatement(
+                "UPDATE " + Tables.CONTACTS +
+                " SET " + Contacts.PHOTO_ID + "=?," + Contacts.PHOTO_FILE_ID + "=? " +
+                " WHERE " + Contacts._ID + "=?");
+
+        mDisplayNameUpdate = db.compileStatement(
+                "UPDATE " + Tables.CONTACTS +
+                " SET " + Contacts.NAME_RAW_CONTACT_ID + "=? " +
+                " WHERE " + Contacts._ID + "=?");
+
+        mLookupKeyUpdate = db.compileStatement(
+                "UPDATE " + Tables.CONTACTS +
+                " SET " + Contacts.LOOKUP_KEY + "=? " +
+                " WHERE " + Contacts._ID + "=?");
+
+        mStarredUpdate = db.compileStatement("UPDATE " + Tables.CONTACTS + " SET "
+                + Contacts.STARRED + "=(SELECT (CASE WHEN COUNT(" + RawContacts.STARRED
+                + ")=0 THEN 0 ELSE 1 END) FROM " + Tables.RAW_CONTACTS + " WHERE "
+                + RawContacts.CONTACT_ID + "=" + ContactsColumns.CONCRETE_ID + " AND "
+                + RawContacts.STARRED + "=1)" + " WHERE " + Contacts._ID + "=?");
+
+        mPinnedUpdate = db.compileStatement("UPDATE " + Tables.CONTACTS + " SET "
+                + Contacts.PINNED + " = IFNULL((SELECT MIN(" + RawContacts.PINNED + ") FROM "
+                + Tables.RAW_CONTACTS + " WHERE " + RawContacts.CONTACT_ID + "="
+                + ContactsColumns.CONCRETE_ID + " AND " + RawContacts.PINNED + ">"
+                + PinnedPositions.UNPINNED + ")," + PinnedPositions.UNPINNED + ") "
+                + "WHERE " + Contacts._ID + "=?");
+
+        mContactIdAndMarkAggregatedUpdate = db.compileStatement(
+                "UPDATE " + Tables.RAW_CONTACTS +
+                " SET " + RawContacts.CONTACT_ID + "=?, "
+                        + RawContactsColumns.AGGREGATION_NEEDED + "=0" +
+                " WHERE " + RawContacts._ID + "=?");
+
+        mContactIdUpdate = db.compileStatement(
+                "UPDATE " + Tables.RAW_CONTACTS +
+                " SET " + RawContacts.CONTACT_ID + "=?" +
+                " WHERE " + RawContacts._ID + "=?");
+
+        mMarkAggregatedUpdate = db.compileStatement(
+                "UPDATE " + Tables.RAW_CONTACTS +
+                " SET " + RawContactsColumns.AGGREGATION_NEEDED + "=0" +
+                " WHERE " + RawContacts._ID + "=?");
+
+        mPresenceContactIdUpdate = db.compileStatement(
+                "UPDATE " + Tables.PRESENCE +
+                " SET " + PresenceColumns.CONTACT_ID + "=?" +
+                " WHERE " + PresenceColumns.RAW_CONTACT_ID + "=?");
+
+        mContactUpdate = db.compileStatement(ContactReplaceSqlStatement.UPDATE_SQL);
+        mContactInsert = db.compileStatement(ContactReplaceSqlStatement.INSERT_SQL);
+
+        mResetPinnedForRawContact = db.compileStatement(
+                "UPDATE " + Tables.RAW_CONTACTS +
+                " SET " + RawContacts.PINNED + "=" + PinnedPositions.UNPINNED +
+                " WHERE " + RawContacts._ID + "=?");
+
+        mMimeTypeIdEmail = mDbHelper.getMimeTypeId(Email.CONTENT_ITEM_TYPE);
+        mMimeTypeIdIdentity = mDbHelper.getMimeTypeId(Identity.CONTENT_ITEM_TYPE);
+        mMimeTypeIdPhoto = mDbHelper.getMimeTypeId(Photo.CONTENT_ITEM_TYPE);
+        mMimeTypeIdPhone = mDbHelper.getMimeTypeId(Phone.CONTENT_ITEM_TYPE);
+
+        // Query used to retrieve data from raw contacts to populate the corresponding aggregate
+        mRawContactsQueryByRawContactId = String.format(Locale.US,
+                RawContactsQuery.SQL_FORMAT_BY_RAW_CONTACT_ID,
+                mDbHelper.getMimeTypeIdForStructuredName(), mMimeTypeIdPhoto, mMimeTypeIdPhone);
+
+        mRawContactsQueryByContactId = String.format(Locale.US,
+                RawContactsQuery.SQL_FORMAT_BY_CONTACT_ID,
+                mDbHelper.getMimeTypeIdForStructuredName(), mMimeTypeIdPhoto, mMimeTypeIdPhone);
+    }
+
+    public void setEnabled(boolean enabled) {
+        mEnabled = enabled;
+    }
+
+    public boolean isEnabled() {
+        return mEnabled;
+    }
+
+    private interface AggregationQuery {
+        String SQL =
+                "SELECT " + RawContacts._ID + "," + RawContacts.CONTACT_ID +
+                        ", " + RawContactsColumns.ACCOUNT_ID +
+                " FROM " + Tables.RAW_CONTACTS +
+                " WHERE " + RawContacts._ID + " IN(";
+
+        int _ID = 0;
+        int CONTACT_ID = 1;
+        int ACCOUNT_ID = 2;
+    }
+
+    /**
+     * Aggregate all raw contacts that were marked for aggregation in the current transaction.
+     * Call just before committing the transaction.
+     */
+    public void aggregateInTransaction(TransactionContext txContext, SQLiteDatabase db) {
+        final int markedCount = mRawContactsMarkedForAggregation.size();
+        if (markedCount == 0) {
+            return;
+        }
+
+        final long start = System.currentTimeMillis();
+        if (DEBUG_LOGGING) {
+            Log.d(TAG, "aggregateInTransaction for " + markedCount + " contacts");
+        }
+
+        EventLog.writeEvent(LOG_SYNC_CONTACTS_AGGREGATION, start, -markedCount);
+
+        int index = 0;
+
+        // We don't use the cached string builder (namely mSb)  here, as this string can be very
+        // long when upgrading (where we re-aggregate all visible contacts) and StringBuilder won't
+        // shrink the internal storage.
+        // Note: don't use selection args here.  We just include all IDs directly in the selection,
+        // because there's a limit for the number of parameters in a query.
+        final StringBuilder sbQuery = new StringBuilder();
+        sbQuery.append(AggregationQuery.SQL);
+        for (long rawContactId : mRawContactsMarkedForAggregation.keySet()) {
+            if (index > 0) {
+                sbQuery.append(',');
+            }
+            sbQuery.append(rawContactId);
+            index++;
+        }
+
+        sbQuery.append(')');
+
+        final long[] rawContactIds;
+        final long[] contactIds;
+        final long[] accountIds;
+        final int actualCount;
+        final Cursor c = db.rawQuery(sbQuery.toString(), null);
+        try {
+            actualCount = c.getCount();
+            rawContactIds = new long[actualCount];
+            contactIds = new long[actualCount];
+            accountIds = new long[actualCount];
+
+            index = 0;
+            while (c.moveToNext()) {
+                rawContactIds[index] = c.getLong(AggregationQuery._ID);
+                contactIds[index] = c.getLong(AggregationQuery.CONTACT_ID);
+                accountIds[index] = c.getLong(AggregationQuery.ACCOUNT_ID);
+                index++;
+            }
+        } finally {
+            c.close();
+        }
+
+        if (DEBUG_LOGGING) {
+            Log.d(TAG, "aggregateInTransaction: initial query done.");
+        }
+
+        for (int i = 0; i < actualCount; i++) {
+            aggregateContact(txContext, db, rawContactIds[i], accountIds[i], contactIds[i],
+                    mCandidates, mMatcher);
+        }
+
+        long elapsedTime = System.currentTimeMillis() - start;
+        EventLog.writeEvent(LOG_SYNC_CONTACTS_AGGREGATION, elapsedTime, actualCount);
+
+        if (DEBUG_LOGGING) {
+            Log.d(TAG, "Contact aggregation complete: " + actualCount +
+                    (actualCount == 0 ? "" : ", " + (elapsedTime / actualCount)
+                            + " ms per raw contact"));
+        }
+    }
+
+    @SuppressWarnings("deprecation")
+    public void triggerAggregation(TransactionContext txContext, long rawContactId) {
+        if (!mEnabled) {
+            return;
+        }
+
+        int aggregationMode = mDbHelper.getAggregationMode(rawContactId);
+        switch (aggregationMode) {
+            case RawContacts.AGGREGATION_MODE_DISABLED:
+                break;
+
+            case RawContacts.AGGREGATION_MODE_DEFAULT: {
+                markForAggregation(rawContactId, aggregationMode, false);
+                break;
+            }
+
+            case RawContacts.AGGREGATION_MODE_SUSPENDED: {
+                long contactId = mDbHelper.getContactId(rawContactId);
+
+                if (contactId != 0) {
+                    updateAggregateData(txContext, contactId);
+                }
+                break;
+            }
+
+            case RawContacts.AGGREGATION_MODE_IMMEDIATE: {
+                aggregateContact(txContext, mDbHelper.getWritableDatabase(), rawContactId);
+                break;
+            }
+        }
+    }
+
+    public void clearPendingAggregations() {
+        // HashMap woulnd't shrink the internal table once expands it, so let's just re-create
+        // a new one instead of clear()ing it.
+        mRawContactsMarkedForAggregation = Maps.newHashMap();
+    }
+
+    public void markNewForAggregation(long rawContactId, int aggregationMode) {
+        mRawContactsMarkedForAggregation.put(rawContactId, aggregationMode);
+    }
+
+    public void markForAggregation(long rawContactId, int aggregationMode, boolean force) {
+        final int effectiveAggregationMode;
+        if (!force && mRawContactsMarkedForAggregation.containsKey(rawContactId)) {
+            // As per ContactsContract documentation, default aggregation mode
+            // does not override a previously set mode
+            if (aggregationMode == RawContacts.AGGREGATION_MODE_DEFAULT) {
+                effectiveAggregationMode = mRawContactsMarkedForAggregation.get(rawContactId);
+            } else {
+                effectiveAggregationMode = aggregationMode;
+            }
+        } else {
+            mMarkForAggregation.bindLong(1, rawContactId);
+            mMarkForAggregation.execute();
+            effectiveAggregationMode = aggregationMode;
+        }
+
+        mRawContactsMarkedForAggregation.put(rawContactId, effectiveAggregationMode);
+    }
+
+    private static class RawContactIdAndAggregationModeQuery {
+        public static final String TABLE = Tables.RAW_CONTACTS;
+
+        public static final String[] COLUMNS = { RawContacts._ID, RawContacts.AGGREGATION_MODE };
+
+        public static final String SELECTION = RawContacts.CONTACT_ID + "=?";
+
+        public static final int _ID = 0;
+        public static final int AGGREGATION_MODE = 1;
+    }
+
+    /**
+     * Marks all constituent raw contacts of an aggregated contact for re-aggregation.
+     */
+    private void markContactForAggregation(SQLiteDatabase db, long contactId) {
+        mSelectionArgs1[0] = String.valueOf(contactId);
+        Cursor cursor = db.query(RawContactIdAndAggregationModeQuery.TABLE,
+                RawContactIdAndAggregationModeQuery.COLUMNS,
+                RawContactIdAndAggregationModeQuery.SELECTION, mSelectionArgs1, null, null, null);
+        try {
+            if (cursor.moveToFirst()) {
+                long rawContactId = cursor.getLong(RawContactIdAndAggregationModeQuery._ID);
+                int aggregationMode = cursor.getInt(
+                        RawContactIdAndAggregationModeQuery.AGGREGATION_MODE);
+                // Don't re-aggregate AGGREGATION_MODE_SUSPENDED / AGGREGATION_MODE_DISABLED.
+                // (Also just ignore deprecated AGGREGATION_MODE_IMMEDIATE)
+                if (aggregationMode == RawContacts.AGGREGATION_MODE_DEFAULT) {
+                    markForAggregation(rawContactId, aggregationMode, true);
+                }
+            }
+        } finally {
+            cursor.close();
+        }
+    }
+
+    /**
+     * Mark all visible contacts for re-aggregation.
+     *
+     * - Set {@link RawContactsColumns#AGGREGATION_NEEDED} For all visible raw_contacts with
+     *   {@link RawContacts#AGGREGATION_MODE_DEFAULT}.
+     * - Also put them into {@link #mRawContactsMarkedForAggregation}.
+     */
+    public int markAllVisibleForAggregation(SQLiteDatabase db) {
+        final long start = System.currentTimeMillis();
+
+        // Set AGGREGATION_NEEDED for all visible raw_cotnacts with AGGREGATION_MODE_DEFAULT.
+        // (Don't re-aggregate AGGREGATION_MODE_SUSPENDED / AGGREGATION_MODE_DISABLED)
+        db.execSQL("UPDATE " + Tables.RAW_CONTACTS + " SET " +
+                RawContactsColumns.AGGREGATION_NEEDED + "=1" +
+                " WHERE " + RawContacts.CONTACT_ID + " IN " + Tables.DEFAULT_DIRECTORY +
+                " AND " + RawContacts.AGGREGATION_MODE + "=" + RawContacts.AGGREGATION_MODE_DEFAULT
+                );
+
+        final int count;
+        final Cursor cursor = db.rawQuery("SELECT " + RawContacts._ID +
+                " FROM " + Tables.RAW_CONTACTS +
+                " WHERE " + RawContactsColumns.AGGREGATION_NEEDED + "=1", null);
+        try {
+            count = cursor.getCount();
+            cursor.moveToPosition(-1);
+            while (cursor.moveToNext()) {
+                final long rawContactId = cursor.getLong(0);
+                mRawContactsMarkedForAggregation.put(rawContactId,
+                        RawContacts.AGGREGATION_MODE_DEFAULT);
+            }
+        } finally {
+            cursor.close();
+        }
+
+        final long end = System.currentTimeMillis();
+        Log.i(TAG, "Marked all visible contacts for aggregation: " + count + " raw contacts, " +
+                (end - start) + " ms");
+        return count;
+    }
+
+    /**
+     * Creates a new contact based on the given raw contact.  Does not perform aggregation.  Returns
+     * the ID of the contact that was created.
+     */
+    public long onRawContactInsert(
+            TransactionContext txContext, SQLiteDatabase db, long rawContactId) {
+        long contactId = insertContact(db, rawContactId);
+        setContactId(rawContactId, contactId);
+        mDbHelper.updateContactVisible(txContext, contactId);
+        return contactId;
+    }
+
+    protected long insertContact(SQLiteDatabase db, long rawContactId) {
+        mSelectionArgs1[0] = String.valueOf(rawContactId);
+        computeAggregateData(db, mRawContactsQueryByRawContactId, mSelectionArgs1, mContactInsert);
+        return mContactInsert.executeInsert();
+    }
+
+    private static final class RawContactIdAndAccountQuery {
+        public static final String TABLE = Tables.RAW_CONTACTS;
+
+        public static final String[] COLUMNS = {
+                RawContacts.CONTACT_ID,
+                RawContactsColumns.ACCOUNT_ID
+        };
+
+        public static final String SELECTION = RawContacts._ID + "=?";
+
+        public static final int CONTACT_ID = 0;
+        public static final int ACCOUNT_ID = 1;
+    }
+
+    public void aggregateContact(
+            TransactionContext txContext, SQLiteDatabase db, long rawContactId) {
+        if (!mEnabled) {
+            return;
+        }
+
+        MatchCandidateList candidates = new MatchCandidateList();
+        ContactMatcher matcher = new ContactMatcher();
+
+        long contactId = 0;
+        long accountId = 0;
+        mSelectionArgs1[0] = String.valueOf(rawContactId);
+        Cursor cursor = db.query(RawContactIdAndAccountQuery.TABLE,
+                RawContactIdAndAccountQuery.COLUMNS, RawContactIdAndAccountQuery.SELECTION,
+                mSelectionArgs1, null, null, null);
+        try {
+            if (cursor.moveToFirst()) {
+                contactId = cursor.getLong(RawContactIdAndAccountQuery.CONTACT_ID);
+                accountId = cursor.getLong(RawContactIdAndAccountQuery.ACCOUNT_ID);
+            }
+        } finally {
+            cursor.close();
+        }
+
+        aggregateContact(txContext, db, rawContactId, accountId, contactId,
+                candidates, matcher);
+    }
+
+    public void updateAggregateData(TransactionContext txContext, long contactId) {
+        if (!mEnabled) {
+            return;
+        }
+
+        final SQLiteDatabase db = mDbHelper.getWritableDatabase();
+        computeAggregateData(db, contactId, mContactUpdate);
+        mContactUpdate.bindLong(ContactReplaceSqlStatement.CONTACT_ID, contactId);
+        mContactUpdate.execute();
+
+        mDbHelper.updateContactVisible(txContext, contactId);
+        updateAggregatedStatusUpdate(contactId);
+    }
+
+    private void updateAggregatedStatusUpdate(long contactId) {
+        mAggregatedPresenceReplace.bindLong(1, contactId);
+        mAggregatedPresenceReplace.bindLong(2, contactId);
+        mAggregatedPresenceReplace.execute();
+        updateLastStatusUpdateId(contactId);
+    }
+
+    /**
+     * Adjusts the reference to the latest status update for the specified contact.
+     */
+    public void updateLastStatusUpdateId(long contactId) {
+        String contactIdString = String.valueOf(contactId);
+        mDbHelper.getWritableDatabase().execSQL(UPDATE_LAST_STATUS_UPDATE_ID_SQL,
+                new String[]{contactIdString, contactIdString});
+    }
+
+    /**
+     * Given a specific raw contact, finds all matching aggregate contacts and chooses the one
+     * with the highest match score.  If no such contact is found, creates a new contact.
+     */
+    private synchronized void aggregateContact(TransactionContext txContext, SQLiteDatabase db,
+            long rawContactId, long accountId, long currentContactId, MatchCandidateList candidates,
+            ContactMatcher matcher) {
+
+        if (VERBOSE_LOGGING) {
+            Log.v(TAG, "aggregateContact: rid=" + rawContactId + " cid=" + currentContactId);
+        }
+
+        int aggregationMode = RawContacts.AGGREGATION_MODE_DEFAULT;
+
+        Integer aggModeObject = mRawContactsMarkedForAggregation.remove(rawContactId);
+        if (aggModeObject != null) {
+            aggregationMode = aggModeObject;
+        }
+
+        long contactId = -1; // Best matching contact ID.
+        boolean needReaggregate = false;
+
+        final Set<Long> rawContactIdsInSameAccount = new HashSet<Long>();
+        final Set<Long> rawContactIdsInOtherAccount = new HashSet<Long>();
+        if (aggregationMode == RawContacts.AGGREGATION_MODE_DEFAULT) {
+            candidates.clear();
+            matcher.clear();
+
+            contactId = pickBestMatchBasedOnExceptions(db, rawContactId, matcher);
+            if (contactId == -1) {
+
+                // If this is a newly inserted contact or a visible contact, look for
+                // data matches.
+                if (currentContactId == 0
+                        || mDbHelper.isContactInDefaultDirectory(db, currentContactId)) {
+                    contactId = pickBestMatchBasedOnData(db, rawContactId, candidates, matcher);
+                }
+
+                // If we found an best matched contact, find out if the raw contact can be joined
+                // into it
+                if (contactId != -1 && contactId != currentContactId) {
+                    // List all raw contact ID and their account ID mappings in contact
+                    // [contactId] excluding raw_contact [rawContactId].
+
+                    // Based on the mapping, create two sets of raw contact IDs in
+                    // [rawContactAccountId] and not in [rawContactAccountId]. We don't always
+                    // need them, so lazily initialize them.
+                    mSelectionArgs2[0] = String.valueOf(contactId);
+                    mSelectionArgs2[1] = String.valueOf(rawContactId);
+                    final Cursor rawContactsToAccountsCursor = db.rawQuery(
+                            "SELECT " + RawContacts._ID + ", " + RawContactsColumns.ACCOUNT_ID +
+                                    " FROM " + Tables.RAW_CONTACTS +
+                                    " WHERE " + RawContacts.CONTACT_ID + "=?" +
+                                    " AND " + RawContacts._ID + "!=?",
+                            mSelectionArgs2);
+                    try {
+                        rawContactsToAccountsCursor.moveToPosition(-1);
+                        while (rawContactsToAccountsCursor.moveToNext()) {
+                            final long rcId = rawContactsToAccountsCursor.getLong(0);
+                            final long rc_accountId = rawContactsToAccountsCursor.getLong(1);
+                            if (rc_accountId == accountId) {
+                                rawContactIdsInSameAccount.add(rcId);
+                            } else {
+                                rawContactIdsInOtherAccount.add(rcId);
+                            }
+                        }
+                    } finally {
+                        rawContactsToAccountsCursor.close();
+                    }
+                    final int actionCode;
+                    final int totalNumOfRawContactsInCandidate = rawContactIdsInSameAccount.size()
+                            + rawContactIdsInOtherAccount.size();
+                    if (totalNumOfRawContactsInCandidate >= AGGREGATION_CONTACT_SIZE_LIMIT) {
+                        if (VERBOSE_LOGGING) {
+                            Log.v(TAG, "Too many raw contacts (" + totalNumOfRawContactsInCandidate
+                                    + ") in the best matching contact, so skip aggregation");
+                        }
+                        actionCode = KEEP_SEPARATE;
+                    } else {
+                        actionCode = canJoinIntoContact(db, rawContactId,
+                                rawContactIdsInSameAccount, rawContactIdsInOtherAccount);
+                    }
+                    if (actionCode == KEEP_SEPARATE) {
+                        contactId = -1;
+                    } else if (actionCode == RE_AGGREGATE) {
+                        needReaggregate = true;
+                    }
+                }
+            }
+        } else if (aggregationMode == RawContacts.AGGREGATION_MODE_DISABLED) {
+            return;
+        }
+
+        // # of raw_contacts in the [currentContactId] contact excluding the [rawContactId]
+        // raw_contact.
+        long currentContactContentsCount = 0;
+
+        if (currentContactId != 0) {
+            mRawContactCountQuery.bindLong(1, currentContactId);
+            mRawContactCountQuery.bindLong(2, rawContactId);
+            currentContactContentsCount = mRawContactCountQuery.simpleQueryForLong();
+        }
+
+        // If there are no other raw contacts in the current aggregate, we might as well reuse it.
+        // Also, if the aggregation mode is SUSPENDED, we must reuse the same aggregate.
+        if (contactId == -1
+                && currentContactId != 0
+                && (currentContactContentsCount == 0
+                        || aggregationMode == RawContacts.AGGREGATION_MODE_SUSPENDED)) {
+            contactId = currentContactId;
+        }
+
+        if (contactId == currentContactId) {
+            // Aggregation unchanged
+            markAggregated(rawContactId);
+            if (VERBOSE_LOGGING) {
+                Log.v(TAG, "Aggregation unchanged");
+            }
+        } else if (contactId == -1) {
+            // create new contact for [rawContactId]
+            createContactForRawContacts(db, txContext, Sets.newHashSet(rawContactId), null);
+            if (currentContactContentsCount > 0) {
+                updateAggregateData(txContext, currentContactId);
+            }
+            if (VERBOSE_LOGGING) {
+                Log.v(TAG, "create new contact for rid=" + rawContactId);
+            }
+        } else if (needReaggregate) {
+            // re-aggregate
+            final Set<Long> allRawContactIdSet = new HashSet<Long>();
+            allRawContactIdSet.addAll(rawContactIdsInSameAccount);
+            allRawContactIdSet.addAll(rawContactIdsInOtherAccount);
+            // If there is no other raw contacts aggregated with the given raw contact currently,
+            // we might as well reuse it.
+            currentContactId = (currentContactId != 0 && currentContactContentsCount == 0)
+                    ? currentContactId : 0;
+            reAggregateRawContacts(txContext, db, contactId, currentContactId, rawContactId,
+                    allRawContactIdSet);
+            if (VERBOSE_LOGGING) {
+                Log.v(TAG, "Re-aggregating rid=" + rawContactId + " and cid=" + contactId);
+            }
+        } else {
+            // Joining with an existing aggregate
+            if (currentContactContentsCount == 0) {
+                // Delete a previous aggregate if it only contained this raw contact
+                ContactsTableUtil.deleteContact(db, currentContactId);
+
+                mAggregatedPresenceDelete.bindLong(1, currentContactId);
+                mAggregatedPresenceDelete.execute();
+            }
+
+            clearSuperPrimarySetting(db, contactId, rawContactId);
+            setContactIdAndMarkAggregated(rawContactId, contactId);
+            computeAggregateData(db, contactId, mContactUpdate);
+            mContactUpdate.bindLong(ContactReplaceSqlStatement.CONTACT_ID, contactId);
+            mContactUpdate.execute();
+            mDbHelper.updateContactVisible(txContext, contactId);
+            updateAggregatedStatusUpdate(contactId);
+            // Make sure the raw contact does not contribute to the current contact
+            if (currentContactId != 0) {
+                updateAggregateData(txContext, currentContactId);
+            }
+            if (VERBOSE_LOGGING) {
+                Log.v(TAG, "Join rid=" + rawContactId + " with cid=" + contactId);
+            }
+        }
+    }
+
+    /**
+     * Find out which mime-types are shared by raw contact of {@code rawContactId} and raw contacts
+     * of {@code contactId}. Clear the is_super_primary settings for these mime-types.
+     */
+    private void clearSuperPrimarySetting(SQLiteDatabase db, long contactId, long rawContactId) {
+        final String[] args = {String.valueOf(contactId), String.valueOf(rawContactId)};
+
+        // Find out which mime-types exist with is_super_primary=true on both the raw contact of
+        // rawContactId and raw contacts of contactId
+        int index = 0;
+        final StringBuilder mimeTypeCondition = new StringBuilder();
+        mimeTypeCondition.append(" AND " + DataColumns.MIMETYPE_ID + " IN (");
+
+        final Cursor c = db.rawQuery(
+                "SELECT DISTINCT(a." + DataColumns.MIMETYPE_ID + ")" +
+                " FROM (SELECT " + DataColumns.MIMETYPE_ID + " FROM " + Tables.DATA + " WHERE " +
+                        Data.IS_SUPER_PRIMARY + " =1 AND " +
+                        Data.RAW_CONTACT_ID + " IN (SELECT " + RawContacts._ID + " FROM " +
+                        Tables.RAW_CONTACTS + " WHERE " + RawContacts.CONTACT_ID + "=?1)) AS a" +
+                " JOIN  (SELECT " + DataColumns.MIMETYPE_ID + " FROM " + Tables.DATA + " WHERE " +
+                        Data.IS_SUPER_PRIMARY + " =1 AND " +
+                        Data.RAW_CONTACT_ID + "=?2) AS b" +
+                " ON a." + DataColumns.MIMETYPE_ID + "=b." + DataColumns.MIMETYPE_ID,
+                args);
+        try {
+            c.moveToPosition(-1);
+            while (c.moveToNext()) {
+                if (index > 0) {
+                    mimeTypeCondition.append(',');
+                }
+                mimeTypeCondition.append(c.getLong((0)));
+                index++;
+            }
+        } finally {
+            c.close();
+        }
+
+        if (index == 0) {
+            return;
+        }
+
+        // Clear is_super_primary setting for all the mime-types with is_super_primary=true
+        // in both raw contact of rawContactId and raw contacts of contactId
+        String superPrimaryUpdateSql = "UPDATE " + Tables.DATA +
+                " SET " + Data.IS_SUPER_PRIMARY + "=0" +
+                " WHERE (" +  Data.RAW_CONTACT_ID +
+                        " IN (SELECT " + RawContacts._ID +  " FROM " + Tables.RAW_CONTACTS +
+                        " WHERE " + RawContacts.CONTACT_ID + "=?1)" +
+                        " OR " +  Data.RAW_CONTACT_ID + "=?2)";
+
+        mimeTypeCondition.append(')');
+        superPrimaryUpdateSql += mimeTypeCondition.toString();
+        db.execSQL(superPrimaryUpdateSql, args);
+    }
+
+    /**
+     * @return JOIN if the raw contact of {@code rawContactId} can be joined into the existing
+     * contact of {@code contactId}. KEEP_SEPARATE if the raw contact of {@code rawContactId}
+     * cannot be joined into the existing contact of {@code contactId}. RE_AGGREGATE if raw contact
+     * of {@code rawContactId} and all the raw contacts of contact of {@code contactId} need to be
+     * re-aggregated.
+     *
+     * If contact of {@code contactId} doesn't contain any raw contacts from the same account as
+     * raw contact of {@code rawContactId}, join raw contact with contact if there is no identity
+     * mismatch between them on the same namespace, otherwise, keep them separate.
+     *
+     * If contact of {@code contactId} contains raw contacts from the same account as raw contact of
+     * {@code rawContactId}, join raw contact with contact if there's at least one raw contact in
+     * those raw contacts that shares at least one email address, phone number, or identity;
+     * otherwise, re-aggregate raw contact and all the raw contacts of contact.
+     */
+    private int canJoinIntoContact(SQLiteDatabase db, long rawContactId,
+            Set<Long> rawContactIdsInSameAccount, Set<Long> rawContactIdsInOtherAccount ) {
+
+        if (rawContactIdsInSameAccount.isEmpty()) {
+            final String rid = String.valueOf(rawContactId);
+            final String ridsInOtherAccts = TextUtils.join(",", rawContactIdsInOtherAccount);
+            // If there is no identity match between raw contact of [rawContactId] and
+            // any raw contact in other accounts on the same namespace, and there is at least
+            // one identity mismatch exist, keep raw contact separate from contact.
+            if (DatabaseUtils.longForQuery(db, buildIdentityMatchingSql(rid, ridsInOtherAccts,
+                    /* isIdentityMatching =*/ true, /* countOnly =*/ true), null) == 0 &&
+                    DatabaseUtils.longForQuery(db, buildIdentityMatchingSql(rid, ridsInOtherAccts,
+                            /* isIdentityMatching =*/ false, /* countOnly =*/ true), null) > 0) {
+                if (VERBOSE_LOGGING) {
+                    Log.v(TAG, "canJoinIntoContact: no duplicates, but has no matching identity " +
+                            "and has mis-matching identity on the same namespace between rid=" +
+                            rid + " and ridsInOtherAccts=" + ridsInOtherAccts);
+                }
+                return KEEP_SEPARATE; // has identity and identity doesn't match
+            } else {
+                if (VERBOSE_LOGGING) {
+                    Log.v(TAG, "canJoinIntoContact: can join the first raw contact from the same " +
+                            "account without any identity mismatch.");
+                }
+                return JOIN; // no identity or identity match
+            }
+        }
+        if (VERBOSE_LOGGING) {
+            Log.v(TAG, "canJoinIntoContact: " + rawContactIdsInSameAccount.size() +
+                    " duplicate(s) found");
+        }
+
+
+        final Set<Long> rawContactIdSet = new HashSet<Long>();
+        rawContactIdSet.add(rawContactId);
+        if (rawContactIdsInSameAccount.size() > 0 &&
+                isDataMaching(db, rawContactIdSet, rawContactIdsInSameAccount)) {
+            if (VERBOSE_LOGGING) {
+                Log.v(TAG, "canJoinIntoContact: join if there is a data matching found in the " +
+                        "same account");
+            }
+            return JOIN;
+        } else {
+            if (VERBOSE_LOGGING) {
+                Log.v(TAG, "canJoinIntoContact: re-aggregate rid=" + rawContactId +
+                        " with its best matching contact to connected component");
+            }
+            return RE_AGGREGATE;
+        }
+    }
+
+    private interface RawContactMatchingSelectionStatement {
+        String SELECT_COUNT =  "SELECT count(*) " ;
+        String SELECT_ID = "SELECT d1." + Data.RAW_CONTACT_ID + ",d2."  + Data.RAW_CONTACT_ID ;
+    }
+
+    /**
+     * Build sql to check if there is any identity match/mis-match between two sets of raw contact
+     * ids on the same namespace.
+     */
+    private String buildIdentityMatchingSql(String rawContactIdSet1, String rawContactIdSet2,
+            boolean isIdentityMatching, boolean countOnly) {
+        final String identityType = String.valueOf(mMimeTypeIdIdentity);
+        final String matchingOperator = (isIdentityMatching) ? "=" : "!=";
+        final String sql =
+                " FROM " + Tables.DATA + " AS d1" +
+                " JOIN " + Tables.DATA + " AS d2" +
+                        " ON (d1." + Identity.IDENTITY + matchingOperator +
+                        " d2." + Identity.IDENTITY + " AND" +
+                        " d1." + Identity.NAMESPACE + " = d2." + Identity.NAMESPACE + " )" +
+                " WHERE d1." + DataColumns.MIMETYPE_ID + " = " + identityType +
+                " AND d2." + DataColumns.MIMETYPE_ID + " = " + identityType +
+                " AND d1." + Data.RAW_CONTACT_ID + " IN (" + rawContactIdSet1 + ")" +
+                " AND d2." + Data.RAW_CONTACT_ID + " IN (" + rawContactIdSet2 + ")";
+        return (countOnly) ? RawContactMatchingSelectionStatement.SELECT_COUNT + sql :
+                RawContactMatchingSelectionStatement.SELECT_ID + sql;
+    }
+
+    private String buildEmailMatchingSql(String rawContactIdSet1, String rawContactIdSet2,
+            boolean countOnly) {
+        final String emailType = String.valueOf(mMimeTypeIdEmail);
+        final String sql =
+                " FROM " + Tables.DATA + " AS d1" +
+                " JOIN " + Tables.DATA + " AS d2" +
+                        " ON lower(d1." + Email.ADDRESS + ")= lower(d2." + Email.ADDRESS + ")" +
+                " WHERE d1." + DataColumns.MIMETYPE_ID + " = " + emailType +
+                " AND d2." + DataColumns.MIMETYPE_ID + " = " + emailType +
+                " AND d1." + Data.RAW_CONTACT_ID + " IN (" + rawContactIdSet1 + ")" +
+                " AND d2." + Data.RAW_CONTACT_ID + " IN (" + rawContactIdSet2 + ")";
+        return (countOnly) ? RawContactMatchingSelectionStatement.SELECT_COUNT + sql :
+                RawContactMatchingSelectionStatement.SELECT_ID + sql;
+    }
+
+    private String buildPhoneMatchingSql(String rawContactIdSet1, String rawContactIdSet2,
+            boolean countOnly) {
+        // It's a bit tricker because it has to be consistent with
+        // updateMatchScoresBasedOnPhoneMatches().
+        final String phoneType = String.valueOf(mMimeTypeIdPhone);
+        final String sql =
+                " FROM " + Tables.PHONE_LOOKUP + " AS p1" +
+                " JOIN " + Tables.DATA + " AS d1 ON " +
+                        "(d1." + Data._ID + "=p1." + PhoneLookupColumns.DATA_ID + ")" +
+                " JOIN " + Tables.PHONE_LOOKUP + " AS p2 ON (p1." + PhoneLookupColumns.MIN_MATCH +
+                        "=p2." + PhoneLookupColumns.MIN_MATCH + ")" +
+                " JOIN " + Tables.DATA + " AS d2 ON " +
+                        "(d2." + Data._ID + "=p2." + PhoneLookupColumns.DATA_ID + ")" +
+                " WHERE d1." + DataColumns.MIMETYPE_ID + " = " + phoneType +
+                " AND d2." + DataColumns.MIMETYPE_ID + " = " + phoneType +
+                " AND d1." + Data.RAW_CONTACT_ID + " IN (" + rawContactIdSet1 + ")" +
+                " AND d2." + Data.RAW_CONTACT_ID + " IN (" + rawContactIdSet2 + ")" +
+                " AND PHONE_NUMBERS_EQUAL(d1." + Phone.NUMBER + ",d2." + Phone.NUMBER + "," +
+                        String.valueOf(mDbHelper.getUseStrictPhoneNumberComparisonParameter()) +
+                        ")";
+        return (countOnly) ? RawContactMatchingSelectionStatement.SELECT_COUNT + sql :
+                RawContactMatchingSelectionStatement.SELECT_ID + sql;
+    }
+
+    private String buildExceptionMatchingSql(String rawContactIdSet1, String rawContactIdSet2) {
+        return "SELECT " + AggregationExceptions.RAW_CONTACT_ID1 + ", " +
+                AggregationExceptions.RAW_CONTACT_ID2 +
+                " FROM " + Tables.AGGREGATION_EXCEPTIONS +
+                " WHERE " + AggregationExceptions.RAW_CONTACT_ID1 + " IN (" +
+                        rawContactIdSet1 + ")" +
+                " AND " + AggregationExceptions.RAW_CONTACT_ID2 + " IN (" + rawContactIdSet2 + ")" +
+                " AND " + AggregationExceptions.TYPE + "=" +
+                        AggregationExceptions.TYPE_KEEP_TOGETHER ;
+    }
+
+    private boolean isFirstColumnGreaterThanZero(SQLiteDatabase db, String query) {
+        return DatabaseUtils.longForQuery(db, query, null) > 0;
+    }
+
+    /**
+     * If there's any identity, email address or a phone number matching between two raw contact
+     * sets.
+     */
+    private boolean isDataMaching(SQLiteDatabase db, Set<Long> rawContactIdSet1,
+            Set<Long> rawContactIdSet2) {
+        final String rawContactIds1 = TextUtils.join(",", rawContactIdSet1);
+        final String rawContactIds2 = TextUtils.join(",", rawContactIdSet2);
+        // First, check for the identity
+        if (isFirstColumnGreaterThanZero(db, buildIdentityMatchingSql(
+                rawContactIds1, rawContactIds2,  /* isIdentityMatching =*/ true,
+                /* countOnly =*/true))) {
+            if (VERBOSE_LOGGING) {
+                Log.v(TAG, "canJoinIntoContact: identity match found between " + rawContactIds1 +
+                        " and " + rawContactIds2);
+            }
+            return true;
+        }
+
+        // Next, check for the email address.
+        if (isFirstColumnGreaterThanZero(db,
+                buildEmailMatchingSql(rawContactIds1, rawContactIds2, true))) {
+            if (VERBOSE_LOGGING) {
+                Log.v(TAG, "canJoinIntoContact: email match found between " + rawContactIds1 +
+                        " and " + rawContactIds2);
+            }
+            return true;
+        }
+
+        // Lastly, the phone number.
+        if (isFirstColumnGreaterThanZero(db,
+                buildPhoneMatchingSql(rawContactIds1, rawContactIds2, true))) {
+            if (VERBOSE_LOGGING) {
+                Log.v(TAG, "canJoinIntoContact: phone match found between " + rawContactIds1 +
+                        " and " + rawContactIds2);
+            }
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Re-aggregate rawContact of {@code rawContactId} and all the raw contacts of
+     * {@code existingRawContactIds} into connected components. This only happens when a given
+     * raw contacts cannot be joined with its best matching contacts directly.
+     *
+     *  Two raw contacts are considered connected if they share at least one email address, phone
+     *  number or identity. Create new contact for each connected component except the very first
+     *  one that doesn't contain rawContactId of {@code rawContactId}.
+     */
+    private void reAggregateRawContacts(TransactionContext txContext, SQLiteDatabase db,
+            long contactId, long currentContactId, long rawContactId,
+            Set<Long> existingRawContactIds) {
+        // Find the connected component based on the aggregation exceptions or
+        // identity/email/phone matching for all the raw contacts of [contactId] and the give
+        // raw contact.
+        final Set<Long> allIds = new HashSet<Long>();
+        allIds.add(rawContactId);
+        allIds.addAll(existingRawContactIds);
+        final Set<Set<Long>> connectedRawContactSets = findConnectedRawContacts(db, allIds);
+
+        if (connectedRawContactSets.size() == 1) {
+            // If everything is connected, create one contact with [contactId]
+            createContactForRawContacts(db, txContext, connectedRawContactSets.iterator().next(),
+                    contactId);
+        } else {
+            for (Set<Long> connectedRawContactIds : connectedRawContactSets) {
+                if (connectedRawContactIds.contains(rawContactId)) {
+                    // crate contact for connect component containing [rawContactId], reuse
+                    // [currentContactId] if possible.
+                    createContactForRawContacts(db, txContext, connectedRawContactIds,
+                            currentContactId == 0 ? null : currentContactId);
+                    connectedRawContactSets.remove(connectedRawContactIds);
+                    break;
+                }
+            }
+            // Create new contact for each connected component except the last one. The last one
+            // will reuse [contactId]. Only the last one can reuse [contactId] when all other raw
+            // contacts has already been assigned new contact Id, so that the contact aggregation
+            // stats could be updated correctly.
+            int index = connectedRawContactSets.size();
+            for (Set<Long> connectedRawContactIds : connectedRawContactSets) {
+                if (index > 1) {
+                    createContactForRawContacts(db, txContext, connectedRawContactIds, null);
+                    index--;
+                } else {
+                    createContactForRawContacts(db, txContext, connectedRawContactIds, contactId);
+                }
+            }
+        }
+    }
+
+    /**
+     * Partition the given raw contact Ids to connected component based on aggregation exception,
+     * identity matching, email matching or phone matching.
+     */
+    private Set<Set<Long>> findConnectedRawContacts(SQLiteDatabase db, Set<Long> rawContactIdSet) {
+        // Connections between two raw contacts
+       final Multimap<Long, Long> matchingRawIdPairs = HashMultimap.create();
+        String rawContactIds = TextUtils.join(",", rawContactIdSet);
+        findIdPairs(db, buildExceptionMatchingSql(rawContactIds, rawContactIds),
+                matchingRawIdPairs);
+        findIdPairs(db, buildIdentityMatchingSql(rawContactIds, rawContactIds,
+                /* isIdentityMatching =*/ true, /* countOnly =*/false), matchingRawIdPairs);
+        findIdPairs(db, buildEmailMatchingSql(rawContactIds, rawContactIds, /* countOnly =*/false),
+                matchingRawIdPairs);
+        findIdPairs(db, buildPhoneMatchingSql(rawContactIds, rawContactIds,  /* countOnly =*/false),
+                matchingRawIdPairs);
+
+        return ContactAggregatorHelper.findConnectedComponents(rawContactIdSet, matchingRawIdPairs);
+    }
+
+    /**
+     * Given a query which will return two non-null IDs in the first two columns as results, this
+     * method will put two entries into the given result map for each pair of different IDs, one
+     * keyed by each ID.
+     */
+    private void findIdPairs(SQLiteDatabase db, String query, Multimap<Long, Long> results) {
+        Cursor cursor = db.rawQuery(query, null);
+        try {
+            cursor.moveToPosition(-1);
+            while (cursor.moveToNext()) {
+                long idA = cursor.getLong(0);
+                long idB = cursor.getLong(1);
+                if (idA != idB) {
+                    results.put(idA, idB);
+                    results.put(idB, idA);
+                }
+            }
+        } finally {
+            cursor.close();
+        }
+    }
+
+    /**
+     * Creates a new Contact for a given set of the raw contacts of {@code rawContactIds} if the
+     * given contactId is null. Otherwise, regroup them into contact with {@code contactId}.
+     */
+    private void createContactForRawContacts(SQLiteDatabase db, TransactionContext txContext,
+            Set<Long> rawContactIds, Long contactId) {
+        if (rawContactIds.isEmpty()) {
+            // No raw contact id is provided.
+            return;
+        }
+
+        // If contactId is not provided, generates a new one.
+        if (contactId == null) {
+            mSelectionArgs1[0]= String.valueOf(rawContactIds.iterator().next());
+            computeAggregateData(db, mRawContactsQueryByRawContactId, mSelectionArgs1,
+                    mContactInsert);
+            contactId = mContactInsert.executeInsert();
+        }
+        for (Long rawContactId : rawContactIds) {
+            // Regrouped contacts should automatically be unpinned.
+            unpinRawContact(rawContactId);
+            setContactIdAndMarkAggregated(rawContactId, contactId);
+            setPresenceContactId(rawContactId, contactId);
+        }
+        updateAggregateData(txContext, contactId);
+    }
+
+    private static class RawContactIdQuery {
+        public static final String TABLE = Tables.RAW_CONTACTS;
+        public static final String[] COLUMNS = { RawContacts._ID };
+        public static final String SELECTION = RawContacts.CONTACT_ID + "=?";
+        public static final int RAW_CONTACT_ID = 0;
+    }
+
+    /**
+     * Ensures that automatic aggregation rules are followed after a contact
+     * becomes visible or invisible. Specifically, consider this case: there are
+     * three contacts named Foo. Two of them come from account A1 and one comes
+     * from account A2. The aggregation rules say that in this case none of the
+     * three Foo's should be aggregated: two of them are in the same account, so
+     * they don't get aggregated; the third has two affinities, so it does not
+     * join either of them.
+     * <p>
+     * Consider what happens if one of the "Foo"s from account A1 becomes
+     * invisible. Nothing stands in the way of aggregating the other two
+     * anymore, so they should get joined.
+     * <p>
+     * What if the invisible "Foo" becomes visible after that? We should split the
+     * aggregate between the other two.
+     */
+    public void updateAggregationAfterVisibilityChange(long contactId) {
+        SQLiteDatabase db = mDbHelper.getWritableDatabase();
+        boolean visible = mDbHelper.isContactInDefaultDirectory(db, contactId);
+        if (visible) {
+            markContactForAggregation(db, contactId);
+        } else {
+            // Find all contacts that _could be_ aggregated with this one and
+            // rerun aggregation for all of them
+            mSelectionArgs1[0] = String.valueOf(contactId);
+            Cursor cursor = db.query(RawContactIdQuery.TABLE, RawContactIdQuery.COLUMNS,
+                    RawContactIdQuery.SELECTION, mSelectionArgs1, null, null, null);
+            try {
+                while (cursor.moveToNext()) {
+                    long rawContactId = cursor.getLong(RawContactIdQuery.RAW_CONTACT_ID);
+                    mMatcher.clear();
+
+                    updateMatchScoresBasedOnIdentityMatch(db, rawContactId, mMatcher);
+                    updateMatchScoresBasedOnNameMatches(db, rawContactId, mMatcher);
+                    List<MatchScore> bestMatches =
+                            mMatcher.pickBestMatches(ContactMatcher.SCORE_THRESHOLD_PRIMARY);
+                    for (MatchScore matchScore : bestMatches) {
+                        markContactForAggregation(db, matchScore.getContactId());
+                    }
+
+                    mMatcher.clear();
+                    updateMatchScoresBasedOnEmailMatches(db, rawContactId, mMatcher);
+                    updateMatchScoresBasedOnPhoneMatches(db, rawContactId, mMatcher);
+                    bestMatches =
+                            mMatcher.pickBestMatches(ContactMatcher.SCORE_THRESHOLD_SECONDARY);
+                    for (MatchScore matchScore : bestMatches) {
+                        markContactForAggregation(db, matchScore.getContactId());
+                    }
+                }
+            } finally {
+                cursor.close();
+            }
+        }
+    }
+
+    /**
+     * Updates the contact ID for the specified contact.
+     */
+    protected void setContactId(long rawContactId, long contactId) {
+        mContactIdUpdate.bindLong(1, contactId);
+        mContactIdUpdate.bindLong(2, rawContactId);
+        mContactIdUpdate.execute();
+    }
+
+    /**
+     * Marks the specified raw contact ID as aggregated
+     */
+    private void markAggregated(long rawContactId) {
+        mMarkAggregatedUpdate.bindLong(1, rawContactId);
+        mMarkAggregatedUpdate.execute();
+    }
+
+    /**
+     * Updates the contact ID for the specified contact and marks the raw contact as aggregated.
+     */
+    private void setContactIdAndMarkAggregated(long rawContactId, long contactId) {
+        mContactIdAndMarkAggregatedUpdate.bindLong(1, contactId);
+        mContactIdAndMarkAggregatedUpdate.bindLong(2, rawContactId);
+        mContactIdAndMarkAggregatedUpdate.execute();
+    }
+
+    private void setPresenceContactId(long rawContactId, long contactId) {
+        mPresenceContactIdUpdate.bindLong(1, contactId);
+        mPresenceContactIdUpdate.bindLong(2, rawContactId);
+        mPresenceContactIdUpdate.execute();
+    }
+
+    private void unpinRawContact(long rawContactId) {
+        mResetPinnedForRawContact.bindLong(1, rawContactId);
+        mResetPinnedForRawContact.execute();
+    }
+
+    interface AggregateExceptionPrefetchQuery {
+        String TABLE = Tables.AGGREGATION_EXCEPTIONS;
+
+        String[] COLUMNS = {
+            AggregationExceptions.RAW_CONTACT_ID1,
+            AggregationExceptions.RAW_CONTACT_ID2,
+        };
+
+        int RAW_CONTACT_ID1 = 0;
+        int RAW_CONTACT_ID2 = 1;
+    }
+
+    // A set of raw contact IDs for which there are aggregation exceptions
+    private final HashSet<Long> mAggregationExceptionIds = new HashSet<Long>();
+    private boolean mAggregationExceptionIdsValid;
+
+    public void invalidateAggregationExceptionCache() {
+        mAggregationExceptionIdsValid = false;
+    }
+
+    /**
+     * Finds all raw contact IDs for which there are aggregation exceptions. The list of
+     * ids is used as an optimization in aggregation: there is no point to run a query against
+     * the agg_exceptions table if it is known that there are no records there for a given
+     * raw contact ID.
+     */
+    private void prefetchAggregationExceptionIds(SQLiteDatabase db) {
+        mAggregationExceptionIds.clear();
+        final Cursor c = db.query(AggregateExceptionPrefetchQuery.TABLE,
+                AggregateExceptionPrefetchQuery.COLUMNS,
+                null, null, null, null, null);
+
+        try {
+            while (c.moveToNext()) {
+                long rawContactId1 = c.getLong(AggregateExceptionPrefetchQuery.RAW_CONTACT_ID1);
+                long rawContactId2 = c.getLong(AggregateExceptionPrefetchQuery.RAW_CONTACT_ID2);
+                mAggregationExceptionIds.add(rawContactId1);
+                mAggregationExceptionIds.add(rawContactId2);
+            }
+        } finally {
+            c.close();
+        }
+
+        mAggregationExceptionIdsValid = true;
+    }
+
+    interface AggregateExceptionQuery {
+        String TABLE = Tables.AGGREGATION_EXCEPTIONS
+            + " JOIN raw_contacts raw_contacts1 "
+                    + " ON (agg_exceptions.raw_contact_id1 = raw_contacts1._id) "
+            + " JOIN raw_contacts raw_contacts2 "
+                    + " ON (agg_exceptions.raw_contact_id2 = raw_contacts2._id) ";
+
+        String[] COLUMNS = {
+            AggregationExceptions.TYPE,
+            AggregationExceptions.RAW_CONTACT_ID1,
+            "raw_contacts1." + RawContacts.CONTACT_ID,
+            "raw_contacts1." + RawContactsColumns.AGGREGATION_NEEDED,
+            "raw_contacts2." + RawContacts.CONTACT_ID,
+            "raw_contacts2." + RawContactsColumns.AGGREGATION_NEEDED,
+        };
+
+        int TYPE = 0;
+        int RAW_CONTACT_ID1 = 1;
+        int CONTACT_ID1 = 2;
+        int AGGREGATION_NEEDED_1 = 3;
+        int CONTACT_ID2 = 4;
+        int AGGREGATION_NEEDED_2 = 5;
+    }
+
+    /**
+     * Computes match scores based on exceptions entered by the user: always match and never match.
+     * Returns the aggregate contact with the always match exception if any.
+     */
+    private long pickBestMatchBasedOnExceptions(SQLiteDatabase db, long rawContactId,
+            ContactMatcher matcher) {
+        if (!mAggregationExceptionIdsValid) {
+            prefetchAggregationExceptionIds(db);
+        }
+
+        // If there are no aggregation exceptions involving this raw contact, there is no need to
+        // run a query and we can just return -1, which stands for "nothing found"
+        if (!mAggregationExceptionIds.contains(rawContactId)) {
+            return -1;
+        }
+
+        final Cursor c = db.query(AggregateExceptionQuery.TABLE,
+                AggregateExceptionQuery.COLUMNS,
+                AggregationExceptions.RAW_CONTACT_ID1 + "=" + rawContactId
+                        + " OR " + AggregationExceptions.RAW_CONTACT_ID2 + "=" + rawContactId,
+                null, null, null, null);
+
+        try {
+            while (c.moveToNext()) {
+                int type = c.getInt(AggregateExceptionQuery.TYPE);
+                long rawContactId1 = c.getLong(AggregateExceptionQuery.RAW_CONTACT_ID1);
+                long contactId = -1;
+                if (rawContactId == rawContactId1) {
+                    if (c.getInt(AggregateExceptionQuery.AGGREGATION_NEEDED_2) == 0
+                            && !c.isNull(AggregateExceptionQuery.CONTACT_ID2)) {
+                        contactId = c.getLong(AggregateExceptionQuery.CONTACT_ID2);
+                    }
+                } else {
+                    if (c.getInt(AggregateExceptionQuery.AGGREGATION_NEEDED_1) == 0
+                            && !c.isNull(AggregateExceptionQuery.CONTACT_ID1)) {
+                        contactId = c.getLong(AggregateExceptionQuery.CONTACT_ID1);
+                    }
+                }
+                if (contactId != -1) {
+                    if (type == AggregationExceptions.TYPE_KEEP_TOGETHER) {
+                        matcher.keepIn(contactId);
+                    } else {
+                        matcher.keepOut(contactId);
+                    }
+                }
+            }
+        } finally {
+            c.close();
+        }
+
+        return matcher.pickBestMatch(ContactMatcher.MAX_SCORE, true);
+    }
+
+    /**
+     * Picks the best matching contact based on matches between data elements.  It considers
+     * name match to be primary and phone, email etc matches to be secondary.  A good primary
+     * match triggers aggregation, while a good secondary match only triggers aggregation in
+     * the absence of a strong primary mismatch.
+     * <p>
+     * Consider these examples:
+     * <p>
+     * John Doe with phone number 111-111-1111 and Jon Doe with phone number 111-111-1111 should
+     * be aggregated (same number, similar names).
+     * <p>
+     * John Doe with phone number 111-111-1111 and Deborah Doe with phone number 111-111-1111 should
+     * not be aggregated (same number, different names).
+     */
+    private long pickBestMatchBasedOnData(SQLiteDatabase db, long rawContactId,
+            MatchCandidateList candidates, ContactMatcher matcher) {
+
+        // Find good matches based on name alone
+        long bestMatch = updateMatchScoresBasedOnDataMatches(db, rawContactId, matcher);
+        if (bestMatch == ContactMatcher.MULTIPLE_MATCHES) {
+            // We found multiple matches on the name - do not aggregate because of the ambiguity
+            return -1;
+        } else if (bestMatch == -1) {
+            // We haven't found a good match on name, see if we have any matches on phone, email etc
+            bestMatch = pickBestMatchBasedOnSecondaryData(db, rawContactId, candidates, matcher);
+            if (bestMatch == ContactMatcher.MULTIPLE_MATCHES) {
+                return -1;
+            }
+        }
+
+        return bestMatch;
+    }
+
+
+    /**
+     * Picks the best matching contact based on secondary data matches.  The method loads
+     * structured names for all candidate contacts and recomputes match scores using approximate
+     * matching.
+     */
+    private long pickBestMatchBasedOnSecondaryData(SQLiteDatabase db,
+            long rawContactId, MatchCandidateList candidates, ContactMatcher matcher) {
+        List<Long> secondaryContactIds = matcher.prepareSecondaryMatchCandidates(
+                ContactMatcher.SCORE_THRESHOLD_PRIMARY);
+        if (secondaryContactIds == null || secondaryContactIds.size() > SECONDARY_HIT_LIMIT) {
+            return -1;
+        }
+
+        loadNameMatchCandidates(db, rawContactId, candidates, true);
+
+        mSb.setLength(0);
+        mSb.append(RawContacts.CONTACT_ID).append(" IN (");
+        for (int i = 0; i < secondaryContactIds.size(); i++) {
+            if (i != 0) {
+                mSb.append(',');
+            }
+            mSb.append(secondaryContactIds.get(i));
+        }
+
+        // We only want to compare structured names to structured names
+        // at this stage, we need to ignore all other sources of name lookup data.
+        mSb.append(") AND " + STRUCTURED_NAME_BASED_LOOKUP_SQL);
+
+        matchAllCandidates(db, mSb.toString(), candidates, matcher,
+                ContactMatcher.MATCHING_ALGORITHM_CONSERVATIVE, null);
+
+        return matcher.pickBestMatch(ContactMatcher.SCORE_THRESHOLD_SECONDARY, false);
+    }
+
+    private interface NameLookupQuery {
+        String TABLE = Tables.NAME_LOOKUP;
+
+        String SELECTION = NameLookupColumns.RAW_CONTACT_ID + "=?";
+        String SELECTION_STRUCTURED_NAME_BASED =
+                SELECTION + " AND " + STRUCTURED_NAME_BASED_LOOKUP_SQL;
+
+        String[] COLUMNS = new String[] {
+                NameLookupColumns.NORMALIZED_NAME,
+                NameLookupColumns.NAME_TYPE
+        };
+
+        int NORMALIZED_NAME = 0;
+        int NAME_TYPE = 1;
+    }
+
+    private void loadNameMatchCandidates(SQLiteDatabase db, long rawContactId,
+            MatchCandidateList candidates, boolean structuredNameBased) {
+        candidates.clear();
+        mSelectionArgs1[0] = String.valueOf(rawContactId);
+        Cursor c = db.query(NameLookupQuery.TABLE, NameLookupQuery.COLUMNS,
+                structuredNameBased
+                        ? NameLookupQuery.SELECTION_STRUCTURED_NAME_BASED
+                        : NameLookupQuery.SELECTION,
+                mSelectionArgs1, null, null, null);
+        try {
+            while (c.moveToNext()) {
+                String normalizedName = c.getString(NameLookupQuery.NORMALIZED_NAME);
+                int type = c.getInt(NameLookupQuery.NAME_TYPE);
+                candidates.add(normalizedName, type);
+            }
+        } finally {
+            c.close();
+        }
+    }
+
+    /**
+     * Computes scores for contacts that have matching data rows.
+     */
+    private long updateMatchScoresBasedOnDataMatches(SQLiteDatabase db, long rawContactId,
+            ContactMatcher matcher) {
+
+        updateMatchScoresBasedOnIdentityMatch(db, rawContactId, matcher);
+        updateMatchScoresBasedOnNameMatches(db, rawContactId, matcher);
+        long bestMatch = matcher.pickBestMatch(ContactMatcher.SCORE_THRESHOLD_PRIMARY, false);
+        if (bestMatch != -1) {
+            return bestMatch;
+        }
+
+        updateMatchScoresBasedOnEmailMatches(db, rawContactId, matcher);
+        updateMatchScoresBasedOnPhoneMatches(db, rawContactId, matcher);
+
+        return -1;
+    }
+
+    private interface IdentityLookupMatchQuery {
+        final String TABLE = Tables.DATA + " dataA"
+                + " JOIN " + Tables.DATA + " dataB" +
+                " ON (dataA." + Identity.NAMESPACE + "=dataB." + Identity.NAMESPACE +
+                " AND dataA." + Identity.IDENTITY + "=dataB." + Identity.IDENTITY + ")"
+                + " JOIN " + Tables.RAW_CONTACTS +
+                " ON (dataB." + Data.RAW_CONTACT_ID + " = "
+                + Tables.RAW_CONTACTS + "." + RawContacts._ID + ")";
+
+        final String SELECTION = "dataA." + Data.RAW_CONTACT_ID + "=?1"
+                + " AND dataA." + DataColumns.MIMETYPE_ID + "=?2"
+                + " AND dataA." + Identity.NAMESPACE + " NOT NULL"
+                + " AND dataA." + Identity.IDENTITY + " NOT NULL"
+                + " AND dataB." + DataColumns.MIMETYPE_ID + "=?2"
+                + " AND " + RawContactsColumns.AGGREGATION_NEEDED + "=0"
+                + " AND " + RawContacts.CONTACT_ID + " IN " + Tables.DEFAULT_DIRECTORY;
+
+        final String[] COLUMNS = new String[] {
+            RawContacts.CONTACT_ID
+        };
+
+        int CONTACT_ID = 0;
+    }
+
+    /**
+     * Finds contacts with exact identity matches to the the specified raw contact.
+     */
+    private void updateMatchScoresBasedOnIdentityMatch(SQLiteDatabase db, long rawContactId,
+            ContactMatcher matcher) {
+        mSelectionArgs2[0] = String.valueOf(rawContactId);
+        mSelectionArgs2[1] = String.valueOf(mMimeTypeIdIdentity);
+        Cursor c = db.query(IdentityLookupMatchQuery.TABLE, IdentityLookupMatchQuery.COLUMNS,
+                IdentityLookupMatchQuery.SELECTION,
+                mSelectionArgs2, RawContacts.CONTACT_ID, null, null);
+        try {
+            while (c.moveToNext()) {
+                final long contactId = c.getLong(IdentityLookupMatchQuery.CONTACT_ID);
+                matcher.matchIdentity(contactId);
+            }
+        } finally {
+            c.close();
+        }
+
+    }
+
+    private interface NameLookupMatchQuery {
+        String TABLE = Tables.NAME_LOOKUP + " nameA"
+                + " JOIN " + Tables.NAME_LOOKUP + " nameB" +
+                " ON (" + "nameA." + NameLookupColumns.NORMALIZED_NAME + "="
+                        + "nameB." + NameLookupColumns.NORMALIZED_NAME + ")"
+                + " JOIN " + Tables.RAW_CONTACTS +
+                " ON (nameB." + NameLookupColumns.RAW_CONTACT_ID + " = "
+                        + Tables.RAW_CONTACTS + "." + RawContacts._ID + ")";
+
+        String SELECTION = "nameA." + NameLookupColumns.RAW_CONTACT_ID + "=?"
+                + " AND " + RawContactsColumns.AGGREGATION_NEEDED + "=0"
+                + " AND " + RawContacts.CONTACT_ID + " IN " + Tables.DEFAULT_DIRECTORY;
+
+        String[] COLUMNS = new String[] {
+            RawContacts.CONTACT_ID,
+            "nameA." + NameLookupColumns.NORMALIZED_NAME,
+            "nameA." + NameLookupColumns.NAME_TYPE,
+            "nameB." + NameLookupColumns.NAME_TYPE,
+        };
+
+        int CONTACT_ID = 0;
+        int NAME = 1;
+        int NAME_TYPE_A = 2;
+        int NAME_TYPE_B = 3;
+    }
+
+    /**
+     * Finds contacts with names matching the name of the specified raw contact.
+     */
+    private void updateMatchScoresBasedOnNameMatches(SQLiteDatabase db, long rawContactId,
+            ContactMatcher matcher) {
+        mSelectionArgs1[0] = String.valueOf(rawContactId);
+        Cursor c = db.query(NameLookupMatchQuery.TABLE, NameLookupMatchQuery.COLUMNS,
+                NameLookupMatchQuery.SELECTION,
+                mSelectionArgs1, null, null, null, PRIMARY_HIT_LIMIT_STRING);
+        try {
+            while (c.moveToNext()) {
+                long contactId = c.getLong(NameLookupMatchQuery.CONTACT_ID);
+                String name = c.getString(NameLookupMatchQuery.NAME);
+                int nameTypeA = c.getInt(NameLookupMatchQuery.NAME_TYPE_A);
+                int nameTypeB = c.getInt(NameLookupMatchQuery.NAME_TYPE_B);
+                matcher.matchName(contactId, nameTypeA, name,
+                        nameTypeB, name, ContactMatcher.MATCHING_ALGORITHM_EXACT);
+                if (nameTypeA == NameLookupType.NICKNAME &&
+                        nameTypeB == NameLookupType.NICKNAME) {
+                    matcher.updateScoreWithNicknameMatch(contactId);
+                }
+            }
+        } finally {
+            c.close();
+        }
+    }
+
+    private interface NameLookupMatchQueryWithParameter {
+        String TABLE = Tables.NAME_LOOKUP
+                + " JOIN " + Tables.RAW_CONTACTS +
+                " ON (" + NameLookupColumns.RAW_CONTACT_ID + " = "
+                        + Tables.RAW_CONTACTS + "." + RawContacts._ID + ")";
+
+        String[] COLUMNS = new String[] {
+            RawContacts.CONTACT_ID,
+            NameLookupColumns.NORMALIZED_NAME,
+            NameLookupColumns.NAME_TYPE,
+        };
+
+        int CONTACT_ID = 0;
+        int NAME = 1;
+        int NAME_TYPE = 2;
+    }
+
+    private final class NameLookupSelectionBuilder extends NameLookupBuilder {
+
+        private final MatchCandidateList mNameLookupCandidates;
+
+        private StringBuilder mSelection = new StringBuilder(
+                NameLookupColumns.NORMALIZED_NAME + " IN(");
+
+
+        public NameLookupSelectionBuilder(NameSplitter splitter, MatchCandidateList candidates) {
+            super(splitter);
+            this.mNameLookupCandidates = candidates;
+        }
+
+        @Override
+        protected String[] getCommonNicknameClusters(String normalizedName) {
+            return mCommonNicknameCache.getCommonNicknameClusters(normalizedName);
+        }
+
+        @Override
+        protected void insertNameLookup(
+                long rawContactId, long dataId, int lookupType, String string) {
+            mNameLookupCandidates.add(string, lookupType);
+            DatabaseUtils.appendEscapedSQLString(mSelection, string);
+            mSelection.append(',');
+        }
+
+        public boolean isEmpty() {
+            return mNameLookupCandidates.isEmpty();
+        }
+
+        public String getSelection() {
+            mSelection.setLength(mSelection.length() - 1);      // Strip last comma
+            mSelection.append(')');
+            return mSelection.toString();
+        }
+
+        public int getLookupType(String name) {
+            for (int i = 0; i < mNameLookupCandidates.mCount; i++) {
+                if (mNameLookupCandidates.mList.get(i).mName.equals(name)) {
+                    return mNameLookupCandidates.mList.get(i).mLookupType;
+                }
+            }
+            throw new IllegalStateException();
+        }
+    }
+
+    /**
+     * Finds contacts with names matching the specified name.
+     */
+    private void updateMatchScoresBasedOnNameMatches(SQLiteDatabase db, String query,
+            MatchCandidateList candidates, ContactMatcher matcher) {
+        candidates.clear();
+        NameLookupSelectionBuilder builder = new NameLookupSelectionBuilder(
+                mNameSplitter, candidates);
+        builder.insertNameLookup(0, 0, query, FullNameStyle.UNDEFINED);
+        if (builder.isEmpty()) {
+            return;
+        }
+
+        Cursor c = db.query(NameLookupMatchQueryWithParameter.TABLE,
+                NameLookupMatchQueryWithParameter.COLUMNS, builder.getSelection(), null, null, null,
+                null, PRIMARY_HIT_LIMIT_STRING);
+        try {
+            while (c.moveToNext()) {
+                long contactId = c.getLong(NameLookupMatchQueryWithParameter.CONTACT_ID);
+                String name = c.getString(NameLookupMatchQueryWithParameter.NAME);
+                int nameTypeA = builder.getLookupType(name);
+                int nameTypeB = c.getInt(NameLookupMatchQueryWithParameter.NAME_TYPE);
+                matcher.matchName(contactId, nameTypeA, name, nameTypeB, name,
+                        ContactMatcher.MATCHING_ALGORITHM_EXACT);
+                if (nameTypeA == NameLookupType.NICKNAME && nameTypeB == NameLookupType.NICKNAME) {
+                    matcher.updateScoreWithNicknameMatch(contactId);
+                }
+            }
+        } finally {
+            c.close();
+        }
+    }
+
+    private interface EmailLookupQuery {
+        String TABLE = Tables.DATA + " dataA"
+                + " JOIN " + Tables.DATA + " dataB" +
+                " ON lower(" + "dataA." + Email.DATA + ")=lower(dataB." + Email.DATA + ")"
+                + " JOIN " + Tables.RAW_CONTACTS +
+                " ON (dataB." + Data.RAW_CONTACT_ID + " = "
+                        + Tables.RAW_CONTACTS + "." + RawContacts._ID + ")";
+
+        String SELECTION = "dataA." + Data.RAW_CONTACT_ID + "=?1"
+                + " AND dataA." + DataColumns.MIMETYPE_ID + "=?2"
+                + " AND dataA." + Email.DATA + " NOT NULL"
+                + " AND dataB." + DataColumns.MIMETYPE_ID + "=?2"
+                + " AND " + RawContactsColumns.AGGREGATION_NEEDED + "=0"
+                + " AND " + RawContacts.CONTACT_ID + " IN " + Tables.DEFAULT_DIRECTORY;
+
+        String[] COLUMNS = new String[] {
+            RawContacts.CONTACT_ID
+        };
+
+        int CONTACT_ID = 0;
+    }
+
+    private void updateMatchScoresBasedOnEmailMatches(SQLiteDatabase db, long rawContactId,
+            ContactMatcher matcher) {
+        mSelectionArgs2[0] = String.valueOf(rawContactId);
+        mSelectionArgs2[1] = String.valueOf(mMimeTypeIdEmail);
+        Cursor c = db.query(EmailLookupQuery.TABLE, EmailLookupQuery.COLUMNS,
+                EmailLookupQuery.SELECTION,
+                mSelectionArgs2, null, null, null, SECONDARY_HIT_LIMIT_STRING);
+        try {
+            while (c.moveToNext()) {
+                long contactId = c.getLong(EmailLookupQuery.CONTACT_ID);
+                matcher.updateScoreWithEmailMatch(contactId);
+            }
+        } finally {
+            c.close();
+        }
+    }
+
+    private interface PhoneLookupQuery {
+        String TABLE = Tables.PHONE_LOOKUP + " phoneA"
+                + " JOIN " + Tables.DATA + " dataA"
+                + " ON (dataA." + Data._ID + "=phoneA." + PhoneLookupColumns.DATA_ID + ")"
+                + " JOIN " + Tables.PHONE_LOOKUP + " phoneB"
+                + " ON (phoneA." + PhoneLookupColumns.MIN_MATCH + "="
+                        + "phoneB." + PhoneLookupColumns.MIN_MATCH + ")"
+                + " JOIN " + Tables.DATA + " dataB"
+                + " ON (dataB." + Data._ID + "=phoneB." + PhoneLookupColumns.DATA_ID + ")"
+                + " JOIN " + Tables.RAW_CONTACTS
+                + " ON (dataB." + Data.RAW_CONTACT_ID + " = "
+                        + Tables.RAW_CONTACTS + "." + RawContacts._ID + ")";
+
+        String SELECTION = "dataA." + Data.RAW_CONTACT_ID + "=?"
+                + " AND PHONE_NUMBERS_EQUAL(dataA." + Phone.NUMBER + ", "
+                        + "dataB." + Phone.NUMBER + ",?)"
+                + " AND " + RawContactsColumns.AGGREGATION_NEEDED + "=0"
+                + " AND " + RawContacts.CONTACT_ID + " IN " + Tables.DEFAULT_DIRECTORY;
+
+        String[] COLUMNS = new String[] {
+            RawContacts.CONTACT_ID
+        };
+
+        int CONTACT_ID = 0;
+    }
+
+    private void updateMatchScoresBasedOnPhoneMatches(SQLiteDatabase db, long rawContactId,
+            ContactMatcher matcher) {
+        mSelectionArgs2[0] = String.valueOf(rawContactId);
+        mSelectionArgs2[1] = mDbHelper.getUseStrictPhoneNumberComparisonParameter();
+        Cursor c = db.query(PhoneLookupQuery.TABLE, PhoneLookupQuery.COLUMNS,
+                PhoneLookupQuery.SELECTION,
+                mSelectionArgs2, null, null, null, SECONDARY_HIT_LIMIT_STRING);
+        try {
+            while (c.moveToNext()) {
+                long contactId = c.getLong(PhoneLookupQuery.CONTACT_ID);
+                matcher.updateScoreWithPhoneNumberMatch(contactId);
+            }
+        } finally {
+            c.close();
+        }
+    }
+
+    /**
+     * Loads name lookup rows for approximate name matching and updates match scores based on that
+     * data.
+     */
+    private void lookupApproximateNameMatches(SQLiteDatabase db, MatchCandidateList candidates,
+            ContactMatcher matcher) {
+        HashSet<String> firstLetters = new HashSet<String>();
+        for (int i = 0; i < candidates.mCount; i++) {
+            final NameMatchCandidate candidate = candidates.mList.get(i);
+            if (candidate.mName.length() >= 2) {
+                String firstLetter = candidate.mName.substring(0, 2);
+                if (!firstLetters.contains(firstLetter)) {
+                    firstLetters.add(firstLetter);
+                    final String selection = "(" + NameLookupColumns.NORMALIZED_NAME + " GLOB '"
+                            + firstLetter + "*') AND "
+                            + "(" + NameLookupColumns.NAME_TYPE + " IN("
+                                    + NameLookupType.NAME_COLLATION_KEY + ","
+                                    + NameLookupType.EMAIL_BASED_NICKNAME + ","
+                                    + NameLookupType.NICKNAME + ")) AND "
+                            + RawContacts.CONTACT_ID + " IN " + Tables.DEFAULT_DIRECTORY;
+                    matchAllCandidates(db, selection, candidates, matcher,
+                            ContactMatcher.MATCHING_ALGORITHM_APPROXIMATE,
+                            String.valueOf(FIRST_LETTER_SUGGESTION_HIT_LIMIT));
+                }
+            }
+        }
+    }
+
+    private interface ContactNameLookupQuery {
+        String TABLE = Tables.NAME_LOOKUP_JOIN_RAW_CONTACTS;
+
+        String[] COLUMNS = new String[] {
+                RawContacts.CONTACT_ID,
+                NameLookupColumns.NORMALIZED_NAME,
+                NameLookupColumns.NAME_TYPE
+        };
+
+        int CONTACT_ID = 0;
+        int NORMALIZED_NAME = 1;
+        int NAME_TYPE = 2;
+    }
+
+    /**
+     * Loads all candidate rows from the name lookup table and updates match scores based
+     * on that data.
+     */
+    private void matchAllCandidates(SQLiteDatabase db, String selection,
+            MatchCandidateList candidates, ContactMatcher matcher, int algorithm, String limit) {
+        final Cursor c = db.query(ContactNameLookupQuery.TABLE, ContactNameLookupQuery.COLUMNS,
+                selection, null, null, null, null, limit);
+
+        try {
+            while (c.moveToNext()) {
+                Long contactId = c.getLong(ContactNameLookupQuery.CONTACT_ID);
+                String name = c.getString(ContactNameLookupQuery.NORMALIZED_NAME);
+                int nameType = c.getInt(ContactNameLookupQuery.NAME_TYPE);
+
+                // Note the N^2 complexity of the following fragment. This is not a huge concern
+                // since the number of candidates is very small and in general secondary hits
+                // in the absence of primary hits are rare.
+                for (int i = 0; i < candidates.mCount; i++) {
+                    NameMatchCandidate candidate = candidates.mList.get(i);
+                    matcher.matchName(contactId, candidate.mLookupType, candidate.mName,
+                            nameType, name, algorithm);
+                }
+            }
+        } finally {
+            c.close();
+        }
+    }
+
+    private interface RawContactsQuery {
+        String SQL_FORMAT_HAS_SUPER_PRIMARY_NAME =
+                " EXISTS(SELECT 1 " +
+                        " FROM " + Tables.DATA + " d " +
+                        " WHERE d." + DataColumns.MIMETYPE_ID + "=%d " +
+                        " AND d." + Data.RAW_CONTACT_ID + "=" + RawContactsColumns.CONCRETE_ID +
+                        " AND d." + Data.IS_SUPER_PRIMARY + "=1)";
+
+        String SQL_FORMAT =
+                "SELECT "
+                        + RawContactsColumns.CONCRETE_ID + ","
+                        + RawContactsColumns.DISPLAY_NAME + ","
+                        + RawContactsColumns.DISPLAY_NAME_SOURCE + ","
+                        + AccountsColumns.CONCRETE_ACCOUNT_TYPE + ","
+                        + AccountsColumns.CONCRETE_ACCOUNT_NAME + ","
+                        + AccountsColumns.CONCRETE_DATA_SET + ","
+                        + RawContacts.SOURCE_ID + ","
+                        + RawContacts.CUSTOM_RINGTONE + ","
+                        + RawContacts.SEND_TO_VOICEMAIL + ","
+                        + RawContacts.LAST_TIME_CONTACTED + ","
+                        + RawContacts.TIMES_CONTACTED + ","
+                        + RawContacts.STARRED + ","
+                        + RawContacts.PINNED + ","
+                        + DataColumns.CONCRETE_ID + ","
+                        + DataColumns.CONCRETE_MIMETYPE_ID + ","
+                        + Data.IS_SUPER_PRIMARY + ","
+                        + Photo.PHOTO_FILE_ID + ","
+                        + SQL_FORMAT_HAS_SUPER_PRIMARY_NAME +
+                " FROM " + Tables.RAW_CONTACTS +
+                " JOIN " + Tables.ACCOUNTS + " ON ("
+                    + AccountsColumns.CONCRETE_ID + "=" + RawContactsColumns.CONCRETE_ACCOUNT_ID
+                    + ")" +
+                " LEFT OUTER JOIN " + Tables.DATA +
+                " ON (" + DataColumns.CONCRETE_RAW_CONTACT_ID + "=" + RawContactsColumns.CONCRETE_ID
+                        + " AND ((" + DataColumns.MIMETYPE_ID + "=%d"
+                                + " AND " + Photo.PHOTO + " NOT NULL)"
+                        + " OR (" + DataColumns.MIMETYPE_ID + "=%d"
+                                + " AND " + Phone.NUMBER + " NOT NULL)))";
+
+        String SQL_FORMAT_BY_RAW_CONTACT_ID = SQL_FORMAT +
+                " WHERE " + RawContactsColumns.CONCRETE_ID + "=?";
+
+        String SQL_FORMAT_BY_CONTACT_ID = SQL_FORMAT +
+                " WHERE " + RawContacts.CONTACT_ID + "=?"
+                + " AND " + RawContacts.DELETED + "=0";
+
+        int RAW_CONTACT_ID = 0;
+        int DISPLAY_NAME = 1;
+        int DISPLAY_NAME_SOURCE = 2;
+        int ACCOUNT_TYPE = 3;
+        int ACCOUNT_NAME = 4;
+        int DATA_SET = 5;
+        int SOURCE_ID = 6;
+        int CUSTOM_RINGTONE = 7;
+        int SEND_TO_VOICEMAIL = 8;
+        int LAST_TIME_CONTACTED = 9;
+        int TIMES_CONTACTED = 10;
+        int STARRED = 11;
+        int PINNED = 12;
+        int DATA_ID = 13;
+        int MIMETYPE_ID = 14;
+        int IS_SUPER_PRIMARY = 15;
+        int PHOTO_FILE_ID = 16;
+        int HAS_SUPER_PRIMARY_NAME = 17;
+    }
+
+    private interface ContactReplaceSqlStatement {
+        String UPDATE_SQL =
+                "UPDATE " + Tables.CONTACTS +
+                " SET "
+                        + Contacts.NAME_RAW_CONTACT_ID + "=?, "
+                        + Contacts.PHOTO_ID + "=?, "
+                        + Contacts.PHOTO_FILE_ID + "=?, "
+                        + Contacts.SEND_TO_VOICEMAIL + "=?, "
+                        + Contacts.CUSTOM_RINGTONE + "=?, "
+                        + Contacts.LAST_TIME_CONTACTED + "=?, "
+                        + Contacts.TIMES_CONTACTED + "=?, "
+                        + Contacts.STARRED + "=?, "
+                        + Contacts.PINNED + "=?, "
+                        + Contacts.HAS_PHONE_NUMBER + "=?, "
+                        + Contacts.LOOKUP_KEY + "=?, "
+                        + Contacts.CONTACT_LAST_UPDATED_TIMESTAMP + "=? " +
+                " WHERE " + Contacts._ID + "=?";
+
+        String INSERT_SQL =
+                "INSERT INTO " + Tables.CONTACTS + " ("
+                        + Contacts.NAME_RAW_CONTACT_ID + ", "
+                        + Contacts.PHOTO_ID + ", "
+                        + Contacts.PHOTO_FILE_ID + ", "
+                        + Contacts.SEND_TO_VOICEMAIL + ", "
+                        + Contacts.CUSTOM_RINGTONE + ", "
+                        + Contacts.LAST_TIME_CONTACTED + ", "
+                        + Contacts.TIMES_CONTACTED + ", "
+                        + Contacts.STARRED + ", "
+                        + Contacts.PINNED + ", "
+                        + Contacts.HAS_PHONE_NUMBER + ", "
+                        + Contacts.LOOKUP_KEY + ", "
+                        + Contacts.CONTACT_LAST_UPDATED_TIMESTAMP
+                        + ") " +
+                " VALUES (?,?,?,?,?,?,?,?,?,?,?,?)";
+
+        int NAME_RAW_CONTACT_ID = 1;
+        int PHOTO_ID = 2;
+        int PHOTO_FILE_ID = 3;
+        int SEND_TO_VOICEMAIL = 4;
+        int CUSTOM_RINGTONE = 5;
+        int LAST_TIME_CONTACTED = 6;
+        int TIMES_CONTACTED = 7;
+        int STARRED = 8;
+        int PINNED = 9;
+        int HAS_PHONE_NUMBER = 10;
+        int LOOKUP_KEY = 11;
+        int CONTACT_LAST_UPDATED_TIMESTAMP = 12;
+        int CONTACT_ID = 13;
+    }
+
+    /**
+     * Computes aggregate-level data for the specified aggregate contact ID.
+     */
+    private void computeAggregateData(SQLiteDatabase db, long contactId,
+            SQLiteStatement statement) {
+        mSelectionArgs1[0] = String.valueOf(contactId);
+        computeAggregateData(db, mRawContactsQueryByContactId, mSelectionArgs1, statement);
+    }
+
+    /**
+     * Indicates whether the given photo entry and priority gives this photo a higher overall
+     * priority than the current best photo entry and priority.
+     */
+    private boolean hasHigherPhotoPriority(PhotoEntry photoEntry, int priority,
+            PhotoEntry bestPhotoEntry, int bestPriority) {
+        int photoComparison = photoEntry.compareTo(bestPhotoEntry);
+        return photoComparison < 0 || photoComparison == 0 && priority > bestPriority;
+    }
+
+    /**
+     * Computes aggregate-level data from constituent raw contacts.
+     */
+    private void computeAggregateData(final SQLiteDatabase db, String sql, String[] sqlArgs,
+            SQLiteStatement statement) {
+        long currentRawContactId = -1;
+        long bestPhotoId = -1;
+        long bestPhotoFileId = 0;
+        PhotoEntry bestPhotoEntry = null;
+        boolean foundSuperPrimaryPhoto = false;
+        int photoPriority = -1;
+        int totalRowCount = 0;
+        int contactSendToVoicemail = 0;
+        String contactCustomRingtone = null;
+        long contactLastTimeContacted = 0;
+        int contactTimesContacted = 0;
+        int contactStarred = 0;
+        int contactPinned = Integer.MAX_VALUE;
+        int hasPhoneNumber = 0;
+        StringBuilder lookupKey = new StringBuilder();
+
+        mDisplayNameCandidate.clear();
+
+        Cursor c = db.rawQuery(sql, sqlArgs);
+        try {
+            while (c.moveToNext()) {
+                long rawContactId = c.getLong(RawContactsQuery.RAW_CONTACT_ID);
+                if (rawContactId != currentRawContactId) {
+                    currentRawContactId = rawContactId;
+                    totalRowCount++;
+
+                    // Assemble sub-account.
+                    String accountType = c.getString(RawContactsQuery.ACCOUNT_TYPE);
+                    String dataSet = c.getString(RawContactsQuery.DATA_SET);
+                    String accountWithDataSet = (!TextUtils.isEmpty(dataSet))
+                            ? accountType + "/" + dataSet
+                            : accountType;
+
+                    // Display name
+                    String displayName = c.getString(RawContactsQuery.DISPLAY_NAME);
+                    int displayNameSource = c.getInt(RawContactsQuery.DISPLAY_NAME_SOURCE);
+                    int isNameSuperPrimary = c.getInt(RawContactsQuery.HAS_SUPER_PRIMARY_NAME);
+                    processDisplayNameCandidate(rawContactId, displayName, displayNameSource,
+                            mContactsProvider.isWritableAccountWithDataSet(accountWithDataSet),
+                            isNameSuperPrimary != 0);
+
+                    // Contact options
+                    if (!c.isNull(RawContactsQuery.SEND_TO_VOICEMAIL)) {
+                        boolean sendToVoicemail =
+                                (c.getInt(RawContactsQuery.SEND_TO_VOICEMAIL) != 0);
+                        if (sendToVoicemail) {
+                            contactSendToVoicemail++;
+                        }
+                    }
+
+                    if (contactCustomRingtone == null
+                            && !c.isNull(RawContactsQuery.CUSTOM_RINGTONE)) {
+                        contactCustomRingtone = c.getString(RawContactsQuery.CUSTOM_RINGTONE);
+                    }
+
+                    long lastTimeContacted = c.getLong(RawContactsQuery.LAST_TIME_CONTACTED);
+                    if (lastTimeContacted > contactLastTimeContacted) {
+                        contactLastTimeContacted = lastTimeContacted;
+                    }
+
+                    int timesContacted = c.getInt(RawContactsQuery.TIMES_CONTACTED);
+                    if (timesContacted > contactTimesContacted) {
+                        contactTimesContacted = timesContacted;
+                    }
+
+                    if (c.getInt(RawContactsQuery.STARRED) != 0) {
+                        contactStarred = 1;
+                    }
+
+                    // contactPinned should be the lowest value of its constituent raw contacts,
+                    // excluding negative integers
+                    final int rawContactPinned = c.getInt(RawContactsQuery.PINNED);
+                    if (rawContactPinned > PinnedPositions.UNPINNED) {
+                        contactPinned = Math.min(contactPinned, rawContactPinned);
+                    }
+
+                    appendLookupKey(
+                            lookupKey,
+                            accountWithDataSet,
+                            c.getString(RawContactsQuery.ACCOUNT_NAME),
+                            rawContactId,
+                            c.getString(RawContactsQuery.SOURCE_ID),
+                            displayName);
+                }
+
+                if (!c.isNull(RawContactsQuery.DATA_ID)) {
+                    long dataId = c.getLong(RawContactsQuery.DATA_ID);
+                    long photoFileId = c.getLong(RawContactsQuery.PHOTO_FILE_ID);
+                    int mimetypeId = c.getInt(RawContactsQuery.MIMETYPE_ID);
+                    boolean superPrimary = c.getInt(RawContactsQuery.IS_SUPER_PRIMARY) != 0;
+                    if (mimetypeId == mMimeTypeIdPhoto) {
+                        if (!foundSuperPrimaryPhoto) {
+                            // Lookup the metadata for the photo, if available.  Note that data set
+                            // does not come into play here, since accounts are looked up in the
+                            // account manager in the priority resolver.
+                            PhotoEntry photoEntry = getPhotoMetadata(db, photoFileId);
+                            String accountType = c.getString(RawContactsQuery.ACCOUNT_TYPE);
+                            int priority = mPhotoPriorityResolver.getPhotoPriority(accountType);
+                            if (superPrimary || hasHigherPhotoPriority(
+                                    photoEntry, priority, bestPhotoEntry, photoPriority)) {
+                                bestPhotoEntry = photoEntry;
+                                photoPriority = priority;
+                                bestPhotoId = dataId;
+                                bestPhotoFileId = photoFileId;
+                                foundSuperPrimaryPhoto |= superPrimary;
+                            }
+                        }
+                    } else if (mimetypeId == mMimeTypeIdPhone) {
+                        hasPhoneNumber = 1;
+                    }
+                }
+            }
+        } finally {
+            c.close();
+        }
+
+        if (contactPinned == Integer.MAX_VALUE) {
+            contactPinned = PinnedPositions.UNPINNED;
+        }
+
+        statement.bindLong(ContactReplaceSqlStatement.NAME_RAW_CONTACT_ID,
+                mDisplayNameCandidate.rawContactId);
+
+        if (bestPhotoId != -1) {
+            statement.bindLong(ContactReplaceSqlStatement.PHOTO_ID, bestPhotoId);
+        } else {
+            statement.bindNull(ContactReplaceSqlStatement.PHOTO_ID);
+        }
+
+        if (bestPhotoFileId != 0) {
+            statement.bindLong(ContactReplaceSqlStatement.PHOTO_FILE_ID, bestPhotoFileId);
+        } else {
+            statement.bindNull(ContactReplaceSqlStatement.PHOTO_FILE_ID);
+        }
+
+        statement.bindLong(ContactReplaceSqlStatement.SEND_TO_VOICEMAIL,
+                totalRowCount == contactSendToVoicemail ? 1 : 0);
+        DatabaseUtils.bindObjectToProgram(statement, ContactReplaceSqlStatement.CUSTOM_RINGTONE,
+                contactCustomRingtone);
+        statement.bindLong(ContactReplaceSqlStatement.LAST_TIME_CONTACTED,
+                contactLastTimeContacted);
+        statement.bindLong(ContactReplaceSqlStatement.TIMES_CONTACTED,
+                contactTimesContacted);
+        statement.bindLong(ContactReplaceSqlStatement.STARRED,
+                contactStarred);
+        statement.bindLong(ContactReplaceSqlStatement.PINNED,
+                contactPinned);
+        statement.bindLong(ContactReplaceSqlStatement.HAS_PHONE_NUMBER,
+                hasPhoneNumber);
+        statement.bindString(ContactReplaceSqlStatement.LOOKUP_KEY,
+                Uri.encode(lookupKey.toString()));
+        statement.bindLong(ContactReplaceSqlStatement.CONTACT_LAST_UPDATED_TIMESTAMP,
+                Clock.getInstance().currentTimeMillis());
+    }
+
+    /**
+     * Builds a lookup key using the given data.
+     */
+    protected void appendLookupKey(StringBuilder sb, String accountTypeWithDataSet,
+            String accountName, long rawContactId, String sourceId, String displayName) {
+        ContactLookupKey.appendToLookupKey(sb, accountTypeWithDataSet, accountName, rawContactId,
+                sourceId, displayName);
+    }
+
+    /**
+     * Uses the supplied values to determine if they represent a "better" display name
+     * for the aggregate contact currently evaluated.  If so, it updates
+     * {@link #mDisplayNameCandidate} with the new values.
+     */
+    private void processDisplayNameCandidate(long rawContactId, String displayName,
+            int displayNameSource, boolean writableAccount, boolean isNameSuperPrimary) {
+
+        boolean replace = false;
+        if (mDisplayNameCandidate.rawContactId == -1) {
+            // No previous values available
+            replace = true;
+        } else if (!TextUtils.isEmpty(displayName)) {
+            if (isNameSuperPrimary) {
+                // A super primary name is better than any other name
+                replace = true;
+            } else if (mDisplayNameCandidate.isNameSuperPrimary == isNameSuperPrimary) {
+                if (mDisplayNameCandidate.displayNameSource < displayNameSource) {
+                    // New values come from an superior source, e.g. structured name vs phone number
+                    replace = true;
+                } else if (mDisplayNameCandidate.displayNameSource == displayNameSource) {
+                    if (!mDisplayNameCandidate.writableAccount && writableAccount) {
+                        replace = true;
+                    } else if (mDisplayNameCandidate.writableAccount == writableAccount) {
+                        if (NameNormalizer.compareComplexity(displayName,
+                                mDisplayNameCandidate.displayName) > 0) {
+                            // New name is more complex than the previously found one
+                            replace = true;
+                        }
+                    }
+                }
+            }
+        }
+
+        if (replace) {
+            mDisplayNameCandidate.rawContactId = rawContactId;
+            mDisplayNameCandidate.displayName = displayName;
+            mDisplayNameCandidate.displayNameSource = displayNameSource;
+            mDisplayNameCandidate.isNameSuperPrimary = isNameSuperPrimary;
+            mDisplayNameCandidate.writableAccount = writableAccount;
+        }
+    }
+
+    private interface PhotoIdQuery {
+        final String[] COLUMNS = new String[] {
+            AccountsColumns.CONCRETE_ACCOUNT_TYPE,
+            DataColumns.CONCRETE_ID,
+            Data.IS_SUPER_PRIMARY,
+            Photo.PHOTO_FILE_ID,
+        };
+
+        int ACCOUNT_TYPE = 0;
+        int DATA_ID = 1;
+        int IS_SUPER_PRIMARY = 2;
+        int PHOTO_FILE_ID = 3;
+    }
+
+    public void updatePhotoId(SQLiteDatabase db, long rawContactId) {
+
+        long contactId = mDbHelper.getContactId(rawContactId);
+        if (contactId == 0) {
+            return;
+        }
+
+        long bestPhotoId = -1;
+        long bestPhotoFileId = 0;
+        int photoPriority = -1;
+
+        long photoMimeType = mDbHelper.getMimeTypeId(Photo.CONTENT_ITEM_TYPE);
+
+        String tables = Tables.RAW_CONTACTS
+                + " JOIN " + Tables.ACCOUNTS + " ON ("
+                    + AccountsColumns.CONCRETE_ID + "=" + RawContactsColumns.CONCRETE_ACCOUNT_ID
+                    + ")"
+                + " JOIN " + Tables.DATA + " ON("
+                + DataColumns.CONCRETE_RAW_CONTACT_ID + "=" + RawContactsColumns.CONCRETE_ID
+                + " AND (" + DataColumns.MIMETYPE_ID + "=" + photoMimeType + " AND "
+                        + Photo.PHOTO + " NOT NULL))";
+
+        mSelectionArgs1[0] = String.valueOf(contactId);
+        final Cursor c = db.query(tables, PhotoIdQuery.COLUMNS,
+                RawContacts.CONTACT_ID + "=?", mSelectionArgs1, null, null, null);
+        try {
+            PhotoEntry bestPhotoEntry = null;
+            while (c.moveToNext()) {
+                long dataId = c.getLong(PhotoIdQuery.DATA_ID);
+                long photoFileId = c.getLong(PhotoIdQuery.PHOTO_FILE_ID);
+                boolean superPrimary = c.getInt(PhotoIdQuery.IS_SUPER_PRIMARY) != 0;
+                PhotoEntry photoEntry = getPhotoMetadata(db, photoFileId);
+
+                // Note that data set does not come into play here, since accounts are looked up in
+                // the account manager in the priority resolver.
+                String accountType = c.getString(PhotoIdQuery.ACCOUNT_TYPE);
+                int priority = mPhotoPriorityResolver.getPhotoPriority(accountType);
+                if (superPrimary || hasHigherPhotoPriority(
+                        photoEntry, priority, bestPhotoEntry, photoPriority)) {
+                    bestPhotoEntry = photoEntry;
+                    photoPriority = priority;
+                    bestPhotoId = dataId;
+                    bestPhotoFileId = photoFileId;
+                    if (superPrimary) {
+                        break;
+                    }
+                }
+            }
+        } finally {
+            c.close();
+        }
+
+        if (bestPhotoId == -1) {
+            mPhotoIdUpdate.bindNull(1);
+        } else {
+            mPhotoIdUpdate.bindLong(1, bestPhotoId);
+        }
+
+        if (bestPhotoFileId == 0) {
+            mPhotoIdUpdate.bindNull(2);
+        } else {
+            mPhotoIdUpdate.bindLong(2, bestPhotoFileId);
+        }
+
+        mPhotoIdUpdate.bindLong(3, contactId);
+        mPhotoIdUpdate.execute();
+    }
+
+    private interface PhotoFileQuery {
+        final String[] COLUMNS = new String[] {
+                PhotoFiles.HEIGHT,
+                PhotoFiles.WIDTH,
+                PhotoFiles.FILESIZE
+        };
+
+        int HEIGHT = 0;
+        int WIDTH = 1;
+        int FILESIZE = 2;
+    }
+
+    private class PhotoEntry implements Comparable<PhotoEntry> {
+        // Pixel count (width * height) for the image.
+        final int pixelCount;
+
+        // File size (in bytes) of the image.  Not populated if the image is a thumbnail.
+        final int fileSize;
+
+        private PhotoEntry(int pixelCount, int fileSize) {
+            this.pixelCount = pixelCount;
+            this.fileSize = fileSize;
+        }
+
+        @Override
+        public int compareTo(PhotoEntry pe) {
+            if (pe == null) {
+                return -1;
+            }
+            if (pixelCount == pe.pixelCount) {
+                return pe.fileSize - fileSize;
+            } else {
+                return pe.pixelCount - pixelCount;
+            }
+        }
+    }
+
+    private PhotoEntry getPhotoMetadata(SQLiteDatabase db, long photoFileId) {
+        if (photoFileId == 0) {
+            // Assume standard thumbnail size.  Don't bother getting a file size for priority;
+            // we should fall back to photo priority resolver if all we have are thumbnails.
+            int thumbDim = mContactsProvider.getMaxThumbnailDim();
+            return new PhotoEntry(thumbDim * thumbDim, 0);
+        } else {
+            Cursor c = db.query(Tables.PHOTO_FILES, PhotoFileQuery.COLUMNS, PhotoFiles._ID + "=?",
+                    new String[]{String.valueOf(photoFileId)}, null, null, null);
+            try {
+                if (c.getCount() == 1) {
+                    c.moveToFirst();
+                    int pixelCount =
+                            c.getInt(PhotoFileQuery.HEIGHT) * c.getInt(PhotoFileQuery.WIDTH);
+                    return new PhotoEntry(pixelCount, c.getInt(PhotoFileQuery.FILESIZE));
+                }
+            } finally {
+                c.close();
+            }
+        }
+        return new PhotoEntry(0, 0);
+    }
+
+    private interface DisplayNameQuery {
+        String SQL_HAS_SUPER_PRIMARY_NAME =
+                " EXISTS(SELECT 1 " +
+                        " FROM " + Tables.DATA + " d " +
+                        " WHERE d." + DataColumns.MIMETYPE_ID + "=? " +
+                        " AND d." + Data.RAW_CONTACT_ID + "=" + Views.RAW_CONTACTS
+                        + "." + RawContacts._ID +
+                        " AND d." + Data.IS_SUPER_PRIMARY + "=1)";
+
+        String SQL =
+                "SELECT "
+                        + RawContacts._ID + ","
+                        + RawContactsColumns.DISPLAY_NAME + ","
+                        + RawContactsColumns.DISPLAY_NAME_SOURCE + ","
+                        + SQL_HAS_SUPER_PRIMARY_NAME + ","
+                        + RawContacts.SOURCE_ID + ","
+                        + RawContacts.ACCOUNT_TYPE_AND_DATA_SET +
+                " FROM " + Views.RAW_CONTACTS +
+                " WHERE " + RawContacts.CONTACT_ID + "=? ";
+
+        int _ID = 0;
+        int DISPLAY_NAME = 1;
+        int DISPLAY_NAME_SOURCE = 2;
+        int HAS_SUPER_PRIMARY_NAME = 3;
+        int SOURCE_ID = 4;
+        int ACCOUNT_TYPE_AND_DATA_SET = 5;
+    }
+
+    public void updateDisplayNameForRawContact(SQLiteDatabase db, long rawContactId) {
+        long contactId = mDbHelper.getContactId(rawContactId);
+        if (contactId == 0) {
+            return;
+        }
+
+        updateDisplayNameForContact(db, contactId);
+    }
+
+    public void updateDisplayNameForContact(SQLiteDatabase db, long contactId) {
+        boolean lookupKeyUpdateNeeded = false;
+
+        mDisplayNameCandidate.clear();
+
+        mSelectionArgs2[0] = String.valueOf(mDbHelper.getMimeTypeIdForStructuredName());
+        mSelectionArgs2[1] = String.valueOf(contactId);
+        final Cursor c = db.rawQuery(DisplayNameQuery.SQL, mSelectionArgs2);
+        try {
+            while (c.moveToNext()) {
+                long rawContactId = c.getLong(DisplayNameQuery._ID);
+                String displayName = c.getString(DisplayNameQuery.DISPLAY_NAME);
+                int displayNameSource = c.getInt(DisplayNameQuery.DISPLAY_NAME_SOURCE);
+                int isNameSuperPrimary = c.getInt(DisplayNameQuery.HAS_SUPER_PRIMARY_NAME);
+                String accountTypeAndDataSet = c.getString(
+                        DisplayNameQuery.ACCOUNT_TYPE_AND_DATA_SET);
+                processDisplayNameCandidate(rawContactId, displayName, displayNameSource,
+                        mContactsProvider.isWritableAccountWithDataSet(accountTypeAndDataSet),
+                        isNameSuperPrimary != 0);
+
+                // If the raw contact has no source id, the lookup key is based on the display
+                // name, so the lookup key needs to be updated.
+                lookupKeyUpdateNeeded |= c.isNull(DisplayNameQuery.SOURCE_ID);
+            }
+        } finally {
+            c.close();
+        }
+
+        if (mDisplayNameCandidate.rawContactId != -1) {
+            mDisplayNameUpdate.bindLong(1, mDisplayNameCandidate.rawContactId);
+            mDisplayNameUpdate.bindLong(2, contactId);
+            mDisplayNameUpdate.execute();
+        }
+
+        if (lookupKeyUpdateNeeded) {
+            updateLookupKeyForContact(db, contactId);
+        }
+    }
+
+
+    /**
+     * Updates the {@link Contacts#HAS_PHONE_NUMBER} flag for the aggregate contact containing the
+     * specified raw contact.
+     */
+    public void updateHasPhoneNumber(SQLiteDatabase db, long rawContactId) {
+
+        long contactId = mDbHelper.getContactId(rawContactId);
+        if (contactId == 0) {
+            return;
+        }
+
+        final SQLiteStatement hasPhoneNumberUpdate = db.compileStatement(
+                "UPDATE " + Tables.CONTACTS +
+                " SET " + Contacts.HAS_PHONE_NUMBER + "="
+                        + "(SELECT (CASE WHEN COUNT(*)=0 THEN 0 ELSE 1 END)"
+                        + " FROM " + Tables.DATA_JOIN_RAW_CONTACTS
+                        + " WHERE " + DataColumns.MIMETYPE_ID + "=?"
+                                + " AND " + Phone.NUMBER + " NOT NULL"
+                                + " AND " + RawContacts.CONTACT_ID + "=?)" +
+                " WHERE " + Contacts._ID + "=?");
+        try {
+            hasPhoneNumberUpdate.bindLong(1, mDbHelper.getMimeTypeId(Phone.CONTENT_ITEM_TYPE));
+            hasPhoneNumberUpdate.bindLong(2, contactId);
+            hasPhoneNumberUpdate.bindLong(3, contactId);
+            hasPhoneNumberUpdate.execute();
+        } finally {
+            hasPhoneNumberUpdate.close();
+        }
+    }
+
+    private interface LookupKeyQuery {
+        String TABLE = Views.RAW_CONTACTS;
+        String[] COLUMNS = new String[] {
+            RawContacts._ID,
+            RawContactsColumns.DISPLAY_NAME,
+            RawContacts.ACCOUNT_TYPE_AND_DATA_SET,
+            RawContacts.ACCOUNT_NAME,
+            RawContacts.SOURCE_ID,
+        };
+
+        int ID = 0;
+        int DISPLAY_NAME = 1;
+        int ACCOUNT_TYPE_AND_DATA_SET = 2;
+        int ACCOUNT_NAME = 3;
+        int SOURCE_ID = 4;
+    }
+
+    public void updateLookupKeyForRawContact(SQLiteDatabase db, long rawContactId) {
+        long contactId = mDbHelper.getContactId(rawContactId);
+        if (contactId == 0) {
+            return;
+        }
+
+        updateLookupKeyForContact(db, contactId);
+    }
+
+    private void updateLookupKeyForContact(SQLiteDatabase db, long contactId) {
+        String lookupKey = computeLookupKeyForContact(db, contactId);
+
+        if (lookupKey == null) {
+            mLookupKeyUpdate.bindNull(1);
+        } else {
+            mLookupKeyUpdate.bindString(1, Uri.encode(lookupKey));
+        }
+        mLookupKeyUpdate.bindLong(2, contactId);
+
+        mLookupKeyUpdate.execute();
+    }
+
+    protected String computeLookupKeyForContact(SQLiteDatabase db, long contactId) {
+        StringBuilder sb = new StringBuilder();
+        mSelectionArgs1[0] = String.valueOf(contactId);
+        final Cursor c = db.query(LookupKeyQuery.TABLE, LookupKeyQuery.COLUMNS,
+                RawContacts.CONTACT_ID + "=?", mSelectionArgs1, null, null, RawContacts._ID);
+        try {
+            while (c.moveToNext()) {
+                ContactLookupKey.appendToLookupKey(sb,
+                        c.getString(LookupKeyQuery.ACCOUNT_TYPE_AND_DATA_SET),
+                        c.getString(LookupKeyQuery.ACCOUNT_NAME),
+                        c.getLong(LookupKeyQuery.ID),
+                        c.getString(LookupKeyQuery.SOURCE_ID),
+                        c.getString(LookupKeyQuery.DISPLAY_NAME));
+            }
+        } finally {
+            c.close();
+        }
+        return sb.length() == 0 ? null : sb.toString();
+    }
+
+    /**
+     * Execute {@link SQLiteStatement} that will update the
+     * {@link Contacts#STARRED} flag for the given {@link RawContacts#_ID}.
+     */
+    public void updateStarred(long rawContactId) {
+        long contactId = mDbHelper.getContactId(rawContactId);
+        if (contactId == 0) {
+            return;
+        }
+
+        mStarredUpdate.bindLong(1, contactId);
+        mStarredUpdate.execute();
+    }
+
+    /**
+     * Execute {@link SQLiteStatement} that will update the
+     * {@link Contacts#PINNED} flag for the given {@link RawContacts#_ID}.
+     */
+    public void updatePinned(long rawContactId) {
+        long contactId = mDbHelper.getContactId(rawContactId);
+        if (contactId == 0) {
+            return;
+        }
+        mPinnedUpdate.bindLong(1, contactId);
+        mPinnedUpdate.execute();
+    }
+
+    /**
+     * Finds matching contacts and returns a cursor on those.
+     */
+    public Cursor queryAggregationSuggestions(SQLiteQueryBuilder qb,
+            String[] projection, long contactId, int maxSuggestions, String filter,
+            ArrayList<AggregationSuggestionParameter> parameters) {
+        final SQLiteDatabase db = mDbHelper.getReadableDatabase();
+        db.beginTransaction();
+        try {
+            List<MatchScore> bestMatches = findMatchingContacts(db, contactId, parameters);
+            return queryMatchingContacts(qb, db, projection, bestMatches, maxSuggestions, filter);
+        } finally {
+            db.endTransaction();
+        }
+    }
+
+    private interface ContactIdQuery {
+        String[] COLUMNS = new String[] {
+            Contacts._ID
+        };
+
+        int _ID = 0;
+    }
+
+    /**
+     * Loads contacts with specified IDs and returns them in the order of IDs in the
+     * supplied list.
+     */
+    private Cursor queryMatchingContacts(SQLiteQueryBuilder qb, SQLiteDatabase db,
+            String[] projection, List<MatchScore> bestMatches, int maxSuggestions, String filter) {
+        StringBuilder sb = new StringBuilder();
+        sb.append(Contacts._ID);
+        sb.append(" IN (");
+        for (int i = 0; i < bestMatches.size(); i++) {
+            MatchScore matchScore = bestMatches.get(i);
+            if (i != 0) {
+                sb.append(",");
+            }
+            sb.append(matchScore.getContactId());
+        }
+        sb.append(")");
+
+        if (!TextUtils.isEmpty(filter)) {
+            sb.append(" AND " + Contacts._ID + " IN ");
+            mContactsProvider.appendContactFilterAsNestedQuery(sb, filter);
+        }
+
+        // Run a query and find ids of best matching contacts satisfying the filter (if any)
+        HashSet<Long> foundIds = new HashSet<Long>();
+        Cursor cursor = db.query(qb.getTables(), ContactIdQuery.COLUMNS, sb.toString(),
+                null, null, null, null);
+        try {
+            while(cursor.moveToNext()) {
+                foundIds.add(cursor.getLong(ContactIdQuery._ID));
+            }
+        } finally {
+            cursor.close();
+        }
+
+        // Exclude all contacts that did not match the filter
+        Iterator<MatchScore> iter = bestMatches.iterator();
+        while (iter.hasNext()) {
+            long id = iter.next().getContactId();
+            if (!foundIds.contains(id)) {
+                iter.remove();
+            }
+        }
+
+        // Limit the number of returned suggestions
+        final List<MatchScore> limitedMatches;
+        if (bestMatches.size() > maxSuggestions) {
+            limitedMatches = bestMatches.subList(0, maxSuggestions);
+        } else {
+            limitedMatches = bestMatches;
+        }
+
+        // Build an in-clause with the remaining contact IDs
+        sb.setLength(0);
+        sb.append(Contacts._ID);
+        sb.append(" IN (");
+        for (int i = 0; i < limitedMatches.size(); i++) {
+            MatchScore matchScore = limitedMatches.get(i);
+            if (i != 0) {
+                sb.append(",");
+            }
+            sb.append(matchScore.getContactId());
+        }
+        sb.append(")");
+
+        // Run the final query with the required projection and contact IDs found by the first query
+        cursor = qb.query(db, projection, sb.toString(), null, null, null, Contacts._ID);
+
+        // Build a sorted list of discovered IDs
+        ArrayList<Long> sortedContactIds = new ArrayList<Long>(limitedMatches.size());
+        for (MatchScore matchScore : limitedMatches) {
+            sortedContactIds.add(matchScore.getContactId());
+        }
+
+        Collections.sort(sortedContactIds);
+
+        // Map cursor indexes according to the descending order of match scores
+        int[] positionMap = new int[limitedMatches.size()];
+        for (int i = 0; i < positionMap.length; i++) {
+            long id = limitedMatches.get(i).getContactId();
+            positionMap[i] = sortedContactIds.indexOf(id);
+        }
+
+        return new ReorderingCursorWrapper(cursor, positionMap);
+    }
+
+    /**
+     * Finds contacts with data matches and returns a list of {@link MatchScore}'s in the
+     * descending order of match score.
+     * @param parameters
+     */
+    private List<MatchScore> findMatchingContacts(final SQLiteDatabase db, long contactId,
+            ArrayList<AggregationSuggestionParameter> parameters) {
+
+        MatchCandidateList candidates = new MatchCandidateList();
+        ContactMatcher matcher = new ContactMatcher();
+
+        // Don't aggregate a contact with itself
+        matcher.keepOut(contactId);
+
+        if (parameters == null || parameters.size() == 0) {
+            final Cursor c = db.query(RawContactIdQuery.TABLE, RawContactIdQuery.COLUMNS,
+                    RawContacts.CONTACT_ID + "=" + contactId, null, null, null, null);
+            try {
+                while (c.moveToNext()) {
+                    long rawContactId = c.getLong(RawContactIdQuery.RAW_CONTACT_ID);
+                    updateMatchScoresForSuggestionsBasedOnDataMatches(db, rawContactId, candidates,
+                            matcher);
+                }
+            } finally {
+                c.close();
+            }
+        } else {
+            updateMatchScoresForSuggestionsBasedOnDataMatches(db, candidates,
+                    matcher, parameters);
+        }
+
+        return matcher.pickBestMatches(ContactMatcher.SCORE_THRESHOLD_SUGGEST);
+    }
+
+    /**
+     * Computes scores for contacts that have matching data rows.
+     */
+    private void updateMatchScoresForSuggestionsBasedOnDataMatches(SQLiteDatabase db,
+            long rawContactId, MatchCandidateList candidates, ContactMatcher matcher) {
+
+        updateMatchScoresBasedOnIdentityMatch(db, rawContactId, matcher);
+        updateMatchScoresBasedOnNameMatches(db, rawContactId, matcher);
+        updateMatchScoresBasedOnEmailMatches(db, rawContactId, matcher);
+        updateMatchScoresBasedOnPhoneMatches(db, rawContactId, matcher);
+        loadNameMatchCandidates(db, rawContactId, candidates, false);
+        lookupApproximateNameMatches(db, candidates, matcher);
+    }
+
+    private void updateMatchScoresForSuggestionsBasedOnDataMatches(SQLiteDatabase db,
+            MatchCandidateList candidates, ContactMatcher matcher,
+            ArrayList<AggregationSuggestionParameter> parameters) {
+        for (AggregationSuggestionParameter parameter : parameters) {
+            if (AggregationSuggestions.PARAMETER_MATCH_NAME.equals(parameter.kind)) {
+                updateMatchScoresBasedOnNameMatches(db, parameter.value, candidates, matcher);
+            }
+
+            // TODO: add support for other parameter kinds
+        }
+    }
+}
