diff --git a/Android.mk b/Android.mk
index b13e757..e963f99 100644
--- a/Android.mk
+++ b/Android.mk
@@ -3,7 +3,8 @@
 
 LOCAL_MODULE_TAGS := user
 
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
+# Only compile source java files in this apk.
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
 LOCAL_JAVA_LIBRARIES := ext
 
@@ -11,3 +12,6 @@
 LOCAL_CERTIFICATE := shared
 
 include $(BUILD_PACKAGE)
+
+# Use the following include to make our test apk.
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 0194108..4491dd6 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -13,11 +13,28 @@
     <uses-permission android:name="android.permission.SUBSCRIBED_FEEDS_WRITE" />
 
     <application android:process="android.process.acore"
-                 android:label="@string/app_label"
-                 android:icon="@drawable/app_icon">
-        <provider android:name="ContactsProvider" android:authorities="contacts;call_log"
-                android:syncable="false" android:multiprocess="false"
-                android:readPermission="android.permission.READ_CONTACTS"
-                android:writePermission="android.permission.WRITE_CONTACTS" />
+        android:label="@string/app_label"
+        android:icon="@drawable/app_icon">
+
+        <provider android:name="ContactsProvider" 
+            android:authorities="contacts;call_log"
+            android:syncable="false" android:multiprocess="false"
+            android:readPermission="android.permission.READ_CONTACTS"
+            android:writePermission="android.permission.WRITE_CONTACTS" />
+
+        <provider android:name="ContactsProvider2"
+            android:authorities="com.android.contacts"
+            android:syncable="false"
+            android:multiprocess="false"
+            android:readPermission="android.permission.READ_CONTACTS"
+            android:writePermission="android.permission.WRITE_CONTACTS" />
+
+        <!-- TODO: create permissions for social data -->
+        <provider android:name="SocialProvider"
+            android:authorities="com.android.social"
+            android:syncable="false"
+            android:multiprocess="false"
+            android:readPermission="android.permission.READ_CONTACTS"
+            android:writePermission="android.permission.WRITE_CONTACTS" />
     </application>
 </manifest>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 45637dd..ac119ed 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2008 The Android Open Source Project
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2009 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.
@@ -14,7 +14,8 @@
      limitations under the License.
 -->
 
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+           xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
 
     <!-- This is the label for the application that stores contacts data -->
     <string name="app_label">Contacts Storage</string>
diff --git a/src/com/android/providers/contacts/ContactAggregationScheduler.java b/src/com/android/providers/contacts/ContactAggregationScheduler.java
new file mode 100644
index 0000000..59bb8cd
--- /dev/null
+++ b/src/com/android/providers/contacts/ContactAggregationScheduler.java
@@ -0,0 +1,176 @@
+/*
+ * Copyright (C) 2009 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;
+
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.Looper;
+import android.os.Message;
+import android.os.Process;
+
+/**
+ * A scheduler for asynchronous aggregation of contacts. Aggregation will start after
+ * a short delay after it is scheduled, unless it is scheduled again, in which case the
+ * aggregation pass is delayed.  There is an upper boundary on how long aggregation can
+ * be delayed.
+ */
+public class ContactAggregationScheduler {
+
+    public interface Aggregator {
+
+        /**
+         * Performs an aggregation run.
+         */
+        void run();
+
+        /**
+         * Interrupts aggregation.
+         */
+        void interrupt();
+    }
+
+    // Message ID used for communication with the aggregator
+    private static final int START_AGGREGATION_MESSAGE_ID = 1;
+
+    // Aggregation is delayed by this many milliseconds to allow changes to accumulate
+    public static final int AGGREGATION_DELAY = 500;
+
+    // Maximum delay of aggregation from the initial aggregation request
+    public static final int MAX_AGGREGATION_DELAY = 5000;
+
+    public static final int STATUS_STAND_BY = 0;
+    public static final int STATUS_SCHEDULED = 1;
+    public static final int STATUS_RUNNING = 2;
+
+    private Aggregator mAggregator;
+
+    // Aggregation status
+    private int mStatus = STATUS_STAND_BY;
+
+    // If true, we need to automatically reschedule aggregation after the current pass is done
+    private boolean mRescheduleWhenComplete;
+
+    // The time when aggregation was request for the first time. Reset when aggregation is completed
+    private long mInitialRequestTimestamp;
+
+    private HandlerThread mHandlerThread;
+    private Handler mMessageHandler;
+
+    public void setAggregator(Aggregator aggregator) {
+        mAggregator = aggregator;
+    }
+
+    public void start() {
+        mHandlerThread = new HandlerThread("ContactAggregator", Process.THREAD_PRIORITY_BACKGROUND);
+        mHandlerThread.start();
+        mMessageHandler = new Handler(mHandlerThread.getLooper()) {
+
+            @Override
+            public void handleMessage(Message msg) {
+                switch (msg.what) {
+                    case START_AGGREGATION_MESSAGE_ID:
+                        run();
+                        break;
+
+                    default:
+                        throw new IllegalStateException("Unhandled message: " + msg.what);
+                }
+            }
+        };
+    }
+
+    public void stop() {
+        mAggregator.interrupt();
+        Looper looper = mHandlerThread.getLooper();
+        if (looper != null) {
+            looper.quit();
+        }
+    }
+
+    /**
+     * Schedules an aggregation pass after a short delay.
+     */
+    public synchronized void schedule() {
+
+        switch (mStatus) {
+            case STATUS_STAND_BY: {
+
+                mInitialRequestTimestamp = currentTime();
+                mStatus = STATUS_SCHEDULED;
+                runDelayed();
+                break;
+            }
+
+            case STATUS_SCHEDULED: {
+
+                // If it has been less than MAX_AGGREGATION_DELAY millis since the initial request,
+                // reschedule the request.
+                if (currentTime() - mInitialRequestTimestamp < MAX_AGGREGATION_DELAY) {
+                    runDelayed();
+                }
+                break;
+            }
+
+            case STATUS_RUNNING: {
+
+                // If it has been less than MAX_AGGREGATION_DELAY millis since the initial request,
+                // interrupt the current pass and reschedule the request.
+                if (currentTime() - mInitialRequestTimestamp < MAX_AGGREGATION_DELAY) {
+                    mAggregator.interrupt();
+                }
+
+                mRescheduleWhenComplete = true;
+                break;
+            }
+        }
+    }
+
+    /**
+     * Called just before an aggregation pass begins.
+     */
+    public void run() {
+        synchronized (this) {
+            mStatus = STATUS_RUNNING;
+            mRescheduleWhenComplete = false;
+        }
+        try {
+            mAggregator.run();
+        } finally {
+            synchronized (this) {
+                mStatus = STATUS_STAND_BY;
+                mInitialRequestTimestamp = 0;
+                if (mRescheduleWhenComplete) {
+                    mRescheduleWhenComplete = false;
+                    schedule();
+                }
+            }
+        }
+    }
+
+    /* package */ void runDelayed() {
+
+        // If aggregation has already been requested, cancel the previous request
+        mMessageHandler.removeMessages(START_AGGREGATION_MESSAGE_ID);
+
+        // Schedule aggregation for AGGREGATION_DELAY milliseconds from now
+        mMessageHandler.sendEmptyMessageDelayed(
+                START_AGGREGATION_MESSAGE_ID, AGGREGATION_DELAY);
+    }
+
+    /* package */ long currentTime() {
+        return System.currentTimeMillis();
+    }
+}
diff --git a/src/com/android/providers/contacts/ContactAggregator.java b/src/com/android/providers/contacts/ContactAggregator.java
new file mode 100644
index 0000000..01e247d
--- /dev/null
+++ b/src/com/android/providers/contacts/ContactAggregator.java
@@ -0,0 +1,1147 @@
+/*
+ * Copyright (C) 2009 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;
+
+import com.android.providers.contacts.ContactMatcher.MatchScore;
+import com.android.providers.contacts.OpenHelper.AggregatesColumns;
+import com.android.providers.contacts.OpenHelper.AggregationExceptionColumns;
+import com.android.providers.contacts.OpenHelper.Clauses;
+import com.android.providers.contacts.OpenHelper.ContactOptionsColumns;
+import com.android.providers.contacts.OpenHelper.ContactsColumns;
+import com.android.providers.contacts.OpenHelper.MimetypesColumns;
+import com.android.providers.contacts.OpenHelper.NameLookupColumns;
+import com.android.providers.contacts.OpenHelper.NameLookupType;
+import com.android.providers.contacts.OpenHelper.Tables;
+
+import android.content.ContentValues;
+import android.content.Context;
+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.provider.ContactsContract.Aggregates;
+import android.provider.ContactsContract.AggregationExceptions;
+import android.provider.ContactsContract.CommonDataKinds;
+import android.provider.ContactsContract.Contacts;
+import android.provider.ContactsContract.Data;
+import android.provider.ContactsContract.CommonDataKinds.Email;
+import android.provider.ContactsContract.CommonDataKinds.Nickname;
+import android.provider.ContactsContract.CommonDataKinds.Phone;
+import android.provider.ContactsContract.CommonDataKinds.StructuredName;
+import android.text.TextUtils;
+import android.text.util.Rfc822Token;
+import android.text.util.Rfc822Tokenizer;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+
+
+/**
+ * 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.
+ * <p>
+ * ContactAggregator runs on a separate thread.
+ */
+public class ContactAggregator implements ContactAggregationScheduler.Aggregator {
+
+    private static final String TAG = "ContactAggregator";
+
+    // Data mime types used in the contact matching algorithm
+    private static final String MIMETYPE_SELECTION_IN_CLAUSE = MimetypesColumns.MIMETYPE + " IN ('"
+            + Email.CONTENT_ITEM_TYPE + "','"
+            + Nickname.CONTENT_ITEM_TYPE + "','"
+            + Phone.CONTENT_ITEM_TYPE + "','"
+            + StructuredName.CONTENT_ITEM_TYPE + "')";
+
+    private static final String[] DATA_JOIN_MIMETYPE_COLUMNS = new String[] {
+            MimetypesColumns.MIMETYPE,
+            Data.DATA1,
+            Data.DATA2
+    };
+
+    private static final int COL_MIMETYPE = 0;
+    private static final int COL_DATA1 = 1;
+    private static final int COL_DATA2 = 2;
+
+    private static final String[] DATA_JOIN_MIMETYPE_AND_CONTACT_COLUMNS = new String[] {
+            Data.DATA1, Data.DATA2, Contacts.AGGREGATE_ID
+    };
+
+    private static final int COL_DATA_CONTACT_DATA1 = 0;
+    private static final int COL_DATA_CONTACT_DATA2 = 1;
+    private static final int COL_DATA_CONTACT_AGGREGATE_ID = 2;
+
+    private static final String[] NAME_LOOKUP_COLUMNS = new String[] {
+            Contacts.AGGREGATE_ID, NameLookupColumns.NORMALIZED_NAME, NameLookupColumns.NAME_TYPE
+    };
+
+    private static final int COL_NAME_LOOKUP_AGGREGATE_ID = 0;
+    private static final int COL_NORMALIZED_NAME = 1;
+    private static final int COL_NAME_TYPE = 2;
+
+    private static final String[] AGGREGATE_EXCEPTION_JOIN_CONTACT_TWICE_COLUMNS = new String[]{
+            AggregationExceptions.TYPE,
+            AggregationExceptionColumns.CONTACT_ID1,
+            "contacts1." + Contacts.AGGREGATE_ID,
+            "contacts2." + Contacts.AGGREGATE_ID
+    };
+
+    private static final int COL_TYPE = 0;
+    private static final int COL_CONTACT_ID1 = 1;
+    private static final int COL_AGGREGATE_ID1 = 2;
+    private static final int COL_AGGREGATE_ID2 = 3;
+
+    private static final String[] CONTACT_ID_COLUMN = new String[] { Contacts._ID };
+    private static final String[] CONTACTS_JOIN_CONTACT_OPTIONS_COLUMNS = new String[] {
+            ContactOptionsColumns.CUSTOM_RINGTONE,
+            ContactOptionsColumns.SEND_TO_VOICEMAIL,
+    };
+
+    private static final int COL_CUSTOM_RINGTONE = 0;
+    private static final int COL_SEND_TO_VOICEMAIL = 1;
+
+    private static final String[] AGGREGATE_ID_COLUMNS = new String[]{ Contacts.AGGREGATE_ID };
+    private static final int COL_AGGREGATE_ID = 0;
+
+    private static final int MODE_INSERT_LOOKUP_DATA = 0;
+    private static final int MODE_AGGREGATION = 1;
+    private static final int MODE_SUGGESTIONS = 2;
+
+    private final OpenHelper mOpenHelper;
+    private final ContactAggregationScheduler mScheduler;
+
+    // Set if the current aggregation pass should be interrupted
+    private volatile boolean mCancel;
+
+    /** Compiled statement for updating {@link Aggregates#IN_VISIBLE_GROUP}. */
+    private SQLiteStatement mUpdateAggregateVisibleStatement;
+
+    /**
+     * 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;
+        }
+    }
+
+    /**
+     * Constructor.  Starts a contact aggregation thread.  Call {@link #quit} to kill the
+     * aggregation thread.  Call {@link #schedule} to kick off the aggregation process after
+     * a delay of {@link #AGGREGATION_DELAY} milliseconds.
+     */
+    public ContactAggregator(Context context, OpenHelper openHelper,
+            ContactAggregationScheduler scheduler) {
+        mOpenHelper = openHelper;
+        mScheduler = scheduler;
+        mScheduler.setAggregator(this);
+        mScheduler.start();
+
+        // Perform an aggregation pass in the beginning, which will most of the time
+        // do nothing.  It will only be useful if the content provider has been killed
+        // before completing aggregation.
+        mScheduler.schedule();
+    }
+
+    /**
+     * Schedules aggregation pass after a short delay.  This method should be called every time
+     * the {@link Contacts#AGGREGATE_ID} field is reset on any record.
+     */
+    public void schedule() {
+        mScheduler.schedule();
+    }
+
+    /**
+     * Kills the contact aggregation thread.
+     */
+    public void quit() {
+        mScheduler.stop();
+    }
+
+    /**
+     * Invoked by the scheduler to cancel aggregation.
+     */
+    public void interrupt() {
+        mCancel = true;
+    }
+
+    /**
+     * Find all contacts that require aggregation and pass them through aggregation one by one.
+     * Do not call directly.  It is invoked by the scheduler.
+     */
+    public void run() {
+        mCancel = false;
+        Log.i(TAG, "Contact aggregation");
+
+        MatchCandidateList candidates = new MatchCandidateList();
+        ContactMatcher matcher = new ContactMatcher();
+        ContentValues values = new ContentValues();
+
+        final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+        final Cursor c = db.query(Tables.CONTACTS, new String[]{Contacts._ID},
+                Contacts.AGGREGATE_ID + " IS NULL", null, null, null, null);
+
+        int totalCount = c.getCount();
+        int count = 0;
+        try {
+            if (c.moveToFirst()) {
+                db.beginTransaction();
+                try {
+                    do {
+                        if (mCancel) {
+                            break;
+                        }
+                        aggregateContact(db, c.getInt(0), candidates, matcher, values);
+                        count++;
+                        db.yieldIfContendedSafely();
+                    } while (c.moveToNext());
+
+                    db.setTransactionSuccessful();
+                } finally {
+                    db.endTransaction();
+                }
+            }
+        } finally {
+            c.close();
+
+            // Unless the aggregation pass was not interrupted, reset the last request timestamp
+            if (count == totalCount) {
+                Log.i(TAG, "Contact aggregation complete: " + totalCount);
+            } else {
+                Log.i(TAG, "Contact aggregation interrupted: " + count + "/" + totalCount);
+            }
+        }
+    }
+
+    /**
+     * Synchronously aggregate the specified contact.
+     */
+    public void aggregateContact(long contactId) {
+        MatchCandidateList candidates = new MatchCandidateList();
+        ContactMatcher matcher = new ContactMatcher();
+        ContentValues values = new ContentValues();
+
+        final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+        db.beginTransaction();
+        try {
+            aggregateContact(db, contactId, candidates, matcher, values);
+            db.setTransactionSuccessful();
+        } finally {
+            db.endTransaction();
+        }
+    }
+
+    /**
+     * Marks the specified contact for (re)aggregation.
+     *
+     * @param contactId contact ID that needs to be (re)aggregated
+     */
+    public void markContactForAggregation(long contactId) {
+        final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+
+        long aggregateId = mOpenHelper.getAggregateId(contactId);
+        if (aggregateId != 0) {
+
+            // Clear out the aggregate ID field on the contact
+            db.execSQL("UPDATE " + Tables.CONTACTS + " SET " + Contacts.AGGREGATE_ID
+                    + " = NULL WHERE " + Contacts._ID + "=" + contactId + ";");
+
+            // Clear out data used for aggregation - we will recreate it during aggregation
+            db.execSQL("DELETE FROM " + Tables.NAME_LOOKUP + " WHERE "
+                    + NameLookupColumns.CONTACT_ID + "=" + contactId);
+
+            // Delete the aggregate itself if it no longer has constituent contacts
+            db.execSQL("DELETE FROM " + Tables.AGGREGATES + " WHERE " + Aggregates._ID + "="
+                    + aggregateId + " AND " + Aggregates._ID + " NOT IN (SELECT "
+                    + Contacts.AGGREGATE_ID + " FROM " + Tables.CONTACTS + ");");
+        }
+    }
+
+    public void updateAggregateData(long aggregateId) {
+        final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+        final ContentValues values = new ContentValues();
+        updateAggregateData(db, aggregateId, values);
+    }
+
+    /**
+     * Given a specific contact, finds all matching aggregates and chooses the aggregate
+     * with the highest match score.  If no such aggregate is found, creates a new aggregate.
+     */
+    /* package */ synchronized void aggregateContact(SQLiteDatabase db, long contactId,
+            MatchCandidateList candidates, ContactMatcher matcher, ContentValues values) {
+        candidates.clear();
+        matcher.clear();
+
+        long aggregateId = pickBestMatchBasedOnExceptions(db, contactId, matcher);
+        if (aggregateId == -1) {
+            aggregateId = pickBestMatchBasedOnData(db, contactId, candidates, matcher);
+        }
+
+        boolean newAgg = false;
+
+        if (aggregateId == -1) {
+            newAgg = true;
+            ContentValues aggregateValues = new ContentValues();
+            aggregateValues.put(Aggregates.DISPLAY_NAME, "");
+            aggregateId = db.insert(Tables.AGGREGATES, Aggregates.DISPLAY_NAME, aggregateValues);
+        }
+
+        updateContactAggregationData(db, contactId, candidates, values);
+        mOpenHelper.setAggregateId(contactId, aggregateId);
+
+        updateAggregateData(db, aggregateId, values);
+        updatePrimaries(db, aggregateId, contactId, newAgg);
+        mOpenHelper.updateAggregateVisible(aggregateId);
+
+    }
+
+    /**
+     * Computes match scores based on exceptions entered by the user: always match and never match.
+     * Returns the aggregate with the always match exception if any.
+     */
+    private long pickBestMatchBasedOnExceptions(SQLiteDatabase db, long contactId,
+            ContactMatcher matcher) {
+        final Cursor c = db.query(Tables.AGGREGATION_EXCEPTIONS_JOIN_CONTACTS_TWICE,
+                AGGREGATE_EXCEPTION_JOIN_CONTACT_TWICE_COLUMNS,
+                AggregationExceptionColumns.CONTACT_ID1 + "=" + contactId
+                        + " OR " + AggregationExceptionColumns.CONTACT_ID2 + "=" + contactId,
+                null, null, null, null);
+
+        try {
+            while (c.moveToNext()) {
+                int type = c.getInt(COL_TYPE);
+                long contactId1 = c.getLong(COL_CONTACT_ID1);
+                long aggregateId = -1;
+                if (contactId == contactId1) {
+                    if (!c.isNull(COL_AGGREGATE_ID2)) {
+                        aggregateId = c.getLong(COL_AGGREGATE_ID2);
+                    }
+                } else {
+                    if (!c.isNull(COL_AGGREGATE_ID1)) {
+                        aggregateId = c.getLong(COL_AGGREGATE_ID1);
+                    }
+                }
+                if (aggregateId != -1) {
+                    if (type == AggregationExceptions.TYPE_KEEP_IN) {
+                        return aggregateId;
+                    } else {
+                        matcher.keepOut(aggregateId);
+                    }
+                }
+            }
+        } finally {
+            c.close();
+        }
+
+        return -1;
+    }
+
+    /**
+     * Picks the best matching aggregate 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 contactId,
+            MatchCandidateList candidates, ContactMatcher matcher) {
+
+        updateMatchScoresBasedOnDataMatches(db, contactId, MODE_AGGREGATION, candidates, matcher);
+
+        // See if we have already found a good match based on name matches alone
+        long bestMatch = matcher.pickBestMatch(ContactMatcher.SCORE_THRESHOLD_PRIMARY);
+        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, candidates, matcher);
+        }
+
+        return bestMatch;
+    }
+
+    /**
+     * Picks the best matching aggregate based on secondary data matches.  The method loads
+     * structured names for all candidate aggregates and recomputes match scores using approximate
+     * matching.
+     */
+    private long pickBestMatchBasedOnSecondaryData(SQLiteDatabase db,
+            MatchCandidateList candidates, ContactMatcher matcher) {
+        List<Long> secondaryAggregateIds = matcher.prepareSecondaryMatchCandidates(
+                ContactMatcher.SCORE_THRESHOLD_PRIMARY);
+        if (secondaryAggregateIds == null) {
+            return -1;
+        }
+
+        StringBuilder selection = new StringBuilder();
+        selection.append(Contacts.AGGREGATE_ID).append(" IN (");
+        for (int i = 0; i < secondaryAggregateIds.size(); i++) {
+            if (i != 0) {
+                selection.append(',');
+            }
+            selection.append(secondaryAggregateIds.get(i));
+        }
+        selection.append(") AND ")
+                .append(MimetypesColumns.MIMETYPE)
+                .append("='")
+                .append(StructuredName.CONTENT_ITEM_TYPE)
+                .append("'");
+
+        final Cursor c = db.query(Tables.DATA_JOIN_MIMETYPE_CONTACTS,
+                DATA_JOIN_MIMETYPE_AND_CONTACT_COLUMNS,
+                selection.toString(), null, null, null, null);
+
+        MatchCandidateList nameCandidates = new MatchCandidateList();
+        try {
+            while (c.moveToNext()) {
+                String givenName = c.getString(COL_DATA_CONTACT_DATA1);
+                String familyName = c.getString(COL_DATA_CONTACT_DATA2);
+                long aggregateId = c.getLong(COL_DATA_CONTACT_AGGREGATE_ID);
+
+                nameCandidates.clear();
+                addMatchCandidatesStructuredName(givenName, familyName, MODE_INSERT_LOOKUP_DATA,
+                        nameCandidates);
+
+                // 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);
+
+                    // We only want to compare structured names to structured names
+                    // at this stage, we need to ignore all other sources of name lookup data.
+                    if (NameLookupType.isBasedOnStructuredName(candidate.mLookupType)) {
+                        for (int j = 0; j < nameCandidates.mCount; j++) {
+                            NameMatchCandidate nameCandidate = nameCandidates.mList.get(j);
+                            matcher.matchName(aggregateId,
+                                    nameCandidate.mLookupType, nameCandidate.mName,
+                                    candidate.mLookupType, candidate.mName, true);
+                        }
+                    }
+                }
+            }
+        } finally {
+            c.close();
+        }
+
+        return matcher.pickBestMatch(ContactMatcher.SCORE_THRESHOLD_SECONDARY);
+    }
+
+    /**
+     * Computes scores for aggregates that have matching data rows.
+     */
+    private void updateMatchScoresBasedOnDataMatches(SQLiteDatabase db, long contactId,
+            int mode, MatchCandidateList candidates, ContactMatcher matcher) {
+
+        final Cursor c = db.query(Tables.DATA_JOIN_MIMETYPE_CONTACTS,
+                DATA_JOIN_MIMETYPE_COLUMNS,
+                DatabaseUtils.concatenateWhere(Data.CONTACT_ID + "=" + contactId,
+                        MIMETYPE_SELECTION_IN_CLAUSE),
+                null, null, null, null);
+
+        try {
+            while (c.moveToNext()) {
+                String mimeType = c.getString(COL_MIMETYPE);
+                String data1 = c.getString(COL_DATA1);
+                String data2 = c.getString(COL_DATA2);
+                if (mimeType.equals(CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE)) {
+                    addMatchCandidatesStructuredName(data1, data2, mode, candidates);
+                } else if (mimeType.equals(CommonDataKinds.Email.CONTENT_ITEM_TYPE)) {
+                    addMatchCandidatesEmail(data2, mode, candidates);
+                    lookupEmailMatches(db, data2, matcher);
+                } else if (mimeType.equals(CommonDataKinds.Phone.CONTENT_ITEM_TYPE)) {
+                    lookupPhoneMatches(db, data2, matcher);
+                } else if (mimeType.equals(CommonDataKinds.Nickname.CONTENT_ITEM_TYPE)) {
+                    addMatchCandidatesNickname(data2, mode, candidates);
+                    lookupNicknameMatches(db, data2, matcher);
+                }
+            }
+        } finally {
+            c.close();
+        }
+
+        lookupNameMatches(db, candidates, matcher);
+
+        if (mode == MODE_SUGGESTIONS) {
+            lookupApproximateNameMatches(db, candidates, matcher);
+        }
+    }
+
+    /**
+     * Looks for matches based on the full name (first + last).
+     */
+    private void addMatchCandidatesStructuredName(String givenName, String familyName, int mode,
+            MatchCandidateList candidates) {
+        if (TextUtils.isEmpty(givenName)) {
+
+            // If neither the first nor last name are specified, we won't
+            // aggregate
+            if (TextUtils.isEmpty(familyName)) {
+                return;
+            }
+
+            addMatchCandidatesFamilyNameOnly(familyName, candidates);
+        } else if (TextUtils.isEmpty(familyName)) {
+            addMatchCandidatesGivenNameOnly(givenName, candidates);
+        } else {
+            addMatchCandidatesFullName(givenName, familyName, mode, candidates);
+        }
+    }
+
+    private void addMatchCandidatesGivenNameOnly(String givenName,
+            MatchCandidateList candidates) {
+        String givenNameN = NameNormalizer.normalize(givenName);
+        candidates.add(givenNameN, NameLookupType.GIVEN_NAME_ONLY);
+
+        String[] clusters = mOpenHelper.getCommonNicknameClusters(givenNameN);
+        if (clusters != null) {
+            for (int i = 0; i < clusters.length; i++) {
+                candidates.add(clusters[i], NameLookupType.GIVEN_NAME_ONLY_AS_NICKNAME);
+            }
+        }
+    }
+
+    private void addMatchCandidatesFamilyNameOnly(String familyName,
+            MatchCandidateList candidates) {
+        String familyNameN = NameNormalizer.normalize(familyName);
+        candidates.add(familyNameN, NameLookupType.FAMILY_NAME_ONLY);
+
+        // Take care of first and last names swapped
+        String[] clusters = mOpenHelper.getCommonNicknameClusters(familyNameN);
+        if (clusters != null) {
+            for (int i = 0; i < clusters.length; i++) {
+                candidates.add(clusters[i], NameLookupType.FAMILY_NAME_ONLY_AS_NICKNAME);
+            }
+        }
+    }
+
+    private void addMatchCandidatesFullName(String givenName, String familyName, int mode,
+            MatchCandidateList candidates) {
+        final String givenNameN = NameNormalizer.normalize(givenName);
+        final String[] givenNameNicknames = mOpenHelper.getCommonNicknameClusters(givenNameN);
+        final String familyNameN = NameNormalizer.normalize(familyName);
+        final String[] familyNameNicknames = mOpenHelper.getCommonNicknameClusters(familyNameN);
+        candidates.add(givenNameN + "." + familyNameN, NameLookupType.FULL_NAME);
+        if (givenNameNicknames != null) {
+            for (int i = 0; i < givenNameNicknames.length; i++) {
+                candidates.add(givenNameNicknames[i] + "." + familyNameN,
+                        NameLookupType.FULL_NAME_WITH_NICKNAME);
+            }
+        }
+        candidates.add(familyNameN + "." + givenNameN, NameLookupType.FULL_NAME_REVERSE);
+        if (familyNameNicknames != null) {
+            for (int i = 0; i < familyNameNicknames.length; i++) {
+                candidates.add(familyNameNicknames[i] + "." + givenNameN,
+                        NameLookupType.FULL_NAME_WITH_NICKNAME_REVERSE);
+            }
+        }
+        candidates.add(givenNameN + familyNameN, NameLookupType.FULL_NAME_CONCATENATED);
+        candidates.add(familyNameN + givenNameN, NameLookupType.FULL_NAME_REVERSE_CONCATENATED);
+
+        if (mode == MODE_AGGREGATION || mode == MODE_SUGGESTIONS) {
+            candidates.add(givenNameN, NameLookupType.GIVEN_NAME_ONLY);
+            if (givenNameNicknames != null) {
+                for (int i = 0; i < givenNameNicknames.length; i++) {
+                    candidates.add(givenNameNicknames[i],
+                            NameLookupType.GIVEN_NAME_ONLY_AS_NICKNAME);
+                }
+            }
+
+            candidates.add(familyNameN, NameLookupType.FAMILY_NAME_ONLY);
+            if (familyNameNicknames != null) {
+                for (int i = 0; i < familyNameNicknames.length; i++) {
+                    candidates.add(familyNameNicknames[i],
+                            NameLookupType.FAMILY_NAME_ONLY_AS_NICKNAME);
+                }
+            }
+        }
+    }
+
+    /**
+     * Extracts the user name portion from an email address and normalizes it so that it
+     * can be matched against names and nicknames.
+     */
+    private void addMatchCandidatesEmail(String email, int mode, MatchCandidateList candidates) {
+        Rfc822Token[] tokens = Rfc822Tokenizer.tokenize(email);
+        if (tokens.length == 0) {
+            return;
+        }
+
+        String address = tokens[0].getAddress();
+        int at = address.indexOf('@');
+        if (at != -1) {
+            address = address.substring(0, at);
+        }
+
+        candidates.add(NameNormalizer.normalize(address), NameLookupType.EMAIL_BASED_NICKNAME);
+    }
+
+
+    /**
+     * Normalizes the nickname and adds it to the list of candidates.
+     */
+    private void addMatchCandidatesNickname(String nickname, int mode,
+            MatchCandidateList candidates) {
+        candidates.add(NameNormalizer.normalize(nickname), NameLookupType.NICKNAME);
+    }
+
+    /**
+     * Given a list of {@link NameMatchCandidate}'s, finds all matches and computes their scores.
+     */
+    private void lookupNameMatches(SQLiteDatabase db, MatchCandidateList candidates,
+            ContactMatcher matcher) {
+
+        if (candidates.mCount == 0) {
+            return;
+        }
+
+        StringBuilder selection = new StringBuilder();
+        selection.append(NameLookupColumns.NORMALIZED_NAME);
+        selection.append(" IN (");
+        for (int i = 0; i < candidates.mCount; i++) {
+            DatabaseUtils.appendEscapedSQLString(selection, candidates.mList.get(i).mName);
+            selection.append(",");
+        }
+
+        // Yank the last comma
+        selection.setLength(selection.length() - 1);
+        selection.append(") AND ");
+        selection.append(Contacts.AGGREGATE_ID);
+        selection.append(" NOT NULL");
+
+        matchAllCandidates(db, selection.toString(), candidates, matcher, false);
+    }
+
+    /**
+     * 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 " + Contacts.AGGREGATE_ID + " NOT NULL";
+                    matchAllCandidates(db, selection, candidates, matcher, true);
+                }
+            }
+        }
+    }
+
+    /**
+     * 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, boolean approximate) {
+        final Cursor c = db.query(Tables.NAME_LOOKUP_JOIN_CONTACTS, NAME_LOOKUP_COLUMNS,
+                selection, null, null, null, null);
+
+        try {
+            while (c.moveToNext()) {
+                Long aggregateId = c.getLong(COL_NAME_LOOKUP_AGGREGATE_ID);
+                String name = c.getString(COL_NORMALIZED_NAME);
+                int nameType = c.getInt(COL_NAME_TYPE);
+
+                // Determine which candidate produced this match
+                for (int i = 0; i < candidates.mCount; i++) {
+                    NameMatchCandidate candidate = candidates.mList.get(i);
+                    matcher.matchName(aggregateId, candidate.mLookupType, candidate.mName,
+                            nameType, name, approximate);
+                }
+            }
+        } finally {
+            c.close();
+        }
+    }
+
+    private void lookupPhoneMatches(SQLiteDatabase db, String phoneNumber, ContactMatcher matcher) {
+        SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
+        OpenHelper.buildPhoneLookupQuery(qb, phoneNumber);
+        Cursor c = qb.query(db, AGGREGATE_ID_COLUMNS,
+                Contacts.AGGREGATE_ID + " NOT NULL", null, null, null, null);
+        try {
+            while (c.moveToNext()) {
+                long aggregateId = c.getLong(COL_AGGREGATE_ID);
+                matcher.updateScoreWithPhoneNumberMatch(aggregateId);
+            }
+        } finally {
+            c.close();
+        }
+    }
+
+    /**
+     * Finds exact email matches and updates their match scores.
+     */
+    private void lookupEmailMatches(SQLiteDatabase db, String address, ContactMatcher matcher) {
+        Cursor c = db.query(Tables.DATA_JOIN_MIMETYPE_CONTACTS, AGGREGATE_ID_COLUMNS,
+                Clauses.WHERE_EMAIL_MATCHES + " AND " + Contacts.AGGREGATE_ID + " NOT NULL",
+                new String[]{address}, null, null, null);
+        try {
+            while (c.moveToNext()) {
+                long aggregateId = c.getLong(COL_AGGREGATE_ID);
+                matcher.updateScoreWithEmailMatch(aggregateId);
+            }
+        } finally {
+            c.close();
+        }
+    }
+
+    /**
+     * Finds exact nickname matches in the name lookup table and updates their match scores.
+     */
+    private void lookupNicknameMatches(SQLiteDatabase db, String nickname, ContactMatcher matcher) {
+        String normalized = NameNormalizer.normalize(nickname);
+        Cursor c = db.query(true, Tables.NAME_LOOKUP_JOIN_CONTACTS, AGGREGATE_ID_COLUMNS,
+                NameLookupColumns.NAME_TYPE + "=" + NameLookupType.NICKNAME + " AND "
+                        + NameLookupColumns.NORMALIZED_NAME + "='" + normalized + "' AND "
+                        + Contacts.AGGREGATE_ID + " NOT NULL",
+                null, null, null, null, null);
+        try {
+            while (c.moveToNext()) {
+                long aggregateId = c.getLong(COL_AGGREGATE_ID);
+                matcher.updateScoreWithNicknameMatch(aggregateId);
+            }
+        } finally {
+            c.close();
+        }
+    }
+
+    /**
+     * Prepares the supplied contact for aggregation with other contacts by (re)computing
+     * match lookup keys.
+     */
+    private void updateContactAggregationData(SQLiteDatabase db, long contactId,
+            MatchCandidateList candidates, ContentValues values) {
+        candidates.clear();
+
+        final Cursor c = db.query(Tables.DATA_JOIN_MIMETYPES,
+                DATA_JOIN_MIMETYPE_COLUMNS,
+                DatabaseUtils.concatenateWhere(Data.CONTACT_ID + "=" + contactId,
+                        MIMETYPE_SELECTION_IN_CLAUSE),
+                null, null, null, null);
+
+        try {
+            while (c.moveToNext()) {
+                String mimeType = c.getString(COL_MIMETYPE);
+                String data1 = c.getString(COL_DATA1);
+                String data2 = c.getString(COL_DATA2);
+                if (mimeType.equals(CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE)) {
+                    addMatchCandidatesStructuredName(data1, data2, MODE_INSERT_LOOKUP_DATA,
+                            candidates);
+                } else if (mimeType.equals(CommonDataKinds.Email.CONTENT_ITEM_TYPE)) {
+                    addMatchCandidatesEmail(data2, MODE_INSERT_LOOKUP_DATA, candidates);
+                } else if (mimeType.equals(CommonDataKinds.Nickname.CONTENT_ITEM_TYPE)) {
+                    addMatchCandidatesNickname(data2, MODE_INSERT_LOOKUP_DATA, candidates);
+                }
+            }
+        } finally {
+            c.close();
+        }
+
+        for (int i = 0; i < candidates.mCount; i++) {
+            NameMatchCandidate candidate = candidates.mList.get(i);
+            mOpenHelper.insertNameLookup(contactId, candidate.mLookupType, candidate.mName);
+        }
+    }
+
+    /**
+     * Updates aggregate-level data from constituent contacts.
+     */
+    private void updateAggregateData(final SQLiteDatabase db, long aggregateId,
+            final ContentValues values) {
+        updateDisplayName(db, aggregateId, values);
+        updateSendToVoicemailAndRingtone(db, aggregateId);
+    }
+
+    /**
+     * Updates the aggregate record's {@link Aggregates#DISPLAY_NAME} field. If none of the
+     * constituent contacts has a suitable name, leaves the aggregate record unchanged.
+     */
+    private void updateDisplayName(SQLiteDatabase db, long aggregateId, ContentValues values) {
+        String displayName = getBestDisplayName(db, aggregateId);
+
+        // If don't have anything to base the display name on, let's just leave what was in
+        // that field hoping that there was something there before and it is still valid.
+        if (displayName == null) {
+            return;
+        }
+
+        values.clear();
+        values.put(Aggregates.DISPLAY_NAME, displayName);
+        db.update(Tables.AGGREGATES, values, Aggregates._ID + "=" + aggregateId, null);
+    }
+
+    /**
+     * Updates the various {@link AggregatesColumns} primary values based on the
+     * newly joined {@link Contacts} entry. If some aggregate primary values are
+     * unassigned, primary values from this contact will be promoted as the new
+     * super-primaries.
+     */
+    private void updatePrimaries(SQLiteDatabase db, long aggId, long contactId, boolean newAgg) {
+        Cursor cursor = null;
+
+        boolean hasOptimalPhone = false;
+        boolean hasFallbackPhone = false;
+        boolean hasOptimalEmail = false;
+        boolean hasFallbackEmail = false;
+
+        // Read currently recorded aggregate primary values
+        try {
+            cursor = db.query(Tables.AGGREGATES, Projections.PROJ_AGGREGATE_PRIMARIES,
+                    Aggregates._ID + "=" + aggId, null, null, null, null);
+            if (cursor.moveToNext()) {
+                hasOptimalPhone = (cursor.getLong(Projections.COL_OPTIMAL_PRIMARY_PHONE_ID) != 0);
+                hasFallbackPhone = (cursor.getLong(Projections.COL_FALLBACK_PRIMARY_PHONE_ID) != 0);
+                hasOptimalEmail = (cursor.getLong(Projections.COL_OPTIMAL_PRIMARY_EMAIL_ID) != 0);
+                hasFallbackEmail = (cursor.getLong(Projections.COL_FALLBACK_PRIMARY_EMAIL_ID) != 0);
+            }
+        } finally {
+            if (cursor != null) {
+                cursor.close();
+            }
+        }
+
+        long candidatePhone = 0;
+        long candidateEmail = 0;
+        long candidatePackageId = 0;
+        boolean candidateIsRestricted = false;
+
+        // Find primary data items from newly-joined contact, returning one
+        // candidate for each mimetype.
+        try {
+            cursor = db.query(Tables.DATA_JOIN_MIMETYPES_CONTACTS_PACKAGES, Projections.PROJ_DATA,
+                    Data.CONTACT_ID + "=" + contactId + " AND " + Data.IS_PRIMARY + "=1 AND "
+                            + Projections.PRIMARY_MIME_CLAUSE, null, Data.MIMETYPE, null, null);
+            while (cursor.moveToNext()) {
+                final long dataId = cursor.getLong(Projections.COL_DATA_ID);
+                final String mimeType = cursor.getString(Projections.COL_DATA_MIMETYPE);
+
+                candidatePackageId = cursor.getLong(Projections.COL_PACKAGE_ID);
+                candidateIsRestricted = (cursor.getInt(Projections.COL_IS_RESTRICTED) == 1);
+
+                if (CommonDataKinds.Phone.CONTENT_ITEM_TYPE.equals(mimeType)) {
+                    candidatePhone = dataId;
+                } else if (CommonDataKinds.Email.CONTENT_ITEM_TYPE.equals(mimeType)) {
+                    candidateEmail = dataId;
+                }
+
+            }
+        } finally {
+            if (cursor != null) {
+                cursor.close();
+            }
+        }
+
+        final ContentValues values = new ContentValues();
+
+        // If a new aggregate, and single child is restricted, then mark
+        // aggregate as being protected by package. Otherwise set as null if
+        // multiple under aggregate or not restricted.
+        if (newAgg && candidateIsRestricted) {
+            values.put(AggregatesColumns.SINGLE_RESTRICTED_PACKAGE_ID, candidatePackageId);
+        } else {
+            values.putNull(AggregatesColumns.SINGLE_RESTRICTED_PACKAGE_ID);
+        }
+
+        // If newly joined contact has a primary phone number, consider
+        // promoting it up into aggregate as super-primary.
+        if (candidatePhone != 0) {
+            if (!hasOptimalPhone) {
+                values.put(AggregatesColumns.OPTIMAL_PRIMARY_PHONE_ID, candidatePhone);
+                values.put(AggregatesColumns.OPTIMAL_PRIMARY_PHONE_PACKAGE_ID, candidatePackageId);
+            }
+
+            // Also promote to unrestricted value, if none provided yet.
+            if (!hasFallbackPhone && !candidateIsRestricted) {
+                values.put(AggregatesColumns.FALLBACK_PRIMARY_PHONE_ID, candidatePhone);
+            }
+        }
+
+        // If newly joined contact has a primary email, consider promoting it up
+        // into aggregate as super-primary.
+        if (candidateEmail != 0) {
+            if (!hasOptimalEmail) {
+                values.put(AggregatesColumns.OPTIMAL_PRIMARY_EMAIL_ID, candidateEmail);
+                values.put(AggregatesColumns.OPTIMAL_PRIMARY_EMAIL_PACKAGE_ID, candidatePackageId);
+            }
+
+            // Also promote to unrestricted value, if none provided yet.
+            if (!hasFallbackEmail && !candidateIsRestricted) {
+                values.put(AggregatesColumns.FALLBACK_PRIMARY_EMAIL_ID, candidateEmail);
+            }
+        }
+
+        // Only write updated aggregate values if we made changes.
+        if (values.size() > 0) {
+            Log.d(TAG, "some sort of promotion is going on: " + values.toString());
+            db.update(Tables.AGGREGATES, values, Aggregates._ID + "=" + aggId, null);
+        }
+
+    }
+
+    /**
+     * Computes display name for the given aggregate.  Chooses a longer name over a shorter name
+     * and a mixed-case name over an all lowercase or uppercase name.
+     */
+    private String getBestDisplayName(SQLiteDatabase db, long aggregateId) {
+        String bestDisplayName = null;
+
+        final Cursor c = db.query(Tables.DATA_JOIN_MIMETYPES_CONTACTS_PACKAGES_AGGREGATES,
+                new String[] {StructuredName.DISPLAY_NAME},
+                DatabaseUtils.concatenateWhere(Contacts.AGGREGATE_ID + "=" + aggregateId,
+                        Data.MIMETYPE + "='" + StructuredName.CONTENT_ITEM_TYPE + "'"),
+                null, null, null, null);
+
+        try {
+            while (c.moveToNext()) {
+                String displayName = c.getString(0);
+                if (bestDisplayName == null) {
+                    bestDisplayName = displayName;
+                } else {
+                    if (NameNormalizer.compareComplexity(displayName, bestDisplayName) > 0) {
+                        bestDisplayName = displayName;
+                    }
+                }
+            }
+        } finally {
+            c.close();
+        }
+        return bestDisplayName;
+    }
+
+    /**
+     * Updates the aggregate's send-to-voicemail and custom-ringtone options based on
+     * constituent contacts' options.
+     */
+    private void updateSendToVoicemailAndRingtone(SQLiteDatabase db, long aggregateId) {
+        int totalContactCount = 0;
+        int sendToVoiceMailCount = 0;
+        String customRingtone = null;
+
+        final Cursor c = db.query(Tables.CONTACTS_JOIN_CONTACT_OPTIONS,
+                CONTACTS_JOIN_CONTACT_OPTIONS_COLUMNS,
+                Contacts.AGGREGATE_ID + "=" + aggregateId,
+                null, null, null, null);
+
+        try {
+            while (c.moveToNext()) {
+                totalContactCount++;
+                if (!c.isNull(COL_SEND_TO_VOICEMAIL)) {
+                    boolean sendToVoicemail = (c.getInt(COL_SEND_TO_VOICEMAIL) != 0);
+                    if (sendToVoicemail) {
+                        sendToVoiceMailCount++;
+                    }
+                }
+
+                if (customRingtone == null && !c.isNull(COL_CUSTOM_RINGTONE)) {
+                    customRingtone = c.getString(COL_CUSTOM_RINGTONE);
+                }
+            }
+        } finally {
+            c.close();
+        }
+
+        ContentValues values = new ContentValues(2);
+        values.put(Aggregates.SEND_TO_VOICEMAIL, totalContactCount == sendToVoiceMailCount);
+        values.put(Aggregates.CUSTOM_RINGTONE, customRingtone);
+
+        db.update(Tables.AGGREGATES, values, Aggregates._ID + "=" + aggregateId, null);
+    }
+
+    /**
+     * Finds matching aggregates and returns a cursor on those.
+     */
+    public Cursor queryAggregationSuggestions(long aggregateId, String[] projection,
+            HashMap<String, String> projectionMap, int maxSuggestions) {
+        final SQLiteDatabase db = mOpenHelper.getReadableDatabase();
+
+        Cursor c;
+
+        // If this method is called in the middle of aggregation pass, we want to pause the
+        // aggregation, but not kill it.
+        db.beginTransaction();
+        try {
+            List<MatchScore> bestMatches = findMatchingAggregates(db, aggregateId, maxSuggestions);
+            c = queryMatchingAggregates(db, aggregateId, projection, projectionMap, bestMatches);
+            db.setTransactionSuccessful();
+        } finally {
+            db.endTransaction();
+        }
+        return c;
+    }
+
+    /**
+     * Loads aggregates with specified IDs and returns them in the order of IDs in the
+     * supplied list.
+     */
+    private Cursor queryMatchingAggregates(final SQLiteDatabase db, long aggregateId,
+            String[] projection, HashMap<String, String> projectionMap,
+            List<MatchScore> bestMatches) {
+
+        StringBuilder selection = new StringBuilder();
+        selection.append(Aggregates._ID);
+        selection.append(" IN (");
+        for (int i = 0; i < bestMatches.size(); i++) {
+            MatchScore matchScore = bestMatches.get(i);
+            if (i != 0) {
+                selection.append(",");
+            }
+            selection.append(matchScore.getAggregateId());
+        }
+        selection.append(")");
+
+        final SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
+        qb.setTables(Tables.AGGREGATES);
+        qb.setProjectionMap(projectionMap);
+
+        final Cursor cursor = qb.query(db, projection, selection.toString(), null, null, null,
+                Aggregates._ID);
+
+        ArrayList<Long> sortedAggregateIds = new ArrayList<Long>(bestMatches.size());
+        for (MatchScore matchScore : bestMatches) {
+            sortedAggregateIds.add(matchScore.getAggregateId());
+        }
+
+        Collections.sort(sortedAggregateIds);
+
+        int[] positionMap = new int[bestMatches.size()];
+        for (int i = 0; i < positionMap.length; i++) {
+            long id = bestMatches.get(i).getAggregateId();
+            positionMap[i] = sortedAggregateIds.indexOf(id);
+        }
+
+        return new ReorderingCursorWrapper(cursor, positionMap);
+    }
+
+    /**
+     * Finds aggregates with data matches and returns a list of {@link MatchScore}'s in the
+     * descending order of match score.
+     */
+    private List<MatchScore> findMatchingAggregates(final SQLiteDatabase db,
+            long aggregateId, int maxSuggestions) {
+
+        MatchCandidateList candidates = new MatchCandidateList();
+        ContactMatcher matcher = new ContactMatcher();
+
+        // Don't aggregate an aggregate with itself
+        matcher.keepOut(aggregateId);
+
+        final Cursor c = db.query(Tables.CONTACTS, CONTACT_ID_COLUMN,
+                Contacts.AGGREGATE_ID + "=" + aggregateId, null, null, null, null);
+        try {
+            while (c.moveToNext()) {
+                long contactId = c.getLong(0);
+                updateMatchScoresBasedOnDataMatches(db, contactId, MODE_SUGGESTIONS, candidates,
+                        matcher);
+            }
+        } finally {
+            c.close();
+        }
+
+        List<MatchScore> matches = matcher.pickBestMatches(maxSuggestions,
+                ContactMatcher.SCORE_THRESHOLD_SUGGEST);
+
+        // TODO: remove the debug logging
+        Log.i(TAG, "MATCHES: " + matches);
+        return matches;
+    }
+
+    /**
+     * Various database projections used internally.
+     */
+    private interface Projections {
+        static final String[] PROJ_AGGREGATE_PRIMARIES = new String[] {
+                AggregatesColumns.OPTIMAL_PRIMARY_PHONE_ID,
+                AggregatesColumns.FALLBACK_PRIMARY_PHONE_ID,
+                AggregatesColumns.OPTIMAL_PRIMARY_EMAIL_ID,
+                AggregatesColumns.FALLBACK_PRIMARY_EMAIL_ID,
+                AggregatesColumns.SINGLE_RESTRICTED_PACKAGE_ID,
+        };
+
+        static final int COL_OPTIMAL_PRIMARY_PHONE_ID = 0;
+        static final int COL_FALLBACK_PRIMARY_PHONE_ID = 1;
+        static final int COL_OPTIMAL_PRIMARY_EMAIL_ID = 2;
+        static final int COL_FALLBACK_PRIMARY_EMAIL_ID = 3;
+        static final int COL_SINGLE_RESTRICTED_PACKAGE_ID = 4;
+
+        static final String[] PROJ_DATA = new String[] {
+                Tables.DATA + "." + Data._ID,
+                Data.MIMETYPE,
+                Contacts.IS_RESTRICTED,
+                ContactsColumns.PACKAGE_ID,
+        };
+
+        static final int COL_DATA_ID = 0;
+        static final int COL_DATA_MIMETYPE = 1;
+        static final int COL_IS_RESTRICTED = 2;
+        static final int COL_PACKAGE_ID = 3;
+
+        static final String PRIMARY_MIME_CLAUSE = "(" + Data.MIMETYPE + "=\""
+                + CommonDataKinds.Phone.CONTENT_ITEM_TYPE + "\" OR " + Data.MIMETYPE + "=\""
+                + CommonDataKinds.Email.CONTENT_ITEM_TYPE + "\")";
+    }
+}
diff --git a/src/com/android/providers/contacts/ContactMatcher.java b/src/com/android/providers/contacts/ContactMatcher.java
new file mode 100644
index 0000000..d4b3349
--- /dev/null
+++ b/src/com/android/providers/contacts/ContactMatcher.java
@@ -0,0 +1,471 @@
+/*
+ * Copyright (C) 2009 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;
+
+import com.android.providers.contacts.OpenHelper.NameLookupType;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+
+/**
+ * Logic for matching contacts' data and accumulating match scores.
+ */
+public class ContactMatcher {
+
+    // Best possible match score
+    public static final int MAX_SCORE = 100;
+
+    // Suggest to aggregate contacts if their match score is equal or greater than this threshold
+    public static final int SCORE_THRESHOLD_SUGGEST = 50;
+
+    // Automatically aggregate contacts if their match score is equal or greater than this threshold
+    public static final int SCORE_THRESHOLD_PRIMARY = 70;
+
+    // Automatically aggregate contacts if the match score is equal or greater than this threshold
+    // and there is a secondary match (phone number, email etc).
+    public static final int SCORE_THRESHOLD_SECONDARY = 50;
+
+    // Score for missing data (as opposed to present data but a bad match)
+    private static final int NO_DATA_SCORE = -1;
+
+    // Score for matching phone numbers
+    private static final int PHONE_MATCH_SCORE = 71;
+
+    // Score for matching email addresses
+    private static final int EMAIL_MATCH_SCORE = 71;
+
+    // Score for matching nickname
+    private static final int NICKNAME_MATCH_SCORE = 71;
+
+    // Minimum edit distance between two names to be considered an approximate match
+    public static final float APPROXIMATE_MATCH_THRESHOLD = 0.7f;
+
+    // Maximum number of characters in a name to be considered by the matching algorithm.
+    private static final int MAX_MATCHED_NAME_LENGTH = 12;
+
+    // Scores a multiplied by this number to allow room for "fractional" scores
+    private static final int SCORE_SCALE = 1000;
+
+
+    /**
+     * Name matching scores: a matrix by name type vs. candidate lookup type.
+     * For example, if the name type is "full name" while we are looking for a
+     * "full name", the score may be 99. If we are looking for a "nickname" but
+     * find "first name", the score may be 50 (see specific scores defined
+     * below.)
+     * <p>
+     * For approximate matching, we have a range of scores, let's say 40-70.  Depending one how
+     * similar the two strings are, the score will be somewhere between 40 and 70, with the exact
+     * match producing the score of 70.  The score may also be 0 if the similarity (distance)
+     * between the strings is below the threshold.
+     * <p>
+     * We use the Jaro-Winkler algorithm, which is particularly suited for
+     * name matching. See {@link JaroWinklerDistance}.
+     */
+    private static int[] sMinScore =
+            new int[NameLookupType.TYPE_COUNT * NameLookupType.TYPE_COUNT];
+    private static int[] sMaxScore =
+            new int[NameLookupType.TYPE_COUNT * NameLookupType.TYPE_COUNT];
+
+    /*
+     * Note: the reverse names ({@link NameLookupType#FULL_NAME_REVERSE},
+     * {@link NameLookupType#FULL_NAME_REVERSE_CONCATENATED} may appear to be redundant. They are
+     * not!  They are useful in three-way aggregation cases when we have, for example, both
+     * John Smith and Smith John.  A third contact with the name John Smith should be aggregated
+     * with the former rather than the latter.  This is why "reverse" matches have slightly lower
+     * scores than direct matches.
+     */
+    static {
+        setScoreRange(NameLookupType.FULL_NAME,
+                NameLookupType.FULL_NAME, 99, 99);
+        setScoreRange(NameLookupType.FULL_NAME,
+                NameLookupType.FULL_NAME_REVERSE, 90, 90);
+
+        setScoreRange(NameLookupType.FULL_NAME_REVERSE,
+                NameLookupType.FULL_NAME, 90, 90);
+        setScoreRange(NameLookupType.FULL_NAME_REVERSE,
+                NameLookupType.FULL_NAME_REVERSE, 99, 99);
+
+        setScoreRange(NameLookupType.FULL_NAME_CONCATENATED,
+                NameLookupType.FULL_NAME_CONCATENATED, 40, 80);
+        setScoreRange(NameLookupType.FULL_NAME_CONCATENATED,
+                NameLookupType.FULL_NAME_REVERSE_CONCATENATED, 30, 70);
+        setScoreRange(NameLookupType.FULL_NAME_CONCATENATED,
+                NameLookupType.EMAIL_BASED_NICKNAME, 30, 60);
+        setScoreRange(NameLookupType.FULL_NAME_CONCATENATED,
+                NameLookupType.NICKNAME, 30, 60);
+
+        setScoreRange(NameLookupType.FULL_NAME_REVERSE_CONCATENATED,
+                NameLookupType.FULL_NAME_CONCATENATED, 30, 70);
+        setScoreRange(NameLookupType.FULL_NAME_REVERSE_CONCATENATED,
+                NameLookupType.FULL_NAME_REVERSE_CONCATENATED, 40, 80);
+
+        setScoreRange(NameLookupType.FULL_NAME_WITH_NICKNAME,
+                NameLookupType.FULL_NAME_WITH_NICKNAME, 75, 75);
+        setScoreRange(NameLookupType.FULL_NAME_WITH_NICKNAME_REVERSE,
+                NameLookupType.FULL_NAME_WITH_NICKNAME_REVERSE, 73, 73);
+
+        setScoreRange(NameLookupType.FAMILY_NAME_ONLY,
+                NameLookupType.FAMILY_NAME_ONLY, 45, 75);
+        setScoreRange(NameLookupType.FAMILY_NAME_ONLY,
+                NameLookupType.FULL_NAME_CONCATENATED, 32, 72);
+        setScoreRange(NameLookupType.FAMILY_NAME_ONLY,
+                NameLookupType.FULL_NAME_REVERSE_CONCATENATED, 30, 70);
+        setScoreRange(NameLookupType.FAMILY_NAME_ONLY,
+                NameLookupType.EMAIL_BASED_NICKNAME, 30, 60);
+        setScoreRange(NameLookupType.FAMILY_NAME_ONLY,
+                NameLookupType.NICKNAME, 30, 60);
+
+        setScoreRange(NameLookupType.FAMILY_NAME_ONLY_AS_NICKNAME,
+                NameLookupType.FAMILY_NAME_ONLY_AS_NICKNAME, 71, 71);
+        setScoreRange(NameLookupType.FAMILY_NAME_ONLY_AS_NICKNAME,
+                NameLookupType.GIVEN_NAME_ONLY_AS_NICKNAME, 70, 70);
+
+        setScoreRange(NameLookupType.GIVEN_NAME_ONLY,
+                NameLookupType.GIVEN_NAME_ONLY, 40, 70);
+        setScoreRange(NameLookupType.GIVEN_NAME_ONLY,
+                NameLookupType.FULL_NAME_CONCATENATED, 32, 72);
+        setScoreRange(NameLookupType.GIVEN_NAME_ONLY,
+                NameLookupType.FULL_NAME_REVERSE_CONCATENATED, 30, 70);
+        setScoreRange(NameLookupType.GIVEN_NAME_ONLY,
+                NameLookupType.EMAIL_BASED_NICKNAME, 30, 60);
+        setScoreRange(NameLookupType.GIVEN_NAME_ONLY,
+                NameLookupType.NICKNAME, 30, 60);
+
+        setScoreRange(NameLookupType.GIVEN_NAME_ONLY_AS_NICKNAME,
+                NameLookupType.GIVEN_NAME_ONLY_AS_NICKNAME, 73, 73);
+        setScoreRange(NameLookupType.GIVEN_NAME_ONLY_AS_NICKNAME,
+                NameLookupType.FAMILY_NAME_ONLY_AS_NICKNAME, 70, 70);
+
+        setScoreRange(NameLookupType.EMAIL_BASED_NICKNAME,
+                NameLookupType.EMAIL_BASED_NICKNAME, 30, 60);
+        setScoreRange(NameLookupType.EMAIL_BASED_NICKNAME,
+                NameLookupType.GIVEN_NAME_ONLY, 30, 60);
+        setScoreRange(NameLookupType.EMAIL_BASED_NICKNAME,
+                NameLookupType.FAMILY_NAME_ONLY, 30, 60);
+        setScoreRange(NameLookupType.EMAIL_BASED_NICKNAME,
+                NameLookupType.FULL_NAME_CONCATENATED, 30, 60);
+        setScoreRange(NameLookupType.EMAIL_BASED_NICKNAME,
+                NameLookupType.FULL_NAME_REVERSE_CONCATENATED, 30, 60);
+        setScoreRange(NameLookupType.EMAIL_BASED_NICKNAME,
+                NameLookupType.NICKNAME, 30, 60);
+
+        setScoreRange(NameLookupType.NICKNAME,
+                NameLookupType.NICKNAME, 30, 60);
+        setScoreRange(NameLookupType.NICKNAME,
+                NameLookupType.GIVEN_NAME_ONLY, 30, 60);
+        setScoreRange(NameLookupType.NICKNAME,
+                NameLookupType.FAMILY_NAME_ONLY, 30, 60);
+        setScoreRange(NameLookupType.NICKNAME,
+                NameLookupType.FULL_NAME_CONCATENATED, 30, 60);
+        setScoreRange(NameLookupType.NICKNAME,
+                NameLookupType.FULL_NAME_REVERSE_CONCATENATED, 30, 60);
+        setScoreRange(NameLookupType.NICKNAME,
+                NameLookupType.EMAIL_BASED_NICKNAME, 30, 60);
+    }
+
+    /**
+     * Populates the cells of the score matrix and score span matrix
+     * corresponding to the {@code candidateNameType} and {@code nameType}.
+     */
+    private static void setScoreRange(int candidateNameType, int nameType, int scoreFrom, int scoreTo) {
+        int index = nameType * NameLookupType.TYPE_COUNT + candidateNameType;
+        sMinScore[index] = scoreFrom;
+        sMaxScore[index] = scoreTo;
+    }
+
+    /**
+     * Returns the lower range for the match score for the given {@code candidateNameType} and
+     * {@code nameType}.
+     */
+    private static int getMinScore(int candidateNameType, int nameType) {
+        int index = nameType * NameLookupType.TYPE_COUNT + candidateNameType;
+        return sMinScore[index];
+    }
+
+    /**
+     * Returns the upper range for the match score for the given {@code candidateNameType} and
+     * {@code nameType}.
+     */
+    private static int getMaxScore(int candidateNameType, int nameType) {
+        int index = nameType * NameLookupType.TYPE_COUNT + candidateNameType;
+        return sMaxScore[index];
+    }
+
+    /**
+     * Captures the max score and match count for a specific aggregate.  Used in an
+     * aggregateId - MatchScore map.
+     */
+    public static class MatchScore implements Comparable<MatchScore> {
+        private long mAggregateId;
+        private boolean mKeepIn;
+        private boolean mKeepOut;
+        private int mPrimaryScore;
+        private int mSecondaryScore;
+        private int mMatchCount;
+
+        public MatchScore(long aggregateId) {
+            this.mAggregateId = aggregateId;
+        }
+
+        public void reset(long aggregateId) {
+            this.mAggregateId = aggregateId;
+            mKeepIn = false;
+            mKeepOut = false;
+            mPrimaryScore = 0;
+            mSecondaryScore = 0;
+            mMatchCount = 0;
+        }
+
+        public long getAggregateId() {
+            return mAggregateId;
+        }
+
+        public void updatePrimaryScore(int score) {
+            if (score > mPrimaryScore) {
+                mPrimaryScore = score;
+            }
+            mMatchCount++;
+        }
+
+        public void updateSecondaryScore(int score) {
+            if (score > mSecondaryScore) {
+                mSecondaryScore = score;
+            }
+            mMatchCount++;
+        }
+
+        public void keepIn() {
+            mKeepIn = true;
+        }
+
+        public void keepOut() {
+            mKeepOut = true;
+        }
+
+        public int getScore() {
+            if (mKeepOut) {
+                return 0;
+            }
+
+            if (mKeepIn) {
+                return MAX_SCORE;
+            }
+
+            int score = (mPrimaryScore > mSecondaryScore ? mPrimaryScore : mSecondaryScore);
+
+            // Ensure that of two aggregates with the same match score the one with more matching
+            // data elements wins.
+            return score * SCORE_SCALE + mMatchCount;
+        }
+
+        /**
+         * Descending order of match score.
+         */
+        public int compareTo(MatchScore another) {
+            return another.getScore() - getScore();
+        }
+
+        @Override
+        public String toString() {
+            return mAggregateId + ": " + mPrimaryScore + "/" + mSecondaryScore + "(" + mMatchCount
+                    + ")";
+        }
+    }
+
+    private final HashMap<Long, MatchScore> mScores = new HashMap<Long, MatchScore>();
+    private final ArrayList<MatchScore> mScoreList = new ArrayList<MatchScore>();
+    private int mScoreCount = 0;
+
+    private final JaroWinklerDistance mJaroWinklerDistance =
+            new JaroWinklerDistance(MAX_MATCHED_NAME_LENGTH);
+
+    private MatchScore getMatchingScore(long aggregateId) {
+        MatchScore matchingScore = mScores.get(aggregateId);
+        if (matchingScore == null) {
+            if (mScoreList.size() > mScoreCount) {
+                matchingScore = mScoreList.get(mScoreCount);
+                matchingScore.reset(aggregateId);
+            } else {
+                matchingScore = new MatchScore(aggregateId);
+                mScoreList.add(matchingScore);
+            }
+            mScoreCount++;
+            mScores.put(aggregateId, matchingScore);
+        }
+        return matchingScore;
+    }
+
+    /**
+     * Checks if there is a match and updates the overall score for the
+     * specified aggregate for a discovered match. The new score is determined
+     * by the prior score, by the type of name we were looking for, the type
+     * of name we found and, if the match is approximate, the distance between the candidate and
+     * actual name.
+     */
+    public void matchName(long aggregateId, int candidateNameType, String candidateName,
+            int nameType, String name, boolean approximate) {
+        int maxScore = getMaxScore(candidateNameType, nameType);
+        if (maxScore == 0) {
+            return;
+        }
+
+        if (candidateName.equals(name)) {
+            updatePrimaryScore(aggregateId, maxScore);
+            return;
+        }
+
+        if (!approximate) {
+            return;
+        }
+
+        int minScore = getMinScore(candidateNameType, nameType);
+        if (minScore == maxScore) {
+            return;
+        }
+
+        float distance = mJaroWinklerDistance.getDistance(
+                Hex.decodeHex(candidateName), Hex.decodeHex(name));
+
+        int score;
+        if (distance > APPROXIMATE_MATCH_THRESHOLD) {
+            float adjustedDistance = (distance - APPROXIMATE_MATCH_THRESHOLD)
+                    / (1f - APPROXIMATE_MATCH_THRESHOLD);
+            score = (int)(minScore +  (maxScore - minScore) * adjustedDistance);
+        } else {
+            score = 0;
+        }
+
+        updatePrimaryScore(aggregateId, score);
+    }
+
+    public void updateScoreWithPhoneNumberMatch(long aggregateId) {
+        updateSecondaryScore(aggregateId, PHONE_MATCH_SCORE);
+    }
+
+    public void updateScoreWithEmailMatch(long aggregateId) {
+        updateSecondaryScore(aggregateId, EMAIL_MATCH_SCORE);
+    }
+
+    public void updateScoreWithNicknameMatch(long aggregateId) {
+        updateSecondaryScore(aggregateId, NICKNAME_MATCH_SCORE);
+    }
+
+    private void updatePrimaryScore(long aggregateId, int score) {
+        getMatchingScore(aggregateId).updatePrimaryScore(score);
+    }
+
+    private void updateSecondaryScore(long aggregateId, int score) {
+        getMatchingScore(aggregateId).updateSecondaryScore(score);
+    }
+
+    public void keepIn(long aggregateId) {
+        getMatchingScore(aggregateId).keepIn();
+    }
+
+    public void keepOut(long aggregateId) {
+        getMatchingScore(aggregateId).keepOut();
+    }
+
+    public void clear() {
+        mScores.clear();
+        mScoreCount = 0;
+    }
+
+    /**
+     * Returns a list of IDs for aggregates that are matched on secondary data elements
+     * (phone number, email address, nickname). We still need to obtain the approximate
+     * primary score for those aggregates to determine if any of them should be aggregated.
+     * <p>
+     * May return null.
+     */
+    public List<Long> prepareSecondaryMatchCandidates(int threshold) {
+        ArrayList<Long> aggregateIds = null;
+
+        for (int i = 0; i < mScoreCount; i++) {
+            MatchScore score = mScoreList.get(i);
+            if (score.mKeepOut) {
+                continue;
+            }
+
+            int s = score.mSecondaryScore;
+            if (s >= threshold) {
+                if (aggregateIds == null) {
+                    aggregateIds = new ArrayList<Long>();
+                }
+                aggregateIds.add(score.mAggregateId);
+                score.mPrimaryScore = NO_DATA_SCORE;
+            }
+        }
+        return aggregateIds;
+    }
+
+    /**
+     * Returns the aggregateId with the best match score over the specified threshold or -1
+     * if no such aggregate is found.
+     */
+    public long pickBestMatch(int threshold) {
+        long aggregateId = -1;
+        int maxScore = 0;
+        for (int i = 0; i < mScoreCount; i++) {
+            MatchScore score = mScoreList.get(i);
+            if (score.mKeepIn) {
+                return score.mAggregateId;
+            }
+
+            if (score.mKeepOut) {
+                continue;
+            }
+
+            int s = score.mPrimaryScore;
+            if (s == NO_DATA_SCORE) {
+                s = score.mSecondaryScore;
+            }
+
+            if (s >= threshold && s > maxScore) {
+                aggregateId = score.mAggregateId;
+                maxScore = s;
+            }
+        }
+        return aggregateId;
+    }
+
+    /**
+     * Returns up to {@code maxSuggestions} best scoring matches.
+     */
+    public List<MatchScore> pickBestMatches(int maxSuggestions, int threshold) {
+        int scaledThreshold = threshold * SCORE_SCALE;
+        List<MatchScore> matches = mScoreList.subList(0, mScoreCount);
+        Collections.sort(matches);
+        int count = 0;
+        for (int i = 0; i < mScoreCount; i++) {
+            MatchScore matchScore = matches.get(i);
+            if (matchScore.getScore() >= scaledThreshold) {
+                count++;
+            } else {
+                break;
+            }
+        }
+
+        if (count > maxSuggestions) {
+            count = maxSuggestions;
+        }
+
+        return matches.subList(0, count);
+    }
+}
diff --git a/src/com/android/providers/contacts/ContactsProvider2.java b/src/com/android/providers/contacts/ContactsProvider2.java
new file mode 100644
index 0000000..49975ed
--- /dev/null
+++ b/src/com/android/providers/contacts/ContactsProvider2.java
@@ -0,0 +1,2134 @@
+/*
+ * Copyright (C) 2009 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;
+
+import com.android.providers.contacts.OpenHelper.AggregatesColumns;
+import com.android.providers.contacts.OpenHelper.AggregationExceptionColumns;
+import com.android.providers.contacts.OpenHelper.Clauses;
+import com.android.providers.contacts.OpenHelper.ContactsColumns;
+import com.android.providers.contacts.OpenHelper.ContactOptionsColumns;
+import com.android.providers.contacts.OpenHelper.DataColumns;
+import com.android.providers.contacts.OpenHelper.GroupsColumns;
+import com.android.providers.contacts.OpenHelper.MimetypesColumns;
+import com.android.providers.contacts.OpenHelper.PhoneLookupColumns;
+import com.android.providers.contacts.OpenHelper.Tables;
+
+import android.accounts.Account;
+import android.accounts.AccountManager;
+import android.accounts.OnAccountsUpdatedListener;
+import android.content.ContentProvider;
+import android.content.ContentProviderOperation;
+import android.content.ContentProviderResult;
+import android.content.ContentUris;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.Entity;
+import android.content.EntityIterator;
+import android.content.OperationApplicationException;
+import android.content.UriMatcher;
+import android.content.pm.PackageManager;
+import android.database.Cursor;
+import android.database.DatabaseUtils;
+import android.database.sqlite.SQLiteCursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteQueryBuilder;
+import android.database.sqlite.SQLiteStatement;
+import android.net.Uri;
+import android.os.Binder;
+import android.os.RemoteException;
+import android.provider.BaseColumns;
+import android.provider.ContactsContract;
+import android.provider.SocialContract;
+import android.provider.Contacts.ContactMethods;
+import android.provider.ContactsContract.Accounts;
+import android.provider.ContactsContract.Aggregates;
+import android.provider.ContactsContract.AggregationExceptions;
+import android.provider.ContactsContract.CommonDataKinds;
+import android.provider.ContactsContract.Contacts;
+import android.provider.ContactsContract.Data;
+import android.provider.ContactsContract.Groups;
+import android.provider.ContactsContract.Presence;
+import android.provider.ContactsContract.RestrictionExceptions;
+import android.provider.ContactsContract.Aggregates.AggregationSuggestions;
+import android.provider.ContactsContract.CommonDataKinds.Email;
+import android.provider.ContactsContract.CommonDataKinds.GroupMembership;
+import android.provider.ContactsContract.CommonDataKinds.Phone;
+import android.provider.ContactsContract.CommonDataKinds.Postal;
+import android.provider.ContactsContract.CommonDataKinds.StructuredName;
+import android.telephony.PhoneNumberUtils;
+import android.text.TextUtils;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.HashMap;
+
+/**
+ * Contacts content provider. The contract between this provider and applications
+ * is defined in {@link ContactsContract}.
+ */
+public class ContactsProvider2 extends ContentProvider implements OnAccountsUpdatedListener {
+    // TODO: clean up debug tag and rename this class
+    private static final String TAG = "ContactsProvider ~~~~";
+
+    // TODO: define broadcastreceiver to catch app uninstalls that should clear exceptions
+    // TODO: carefully prevent all incoming nested queries; they can be gaping security holes
+    // TODO: check for restricted flag during insert(), update(), and delete() calls
+
+    private static final UriMatcher sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
+
+    private static final String STREQUENT_ORDER_BY = Aggregates.STARRED + " DESC, "
+            + Aggregates.TIMES_CONTACTED + " DESC, "
+            + Aggregates.DISPLAY_NAME + " ASC";
+    private static final String STREQUENT_LIMIT =
+            "(SELECT COUNT(1) FROM " + Tables.AGGREGATES + " WHERE "
+            + Aggregates.STARRED + "=1) + 25";
+
+    private static final int AGGREGATES = 1000;
+    private static final int AGGREGATES_ID = 1001;
+    private static final int AGGREGATES_DATA = 1002;
+    private static final int AGGREGATES_SUMMARY = 1003;
+    private static final int AGGREGATES_SUMMARY_ID = 1004;
+    private static final int AGGREGATES_SUMMARY_FILTER = 1005;
+    private static final int AGGREGATES_SUMMARY_STREQUENT = 1006;
+    private static final int AGGREGATES_SUMMARY_STREQUENT_FILTER = 1007;
+
+    private static final int CONTACTS = 2002;
+    private static final int CONTACTS_ID = 2003;
+    private static final int CONTACTS_DATA = 2004;
+    private static final int CONTACTS_FILTER_EMAIL = 2005;
+
+    private static final int DATA = 3000;
+    private static final int DATA_ID = 3001;
+    private static final int PHONES = 3002;
+    private static final int PHONES_FILTER = 3003;
+    private static final int POSTALS = 3004;
+
+    private static final int PHONE_LOOKUP = 4000;
+
+    private static final int ACCOUNTS = 5000;
+    private static final int ACCOUNTS_ID = 5001;
+
+    private static final int AGGREGATION_EXCEPTIONS = 6000;
+    private static final int AGGREGATION_EXCEPTION_ID = 6001;
+
+    private static final int PRESENCE = 7000;
+    private static final int PRESENCE_ID = 7001;
+
+    private static final int AGGREGATION_SUGGESTIONS = 8000;
+
+    private static final int RESTRICTION_EXCEPTIONS = 9000;
+
+    private static final int GROUPS = 10000;
+    private static final int GROUPS_ID = 10001;
+    private static final int GROUPS_SUMMARY = 10003;
+
+    private interface Projections {
+        public static final String[] PROJ_CONTACTS = new String[] {
+            ContactsColumns.CONCRETE_ID,
+        };
+
+        public static final String[] PROJ_DATA_CONTACTS = new String[] {
+                ContactsColumns.CONCRETE_ID,
+                DataColumns.CONCRETE_ID,
+                Contacts.AGGREGATE_ID,
+                ContactsColumns.PACKAGE_ID,
+                Contacts.IS_RESTRICTED,
+                Data.MIMETYPE,
+        };
+
+        public static final int COL_CONTACT_ID = 0;
+        public static final int COL_DATA_ID = 1;
+        public static final int COL_AGGREGATE_ID = 2;
+        public static final int COL_PACKAGE_ID = 3;
+        public static final int COL_IS_RESTRICTED = 4;
+        public static final int COL_MIMETYPE = 5;
+
+        public static final String[] PROJ_DATA_AGGREGATES = new String[] {
+            ContactsColumns.CONCRETE_ID,
+                DataColumns.CONCRETE_ID,
+                AggregatesColumns.CONCRETE_ID,
+                MimetypesColumns.CONCRETE_ID,
+                Phone.NUMBER,
+                Email.DATA,
+                AggregatesColumns.OPTIMAL_PRIMARY_PHONE_ID,
+                AggregatesColumns.FALLBACK_PRIMARY_PHONE_ID,
+                AggregatesColumns.OPTIMAL_PRIMARY_EMAIL_ID,
+                AggregatesColumns.FALLBACK_PRIMARY_EMAIL_ID,
+        };
+
+        public static final int COL_MIMETYPE_ID = 3;
+        public static final int COL_PHONE_NUMBER = 4;
+        public static final int COL_EMAIL_DATA = 5;
+        public static final int COL_OPTIMAL_PHONE_ID = 6;
+        public static final int COL_FALLBACK_PHONE_ID = 7;
+        public static final int COL_OPTIMAL_EMAIL_ID = 8;
+        public static final int COL_FALLBACK_EMAIL_ID = 9;
+
+    }
+
+    /** Default for the maximum number of returned aggregation suggestions. */
+    private static final int DEFAULT_MAX_SUGGESTIONS = 5;
+
+    /** Contains just the contacts columns */
+    private static final HashMap<String, String> sAggregatesProjectionMap;
+    /** Contains the aggregate columns along with primary phone */
+    private static final HashMap<String, String> sAggregatesSummaryProjectionMap;
+    /** Contains the data, contacts, and aggregate columns, for joined tables. */
+    private static final HashMap<String, String> sDataContactsAggregateProjectionMap;
+    /** Contains just the contacts columns */
+    private static final HashMap<String, String> sContactsProjectionMap;
+    /** Contains just the data columns */
+    private static final HashMap<String, String> sDataProjectionMap;
+    /** Contains the data and contacts columns, for joined tables */
+    private static final HashMap<String, String> sDataContactsProjectionMap;
+    /** Contains the data and contacts columns, for joined tables */
+    private static final HashMap<String, String> sDataContactsAccountsProjectionMap;
+    /** Contains just the key and value columns */
+    private static final HashMap<String, String> sAccountsProjectionMap;
+    /** Contains the just the {@link Groups} columns */
+    private static final HashMap<String, String> sGroupsProjectionMap;
+    /** Contains {@link Groups} columns along with summary details */
+    private static final HashMap<String, String> sGroupsSummaryProjectionMap;
+    /** Contains the just the agg_exceptions columns */
+    private static final HashMap<String, String> sAggregationExceptionsProjectionMap;
+    /** Contains the just the {@link RestrictionExceptions} columns */
+    private static final HashMap<String, String> sRestrictionExceptionsProjectionMap;
+
+    private static final HashMap<Account, Long> sAccountsToIdMap = new HashMap<Account, Long>();
+    private static final HashMap<Long, Account> sIdToAccountsMap = new HashMap<Long, Account>();
+
+    /** Sql select statement that returns the contact id associated with a data record. */
+    private static final String sNestedContactIdSelect;
+    /** Sql select statement that returns the mimetype id associated with a data record. */
+    private static final String sNestedMimetypeSelect;
+    /** Sql select statement that returns the aggregate id associated with a contact record. */
+    private static final String sNestedAggregateIdSelect;
+    /** Sql select statement that returns a list of contact ids associated with an aggregate record. */
+    private static final String sNestedContactIdListSelect;
+    /** Sql where statement used to match all the data records that need to be updated when a new
+     * "primary" is selected.*/
+    private static final String sSetPrimaryWhere;
+    /** Sql where statement used to match all the data records that need to be updated when a new
+     * "super primary" is selected.*/
+    private static final String sSetSuperPrimaryWhere;
+    /** Precompiled sql statement for setting a data record to the primary. */
+    private SQLiteStatement mSetPrimaryStatement;
+    /** Precomipled sql statement for setting a data record to the super primary. */
+    private SQLiteStatement mSetSuperPrimaryStatement;
+
+    private static final String GTALK_PROTOCOL_STRING = ContactMethods
+            .encodePredefinedImProtocol(ContactMethods.PROTOCOL_GOOGLE_TALK);
+
+    static {
+        // Contacts URI matching table
+        final UriMatcher matcher = sUriMatcher;
+        matcher.addURI(ContactsContract.AUTHORITY, "accounts", ACCOUNTS);
+        matcher.addURI(ContactsContract.AUTHORITY, "accounts/#", ACCOUNTS_ID);
+        matcher.addURI(ContactsContract.AUTHORITY, "aggregates", AGGREGATES);
+        matcher.addURI(ContactsContract.AUTHORITY, "aggregates/#", AGGREGATES_ID);
+        matcher.addURI(ContactsContract.AUTHORITY, "aggregates/#/data", AGGREGATES_DATA);
+        matcher.addURI(ContactsContract.AUTHORITY, "aggregates_summary", AGGREGATES_SUMMARY);
+        matcher.addURI(ContactsContract.AUTHORITY, "aggregates_summary/#", AGGREGATES_SUMMARY_ID);
+        matcher.addURI(ContactsContract.AUTHORITY, "aggregates_summary/filter/*",
+                AGGREGATES_SUMMARY_FILTER);
+        matcher.addURI(ContactsContract.AUTHORITY, "aggregates_summary/strequent/",
+                AGGREGATES_SUMMARY_STREQUENT);
+        matcher.addURI(ContactsContract.AUTHORITY, "aggregates_summary/strequent/filter/*",
+                AGGREGATES_SUMMARY_STREQUENT_FILTER);
+        matcher.addURI(ContactsContract.AUTHORITY, "aggregates/#/suggestions",
+                AGGREGATION_SUGGESTIONS);
+        matcher.addURI(ContactsContract.AUTHORITY, "contacts", CONTACTS);
+        matcher.addURI(ContactsContract.AUTHORITY, "contacts/#", CONTACTS_ID);
+        matcher.addURI(ContactsContract.AUTHORITY, "contacts/#/data", CONTACTS_DATA);
+        matcher.addURI(ContactsContract.AUTHORITY, "contacts/filter_email/*",
+                CONTACTS_FILTER_EMAIL);
+
+        matcher.addURI(ContactsContract.AUTHORITY, "data", DATA);
+        matcher.addURI(ContactsContract.AUTHORITY, "data/#", DATA_ID);
+        matcher.addURI(ContactsContract.AUTHORITY, "data/phones", PHONES);
+        matcher.addURI(ContactsContract.AUTHORITY, "data/phones/filter/*", PHONES_FILTER);
+        matcher.addURI(ContactsContract.AUTHORITY, "data/postals", POSTALS);
+
+        matcher.addURI(ContactsContract.AUTHORITY, "groups", GROUPS);
+        matcher.addURI(ContactsContract.AUTHORITY, "groups/#", GROUPS_ID);
+        matcher.addURI(ContactsContract.AUTHORITY, "groups_summary", GROUPS_SUMMARY);
+
+        matcher.addURI(ContactsContract.AUTHORITY, "phone_lookup/*", PHONE_LOOKUP);
+        matcher.addURI(ContactsContract.AUTHORITY, "aggregation_exceptions",
+                AGGREGATION_EXCEPTIONS);
+        matcher.addURI(ContactsContract.AUTHORITY, "aggregation_exceptions/*",
+                AGGREGATION_EXCEPTION_ID);
+
+        matcher.addURI(ContactsContract.AUTHORITY, "presence", PRESENCE);
+        matcher.addURI(ContactsContract.AUTHORITY, "presence/#", PRESENCE_ID);
+
+        matcher.addURI(ContactsContract.AUTHORITY, "restriction_exceptions", RESTRICTION_EXCEPTIONS);
+
+        HashMap<String, String> columns;
+
+        // Accounts projection map
+        columns = new HashMap<String, String>();
+        columns.put(Accounts._ID, "accounts._id AS _id");
+        columns.put(Accounts.NAME, Accounts.NAME);
+        columns.put(Accounts.TYPE, Accounts.TYPE);
+        columns.put(Accounts.DATA1, Accounts.DATA1);
+        columns.put(Accounts.DATA2, Accounts.DATA2);
+        columns.put(Accounts.DATA3, Accounts.DATA3);
+        columns.put(Accounts.DATA4, Accounts.DATA4);
+        columns.put(Accounts.DATA5, Accounts.DATA5);
+        sAccountsProjectionMap = columns;
+
+        // Aggregates projection map
+        columns = new HashMap<String, String>();
+        columns.put(Aggregates._ID, "aggregates._id AS _id");
+        columns.put(Aggregates.DISPLAY_NAME, Aggregates.DISPLAY_NAME);
+        columns.put(Aggregates.LAST_TIME_CONTACTED, Aggregates.LAST_TIME_CONTACTED);
+        columns.put(Aggregates.TIMES_CONTACTED, Aggregates.TIMES_CONTACTED);
+        columns.put(Aggregates.STARRED, Aggregates.STARRED);
+        columns.put(Aggregates.IN_VISIBLE_GROUP, Aggregates.IN_VISIBLE_GROUP);
+        columns.put(Aggregates.PRIMARY_PHONE_ID, Aggregates.PRIMARY_PHONE_ID);
+        columns.put(Aggregates.PRIMARY_EMAIL_ID, Aggregates.PRIMARY_EMAIL_ID);
+        columns.put(Aggregates.CUSTOM_RINGTONE, Aggregates.CUSTOM_RINGTONE);
+        columns.put(Aggregates.SEND_TO_VOICEMAIL, Aggregates.SEND_TO_VOICEMAIL);
+        columns.put(AggregatesColumns.FALLBACK_PRIMARY_PHONE_ID,
+                AggregatesColumns.FALLBACK_PRIMARY_PHONE_ID);
+        columns.put(AggregatesColumns.FALLBACK_PRIMARY_EMAIL_ID,
+                AggregatesColumns.FALLBACK_PRIMARY_EMAIL_ID);
+        sAggregatesProjectionMap = columns;
+
+        // Aggregates primaries projection map. The overall presence status is
+        // the most-present value, as indicated by the largest value.
+        columns = new HashMap<String, String>();
+        columns.putAll(sAggregatesProjectionMap);
+        columns.put(CommonDataKinds.Phone.TYPE, CommonDataKinds.Phone.TYPE);
+        columns.put(CommonDataKinds.Phone.LABEL, CommonDataKinds.Phone.LABEL);
+        columns.put(CommonDataKinds.Phone.NUMBER, CommonDataKinds.Phone.NUMBER);
+        columns.put(Presence.PRESENCE_STATUS, "MAX(" + Presence.PRESENCE_STATUS + ")");
+        sAggregatesSummaryProjectionMap = columns;
+
+        // Contacts projection map
+        columns = new HashMap<String, String>();
+        columns.put(Contacts._ID, "contacts._id AS _id");
+        columns.put(Contacts.PACKAGE, Contacts.PACKAGE);
+        columns.put(Contacts.AGGREGATE_ID, Contacts.AGGREGATE_ID);
+        columns.put(Accounts.NAME, Accounts.NAME);
+        columns.put(Accounts.TYPE, Accounts.TYPE);
+        columns.put(Contacts.SOURCE_ID, Contacts.SOURCE_ID);
+        columns.put(Contacts.VERSION, Contacts.VERSION);
+        columns.put(Contacts.DIRTY, Contacts.DIRTY);
+        sContactsProjectionMap = columns;
+
+        // Data projection map
+        columns = new HashMap<String, String>();
+        columns.put(Data._ID, "data._id AS _id");
+        columns.put(Data.CONTACT_ID, Data.CONTACT_ID);
+        columns.put(Data.MIMETYPE, Data.MIMETYPE);
+        columns.put(Data.IS_PRIMARY, Data.IS_PRIMARY);
+        columns.put(Data.IS_SUPER_PRIMARY, Data.IS_SUPER_PRIMARY);
+        columns.put(Data.DATA_VERSION, Data.DATA_VERSION);
+        columns.put(Data.DATA1, "data.data1 as data1");
+        columns.put(Data.DATA2, "data.data2 as data2");
+        columns.put(Data.DATA3, "data.data3 as data3");
+        columns.put(Data.DATA4, "data.data4 as data4");
+        columns.put(Data.DATA5, "data.data5 as data5");
+        columns.put(Data.DATA6, "data.data6 as data6");
+        columns.put(Data.DATA7, "data.data7 as data7");
+        columns.put(Data.DATA8, "data.data8 as data8");
+        columns.put(Data.DATA9, "data.data9 as data9");
+        columns.put(Data.DATA10, "data.data10 as data10");
+        // Mappings used for backwards compatibility.
+        columns.put("number", Phone.NUMBER);
+        sDataProjectionMap = columns;
+
+        // Data and contacts projection map for joins. _id comes from the data table
+        columns = new HashMap<String, String>();
+        columns.putAll(sContactsProjectionMap);
+        columns.putAll(sDataProjectionMap); // _id will be replaced with the one from data
+        columns.put(Data.CONTACT_ID, DataColumns.CONCRETE_CONTACT_ID);
+        sDataContactsProjectionMap = columns;
+
+        columns = new HashMap<String, String>();
+        columns.put(Accounts.NAME, Accounts.NAME);
+        columns.put(Accounts.TYPE, Accounts.TYPE);
+        columns.putAll(sDataContactsProjectionMap);
+        sDataContactsAccountsProjectionMap = columns;
+
+        // Data and contacts projection map for joins. _id comes from the data table
+        columns = new HashMap<String, String>();
+        columns.putAll(sAggregatesProjectionMap);
+        columns.putAll(sContactsProjectionMap); //
+        columns.putAll(sDataProjectionMap); // _id will be replaced with the one from data
+        columns.put(Data.CONTACT_ID, DataColumns.CONCRETE_CONTACT_ID);
+        sDataContactsAggregateProjectionMap = columns;
+
+        // Groups projection map
+        columns = new HashMap<String, String>();
+        columns.put(Groups._ID, "groups._id AS _id");
+        columns.put(Groups.PACKAGE, Groups.PACKAGE);
+        columns.put(Groups.PACKAGE_ID, GroupsColumns.CONCRETE_PACKAGE_ID);
+        columns.put(Groups.TITLE, Groups.TITLE);
+        columns.put(Groups.TITLE_RESOURCE, Groups.TITLE_RESOURCE);
+        columns.put(Groups.GROUP_VISIBLE, Groups.GROUP_VISIBLE);
+        sGroupsProjectionMap = columns;
+
+        // Contacts and groups projection map
+        columns = new HashMap<String, String>();
+        columns.putAll(sGroupsProjectionMap);
+
+        columns.put(Groups.SUMMARY_COUNT, "(SELECT COUNT(DISTINCT " + AggregatesColumns.CONCRETE_ID
+                + ") FROM " + Tables.DATA_JOIN_MIMETYPES_CONTACTS_AGGREGATES + " WHERE "
+                + Clauses.MIMETYPE_IS_GROUP_MEMBERSHIP + " AND " + Clauses.BELONGS_TO_GROUP
+                + ") AS " + Groups.SUMMARY_COUNT);
+
+        columns.put(Groups.SUMMARY_WITH_PHONES, "(SELECT COUNT(DISTINCT "
+                + AggregatesColumns.CONCRETE_ID + ") FROM "
+                + Tables.DATA_JOIN_MIMETYPES_CONTACTS_AGGREGATES + " WHERE "
+                + Clauses.MIMETYPE_IS_GROUP_MEMBERSHIP + " AND " + Clauses.BELONGS_TO_GROUP
+                + " AND " + Clauses.HAS_PRIMARY_PHONE + ") AS " + Groups.SUMMARY_WITH_PHONES);
+
+        sGroupsSummaryProjectionMap = columns;
+
+        // Aggregate exception projection map
+        columns = new HashMap<String, String>();
+        columns.put(AggregationExceptionColumns._ID, Tables.AGGREGATION_EXCEPTIONS + "._id AS _id");
+        columns.put(AggregationExceptions.TYPE, AggregationExceptions.TYPE);
+        columns.put(AggregationExceptions.AGGREGATE_ID,
+                "contacts1." + Contacts.AGGREGATE_ID + " AS " + AggregationExceptions.AGGREGATE_ID);
+        columns.put(AggregationExceptions.CONTACT_ID, AggregationExceptionColumns.CONTACT_ID2);
+        sAggregationExceptionsProjectionMap = columns;
+
+        // Restriction exception projection map
+        columns = new HashMap<String, String>();
+        columns.put(RestrictionExceptions.PACKAGE_PROVIDER, RestrictionExceptions.PACKAGE_PROVIDER);
+        columns.put(RestrictionExceptions.PACKAGE_CLIENT, RestrictionExceptions.PACKAGE_CLIENT);
+        columns.put(RestrictionExceptions.ALLOW_ACCESS, "1"); // Access granted if row returned
+        sRestrictionExceptionsProjectionMap = columns;
+
+        sNestedContactIdSelect = "SELECT " + Data.CONTACT_ID + " FROM " + Tables.DATA + " WHERE "
+                + Data._ID + "=?";
+        sNestedMimetypeSelect = "SELECT " + DataColumns.MIMETYPE_ID + " FROM " + Tables.DATA
+                + " WHERE " + Data._ID + "=?";
+        sNestedAggregateIdSelect = "SELECT " + Contacts.AGGREGATE_ID + " FROM " + Tables.CONTACTS
+                + " WHERE " + Contacts._ID + "=(" + sNestedContactIdSelect + ")";
+        sNestedContactIdListSelect = "SELECT " + Contacts._ID + " FROM " + Tables.CONTACTS
+                + " WHERE " + Contacts.AGGREGATE_ID + "=(" + sNestedAggregateIdSelect + ")";
+        sSetPrimaryWhere = Data.CONTACT_ID + "=(" + sNestedContactIdSelect + ") AND "
+                + DataColumns.MIMETYPE_ID + "=(" + sNestedMimetypeSelect + ")";
+        sSetSuperPrimaryWhere  = Data.CONTACT_ID + " IN (" + sNestedContactIdListSelect + ") AND "
+                + DataColumns.MIMETYPE_ID + "=(" + sNestedMimetypeSelect + ")";
+    }
+
+    private final ContactAggregationScheduler mAggregationScheduler;
+    private OpenHelper mOpenHelper;
+    private static final AccountComparator sAccountComparator = new AccountComparator();
+
+    private ContactAggregator mContactAggregator;
+    private NameSplitter mNameSplitter;
+
+    public ContactsProvider2() {
+        this(new ContactAggregationScheduler());
+    }
+
+    /**
+     * Constructor for testing.
+     */
+    /* package */ ContactsProvider2(ContactAggregationScheduler scheduler) {
+        mAggregationScheduler = scheduler;
+    }
+
+    @Override
+    public boolean onCreate() {
+        final Context context = getContext();
+        mOpenHelper = getOpenHelper(context);
+        final SQLiteDatabase db = mOpenHelper.getReadableDatabase();
+
+        loadAccountsMaps();
+
+        mContactAggregator = new ContactAggregator(context, mOpenHelper, mAggregationScheduler);
+
+        mSetPrimaryStatement = db.compileStatement(
+                "UPDATE " + Tables.DATA + " SET " + Data.IS_PRIMARY
+                + "=(_id=?) WHERE " + sSetPrimaryWhere);
+        mSetSuperPrimaryStatement = db.compileStatement(
+                "UPDATE " + Tables.DATA + " SET " + Data.IS_SUPER_PRIMARY
+                + "=(_id=?) WHERE " + sSetSuperPrimaryWhere);
+
+        mNameSplitter = new NameSplitter(
+                context.getString(com.android.internal.R.string.common_name_prefixes),
+                context.getString(com.android.internal.R.string.common_last_name_prefixes),
+                context.getString(com.android.internal.R.string.common_name_suffixes),
+                context.getString(com.android.internal.R.string.common_name_conjunctions));
+
+        return (db != null);
+    }
+
+    /* Visible for testing */
+    protected OpenHelper getOpenHelper(final Context context) {
+        return OpenHelper.getInstance(context);
+    }
+
+    @Override
+    protected void finalize() throws Throwable {
+        if (mContactAggregator != null) {
+            mContactAggregator.quit();
+        }
+
+        super.finalize();
+    }
+
+    /**
+     * Wipes all data from the contacts database.
+     */
+    /* package */ void wipeData() {
+        mOpenHelper.wipeData();
+    }
+
+    /**
+     * Read the rows from the accounts table and populate the in-memory accounts maps.
+     */
+    private void loadAccountsMaps() {
+        synchronized (sAccountsToIdMap) {
+            sAccountsToIdMap.clear();
+            sIdToAccountsMap.clear();
+            Cursor c = mOpenHelper.getReadableDatabase().query(Tables.ACCOUNTS,
+                    new String[]{Accounts._ID, Accounts.NAME, Accounts.TYPE},
+                    null, null, null, null, null);
+            try {
+                while (c.moveToNext()) {
+                    addToAccountsMaps(c.getLong(0), new Account(c.getString(1), c.getString(2)));
+                }
+            } finally {
+                c.close();
+            }
+        }
+    }
+
+    /**
+     * Return the Accounts rowId that matches the account that is passed in or null if
+     * no match exists. If refreshIfNotFound is set then if the account cannot be found in the
+     * map then the AccountManager will be queried synchronously for the current set of
+     * accounts.
+     */
+    private Long readAccountByName(Account account, boolean refreshIfNotFound) {
+        synchronized (sAccountsToIdMap) {
+            Long id = sAccountsToIdMap.get(account);
+            if (id == null && refreshIfNotFound) {
+                onAccountsUpdated(AccountManager.get(getContext()).blockingGetAccounts());
+                id = sAccountsToIdMap.get(account);
+            }
+            return id;
+        }
+    }
+
+    /**
+     * Return the Account that has the specified rowId or null if it does not exist.
+     */
+    private Account readAccountById(long id) {
+        synchronized (sAccountsToIdMap) {
+            return sIdToAccountsMap.get(id);
+        }
+    }
+
+    /**
+     * Add the contents from the Accounts row to the accounts maps.
+     */
+    private void addToAccountsMaps(long id, Account account) {
+        synchronized (sAccountsToIdMap) {
+            sAccountsToIdMap.put(account, id);
+            sIdToAccountsMap.put(id, account);
+        }
+    }
+
+    /**
+     * Reads the current set of accounts from the AccountManager and makes the local
+     * Accounts table and the in-memory accounts maps consistent with it.
+     */
+    public void onAccountsUpdated(Account[] accounts) {
+        synchronized (sAccountsToIdMap) {
+            Arrays.sort(accounts);
+
+            // if there is an account in the array that we don't know about yet add it to our
+            // cache and our database copy of accounts
+            final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+            for (Account account : accounts) {
+                if (readAccountByName(account, false /* refreshIfNotFound */) == null) {
+                    // add this account
+                    ContentValues values = new ContentValues();
+                    values.put(Accounts.NAME, account.mName);
+                    values.put(Accounts.TYPE, account.mType);
+                    long id = db.insert(Tables.ACCOUNTS, Accounts.NAME, values);
+                    if (id < 0) {
+                        throw new IllegalStateException("error inserting account in db");
+                    }
+                    addToAccountsMaps(id, account);
+                }
+            }
+
+            ArrayList<Account> accountsToRemove = new ArrayList<Account>();
+            // now check our list of accounts and remove any that are not in the array
+            for (Account account : sAccountsToIdMap.keySet()) {
+                if (Arrays.binarySearch(accounts, account, sAccountComparator) < 0) {
+                    accountsToRemove.add(account);
+                }
+            }
+
+            for (Account account : accountsToRemove) {
+                final Long id = sAccountsToIdMap.remove(account);
+                sIdToAccountsMap.remove(id);
+                db.delete(Tables.ACCOUNTS, Accounts._ID + "=" + id, null);
+            }
+        }
+    }
+
+    private static class AccountComparator implements Comparator<Account> {
+        public int compare(Account object1, Account object2) {
+            if (object1 == object2) {
+                return 0;
+            }
+            int result = object1.mType.compareTo(object2.mType);
+            if (result != 0) {
+                return result;
+            }
+            return object1.mName.compareTo(object2.mName);
+        }
+    }
+
+    /**
+     * Called when a change has been made.
+     *
+     * @param uri the uri that the change was made to
+     */
+    private void onChange(Uri uri) {
+        getContext().getContentResolver().notifyChange(ContactsContract.AUTHORITY_URI, null);
+    }
+
+    @Override
+    public boolean isTemporary() {
+        return false;
+    }
+
+    @Override
+    public Uri insert(Uri uri, ContentValues values) {
+        final int match = sUriMatcher.match(uri);
+        long id = 0;
+        switch (match) {
+            case ACCOUNTS: {
+                id = insertAccountData(values);
+                break;
+            }
+
+            case AGGREGATES: {
+                id = insertAggregate(values);
+                break;
+            }
+
+            case CONTACTS: {
+                final Account account = readAccountFromQueryParams(uri);
+                id = insertContact(values, account);
+                break;
+            }
+
+            case CONTACTS_DATA: {
+                final Account account = readAccountFromQueryParams(uri);
+                values.put(Data.CONTACT_ID, uri.getPathSegments().get(1));
+                id = insertData(values, account);
+                break;
+            }
+
+            case DATA: {
+                final Account account = readAccountFromQueryParams(uri);
+                id = insertData(values, account);
+                break;
+            }
+
+            case GROUPS: {
+                final Account account = readAccountFromQueryParams(uri);
+                id = insertGroup(values, account);
+                break;
+            }
+
+            case PRESENCE: {
+                id = insertPresence(values);
+                break;
+            }
+
+            default:
+                throw new UnsupportedOperationException("Unknown uri: " + uri);
+        }
+
+        if (id < 0) {
+            return null;
+        }
+
+        final Uri result = ContentUris.withAppendedId(uri, id);
+        onChange(result);
+        return result;
+    }
+
+    /**
+     * Inserts an item in the accounts table
+     *
+     * @param values the values for the new row
+     * @return the row ID of the newly created row
+     */
+    private long insertAccountData(ContentValues values) {
+        final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+        return db.insert(Tables.ACCOUNTS, Accounts.DATA1, values);
+    }
+
+    /**
+     * Inserts an item in the aggregates table
+     *
+     * @param values the values for the new row
+     * @return the row ID of the newly created row
+     */
+    private long insertAggregate(ContentValues values) {
+        throw new UnsupportedOperationException("Aggregates are created automatically");
+    }
+
+    /**
+     * Inserts an item in the contacts table
+     *
+     * @param values the values for the new row
+     * @param account the account this contact should be associated with. may be null.
+     * @return the row ID of the newly created row
+     */
+    private long insertContact(ContentValues values, Account account) {
+        /*
+         * The contact record is inserted in the contacts table, but it needs to
+         * be processed by the aggregator before it will be returned by the
+         * "aggregates" queries.
+         */
+        final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+
+        ContentValues overriddenValues = new ContentValues(values);
+        overriddenValues.putNull(Contacts.AGGREGATE_ID);
+        if (!resolveAccount(overriddenValues, account)) {
+            return -1;
+        }
+
+        // Replace package with internal mapping
+        final String packageName = overriddenValues.getAsString(Contacts.PACKAGE);
+        overriddenValues.put(ContactsColumns.PACKAGE_ID, mOpenHelper.getPackageId(packageName));
+        overriddenValues.remove(Contacts.PACKAGE);
+
+        long rowId = db.insert(Tables.CONTACTS, Contacts.AGGREGATE_ID, overriddenValues);
+
+        mContactAggregator.schedule();
+
+        return rowId;
+    }
+
+    /**
+     * If an account name or type is specified in values then create an Account from it or
+     * use the account that is passed in, if account is non-null, then look up the Accounts
+     * rowId that corresponds to the Account. Then insert
+     * the Accounts rowId into the values with key {@link Contacts#ACCOUNTS_ID}. Remove any
+     * value for {@link Accounts#NAME} or {@link Accounts#TYPE} from the values.
+     * @param values the ContentValues to read from and update
+     * @param account the Account to resolve. may be null.
+     * @return false if an account was present in the values that is not in the Accounts table
+     */
+    private boolean resolveAccount(ContentValues values, Account account) {
+        // If an account name and type is specified then resolve it into an accounts_id.
+        // If either is specified then both must be specified.
+        final String accountName = values.getAsString(Accounts.NAME);
+        final String accountType = values.getAsString(Accounts.TYPE);
+        if (!TextUtils.isEmpty(accountName) || !TextUtils.isEmpty(accountType)) {
+            final Account valuesAccount = new Account(accountName, accountType);
+            if (account != null && !valuesAccount.equals(account)) {
+                throw new IllegalArgumentException("account in params doesn't match account in "
+                        + "values: " + account + "!=" + valuesAccount);
+            }
+            account = valuesAccount;
+        }
+        if (account != null) {
+            final Long accountId = readAccountByName(account, true /* refreshIfNotFound */);
+            if (accountId == null) {
+                // an invalid account was passed in or the account was deleted after this
+                // request was made. fail this request.
+                return false;
+            }
+            values.put(Contacts.ACCOUNTS_ID, accountId);
+        }
+        values.remove(Accounts.NAME);
+        values.remove(Accounts.TYPE);
+        return true;
+    }
+
+    /**
+     * Inserts an item in the data table
+     *
+     * @param values the values for the new row
+     * @param account the account this data row should be associated with. may be null.
+     * @return the row ID of the newly created row
+     */
+    private long insertData(ContentValues values, Account account) {
+        boolean success = false;
+
+        final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+        long id = 0;
+        db.beginTransaction();
+        try {
+            long contactId = values.getAsLong(Data.CONTACT_ID);
+
+            // Replace mimetype with internal mapping
+            final String mimeType = values.getAsString(Data.MIMETYPE);
+            values.put(DataColumns.MIMETYPE_ID, mOpenHelper.getMimeTypeId(mimeType));
+            values.remove(Data.MIMETYPE);
+
+            if (StructuredName.CONTENT_ITEM_TYPE.equals(mimeType)) {
+                parseStructuredName(values);
+            }
+
+            // Insert the data row itself
+            id = db.insert(Tables.DATA, Data.DATA1, values);
+
+            // If it's a phone number add the normalized version to the lookup table
+            if (Phone.CONTENT_ITEM_TYPE.equals(mimeType)) {
+                final ContentValues phoneValues = new ContentValues();
+                final String number = values.getAsString(Phone.NUMBER);
+                phoneValues.put(PhoneLookupColumns.NORMALIZED_NUMBER,
+                        PhoneNumberUtils.getStrippedReversed(number));
+                phoneValues.put(PhoneLookupColumns.DATA_ID, id);
+                phoneValues.put(PhoneLookupColumns.CONTACT_ID, contactId);
+                db.insert(Tables.PHONE_LOOKUP, null, phoneValues);
+            }
+
+            mContactAggregator.markContactForAggregation(contactId);
+
+            db.setTransactionSuccessful();
+            success = true;
+        } finally {
+            db.endTransaction();
+        }
+
+        if (success) {
+            mContactAggregator.schedule();
+        }
+
+        return id;
+    }
+
+    /**
+     * Delete the given {@link Data} row, fixing up any {@link Aggregates}
+     * primaries that reference it.
+     */
+    private int deleteData(long dataId) {
+        final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+
+        final long mimePhone = mOpenHelper.getMimeTypeId(Phone.CONTENT_ITEM_TYPE);
+        final long mimeEmail = mOpenHelper.getMimeTypeId(Email.CONTENT_ITEM_TYPE);
+
+        // Check to see if the data about to be deleted was a super-primary on
+        // the parent aggregate, and set flags to fix-up once deleted.
+        long aggId = -1;
+        long mimeId = -1;
+        String dataRaw = null;
+        boolean fixOptimal = false;
+        boolean fixFallback = false;
+
+        Cursor cursor = null;
+        try {
+            cursor = db.query(Tables.DATA_JOIN_MIMETYPES_CONTACTS_AGGREGATES,
+                    Projections.PROJ_DATA_AGGREGATES, DataColumns.CONCRETE_ID + "=" + dataId, null,
+                    null, null, null);
+            if (cursor.moveToFirst()) {
+                aggId = cursor.getLong(Projections.COL_AGGREGATE_ID);
+                mimeId = cursor.getLong(Projections.COL_MIMETYPE_ID);
+                if (mimeId == mimePhone) {
+                    dataRaw = cursor.getString(Projections.COL_PHONE_NUMBER);
+                    fixOptimal = (cursor.getLong(Projections.COL_OPTIMAL_PHONE_ID) == dataId);
+                    fixFallback = (cursor.getLong(Projections.COL_FALLBACK_PHONE_ID) == dataId);
+                } else if (mimeId == mimeEmail) {
+                    dataRaw = cursor.getString(Projections.COL_EMAIL_DATA);
+                    fixOptimal = (cursor.getLong(Projections.COL_OPTIMAL_EMAIL_ID) == dataId);
+                    fixFallback = (cursor.getLong(Projections.COL_FALLBACK_EMAIL_ID) == dataId);
+                }
+            }
+        } finally {
+            if (cursor != null) {
+                cursor.close();
+                cursor = null;
+            }
+        }
+
+        // Delete the requested data item.
+        int dataDeleted = db.delete(Tables.DATA, Data._ID + "=" + dataId, null);
+
+        // Fix-up any super-primary values that are now invalid.
+        if (fixOptimal || fixFallback) {
+            final ContentValues values = new ContentValues();
+            final StringBuilder scoreClause = new StringBuilder();
+
+            final String SCORE = "score";
+
+            // Build scoring clause that will first pick data items under the
+            // same aggregate that have identical values, otherwise fall back to
+            // normal primary scoring from the member contacts.
+            scoreClause.append("(CASE WHEN ");
+            if (mimeId == mimePhone) {
+                scoreClause.append(Phone.NUMBER);
+            } else if (mimeId == mimeEmail) {
+                scoreClause.append(Email.DATA);
+            }
+            scoreClause.append("=");
+            DatabaseUtils.appendEscapedSQLString(scoreClause, dataRaw);
+            scoreClause.append(" THEN 2 ELSE " + Data.IS_PRIMARY + " END) AS " + SCORE);
+
+            final String[] PROJ_PRIMARY = new String[] {
+                    DataColumns.CONCRETE_ID,
+                    Contacts.IS_RESTRICTED,
+                    ContactsColumns.PACKAGE_ID,
+                    scoreClause.toString(),
+            };
+
+            final int COL_DATA_ID = 0;
+            final int COL_IS_RESTRICTED = 1;
+            final int COL_PACKAGE_ID = 2;
+            final int COL_SCORE = 3;
+
+            cursor = db.query(Tables.DATA_JOIN_MIMETYPES_CONTACTS_AGGREGATES, PROJ_PRIMARY,
+                    AggregatesColumns.CONCRETE_ID + "=" + aggId + " AND " + DataColumns.MIMETYPE_ID
+                            + "=" + mimeId, null, null, null, SCORE);
+
+            if (fixOptimal) {
+                String colId = null;
+                String colPackageId = null;
+                if (mimeId == mimePhone) {
+                    colId = AggregatesColumns.OPTIMAL_PRIMARY_PHONE_ID;
+                    colPackageId = AggregatesColumns.OPTIMAL_PRIMARY_PHONE_PACKAGE_ID;
+                } else if (mimeId == mimeEmail) {
+                    colId = AggregatesColumns.OPTIMAL_PRIMARY_EMAIL_ID;
+                    colPackageId = AggregatesColumns.OPTIMAL_PRIMARY_EMAIL_PACKAGE_ID;
+                }
+
+                // Start by replacing with null, since fixOptimal told us that
+                // the previous aggregate values are bad.
+                values.putNull(colId);
+                values.putNull(colPackageId);
+
+                // When finding a new optimal primary, we only care about the
+                // highest scoring value, regardless of source.
+                if (cursor.moveToFirst()) {
+                    final long newOptimal = cursor.getLong(COL_DATA_ID);
+                    final long newOptimalPackage = cursor.getLong(COL_PACKAGE_ID);
+
+                    if (newOptimal != 0) {
+                        values.put(colId, newOptimal);
+                    }
+                    if (newOptimalPackage != 0) {
+                        values.put(colPackageId, newOptimalPackage);
+                    }
+                }
+            }
+
+            if (fixFallback) {
+                String colId = null;
+                if (mimeId == mimePhone) {
+                    colId = AggregatesColumns.FALLBACK_PRIMARY_PHONE_ID;
+                } else if (mimeId == mimeEmail) {
+                    colId = AggregatesColumns.FALLBACK_PRIMARY_EMAIL_ID;
+                }
+
+                // Start by replacing with null, since fixFallback told us that
+                // the previous aggregate values are bad.
+                values.putNull(colId);
+
+                // The best fallback value is the highest scoring data item that
+                // hasn't been restricted.
+                cursor.moveToPosition(-1);
+                while (cursor.moveToNext()) {
+                    final boolean isRestricted = (cursor.getInt(COL_IS_RESTRICTED) == 1);
+                    if (!isRestricted) {
+                        values.put(colId, cursor.getLong(COL_DATA_ID));
+                        break;
+                    }
+                }
+            }
+
+            // Push through any aggregate updates we have
+            if (values.size() > 0) {
+                db.update(Tables.AGGREGATES, values, AggregatesColumns.CONCRETE_ID + "=" + aggId,
+                        null);
+            }
+        }
+
+        return dataDeleted;
+    }
+
+    /**
+     * Parse the supplied display name, but only if the incoming values do not already contain
+     * structured name parts.
+     */
+    private void parseStructuredName(ContentValues values) {
+        final String fullName = values.getAsString(StructuredName.DISPLAY_NAME);
+        if (TextUtils.isEmpty(fullName)
+                || !TextUtils.isEmpty(values.getAsString(StructuredName.PREFIX))
+                || !TextUtils.isEmpty(values.getAsString(StructuredName.GIVEN_NAME))
+                || !TextUtils.isEmpty(values.getAsString(StructuredName.MIDDLE_NAME))
+                || !TextUtils.isEmpty(values.getAsString(StructuredName.FAMILY_NAME))
+                || !TextUtils.isEmpty(values.getAsString(StructuredName.SUFFIX))) {
+            return;
+        }
+
+        NameSplitter.Name name = new NameSplitter.Name();
+        mNameSplitter.split(name, fullName);
+
+        values.put(StructuredName.PREFIX, name.getPrefix());
+        values.put(StructuredName.GIVEN_NAME, name.getGivenNames());
+        values.put(StructuredName.MIDDLE_NAME, name.getMiddleName());
+        values.put(StructuredName.FAMILY_NAME, name.getFamilyName());
+        values.put(StructuredName.SUFFIX, name.getSuffix());
+    }
+
+    /**
+     * Inserts an item in the groups table
+     */
+    private long insertGroup(ContentValues values, Account account) {
+        final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+
+        ContentValues overriddenValues = new ContentValues(values);
+        if (!resolveAccount(overriddenValues, account)) {
+            return -1;
+        }
+
+        // Replace package with internal mapping
+        final String packageName = overriddenValues.getAsString(Groups.PACKAGE);
+        overriddenValues.put(Groups.PACKAGE_ID, mOpenHelper.getPackageId(packageName));
+        overriddenValues.remove(Groups.PACKAGE);
+
+        return db.insert(Tables.GROUPS, Groups.TITLE, overriddenValues);
+    }
+
+    /**
+     * Inserts a presence update.
+     */
+    private long insertPresence(ContentValues values) {
+        final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+        final String handle = values.getAsString(Presence.IM_HANDLE);
+        final String protocol = values.getAsString(Presence.IM_PROTOCOL);
+        if (TextUtils.isEmpty(handle) || TextUtils.isEmpty(protocol)) {
+            throw new IllegalArgumentException("IM_PROTOCOL and IM_HANDLE are required");
+        }
+
+        // TODO: generalize to allow other providers to match against email
+        boolean matchEmail = GTALK_PROTOCOL_STRING.equals(protocol);
+
+        String selection;
+        String[] selectionArgs;
+        if (matchEmail) {
+            selection = "(" + Clauses.WHERE_IM_MATCHES + ") OR (" + Clauses.WHERE_EMAIL_MATCHES + ")";
+            selectionArgs = new String[] { protocol, handle, handle };
+        } else {
+            selection = Clauses.WHERE_IM_MATCHES;
+            selectionArgs = new String[] { protocol, handle };
+        }
+
+        long dataId = -1;
+        long aggId = -1;
+        Cursor cursor = null;
+        try {
+            cursor = db.query(Tables.DATA_JOIN_MIMETYPES_CONTACTS_PACKAGES_AGGREGATES,
+                    Projections.PROJ_DATA_CONTACTS, selection, selectionArgs, null, null, null);
+            if (cursor.moveToFirst()) {
+                dataId = cursor.getLong(Projections.COL_DATA_ID);
+                aggId = cursor.getLong(Projections.COL_AGGREGATE_ID);
+            } else {
+                // No contact found, return a null URI
+                return -1;
+            }
+        } finally {
+            if (cursor != null) {
+                cursor.close();
+            }
+        }
+
+        values.put(Presence.DATA_ID, dataId);
+        values.put(Presence.AGGREGATE_ID, aggId);
+
+        // Insert the presence update
+        long presenceId = db.replace(Tables.PRESENCE, null, values);
+        return presenceId;
+    }
+
+    @Override
+    public int delete(Uri uri, String selection, String[] selectionArgs) {
+        final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+
+        final int match = sUriMatcher.match(uri);
+        switch (match) {
+            case AGGREGATES_ID: {
+                long aggregateId = ContentUris.parseId(uri);
+
+                // Remove references to the aggregate first
+                ContentValues values = new ContentValues();
+                values.putNull(Contacts.AGGREGATE_ID);
+                db.update(Tables.CONTACTS, values, Contacts.AGGREGATE_ID + "=" + aggregateId, null);
+
+                return db.delete(Tables.AGGREGATES, BaseColumns._ID + "=" + aggregateId, null);
+            }
+
+            case ACCOUNTS_ID: {
+                long accountId = ContentUris.parseId(uri);
+
+                return db.delete(Tables.ACCOUNTS, BaseColumns._ID + "=" + accountId, null);
+            }
+
+            case CONTACTS_ID: {
+                long contactId = ContentUris.parseId(uri);
+                int contactsDeleted = db.delete(Tables.CONTACTS, Contacts._ID + "=" + contactId, null);
+                int dataDeleted = db.delete(Tables.DATA, Data.CONTACT_ID + "=" + contactId, null);
+                return contactsDeleted + dataDeleted;
+            }
+
+            case DATA_ID: {
+                long dataId = ContentUris.parseId(uri);
+                return deleteData(dataId);
+            }
+
+            case GROUPS_ID: {
+                long groupId = ContentUris.parseId(uri);
+                final long groupMembershipMimetypeId = mOpenHelper
+                        .getMimeTypeId(GroupMembership.CONTENT_ITEM_TYPE);
+                int groupsDeleted = db.delete(Tables.GROUPS, Groups._ID + "=" + groupId, null);
+                int dataDeleted = db.delete(Tables.DATA, DataColumns.MIMETYPE_ID + "="
+                        + groupMembershipMimetypeId + " AND " + GroupMembership.GROUP_ROW_ID + "="
+                        + groupId, null);
+                mOpenHelper.updateAllVisible();
+                return groupsDeleted + dataDeleted;
+            }
+
+            case PRESENCE: {
+                return db.delete(Tables.PRESENCE, null, null);
+            }
+
+            default:
+                throw new UnsupportedOperationException("Unknown uri: " + uri);
+        }
+    }
+
+    private static Account readAccountFromQueryParams(Uri uri) {
+        final String name = uri.getQueryParameter(Accounts.NAME);
+        final String type = uri.getQueryParameter(Accounts.TYPE);
+        if (TextUtils.isEmpty(name) || TextUtils.isEmpty(type)) {
+            return null;
+        }
+        return new Account(name, type);
+    }
+
+
+    @Override
+    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
+        int count = 0;
+        final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+
+        final int match = sUriMatcher.match(uri);
+        switch(match) {
+            case ACCOUNTS: {
+                final String accountName = uri.getQueryParameter(Accounts.NAME);
+                final String accountType = uri.getQueryParameter(Accounts.TYPE);
+                if (TextUtils.isEmpty(accountName) || TextUtils.isEmpty(accountType)) {
+                    return 0;
+                }
+                final Long accountId = readAccountByName(
+                        new Account(accountName, accountType), true /* refreshIfNotFound */);
+                if (accountId == null) {
+                    return 0;
+                }
+                String selectionWithId = (Accounts._ID + " = " + accountId + " ")
+                        + (selection == null ? "" : " AND " + selection);
+                count = db.update(Tables.ACCOUNTS, values, selectionWithId, selectionArgs);
+                break;
+            }
+
+            case ACCOUNTS_ID: {
+                String selectionWithId = (Accounts._ID + " = " + ContentUris.parseId(uri) + " ")
+                        + (selection == null ? "" : " AND " + selection);
+                count = db.update(Tables.ACCOUNTS, values, selectionWithId, selectionArgs);
+                Log.i(TAG, "Selection is: " + selectionWithId);
+                break;
+            }
+
+            // TODO(emillar): We will want to disallow editing the aggregates table at some point.
+            case AGGREGATES: {
+                count = db.update(Tables.AGGREGATES, values, selection, selectionArgs);
+                break;
+            }
+
+            case AGGREGATES_ID: {
+                count = updateAggregateData(db, ContentUris.parseId(uri), values);
+                break;
+            }
+
+            case DATA_ID: {
+                boolean containsIsSuperPrimary = values.containsKey(Data.IS_SUPER_PRIMARY);
+                boolean containsIsPrimary = values.containsKey(Data.IS_PRIMARY);
+                final long id = ContentUris.parseId(uri);
+
+                // Remove primary or super primary values being set to 0. This is disallowed by the
+                // content provider.
+                if (containsIsSuperPrimary && values.getAsInteger(Data.IS_SUPER_PRIMARY) == 0) {
+                    containsIsSuperPrimary = false;
+                    values.remove(Data.IS_SUPER_PRIMARY);
+                }
+                if (containsIsPrimary && values.getAsInteger(Data.IS_PRIMARY) == 0) {
+                    containsIsPrimary = false;
+                    values.remove(Data.IS_PRIMARY);
+                }
+
+                if (containsIsSuperPrimary) {
+                    setIsSuperPrimary(id);
+                    setIsPrimary(id);
+
+                    // Now that we've taken care of setting these, remove them from "values".
+                    values.remove(Data.IS_SUPER_PRIMARY);
+                    if (containsIsPrimary) {
+                        values.remove(Data.IS_PRIMARY);
+                    }
+                } else if (containsIsPrimary) {
+                    setIsPrimary(id);
+
+                    // Now that we've taken care of setting this, remove it from "values".
+                    values.remove(Data.IS_PRIMARY);
+                }
+
+                if (values.size() > 0) {
+                    String selectionWithId = (Data._ID + " = " + ContentUris.parseId(uri) + " ")
+                            + (selection == null ? "" : " AND " + selection);
+                    count = db.update(Tables.DATA, values, selectionWithId, selectionArgs);
+                }
+                break;
+            }
+
+            case CONTACTS: {
+                count = db.update(Tables.CONTACTS, values, selection, selectionArgs);
+                break;
+            }
+
+            case CONTACTS_ID: {
+                String selectionWithId = (Contacts._ID + " = " + ContentUris.parseId(uri) + " ")
+                        + (selection == null ? "" : " AND " + selection);
+                count = db.update(Tables.CONTACTS, values, selectionWithId, selectionArgs);
+                Log.i(TAG, "Selection is: " + selectionWithId);
+                break;
+            }
+
+            case DATA: {
+                count = db.update(Tables.DATA, values, selection, selectionArgs);
+                break;
+            }
+
+            case GROUPS: {
+                count = db.update(Tables.GROUPS, values, selection, selectionArgs);
+                mOpenHelper.updateAllVisible();
+                break;
+            }
+
+            case GROUPS_ID: {
+                long groupId = ContentUris.parseId(uri);
+                String selectionWithId = (Groups._ID + "=" + groupId + " ")
+                        + (selection == null ? "" : " AND " + selection);
+                count = db.update(Tables.GROUPS, values, selectionWithId, selectionArgs);
+
+                // If changing visibility, then update aggregates
+                if (values.containsKey(Groups.GROUP_VISIBLE)) {
+                    mOpenHelper.updateAllVisible();
+                }
+
+                break;
+            }
+
+            case AGGREGATION_EXCEPTIONS: {
+                count = updateAggregationException(db, values);
+                break;
+            }
+
+            case RESTRICTION_EXCEPTIONS: {
+                // Enforce required fields
+                boolean hasFields = values.containsKey(RestrictionExceptions.PACKAGE_PROVIDER)
+                        && values.containsKey(RestrictionExceptions.PACKAGE_CLIENT)
+                        && values.containsKey(RestrictionExceptions.ALLOW_ACCESS);
+                if (!hasFields) {
+                    throw new IllegalArgumentException("PACKAGE_PROVIDER, PACKAGE_CLIENT, and"
+                            + "ALLOW_ACCESS are all required fields");
+                }
+
+                final String packageProvider = values
+                        .getAsString(RestrictionExceptions.PACKAGE_PROVIDER);
+                final boolean allowAccess = (values
+                        .getAsInteger(RestrictionExceptions.ALLOW_ACCESS) == 1);
+
+                final Context context = getContext();
+                final PackageManager pm = context.getPackageManager();
+
+                // Enforce that caller has authority over the requested package
+                // TODO: move back to Binder.getCallingUid() when we can stub-out test suite
+                final int callingUid = OpenHelper
+                        .getUidForPackageName(pm, context.getPackageName());
+                final String[] ownedPackages = pm.getPackagesForUid(callingUid);
+                if (!isContained(ownedPackages, packageProvider)) {
+                    throw new RuntimeException(
+                            "Requested PACKAGE_PROVIDER doesn't belong to calling UID.");
+                }
+
+                // Add or remove exception using exception helper
+                if (allowAccess) {
+                    mOpenHelper.addRestrictionException(context, values);
+                } else {
+                    mOpenHelper.removeRestrictionException(context, values);
+                }
+
+                break;
+            }
+
+            default:
+                throw new UnsupportedOperationException("Unknown uri: " + uri);
+        }
+
+        if (count > 0) {
+            getContext().getContentResolver().notifyChange(uri, null);
+        }
+        return count;
+    }
+
+    private int updateAggregateData(SQLiteDatabase db, long aggregateId, ContentValues values) {
+
+        // First update all constituent contacts
+        ContentValues optionValues = new ContentValues(3);
+        if (values.containsKey(Aggregates.CUSTOM_RINGTONE)) {
+            optionValues.put(ContactOptionsColumns.CUSTOM_RINGTONE,
+                    values.getAsString(Aggregates.CUSTOM_RINGTONE));
+        }
+        if (values.containsKey(Aggregates.SEND_TO_VOICEMAIL)) {
+            optionValues.put(ContactOptionsColumns.SEND_TO_VOICEMAIL,
+                    values.getAsBoolean(Aggregates.SEND_TO_VOICEMAIL));
+        }
+
+        // Nothing to update - just return
+        if (optionValues.size() == 0) {
+            return 0;
+        }
+
+        Cursor c = db.query(Tables.CONTACTS, Projections.PROJ_CONTACTS, Contacts.AGGREGATE_ID + "="
+                + aggregateId, null, null, null, null);
+        try {
+            while (c.moveToNext()) {
+                long contactId = c.getLong(Projections.COL_CONTACT_ID);
+
+                optionValues.put(ContactOptionsColumns._ID, contactId);
+                db.replace(Tables.CONTACT_OPTIONS, null, optionValues);
+            }
+        } finally {
+            c.close();
+        }
+
+        // Now update the aggregate itself.  Ignore all supplied fields except rington and
+        // send_to_voicemail
+        optionValues.clear();
+        if (values.containsKey(Aggregates.CUSTOM_RINGTONE)) {
+            optionValues.put(Aggregates.CUSTOM_RINGTONE,
+                    values.getAsString(Aggregates.CUSTOM_RINGTONE));
+        }
+        if (values.containsKey(Aggregates.SEND_TO_VOICEMAIL)) {
+            optionValues.put(Aggregates.SEND_TO_VOICEMAIL,
+                    values.getAsBoolean(Aggregates.SEND_TO_VOICEMAIL));
+        }
+
+        return db.update(Tables.AGGREGATES, optionValues, Aggregates._ID + "=" + aggregateId, null);
+    }
+
+    private static class ContactPair {
+        final long contactId1;
+        final long contactId2;
+
+        /**
+         * Constructor that ensures that this.contactId1 &lt; this.contactId2
+         */
+        public ContactPair(long contactId1, long contactId2) {
+            if (contactId1 < contactId2) {
+                this.contactId1 = contactId1;
+                this.contactId2 = contactId2;
+            } else {
+                this.contactId2 = contactId1;
+                this.contactId1 = contactId2;
+            }
+        }
+    }
+
+    private int updateAggregationException(SQLiteDatabase db, ContentValues values) {
+        int exceptionType = values.getAsInteger(AggregationExceptions.TYPE);
+        long aggregateId = values.getAsInteger(AggregationExceptions.AGGREGATE_ID);
+        long contactId = values.getAsInteger(AggregationExceptions.CONTACT_ID);
+
+        // First, we build a list of contactID-contactID pairs for the given aggregate and contact.
+        ArrayList<ContactPair> pairs = new ArrayList<ContactPair>();
+        Cursor c = db.query(Tables.CONTACTS, Projections.PROJ_CONTACTS,
+                Contacts.AGGREGATE_ID + "=" + aggregateId,
+                null, null, null, null);
+        try {
+            while (c.moveToNext()) {
+                long aggregatedContactId = c.getLong(Projections.COL_CONTACT_ID);
+                if (aggregatedContactId != contactId) {
+                    pairs.add(new ContactPair(aggregatedContactId, contactId));
+                }
+            }
+        } finally {
+            c.close();
+        }
+
+        // Now we iterate through all contact pairs to see if we need to insert/delete/update
+        // the corresponding exception
+        ContentValues exceptionValues = new ContentValues(3);
+        exceptionValues.put(AggregationExceptions.TYPE, exceptionType);
+        for (ContactPair pair : pairs) {
+            final String whereClause =
+                    AggregationExceptionColumns.CONTACT_ID1 + "=" + pair.contactId1 + " AND "
+                    + AggregationExceptionColumns.CONTACT_ID2 + "=" + pair.contactId2;
+            if (exceptionType == AggregationExceptions.TYPE_AUTOMATIC) {
+                db.delete(Tables.AGGREGATION_EXCEPTIONS, whereClause, null);
+            } else {
+                exceptionValues.put(AggregationExceptionColumns.CONTACT_ID1, pair.contactId1);
+                exceptionValues.put(AggregationExceptionColumns.CONTACT_ID2, pair.contactId2);
+                db.replace(Tables.AGGREGATION_EXCEPTIONS, AggregationExceptions._ID,
+                        exceptionValues);
+            }
+        }
+
+        mContactAggregator.markContactForAggregation(contactId);
+        mContactAggregator.aggregateContact(contactId);
+        if (exceptionType == AggregationExceptions.TYPE_AUTOMATIC
+                || exceptionType == AggregationExceptions.TYPE_KEEP_OUT) {
+            mContactAggregator.updateAggregateData(aggregateId);
+        }
+
+        // The return value is fake - we just confirm that we made a change, not count actual
+        // rows changed.
+        return 1;
+    }
+
+    /**
+     * Test if a {@link String} value appears in the given list.
+     */
+    private boolean isContained(String[] array, String value) {
+        if (array != null) {
+            for (String test : array) {
+                if (value.equals(test)) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Test if a {@link String} value appears in the given list, and add to the
+     * array if the value doesn't already appear.
+     */
+    private String[] assertContained(String[] array, String value) {
+        if (array == null) {
+            array = new String[] {value};
+        } else if (!isContained(array, value)) {
+            String[] newArray = new String[array.length + 1];
+            System.arraycopy(array, 0, newArray, 0, array.length);
+            newArray[array.length] = value;
+            array = newArray;
+        }
+        return array;
+    }
+
+    @Override
+    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
+            String sortOrder) {
+        final SQLiteDatabase db = mOpenHelper.getReadableDatabase();
+        SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
+        String groupBy = null;
+        String limit = null;
+        String aggregateIdColName = Tables.AGGREGATES + "." + Aggregates._ID;
+
+        // TODO: Consider writing a test case for RestrictionExceptions when you
+        // write a new query() block to make sure it protects restricted data.
+        final int match = sUriMatcher.match(uri);
+        switch (match) {
+            case ACCOUNTS: {
+                qb.setTables(Tables.ACCOUNTS);
+                qb.setProjectionMap(sAccountsProjectionMap);
+                break;
+            }
+
+            case ACCOUNTS_ID: {
+                qb.setTables(Tables.ACCOUNTS);
+                qb.setProjectionMap(sAccountsProjectionMap);
+                qb.appendWhere(BaseColumns._ID + " = " + ContentUris.parseId(uri));
+                break;
+            }
+
+            case AGGREGATES: {
+                qb.setTables(Tables.AGGREGATES);
+                applyAggregateRestrictionExceptions(qb);
+                applyAggregatePrimaryRestrictionExceptions(sAggregatesProjectionMap);
+                qb.setProjectionMap(sAggregatesProjectionMap);
+                break;
+            }
+
+            case AGGREGATES_ID: {
+                long aggId = ContentUris.parseId(uri);
+                qb.setTables(Tables.AGGREGATES);
+                qb.appendWhere(AggregatesColumns.CONCRETE_ID + "=" + aggId + " AND ");
+                applyAggregateRestrictionExceptions(qb);
+                applyAggregatePrimaryRestrictionExceptions(sAggregatesProjectionMap);
+                qb.setProjectionMap(sAggregatesProjectionMap);
+                break;
+            }
+
+            case AGGREGATES_SUMMARY: {
+                // TODO: join into social status tables
+                qb.setTables(Tables.AGGREGATES_JOIN_PRESENCE_PRIMARY_PHONE);
+                applyAggregateRestrictionExceptions(qb);
+                applyAggregatePrimaryRestrictionExceptions(sAggregatesSummaryProjectionMap);
+                projection = assertContained(projection, Aggregates.PRIMARY_PHONE_ID);
+                qb.setProjectionMap(sAggregatesSummaryProjectionMap);
+                groupBy = aggregateIdColName;
+                break;
+            }
+
+            case AGGREGATES_SUMMARY_ID: {
+                // TODO: join into social status tables
+                long aggId = ContentUris.parseId(uri);
+                qb.setTables(Tables.AGGREGATES_JOIN_PRESENCE_PRIMARY_PHONE);
+                qb.appendWhere(AggregatesColumns.CONCRETE_ID + "=" + aggId + " AND ");
+                applyAggregateRestrictionExceptions(qb);
+                applyAggregatePrimaryRestrictionExceptions(sAggregatesSummaryProjectionMap);
+                projection = assertContained(projection, Aggregates.PRIMARY_PHONE_ID);
+                qb.setProjectionMap(sAggregatesSummaryProjectionMap);
+                groupBy = aggregateIdColName;
+                break;
+            }
+
+            case AGGREGATES_SUMMARY_FILTER: {
+                // TODO: filter query based on callingUid
+                qb.setTables(Tables.AGGREGATES_JOIN_PRESENCE_PRIMARY_PHONE);
+                qb.setProjectionMap(sAggregatesSummaryProjectionMap);
+                if (uri.getPathSegments().size() > 2) {
+                    qb.appendWhere(buildAggregateLookupWhereClause(uri.getLastPathSegment()));
+                }
+                groupBy = aggregateIdColName;
+                break;
+            }
+
+            case AGGREGATES_SUMMARY_STREQUENT_FILTER:
+            case AGGREGATES_SUMMARY_STREQUENT: {
+                // Build the first query for starred
+                qb.setTables(Tables.AGGREGATES_JOIN_PRESENCE_PRIMARY_PHONE);
+                qb.setProjectionMap(sAggregatesSummaryProjectionMap);
+                if (match == AGGREGATES_SUMMARY_STREQUENT_FILTER
+                        && uri.getPathSegments().size() > 3) {
+                    qb.appendWhere(buildAggregateLookupWhereClause(uri.getLastPathSegment()));
+                }
+                final String starredQuery = qb.buildQuery(projection, Aggregates.STARRED + "=1",
+                        null, aggregateIdColName, null, null,
+                        null /* limit */);
+
+                // Build the second query for frequent
+                qb = new SQLiteQueryBuilder();
+                qb.setTables(Tables.AGGREGATES_JOIN_PRESENCE_PRIMARY_PHONE);
+                qb.setProjectionMap(sAggregatesSummaryProjectionMap);
+                if (match == AGGREGATES_SUMMARY_STREQUENT_FILTER
+                        && uri.getPathSegments().size() > 3) {
+                    qb.appendWhere(buildAggregateLookupWhereClause(uri.getLastPathSegment()));
+                }
+                final String frequentQuery = qb.buildQuery(projection,
+                        Aggregates.TIMES_CONTACTED + " > 0 AND (" + Aggregates.STARRED
+                        + " = 0 OR " + Aggregates.STARRED + " IS NULL)",
+                        null, aggregateIdColName, null, null, null);
+
+                // Put them together
+                final String query = qb.buildUnionQuery(new String[] {starredQuery, frequentQuery},
+                        STREQUENT_ORDER_BY, STREQUENT_LIMIT);
+                Cursor c = db.rawQueryWithFactory(null, query, null,
+                        Tables.AGGREGATES_JOIN_PRESENCE_PRIMARY_PHONE);
+
+                if ((c != null) && !isTemporary()) {
+                    c.setNotificationUri(getContext().getContentResolver(),
+                            ContactsContract.AUTHORITY_URI);
+                }
+                return c;
+            }
+
+            case AGGREGATES_DATA: {
+                long aggId = Long.parseLong(uri.getPathSegments().get(1));
+                qb.setTables(Tables.DATA_JOIN_MIMETYPES_CONTACTS_PACKAGES_AGGREGATES);
+                qb.setProjectionMap(sDataContactsAggregateProjectionMap);
+                qb.appendWhere(Contacts.AGGREGATE_ID + "=" + aggId + " AND ");
+                applyDataRestrictionExceptions(qb);
+                break;
+            }
+
+            case PHONES_FILTER: {
+                qb.setTables(Tables.DATA_JOIN_MIMETYPES_CONTACTS_PACKAGES_AGGREGATES);
+                qb.setProjectionMap(sDataContactsAggregateProjectionMap);
+                qb.appendWhere(Data.MIMETYPE + " = '" + Phone.CONTENT_ITEM_TYPE + "'");
+                if (uri.getPathSegments().size() > 2) {
+                    qb.appendWhere(" AND " + buildAggregateLookupWhereClause(
+                            uri.getLastPathSegment()));
+                }
+                break;
+            }
+
+            case PHONES: {
+                qb.setTables(Tables.DATA_JOIN_MIMETYPES_CONTACTS_PACKAGES_AGGREGATES);
+                qb.setProjectionMap(sDataContactsAggregateProjectionMap);
+                qb.appendWhere(Data.MIMETYPE + " = \"" + Phone.CONTENT_ITEM_TYPE + "\"");
+                break;
+            }
+
+            case POSTALS: {
+                qb.setTables(Tables.DATA_JOIN_MIMETYPES_CONTACTS_PACKAGES_AGGREGATES);
+                qb.setProjectionMap(sDataContactsAggregateProjectionMap);
+                qb.appendWhere(Data.MIMETYPE + " = \"" + Postal.CONTENT_ITEM_TYPE + "\"");
+                break;
+            }
+
+            case CONTACTS: {
+                qb.setTables(Tables.CONTACTS_JOIN_PACKAGES_ACCOUNTS);
+                qb.setProjectionMap(sContactsProjectionMap);
+                applyContactsRestrictionExceptions(qb);
+                break;
+            }
+
+            case CONTACTS_ID: {
+                long contactId = ContentUris.parseId(uri);
+                qb.setTables(Tables.CONTACTS_JOIN_PACKAGES_ACCOUNTS);
+                qb.setProjectionMap(sContactsProjectionMap);
+                qb.appendWhere(ContactsColumns.CONCRETE_ID + "=" + contactId + " AND ");
+                applyContactsRestrictionExceptions(qb);
+                break;
+            }
+
+            case CONTACTS_DATA: {
+                long contactId = Long.parseLong(uri.getPathSegments().get(1));
+                qb.setTables(Tables.DATA_JOIN_MIMETYPES_CONTACTS_PACKAGES);
+                qb.setProjectionMap(sDataContactsProjectionMap);
+                qb.appendWhere(Data.CONTACT_ID + "=" + contactId + " AND ");
+                applyDataRestrictionExceptions(qb);
+                break;
+            }
+
+            case CONTACTS_FILTER_EMAIL: {
+                // TODO: filter query based on callingUid
+                qb.setTables(Tables.DATA_JOIN_MIMETYPES_CONTACTS_PACKAGES_AGGREGATES);
+                qb.setProjectionMap(sDataContactsProjectionMap);
+                qb.appendWhere(Data.MIMETYPE + "='" + CommonDataKinds.Email.CONTENT_ITEM_TYPE + "'");
+                qb.appendWhere(" AND " + CommonDataKinds.Email.DATA + "=");
+                qb.appendWhereEscapeString(uri.getPathSegments().get(2));
+                break;
+            }
+
+            case DATA: {
+                final String accountName = uri.getQueryParameter(Accounts.NAME);
+                final String accountType = uri.getQueryParameter(Accounts.TYPE);
+                if (!TextUtils.isEmpty(accountName)) {
+                    Account account = new Account(accountName, accountType);
+                    Long accountId = readAccountByName(account, true /* refreshIfNotFound */);
+                    if (accountId == null) {
+                        // use -1 as the account to ensure that no rows are returned
+                        accountId = (long) -1;
+                    }
+                    qb.appendWhere(Contacts.ACCOUNTS_ID + "=" + accountId + " AND ");
+                }
+                qb.setTables(Tables.DATA_JOIN_MIMETYPES_CONTACTS_PACKAGES);
+                qb.setProjectionMap(sDataProjectionMap);
+                applyDataRestrictionExceptions(qb);
+                break;
+            }
+
+            case DATA_ID: {
+                qb.setTables(Tables.DATA_JOIN_MIMETYPES_CONTACTS_PACKAGES);
+                qb.setProjectionMap(sDataProjectionMap);
+                qb.appendWhere(DataColumns.CONCRETE_ID + "=" + ContentUris.parseId(uri) + " AND ");
+                applyDataRestrictionExceptions(qb);
+                break;
+            }
+
+            case PHONE_LOOKUP: {
+                // TODO: filter query based on callingUid
+                if (TextUtils.isEmpty(sortOrder)) {
+                    // Default the sort order to something reasonable so we get consistent
+                    // results when callers don't request an ordering
+                    sortOrder = Data.CONTACT_ID;
+                }
+
+                final String number = uri.getLastPathSegment();
+                OpenHelper.buildPhoneLookupQuery(qb, number);
+                qb.setProjectionMap(sDataContactsProjectionMap);
+                break;
+            }
+
+            case GROUPS: {
+                qb.setTables(Tables.GROUPS_JOIN_PACKAGES);
+                qb.setProjectionMap(sGroupsProjectionMap);
+                break;
+            }
+
+            case GROUPS_ID: {
+                long groupId = ContentUris.parseId(uri);
+                qb.setTables(Tables.GROUPS_JOIN_PACKAGES);
+                qb.setProjectionMap(sGroupsProjectionMap);
+                qb.appendWhere(GroupsColumns.CONCRETE_ID + "=" + groupId);
+                break;
+            }
+
+            case GROUPS_SUMMARY: {
+                qb.setTables(Tables.GROUPS_JOIN_PACKAGES_DATA_CONTACTS_AGGREGATES);
+                qb.setProjectionMap(sGroupsSummaryProjectionMap);
+                groupBy = GroupsColumns.CONCRETE_ID;
+                break;
+            }
+
+            case AGGREGATION_EXCEPTIONS: {
+                qb.setTables(Tables.AGGREGATION_EXCEPTIONS_JOIN_CONTACTS);
+                qb.setProjectionMap(sAggregationExceptionsProjectionMap);
+                break;
+            }
+
+            case AGGREGATION_SUGGESTIONS: {
+                long aggregateId = Long.parseLong(uri.getPathSegments().get(1));
+                final String maxSuggestionsParam =
+                        uri.getQueryParameter(AggregationSuggestions.MAX_SUGGESTIONS);
+
+                final int maxSuggestions;
+                if (maxSuggestionsParam != null) {
+                    maxSuggestions = Integer.parseInt(maxSuggestionsParam);
+                } else {
+                    maxSuggestions = DEFAULT_MAX_SUGGESTIONS;
+                }
+
+                return mContactAggregator.queryAggregationSuggestions(aggregateId, projection,
+                        sAggregatesProjectionMap, maxSuggestions);
+            }
+
+            case RESTRICTION_EXCEPTIONS: {
+                qb.setTables(Tables.RESTRICTION_EXCEPTIONS);
+                qb.setProjectionMap(sRestrictionExceptionsProjectionMap);
+                break;
+            }
+
+            default:
+                throw new UnsupportedOperationException("Unknown uri: " + uri);
+        }
+
+        // Perform the query and set the notification uri
+        final Cursor c = qb.query(db, projection, selection, selectionArgs,
+                groupBy, null, sortOrder, limit);
+        if (c != null) {
+            c.setNotificationUri(getContext().getContentResolver(), ContactsContract.AUTHORITY_URI);
+        }
+        return c;
+    }
+
+    /**
+     * Restrict selection of {@link Aggregates} to only public ones, or those
+     * the caller has been granted a {@link RestrictionExceptions} to.
+     */
+    private void applyAggregateRestrictionExceptions(SQLiteQueryBuilder qb) {
+        final int clientUid = OpenHelper.getUidForPackageName(getContext().getPackageManager(),
+                getContext().getPackageName());
+
+        qb.appendWhere("(" + AggregatesColumns.SINGLE_RESTRICTED_PACKAGE_ID + " IS NULL");
+        final String exceptionClause = mOpenHelper.getRestrictionExceptionClause(clientUid,
+                AggregatesColumns.SINGLE_RESTRICTED_PACKAGE_ID);
+        if (exceptionClause != null) {
+            qb.appendWhere(" OR (" + exceptionClause + ")");
+        }
+        qb.appendWhere(")");
+    }
+
+    /**
+     * Find any exceptions that have been granted to the calling process, and
+     * add projections to correctly select {@link Aggregates#PRIMARY_PHONE_ID}
+     * and {@link Aggregates#PRIMARY_EMAIL_ID}.
+     */
+    private void applyAggregatePrimaryRestrictionExceptions(HashMap<String, String> projection) {
+        // TODO: move back to Binder.getCallingUid() when we can stub-out test suite
+        final int clientUid = OpenHelper.getUidForPackageName(getContext().getPackageManager(),
+                getContext().getPackageName());
+
+        final String projectionPhone = "(CASE WHEN "
+                + mOpenHelper.getRestrictionExceptionClause(clientUid,
+                        AggregatesColumns.OPTIMAL_PRIMARY_PHONE_PACKAGE_ID) + " THEN "
+                + AggregatesColumns.OPTIMAL_PRIMARY_PHONE_ID + " ELSE "
+                + AggregatesColumns.FALLBACK_PRIMARY_PHONE_ID + " END) AS "
+                + Aggregates.PRIMARY_PHONE_ID;
+        projection.remove(Aggregates.PRIMARY_PHONE_ID);
+        projection.put(Aggregates.PRIMARY_PHONE_ID, projectionPhone);
+
+        final String projectionEmail = "(CASE WHEN "
+            + mOpenHelper.getRestrictionExceptionClause(clientUid,
+                    AggregatesColumns.OPTIMAL_PRIMARY_EMAIL_PACKAGE_ID) + " THEN "
+            + AggregatesColumns.OPTIMAL_PRIMARY_EMAIL_ID + " ELSE "
+            + AggregatesColumns.FALLBACK_PRIMARY_EMAIL_ID + " END) AS "
+            + Aggregates.PRIMARY_EMAIL_ID;
+        projection.remove(Aggregates.PRIMARY_EMAIL_ID);
+        projection.put(Aggregates.PRIMARY_EMAIL_ID, projectionEmail);
+    }
+
+    /**
+     * Find any exceptions that have been granted to the
+     * {@link Binder#getCallingUid()}, and add a limiting clause to the given
+     * {@link SQLiteQueryBuilder} to hide restricted data.
+     */
+    private void applyContactsRestrictionExceptions(SQLiteQueryBuilder qb) {
+        // TODO: move back to Binder.getCallingUid() when we can stub-out test suite
+        final int clientUid = OpenHelper.getUidForPackageName(getContext().getPackageManager(),
+                getContext().getPackageName());
+
+        qb.appendWhere("(" + Contacts.IS_RESTRICTED + "=0");
+        final String exceptionClause = mOpenHelper.getRestrictionExceptionClause(clientUid,
+                ContactsColumns.PACKAGE_ID);
+        if (exceptionClause != null) {
+            qb.appendWhere(" OR (" + exceptionClause + ")");
+        }
+        qb.appendWhere(")");
+    }
+
+    /**
+     * Find any exceptions that have been granted to the
+     * {@link Binder#getCallingUid()}, and add a limiting clause to the given
+     * {@link SQLiteQueryBuilder} to hide restricted data.
+     */
+    private void applyDataRestrictionExceptions(SQLiteQueryBuilder qb) {
+        applyContactsRestrictionExceptions(qb);
+    }
+
+    /**
+     * An implementation of EntityIterator that joins the contacts and data tables
+     * and consumes all the data rows for a contact in order to build the Entity for a contact.
+     */
+    private static class ContactsEntityIterator implements EntityIterator {
+        private final Cursor mEntityCursor;
+        private volatile boolean mIsClosed;
+        private final Account mAccount;
+
+        private static final String[] DATA_KEYS = new String[]{
+                "data1",
+                "data2",
+                "data3",
+                "data4",
+                "data5",
+                "data6",
+                "data7",
+                "data8",
+                "data9",
+                "data10"};
+
+        private static final String[] PROJECTION = new String[]{
+            Contacts.ACCOUNTS_ID,
+            Contacts.SOURCE_ID,
+            Contacts.VERSION,
+            Contacts.DIRTY,
+            Contacts.Data._ID,
+            Contacts.Data.MIMETYPE,
+            Contacts.Data.DATA1,
+            Contacts.Data.DATA2,
+            Contacts.Data.DATA3,
+            Contacts.Data.DATA4,
+            Contacts.Data.DATA5,
+            Contacts.Data.DATA6,
+            Contacts.Data.DATA7,
+            Contacts.Data.DATA8,
+            Contacts.Data.DATA9,
+            Contacts.Data.DATA10,
+            Contacts.Data.CONTACT_ID,
+            Contacts.Data.IS_PRIMARY,
+            Contacts.Data.DATA_VERSION};
+
+        private static final int COLUMN_SOURCE_ID = 1;
+        private static final int COLUMN_VERSION = 2;
+        private static final int COLUMN_DIRTY = 3;
+        private static final int COLUMN_DATA_ID = 4;
+        private static final int COLUMN_MIMETYPE = 5;
+        private static final int COLUMN_DATA1 = 6;
+        private static final int COLUMN_CONTACT_ID = 16;
+        private static final int COLUMN_IS_PRIMARY = 17;
+        private static final int COLUMN_DATA_VERSION = 18;
+
+        public ContactsEntityIterator(ContactsProvider2 provider, String contactsIdString, Uri uri,
+                String selection, String[] selectionArgs, String sortOrder) {
+            mIsClosed = false;
+
+            final String accountName = uri.getQueryParameter(Accounts.NAME);
+            final String accountType = uri.getQueryParameter(Accounts.TYPE);
+            if (TextUtils.isEmpty(accountName) || TextUtils.isEmpty(accountType)) {
+                throw new IllegalArgumentException("the account name and type must be "
+                        + "specified in the query params of the uri");
+            }
+            mAccount = new Account(accountName, accountType);
+            final Long accountId = provider.readAccountByName(mAccount,
+                    true /* refreshIfNotFound */);
+            if (accountId == null) {
+                throw new IllegalArgumentException("the specified account does not exist");
+            }
+
+            final String updatedSortOrder = (sortOrder == null)
+                    ? Contacts.Data.CONTACT_ID
+                    : (Contacts.Data.CONTACT_ID + "," + sortOrder);
+
+            final SQLiteDatabase db = provider.mOpenHelper.getReadableDatabase();
+            final SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
+            qb.setTables(Tables.DATA_JOIN_MIMETYPES_CONTACTS_PACKAGES);
+            qb.setProjectionMap(sDataContactsAccountsProjectionMap);
+            if (contactsIdString != null) {
+                qb.appendWhere(Data.CONTACT_ID + "=" + contactsIdString);
+            }
+            qb.appendWhere(Contacts.ACCOUNTS_ID + "=" + accountId);
+            mEntityCursor = qb.query(db, PROJECTION, selection, selectionArgs,
+                    null, null, updatedSortOrder);
+            mEntityCursor.moveToFirst();
+        }
+
+        public void close() {
+            if (mIsClosed) {
+                throw new IllegalStateException("closing when already closed");
+            }
+            mIsClosed = true;
+            mEntityCursor.close();
+        }
+
+        public boolean hasNext() throws RemoteException {
+            if (mIsClosed) {
+                throw new IllegalStateException("calling hasNext() when the iterator is closed");
+            }
+
+            return !mEntityCursor.isAfterLast();
+        }
+
+        public Entity next() throws RemoteException {
+            if (mIsClosed) {
+                throw new IllegalStateException("calling next() when the iterator is closed");
+            }
+            if (!hasNext()) {
+                throw new IllegalStateException("you may only call next() if hasNext() is true");
+            }
+
+            final SQLiteCursor c = (SQLiteCursor) mEntityCursor;
+
+            final long contactId = c.getLong(COLUMN_CONTACT_ID);
+
+            // we expect the cursor is already at the row we need to read from
+            ContentValues contactValues = new ContentValues();
+            contactValues.put(Accounts.NAME, mAccount.mName);
+            contactValues.put(Accounts.TYPE, mAccount.mType);
+            contactValues.put(Contacts._ID, contactId);
+            contactValues.put(Contacts.DIRTY, c.getLong(COLUMN_DIRTY));
+            contactValues.put(Contacts.VERSION, c.getLong(COLUMN_VERSION));
+            contactValues.put(Contacts.SOURCE_ID, c.getString(COLUMN_SOURCE_ID));
+            Entity contact = new Entity(contactValues);
+
+            // read data rows until the contact id changes
+            do {
+                if (contactId != c.getLong(COLUMN_CONTACT_ID)) {
+                    break;
+                }
+                // add the data to to the contact
+                ContentValues dataValues = new ContentValues();
+                dataValues.put(Contacts.Data._ID, c.getString(COLUMN_DATA_ID));
+                dataValues.put(Contacts.Data.MIMETYPE, c.getString(COLUMN_MIMETYPE));
+                dataValues.put(Contacts.Data.IS_PRIMARY, c.getString(COLUMN_IS_PRIMARY));
+                dataValues.put(Contacts.Data.DATA_VERSION, c.getLong(COLUMN_DATA_VERSION));
+                for (int i = 0; i < 10; i++) {
+                    final int columnIndex = i + COLUMN_DATA1;
+                    String key = DATA_KEYS[i];
+                    if (c.isNull(columnIndex)) {
+                        // don't put anything
+                    } else if (c.isLong(columnIndex)) {
+                        dataValues.put(key, c.getLong(columnIndex));
+                    } else if (c.isFloat(columnIndex)) {
+                        dataValues.put(key, c.getFloat(columnIndex));
+                    } else if (c.isString(columnIndex)) {
+                        dataValues.put(key, c.getString(columnIndex));
+                    } else if (c.isBlob(columnIndex)) {
+                        dataValues.put(key, c.getBlob(columnIndex));
+                    }
+                }
+                contact.addSubValue(Data.CONTENT_URI, dataValues);
+            } while (mEntityCursor.moveToNext());
+
+            return contact;
+        }
+    }
+
+    @Override
+    public EntityIterator queryEntities(Uri uri, String selection, String[] selectionArgs,
+            String sortOrder) {
+        final int match = sUriMatcher.match(uri);
+        switch (match) {
+            case CONTACTS:
+            case CONTACTS_ID:
+                String contactsIdString = null;
+                if (match == CONTACTS_ID) {
+                    contactsIdString = uri.getPathSegments().get(1);
+                }
+
+                return new ContactsEntityIterator(this, contactsIdString,
+                        uri, selection, selectionArgs, sortOrder);
+            default:
+                throw new UnsupportedOperationException("Unknown uri: " + uri);
+        }
+    }
+
+    @Override
+    public String getType(Uri uri) {
+        final int match = sUriMatcher.match(uri);
+        switch (match) {
+            case ACCOUNTS: return Accounts.CONTENT_TYPE;
+            case ACCOUNTS_ID: return Accounts.CONTENT_ITEM_TYPE;
+            case AGGREGATES: return Aggregates.CONTENT_TYPE;
+            case AGGREGATES_ID: return Aggregates.CONTENT_ITEM_TYPE;
+            case CONTACTS: return Contacts.CONTENT_TYPE;
+            case CONTACTS_ID: return Contacts.CONTENT_ITEM_TYPE;
+            case DATA_ID:
+                final SQLiteDatabase db = mOpenHelper.getReadableDatabase();
+                long dataId = ContentUris.parseId(uri);
+                return mOpenHelper.getDataMimeType(dataId);
+            case AGGREGATION_EXCEPTIONS: return AggregationExceptions.CONTENT_TYPE;
+            case AGGREGATION_EXCEPTION_ID: return AggregationExceptions.CONTENT_ITEM_TYPE;
+            case AGGREGATION_SUGGESTIONS: return Aggregates.CONTENT_TYPE;
+        }
+        throw new UnsupportedOperationException("Unknown uri: " + uri);
+    }
+
+    @Override
+    public ContentProviderResult[] applyBatch(ArrayList<ContentProviderOperation> operations)
+            throws OperationApplicationException {
+
+        final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+        db.beginTransaction();
+        try {
+            ContentProviderResult[] results = super.applyBatch(operations);
+            db.setTransactionSuccessful();
+            return results;
+        } finally {
+            db.endTransaction();
+        }
+    }
+
+    /*
+     * Sets the given dataId record in the "data" table to primary, and resets all data records of
+     * the same mimetype and under the same contact to not be primary.
+     *
+     * @param dataId the id of the data record to be set to primary.
+     */
+    private void setIsPrimary(long dataId) {
+        mSetPrimaryStatement.bindLong(1, dataId);
+        mSetPrimaryStatement.bindLong(2, dataId);
+        mSetPrimaryStatement.bindLong(3, dataId);
+        mSetPrimaryStatement.execute();
+    }
+
+    /*
+     * Sets the given dataId record in the "data" table to "super primary", and resets all data
+     * records of the same mimetype and under the same aggregate to not be "super primary".
+     *
+     * @param dataId the id of the data record to be set to primary.
+     */
+    private void setIsSuperPrimary(long dataId) {
+        mSetSuperPrimaryStatement.bindLong(1, dataId);
+        mSetSuperPrimaryStatement.bindLong(2, dataId);
+        mSetSuperPrimaryStatement.bindLong(3, dataId);
+        mSetSuperPrimaryStatement.execute();
+
+        // Find the parent aggregate and package for this new primary
+        final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+
+        long aggId = -1;
+        long packageId = -1;
+        boolean isRestricted = false;
+        String mimeType = null;
+
+        Cursor cursor = null;
+        try {
+            cursor = db.query(Tables.DATA_JOIN_MIMETYPES_CONTACTS_PACKAGES,
+                    Projections.PROJ_DATA_CONTACTS, DataColumns.CONCRETE_ID + "=" + dataId, null,
+                    null, null, null);
+            if (cursor.moveToFirst()) {
+                aggId = cursor.getLong(Projections.COL_AGGREGATE_ID);
+                packageId = cursor.getLong(Projections.COL_PACKAGE_ID);
+                isRestricted = (cursor.getInt(Projections.COL_IS_RESTRICTED) == 1);
+                mimeType = cursor.getString(Projections.COL_MIMETYPE);
+            }
+        } finally {
+            if (cursor != null) {
+                cursor.close();
+            }
+        }
+
+        // Bypass aggregate update if no parent found, or if we don't keep track
+        // of super-primary for this mimetype.
+        if (aggId == -1) {
+            return;
+        }
+
+        boolean isPhone = CommonDataKinds.Phone.CONTENT_ITEM_TYPE.equals(mimeType);
+        boolean isEmail = CommonDataKinds.Email.CONTENT_ITEM_TYPE.equals(mimeType);
+
+        // Record this value as the new primary for the parent aggregate
+        final ContentValues values = new ContentValues();
+        if (isPhone) {
+            values.put(AggregatesColumns.OPTIMAL_PRIMARY_PHONE_ID, dataId);
+            values.put(AggregatesColumns.OPTIMAL_PRIMARY_PHONE_PACKAGE_ID, packageId);
+        } else if (isEmail) {
+            values.put(AggregatesColumns.OPTIMAL_PRIMARY_EMAIL_ID, dataId);
+            values.put(AggregatesColumns.OPTIMAL_PRIMARY_EMAIL_PACKAGE_ID, packageId);
+        }
+
+        // If this data is unrestricted, then also set as fallback
+        if (!isRestricted && isPhone) {
+            values.put(AggregatesColumns.FALLBACK_PRIMARY_PHONE_ID, dataId);
+        } else if (!isRestricted && isEmail) {
+            values.put(AggregatesColumns.FALLBACK_PRIMARY_EMAIL_ID, dataId);
+        }
+
+        // Push update into aggregates table, if needed
+        if (values.size() > 0) {
+            db.update(Tables.AGGREGATES, values, Aggregates._ID + "=" + aggId, null);
+        }
+
+    }
+
+    private String buildAggregateLookupWhereClause(String filterParam) {
+        StringBuilder filter = new StringBuilder();
+        filter.append(Tables.AGGREGATES);
+        filter.append(".");
+        filter.append(Aggregates._ID);
+        filter.append(" IN (SELECT ");
+        filter.append(Contacts.AGGREGATE_ID);
+        filter.append(" FROM ");
+        filter.append(Tables.CONTACTS);
+        filter.append(" WHERE ");
+        filter.append(Contacts._ID);
+        filter.append(" IN (SELECT  contact_id FROM name_lookup WHERE normalized_name GLOB '");
+        // NOTE: Query parameters won't work here since the SQL compiler
+        // needs to parse the actual string to know that it can use the
+        // index to do a prefix scan.
+        filter.append(NameNormalizer.normalize(filterParam) + "*");
+        filter.append("'))");
+        return filter.toString();
+    }
+
+}
diff --git a/src/com/android/providers/contacts/Hex.java b/src/com/android/providers/contacts/Hex.java
new file mode 100644
index 0000000..991f095
--- /dev/null
+++ b/src/com/android/providers/contacts/Hex.java
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2009 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;
+
+/**
+ * Basic hex operations: from byte array to string and vice versa.
+ *
+ * TODO: move to the framework and consider implementing as native code.
+ */
+public class Hex {
+
+    private static final char[] HEX_DIGITS = new char[]{
+            '0', '1', '2', '3', '4', '5', '6', '7',
+            '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
+    };
+
+    private static final char[] FIRST_CHAR = new char[256];
+    private static final char[] SECOND_CHAR = new char[256];
+    static {
+        for (int i = 0; i < 256; i++) {
+            FIRST_CHAR[i] = HEX_DIGITS[(i >> 4) & 0xF];
+            SECOND_CHAR[i] = HEX_DIGITS[i & 0xF];
+        }
+    }
+
+    private static final byte[] DIGITS = new byte['f'+1];
+    static {
+        for (int i = 0; i <= 'F'; i++) {
+            DIGITS[i] = -1;
+        }
+        for (byte i = 0; i < 10; i++) {
+            DIGITS['0' + i] = i;
+        }
+        for (byte i = 0; i < 6; i++) {
+            DIGITS['A' + i] = (byte)(10 + i);
+            DIGITS['a' + i] = (byte)(10 + i);
+        }
+    }
+
+    /**
+     * Quickly converts a byte array to a hexadecimal string representation.
+     *
+     * @param array byte array, possibly zero-terminated.
+     */
+    public static String encodeHex(byte[] array, boolean zeroTerminated) {
+        char[] cArray = new char[array.length * 2];
+
+        int j = 0;
+        for (int i = 0; i < array.length; i++) {
+            int index = array[i] & 0xFF;
+            if (index == 0 && zeroTerminated) {
+                break;
+            }
+
+            cArray[j++] = FIRST_CHAR[index];
+            cArray[j++] = SECOND_CHAR[index];
+        }
+
+        return new String(cArray, 0, j);
+    }
+
+    /**
+     * Quickly converts a hexadecimal string to a byte array.
+     */
+    public static byte[] decodeHex(String hexString) {
+        int length = hexString.length();
+
+        if ((length & 0x01) != 0) {
+            throw new IllegalArgumentException("Odd number of characters.");
+        }
+
+        boolean badHex = false;
+        byte[] out = new byte[length >> 1];
+        for (int i = 0, j = 0; j < length; i++) {
+            int c1 = hexString.charAt(j++);
+            if (c1 > 'f') {
+                badHex = true;
+                break;
+            }
+
+            final byte d1 = DIGITS[c1];
+            if (d1 == -1) {
+                badHex = true;
+                break;
+            }
+
+            int c2 = hexString.charAt(j++);
+            if (c2 > 'f') {
+                badHex = true;
+                break;
+            }
+
+            final byte d2 = DIGITS[c2];
+            if (d2 == -1) {
+                badHex = true;
+                break;
+            }
+
+            out[i] = (byte) (d1 << 4 | d2);
+        }
+
+        if (badHex) {
+            throw new IllegalArgumentException("Invalid hexadecimal digit: " + hexString);
+        }
+
+        return out;
+    }
+}
diff --git a/src/com/android/providers/contacts/JaroWinklerDistance.java b/src/com/android/providers/contacts/JaroWinklerDistance.java
new file mode 100644
index 0000000..730059d
--- /dev/null
+++ b/src/com/android/providers/contacts/JaroWinklerDistance.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2009 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;
+
+import java.util.Arrays;
+
+/**
+ * A string distance calculator, particularly suited for name matching.
+ * <p>
+ * A detailed discussion of the topic of record linkage in general and name matching
+ * in particular can be found in this article:
+ * <blockquote>
+ * Winkler, W. E. (2006). "Overview of Record Linkage and Current Research Directions".
+ * Research Report Series, RRS.
+ * </blockquote>
+ */
+public class JaroWinklerDistance {
+
+    private static final float WINKLER_BONUS_THRESHOLD = 0.7f;
+
+    private final int mMaxLength;
+    private final boolean[] mMatchFlags1;
+    private final boolean[] mMatchFlags2;
+
+    /**
+     * Constructor.
+     *
+     * @param maxLength byte arrays are truncate if longer than this number
+     */
+    public JaroWinklerDistance(int maxLength) {
+        mMaxLength = maxLength;
+        mMatchFlags1 = new boolean[maxLength];
+        mMatchFlags2 = new boolean[maxLength];
+    }
+
+    /**
+     * Computes a string distance between two normalized strings passed as byte arrays.
+     */
+    public float getDistance(byte bytes1[], byte bytes2[]) {
+        byte[] array1, array2;
+
+        if (bytes1.length > bytes2.length) {
+            array2 = bytes1;
+            array1 = bytes2;
+        } else {
+            array2 = bytes2;
+            array1 = bytes1;
+        }
+
+        int length1 = array1.length;
+        if (length1 > mMaxLength) {
+            length1 = mMaxLength;
+        }
+
+        int length2 = array2.length;
+        if (length2 > mMaxLength) {
+            length2 = mMaxLength;
+        }
+
+        Arrays.fill(mMatchFlags1, 0, length1, false);
+        Arrays.fill(mMatchFlags2, 0, length2, false);
+
+        int range = length2 / 2 - 1;
+        if (range < 0) {
+            range = 0;
+        }
+
+        int matches = 0;
+        for (int i = 0; i < length1; i++) {
+            byte c1 = array1[i];
+
+            int from = i - range;
+            if (from < 0) {
+                from = 0;
+            }
+
+            int to = i + range + 1;
+            if (to > length2) {
+                to = length2;
+            }
+
+            for (int j = from; j < to; j++) {
+                if (!mMatchFlags2[j] && c1 == array2[j]) {
+                    mMatchFlags1[i] = mMatchFlags2[j] = true;
+                    matches++;
+                    break;
+                }
+            }
+        }
+
+        if (matches == 0) {
+            return 0f;
+        }
+
+        int transpositions = 0;
+        int j = 0;
+        for (int i = 0; i < length1; i++) {
+            if (mMatchFlags1[i]) {
+                while (!mMatchFlags2[j]) {
+                    j++;
+                }
+                if (array1[i] != array2[j]) {
+                    transpositions++;
+                }
+                j++;
+            }
+        }
+
+        float m = matches;
+        float jaro = ((m / length1 + m / length2 + (m - (transpositions / 2)) / m)) / 3;
+
+        if (jaro < WINKLER_BONUS_THRESHOLD) {
+            return jaro;
+        }
+
+        // Add Winkler bonus
+        int prefix = 0;
+        for (int i = 0; i < length1; i++) {
+            if (bytes1[i] != bytes2[i]) {
+                break;
+            }
+            prefix++;
+        }
+
+        return jaro + Math.min(0.1f, 1f / length2) * prefix * (1 - jaro);
+    }
+}
diff --git a/src/com/android/providers/contacts/NameNormalizer.java b/src/com/android/providers/contacts/NameNormalizer.java
new file mode 100644
index 0000000..eca40fc
--- /dev/null
+++ b/src/com/android/providers/contacts/NameNormalizer.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2009 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;
+
+import com.ibm.icu4jni.text.CollationAttribute;
+import com.ibm.icu4jni.text.Collator;
+import com.ibm.icu4jni.text.RuleBasedCollator;
+
+/**
+ * Converts a name to a normalized form by removing all non-letter characters and normalizing
+ * UNICODE according to http://unicode.org/unicode/reports/tr15
+ */
+public class NameNormalizer {
+
+    private static final RuleBasedCollator sCompressingCollator;
+    static {
+        sCompressingCollator = (RuleBasedCollator)Collator.getInstance(null);
+        sCompressingCollator.setStrength(Collator.PRIMARY);
+        sCompressingCollator.setDecomposition(Collator.CANONICAL_DECOMPOSITION);
+    }
+
+    private static final RuleBasedCollator sComplexityCollator;
+    static {
+        sComplexityCollator = (RuleBasedCollator)Collator.getInstance(null);
+        sComplexityCollator.setStrength(Collator.TERTIARY);
+        sComplexityCollator.setAttribute(CollationAttribute.CASE_FIRST,
+                CollationAttribute.VALUE_LOWER_FIRST);
+    }
+
+    /**
+     * Converts the supplied name to a string that can be used to perform approximate matching
+     * of names.  It ignores non-letter characters and removes accents.
+     */
+    public static String normalize(String name) {
+        return Hex.encodeHex(sCompressingCollator.getSortKey(lettersOnly(name)), true);
+    }
+
+    /**
+     * Compares "complexity" of two names, which is determined by the presence
+     * of mixed case characters, accents and, if all else is equal, length.
+     */
+    public static int compareComplexity(String name1, String name2) {
+        int diff = sComplexityCollator.compare(lettersOnly(name1), lettersOnly(name2));
+        if (diff != 0) {
+            return diff;
+        }
+
+        return name1.length() - name2.length();
+    }
+
+    /**
+     * Returns a string containing just the letters from the original string.
+     */
+    private static String lettersOnly(String name) {
+        char[] letters = name.toCharArray();
+        int length = 0;
+        for (int i = 0; i < letters.length; i++) {
+            final char c = letters[i];
+            if (Character.isLetter(c)) {
+                letters[length++] = c;
+            }
+        }
+
+        if (length != letters.length) {
+            return new String(letters, 0, length);
+        }
+
+        return name;
+    }
+}
diff --git a/src/com/android/providers/contacts/NameSplitter.java b/src/com/android/providers/contacts/NameSplitter.java
new file mode 100644
index 0000000..aad3bc5
--- /dev/null
+++ b/src/com/android/providers/contacts/NameSplitter.java
@@ -0,0 +1,297 @@
+/*
+ * Copyright (C) 2009 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;
+
+import java.util.HashSet;
+import java.util.StringTokenizer;
+
+/**
+ * The purpose of this class is to split a full name into given names and last
+ * name. The logic only supports having a single last name. If the full name has
+ * multiple last names the output will be incorrect.
+ * <p>
+ * Core algorithm:
+ * <ol>
+ * <li>Remove the suffixes (III, Ph.D., M.D.).</li>
+ * <li>Remove the prefixes (Mr., Pastor, Reverend, Sir).</li>
+ * <li>Assign the last remaining token as the last name.</li>
+ * <li>If the previous word to the last name is one from LASTNAME_PREFIXES, use
+ * this word also as the last name.</li>
+ * <li>Assign the rest of the words as the "given names".</li>
+ * </ol>
+ */
+public class NameSplitter {
+
+    private final HashSet<String> mPrefixesSet;
+    private final HashSet<String> mSuffixesSet;
+    private final int mMaxSuffixLength;
+    private final HashSet<String> mLastNamePrefixesSet;
+    private final HashSet<String> mConjuctions;
+
+    public static class Name {
+        private String prefix;
+        private String givenNames;
+        private String middleName;
+        private String familyName;
+        private String suffix;
+
+        public String getPrefix() {
+            return prefix;
+        }
+
+        public String getGivenNames() {
+            return givenNames;
+        }
+
+        public String getMiddleName() {
+            return middleName;
+        }
+
+        public String getFamilyName() {
+            return familyName;
+        }
+
+        public String getSuffix() {
+            return suffix;
+        }
+    }
+
+    private static class NameTokenizer extends StringTokenizer {
+        private static final int MAX_TOKENS = 10;
+        private final String[] mTokens;
+        private int mDotBitmask;
+        private int mStartPointer;
+        private int mEndPointer;
+
+        public NameTokenizer(String fullName) {
+            super(fullName, " .,", true);
+
+            mTokens = new String[MAX_TOKENS];
+
+            // Iterate over tokens, skipping over empty ones and marking tokens that
+            // are followed by dots.
+            while (hasMoreTokens() && mEndPointer < MAX_TOKENS) {
+                final String token = nextToken();
+                if (token.length() > 0) {
+                    final char c = token.charAt(0);
+                    if (c == ' ' || c == ',') {
+                        continue;
+                    }
+                }
+
+                if (mEndPointer > 0 && token.charAt(0) == '.') {
+                    mDotBitmask |= (1 << (mEndPointer - 1));
+                } else {
+                    mTokens[mEndPointer] = token;
+                    mEndPointer++;
+                }
+            }
+        }
+
+        /**
+         * Returns true if the token is followed by a dot in the original full name.
+         */
+        public boolean hasDot(int index) {
+            return (mDotBitmask & (1 << index)) != 0;
+        }
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param commonPrefixes comma-separated list of common prefixes,
+     *            e.g. "Mr, Ms, Mrs"
+     * @param commonLastNamePrefixes comma-separated list of common last name prefixes,
+     *           e.g. "d', st, st., von"
+     * @param commonSuffixes comma-separated list of common suffixes,
+     *            e.g. "Jr, M.D., MD, D.D.S."
+     * @param commonConjunctions comma-separated list of common conjuctions,
+     *            e.g. "AND, Or"
+     */
+    public NameSplitter(String commonPrefixes, String commonLastNamePrefixes,
+            String commonSuffixes, String commonConjunctions) {
+        mPrefixesSet = convertToSet(commonPrefixes);
+        mLastNamePrefixesSet = convertToSet(commonLastNamePrefixes);
+        mSuffixesSet = convertToSet(commonSuffixes);
+        mConjuctions = convertToSet(commonConjunctions);
+
+        int maxLength = 0;
+        for (String suffix : mSuffixesSet) {
+            if (suffix.length() > maxLength) {
+                maxLength = suffix.length();
+            }
+        }
+
+        mMaxSuffixLength = maxLength;
+    }
+
+    /**
+     * Converts a comma-separated list of Strings to a set of Strings. Trims strings
+     * and converts them to upper case.
+     */
+    private static HashSet<String> convertToSet(String strings) {
+        HashSet<String> set = new HashSet<String>();
+        if (strings != null) {
+            String[] split = strings.split(",");
+            for (int i = 0; i < split.length; i++) {
+                set.add(split[i].trim().toUpperCase());
+            }
+        }
+        return set;
+    }
+
+    /**
+     * Parses a full name and returns parsed components in the Name object.
+     */
+    public void split(Name name, String fullName) {
+        if (fullName == null) {
+            return;
+        }
+
+        NameTokenizer tokens = new NameTokenizer(fullName);
+        parsePrefix(name, tokens);
+        parseSuffix(name, tokens);
+        parseLastName(name, tokens);
+        parseMiddleName(name, tokens);
+        parseGivenNames(name, tokens);
+    }
+
+    /**
+     * Parses the first word from the name if it is a prefix.
+     */
+    private void parsePrefix(Name name, NameTokenizer tokens) {
+        if (tokens.mStartPointer == tokens.mEndPointer) {
+            return;
+        }
+
+        String firstToken = tokens.mTokens[tokens.mStartPointer];
+        if (mPrefixesSet.contains(firstToken.toUpperCase())) {
+            name.prefix = firstToken;
+            tokens.mStartPointer++;
+        }
+    }
+
+    /**
+     * Parses the last word(s) from the name if it is a suffix.
+     */
+    private void parseSuffix(Name name, NameTokenizer tokens) {
+        if (tokens.mStartPointer == tokens.mEndPointer) {
+            return;
+        }
+
+        String lastToken = tokens.mTokens[tokens.mEndPointer - 1];
+        if (lastToken.length() > mMaxSuffixLength) {
+            return;
+        }
+
+        String normalized = lastToken.toUpperCase();
+        if (mSuffixesSet.contains(normalized)) {
+            name.suffix = lastToken;
+            tokens.mEndPointer--;
+            return;
+        }
+
+        if (tokens.hasDot(tokens.mEndPointer - 1)) {
+            lastToken += '.';
+        }
+        normalized += ".";
+
+        // Take care of suffixes like M.D. and D.D.S.
+        int pos = tokens.mEndPointer - 1;
+        while (normalized.length() <= mMaxSuffixLength) {
+
+            if (mSuffixesSet.contains(normalized)) {
+                name.suffix = lastToken;
+                tokens.mEndPointer = pos;
+                return;
+            }
+
+            if (pos == tokens.mStartPointer) {
+                break;
+            }
+
+            pos--;
+            if (tokens.hasDot(pos)) {
+                lastToken = tokens.mTokens[pos] + "." + lastToken;
+            } else {
+                lastToken = tokens.mTokens[pos] + " " + lastToken;
+            }
+
+            normalized = tokens.mTokens[pos].toUpperCase() + "." + normalized;
+        }
+    }
+
+    private void parseLastName(Name name, NameTokenizer tokens) {
+        if (tokens.mStartPointer == tokens.mEndPointer) {
+            return;
+        }
+
+        name.familyName = tokens.mTokens[tokens.mEndPointer - 1];
+        tokens.mEndPointer--;
+
+        // Take care of last names like "D'Onofrio" and "von Cliburn"
+        if ((tokens.mEndPointer - tokens.mStartPointer) > 0) {
+            String lastNamePrefix = tokens.mTokens[tokens.mEndPointer - 1];
+            final String normalized = lastNamePrefix.toUpperCase();
+            if (mLastNamePrefixesSet.contains(normalized)
+                    || mLastNamePrefixesSet.contains(normalized + ".")) {
+                if (tokens.hasDot(tokens.mEndPointer - 1)) {
+                    lastNamePrefix += '.';
+                }
+                name.familyName = lastNamePrefix + " " + name.familyName;
+                tokens.mEndPointer--;
+            }
+        }
+    }
+
+
+    private void parseMiddleName(Name name, NameTokenizer tokens) {
+        if (tokens.mStartPointer == tokens.mEndPointer) {
+            return;
+        }
+
+        if ((tokens.mEndPointer - tokens.mStartPointer) > 1) {
+            if ((tokens.mEndPointer - tokens.mStartPointer) == 2
+                    || !mConjuctions.contains(tokens.mTokens[tokens.mEndPointer - 2].
+                            toUpperCase())) {
+                name.middleName = tokens.mTokens[tokens.mEndPointer - 1];
+                tokens.mEndPointer--;
+            }
+        }
+    }
+
+    private void parseGivenNames(Name name, NameTokenizer tokens) {
+        if (tokens.mStartPointer == tokens.mEndPointer) {
+            return;
+        }
+
+        if ((tokens.mEndPointer - tokens.mStartPointer) == 1) {
+            name.givenNames = tokens.mTokens[tokens.mStartPointer];
+        } else {
+            StringBuilder sb = new StringBuilder();
+            for (int i = tokens.mStartPointer; i < tokens.mEndPointer; i++) {
+                if (i != tokens.mStartPointer) {
+                    sb.append(' ');
+                }
+                sb.append(tokens.mTokens[i]);
+                if (tokens.hasDot(i)) {
+                    sb.append('.');
+                }
+            }
+            name.givenNames = sb.toString();
+        }
+    }
+}
diff --git a/src/com/android/providers/contacts/OpenHelper.java b/src/com/android/providers/contacts/OpenHelper.java
new file mode 100644
index 0000000..d7f34c4
--- /dev/null
+++ b/src/com/android/providers/contacts/OpenHelper.java
@@ -0,0 +1,1162 @@
+/*
+ * Copyright (C) 2009 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;
+
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.database.Cursor;
+import android.database.DatabaseUtils;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteDoneException;
+import android.database.sqlite.SQLiteException;
+import android.database.sqlite.SQLiteOpenHelper;
+import android.database.sqlite.SQLiteQueryBuilder;
+import android.database.sqlite.SQLiteStatement;
+import android.os.Binder;
+import android.provider.BaseColumns;
+import android.provider.SocialContract.Activities;
+import android.provider.ContactsContract.Accounts;
+import android.provider.ContactsContract.Aggregates;
+import android.provider.ContactsContract.AggregationExceptions;
+import android.provider.ContactsContract.CommonDataKinds;
+import android.provider.ContactsContract.Contacts;
+import android.provider.ContactsContract.Data;
+import android.provider.ContactsContract.Groups;
+import android.provider.ContactsContract.Presence;
+import android.provider.ContactsContract.RestrictionExceptions;
+import android.provider.ContactsContract.CommonDataKinds.Email;
+import android.provider.ContactsContract.CommonDataKinds.GroupMembership;
+import android.provider.ContactsContract.CommonDataKinds.Im;
+import android.provider.ContactsContract.CommonDataKinds.Phone;
+
+import android.telephony.PhoneNumberUtils;
+import android.util.Log;
+
+import java.util.HashMap;
+import java.util.LinkedList;
+
+/**
+ * Database open helper for contacts and social activity data. Designed as a
+ * singleton to make sure that all {@link android.content.ContentProvider} users get the same
+ * reference. Provides handy methods for maintaining package and mime-type
+ * lookup tables.
+ */
+/* package */ class OpenHelper extends SQLiteOpenHelper {
+    private static final String TAG = "OpenHelper";
+
+    private static final int DATABASE_VERSION = 38;
+    private static final String DATABASE_NAME = "contacts2.db";
+    private static final String DATABASE_PRESENCE = "presence_db";
+
+    public interface Tables {
+        public static final String ACCOUNTS = "accounts";
+        public static final String AGGREGATES = "aggregates";
+        public static final String CONTACTS = "contacts";
+        public static final String PACKAGES = "packages";
+        public static final String MIMETYPES = "mimetypes";
+        public static final String PHONE_LOOKUP = "phone_lookup";
+        public static final String NAME_LOOKUP = "name_lookup";
+        public static final String AGGREGATION_EXCEPTIONS = "agg_exceptions";
+        public static final String RESTRICTION_EXCEPTIONS = "rest_exceptions";
+        public static final String CONTACT_OPTIONS = "contact_options";
+        public static final String DATA = "data";
+        public static final String GROUPS = "groups";
+        public static final String PRESENCE = "presence";
+        public static final String NICKNAME_LOOKUP = "nickname_lookup";
+
+        public static final String AGGREGATES_JOIN_PRESENCE_PRIMARY_PHONE = "aggregates "
+                + "LEFT OUTER JOIN presence ON (aggregates._id = presence.aggregate_id) "
+                + "LEFT OUTER JOIN data ON (primary_phone_id = data._id)";
+
+        public static final String DATA_JOIN_MIMETYPES = "data "
+                + "LEFT OUTER JOIN mimetypes ON (data.mimetype_id = mimetypes._id)";
+
+        public static final String DATA_JOIN_MIMETYPE_CONTACTS = "data "
+                + "LEFT OUTER JOIN mimetypes ON (data.mimetype_id = mimetypes._id) "
+                + "LEFT OUTER JOIN contacts ON (data.contact_id = contacts._id)";
+
+        public static final String DATA_JOIN_CONTACTS_GROUPS = "data "
+                + "LEFT OUTER JOIN contacts ON (data.contact_id = contacts._id)"
+                + "LEFT OUTER JOIN groups ON (groups._id = data." + GroupMembership.GROUP_ROW_ID
+                + ")";
+
+        public static final String DATA_JOIN_MIMETYPES_CONTACTS_PACKAGES = "data "
+                + "LEFT OUTER JOIN mimetypes ON (data.mimetype_id = mimetypes._id) "
+                + "LEFT OUTER JOIN contacts ON (data.contact_id = contacts._id) "
+                + "LEFT OUTER JOIN packages ON (contacts.package_id = packages._id)";
+
+        public static final String DATA_JOIN_MIMETYPES_CONTACTS_PACKAGES_AGGREGATES = "data "
+                + "LEFT OUTER JOIN mimetypes ON (data.mimetype_id = mimetypes._id) "
+                + "LEFT OUTER JOIN contacts ON (data.contact_id = contacts._id) "
+                + "LEFT OUTER JOIN packages ON (contacts.package_id = packages._id) "
+                + "LEFT OUTER JOIN aggregates ON (contacts.aggregate_id = aggregates._id)";
+
+        public static final String DATA_JOIN_MIMETYPES_CONTACTS_PACKAGES_GROUPS = "data "
+                + "LEFT OUTER JOIN mimetypes ON (data.mimetype_id = mimetypes._id) "
+                + "LEFT OUTER JOIN contacts ON (data.contact_id = contacts._id) "
+                + "LEFT OUTER JOIN packages ON (contacts.package_id = packages._id) "
+                + "LEFT OUTER JOIN groups ON (groups._id = data." + GroupMembership.GROUP_ROW_ID
+                + ")";
+
+        public static final String GROUPS_JOIN_PACKAGES = "groups "
+                + "LEFT OUTER JOIN packages ON (groups.package_id = packages._id)";
+
+        public static final String DATA_JOIN_MIMETYPES_CONTACTS_AGGREGATES = "data "
+                + "LEFT OUTER JOIN mimetypes ON (data.mimetype_id = mimetypes._id) "
+                + "LEFT OUTER JOIN contacts ON (data.contact_id = contacts._id) "
+                + "LEFT OUTER JOIN aggregates ON (contacts.aggregate_id = aggregates._id)";
+
+        public static final String GROUPS_JOIN_PACKAGES_DATA_CONTACTS_AGGREGATES = "groups "
+                + "LEFT OUTER JOIN packages ON (groups.package_id = packages._id) "
+                + "LEFT OUTER JOIN data ON (groups._id = data." + GroupMembership.GROUP_ROW_ID
+                + ") " + "LEFT OUTER JOIN contacts ON (data.contact_id = contacts._id) "
+                + "LEFT OUTER JOIN aggregates ON (contacts.aggregate_id = aggregates._id)";
+
+        public static final String ACTIVITIES = "activities";
+
+        public static final String ACTIVITIES_JOIN_MIMETYPES = "activities "
+                + "LEFT OUTER JOIN mimetypes ON (activities.mimetype_id = mimetypes._id)";
+
+        public static final String ACTIVITIES_JOIN_MIMETYPES_CONTACTS_PACKAGES_AGGREGATES = "activities "
+                + "LEFT OUTER JOIN mimetypes ON (activities.mimetype_id = mimetypes._id) "
+                + "LEFT OUTER JOIN contacts ON (activities.author_contact_id = contacts._id) "
+                + "LEFT OUTER JOIN packages ON (contacts.package_id = packages._id) "
+                + "LEFT OUTER JOIN aggregates ON (contacts.aggregate_id = aggregates._id)";
+
+        public static final String CONTACTS_JOIN_PACKAGES_ACCOUNTS = "contacts "
+                + "LEFT OUTER JOIN packages ON (contacts.package_id = packages._id) "
+                + "LEFT OUTER JOIN accounts ON (contacts.accounts_id = accounts._id)";
+
+        public static final String NAME_LOOKUP_JOIN_CONTACTS = "name_lookup "
+                + "INNER JOIN contacts ON (name_lookup.contact_id = contacts._id)";
+
+        public static final String AGGREGATION_EXCEPTIONS_JOIN_CONTACTS = "agg_exceptions "
+                + "INNER JOIN contacts contacts1 "
+                + "ON (agg_exceptions.contact_id1 = contacts1._id) ";
+
+        public static final String AGGREGATION_EXCEPTIONS_JOIN_CONTACTS_TWICE = "agg_exceptions "
+                + "INNER JOIN contacts contacts1 "
+                + "ON (agg_exceptions.contact_id1 = contacts1._id) "
+                + "INNER JOIN contacts contacts2 "
+                + "ON (agg_exceptions.contact_id2 = contacts2._id) ";
+
+        public static final String CONTACTS_JOIN_CONTACT_OPTIONS = "contacts "
+                + "LEFT OUTER JOIN contact_options ON (contacts._id = contact_options._id)";
+    }
+
+    public interface Clauses {
+        public static final String WHERE_IM_MATCHES = MimetypesColumns.MIMETYPE + "=" + Im.MIMETYPE
+                + " AND " + Im.PROTOCOL + "=? AND " + Im.DATA + "=?";
+
+        public static final String WHERE_EMAIL_MATCHES = MimetypesColumns.MIMETYPE + "="
+                + Email.MIMETYPE + " AND " + Email.DATA + "=?";
+
+        public static final String MIMETYPE_IS_GROUP_MEMBERSHIP = MimetypesColumns.CONCRETE_MIMETYPE
+                + "='" + GroupMembership.CONTENT_ITEM_TYPE + "'";
+
+        public static final String BELONGS_TO_GROUP = DataColumns.CONCRETE_GROUP_ID + "="
+                + GroupsColumns.CONCRETE_ID;
+
+        public static final String HAS_PRIMARY_PHONE = "("
+                + AggregatesColumns.OPTIMAL_PRIMARY_PHONE_ID + " IS NOT NULL OR "
+                + AggregatesColumns.FALLBACK_PRIMARY_PHONE_ID + " IS NOT NULL)";
+
+        // TODO: add in check against package_visible
+        public static final String IN_VISIBLE_GROUP = "SELECT MIN(COUNT(" + DataColumns.CONCRETE_ID
+                + "),1) FROM " + Tables.DATA_JOIN_CONTACTS_GROUPS + " WHERE "
+                + DataColumns.MIMETYPE_ID + "=? AND " + Contacts.AGGREGATE_ID + "="
+                + AggregatesColumns.CONCRETE_ID + " AND " + Groups.GROUP_VISIBLE + "=1";
+    }
+
+    public interface AggregatesColumns {
+        public static final String OPTIMAL_PRIMARY_PHONE_ID = "optimal_phone_id";
+        public static final String OPTIMAL_PRIMARY_PHONE_PACKAGE_ID = "optimal_phone_package_id";
+        public static final String FALLBACK_PRIMARY_PHONE_ID = "fallback_phone_id";
+
+        public static final String OPTIMAL_PRIMARY_EMAIL_ID = "optimal_email_id";
+        public static final String OPTIMAL_PRIMARY_EMAIL_PACKAGE_ID = "optimal_email_package_id";
+        public static final String FALLBACK_PRIMARY_EMAIL_ID = "fallback_email_id";
+
+        public static final String SINGLE_RESTRICTED_PACKAGE_ID = "single_restricted_package_id";
+
+        public static final String CONCRETE_ID = Tables.AGGREGATES + "." + BaseColumns._ID;
+    }
+
+    public interface ContactsColumns {
+        public static final String PACKAGE_ID = "package_id";
+
+        public static final String CONCRETE_ID = Tables.CONTACTS + "." + BaseColumns._ID;
+    }
+
+    public interface DataColumns {
+        public static final String MIMETYPE_ID = "mimetype_id";
+
+        public static final String CONCRETE_ID = Tables.DATA + "." + BaseColumns._ID;
+        public static final String CONCRETE_CONTACT_ID = Tables.DATA + "." + Data.CONTACT_ID;
+        public static final String CONCRETE_GROUP_ID = Tables.DATA + "."
+                + GroupMembership.GROUP_ROW_ID;
+    }
+
+    public interface GroupsColumns {
+        public static final String CONCRETE_ID = Tables.GROUPS + "." + BaseColumns._ID;
+        public static final String CONCRETE_PACKAGE_ID = Tables.GROUPS + "." + Groups.PACKAGE_ID;
+    }
+
+    public interface ActivitiesColumns {
+        public static final String PACKAGE_ID = "package_id";
+        public static final String MIMETYPE_ID = "mimetype_id";
+    }
+
+    public interface PhoneLookupColumns {
+        public static final String _ID = BaseColumns._ID;
+        public static final String DATA_ID = "data_id";
+        public static final String CONTACT_ID = "contact_id";
+        public static final String NORMALIZED_NUMBER = "normalized_number";
+    }
+
+    public interface NameLookupColumns {
+        public static final String _ID = BaseColumns._ID;
+        public static final String CONTACT_ID = "contact_id";
+        public static final String NORMALIZED_NAME = "normalized_name";
+        public static final String NAME_TYPE = "name_type";
+    }
+
+    public final static class NameLookupType {
+        public static final int FULL_NAME = 0;
+        public static final int FULL_NAME_CONCATENATED = 1;
+        public static final int FULL_NAME_REVERSE = 2;
+        public static final int FULL_NAME_REVERSE_CONCATENATED = 3;
+        public static final int FULL_NAME_WITH_NICKNAME = 4;
+        public static final int FULL_NAME_WITH_NICKNAME_REVERSE = 5;
+        public static final int GIVEN_NAME_ONLY = 6;
+        public static final int GIVEN_NAME_ONLY_AS_NICKNAME = 7;
+        public static final int FAMILY_NAME_ONLY = 8;
+        public static final int FAMILY_NAME_ONLY_AS_NICKNAME = 9;
+        public static final int NICKNAME = 10;
+        public static final int EMAIL_BASED_NICKNAME = 11;
+
+        // This is the highest name lookup type code plus one
+        public static final int TYPE_COUNT = 12;
+
+        public static boolean isBasedOnStructuredName(int nameLookupType) {
+            return nameLookupType != NameLookupType.EMAIL_BASED_NICKNAME
+                    && nameLookupType != NameLookupType.NICKNAME;
+        }
+    }
+
+    public interface PackagesColumns {
+        public static final String _ID = BaseColumns._ID;
+        public static final String PACKAGE = "package";
+    }
+
+    public interface MimetypesColumns {
+        public static final String _ID = BaseColumns._ID;
+        public static final String MIMETYPE = "mimetype";
+
+        public static final String CONCRETE_ID = Tables.MIMETYPES + "." + BaseColumns._ID;
+        public static final String CONCRETE_MIMETYPE = Tables.MIMETYPES + "." + MIMETYPE;
+    }
+
+    public interface AggregationExceptionColumns {
+        public static final String _ID = BaseColumns._ID;
+        public static final String CONTACT_ID1 = "contact_id1";
+        public static final String CONTACT_ID2 = "contact_id2";
+    }
+
+    public interface RestrictionExceptionsColumns {
+        public static final String PACKAGE_PROVIDER_ID = "package_provider_id";
+        public static final String PACKAGE_CLIENT_ID = "package_client_id";
+    }
+
+    public interface ContactOptionsColumns {
+        public static final String _ID = BaseColumns._ID;
+        public static final String CUSTOM_RINGTONE = "custom_ringtone";
+        public static final String SEND_TO_VOICEMAIL = "send_to_voicemail";
+    }
+
+    public interface NicknameLookupColumns {
+        public static final String NAME = "name";
+        public static final String CLUSTER = "cluster";
+    }
+
+    private static final String[] NICKNAME_LOOKUP_COLUMNS = new String[] {
+        NicknameLookupColumns.CLUSTER
+    };
+
+    private static final int COL_NICKNAME_LOOKUP_CLUSTER = 0;
+
+    /** In-memory cache of previously found mimetype mappings */
+    private final HashMap<String, Long> mMimetypeCache = new HashMap<String, Long>();
+    /** In-memory cache of previously found package name mappings */
+    private final HashMap<String, Long> mPackageCache = new HashMap<String, Long>();
+
+
+    /** Compiled statements for querying and inserting mappings */
+    private SQLiteStatement mMimetypeQuery;
+    private SQLiteStatement mPackageQuery;
+    private SQLiteStatement mAggregateIdQuery;
+    private SQLiteStatement mAggregateIdUpdate;
+    private SQLiteStatement mMimetypeInsert;
+    private SQLiteStatement mPackageInsert;
+    private SQLiteStatement mNameLookupInsert;
+
+    private SQLiteStatement mDataMimetypeQuery;
+    private SQLiteStatement mActivitiesMimetypeQuery;
+
+    private final Context mContext;
+    private final RestrictionExceptionsCache mCache;
+    private HashMap<String, String[]> mNicknameClusterCache;
+
+    /** Compiled statements for updating {@link Aggregates#IN_VISIBLE_GROUP}. */
+    private SQLiteStatement mVisibleAllUpdate;
+    private SQLiteStatement mVisibleSpecificUpdate;
+
+
+    private static OpenHelper sSingleton = null;
+
+    public static synchronized OpenHelper getInstance(Context context) {
+        if (sSingleton == null) {
+            sSingleton = new OpenHelper(context);
+        }
+        return sSingleton;
+    }
+
+    /**
+     * Private constructor, callers except unit tests should obtain an instance through
+     * {@link #getInstance(Context)} instead.
+     */
+    /* package */ OpenHelper(Context context) {
+        super(context, DATABASE_NAME, null, DATABASE_VERSION);
+        Log.i(TAG, "Creating OpenHelper");
+
+        mContext = context;
+        mCache = new RestrictionExceptionsCache();
+        mCache.loadFromDatabase(context, getReadableDatabase());
+    }
+
+    @Override
+    public void onOpen(SQLiteDatabase db) {
+        // Create compiled statements for package and mimetype lookups
+        mMimetypeQuery = db.compileStatement("SELECT " + MimetypesColumns._ID + " FROM "
+                + Tables.MIMETYPES + " WHERE " + MimetypesColumns.MIMETYPE + "=?");
+        mPackageQuery = db.compileStatement("SELECT " + PackagesColumns._ID + " FROM "
+                + Tables.PACKAGES + " WHERE " + PackagesColumns.PACKAGE + "=?");
+        mAggregateIdQuery = db.compileStatement("SELECT " + Contacts.AGGREGATE_ID + " FROM "
+                + Tables.CONTACTS + " WHERE " + Contacts._ID + "=?");
+        mAggregateIdUpdate = db.compileStatement("UPDATE " + Tables.CONTACTS + " SET "
+                + Contacts.AGGREGATE_ID + "=?" + " WHERE " + Contacts._ID + "=?");
+        mMimetypeInsert = db.compileStatement("INSERT INTO " + Tables.MIMETYPES + "("
+                + MimetypesColumns.MIMETYPE + ") VALUES (?)");
+        mPackageInsert = db.compileStatement("INSERT INTO " + Tables.PACKAGES + "("
+                + PackagesColumns.PACKAGE + ") VALUES (?)");
+
+        mDataMimetypeQuery = db.compileStatement("SELECT " + MimetypesColumns.MIMETYPE + " FROM "
+                + Tables.DATA_JOIN_MIMETYPES + " WHERE " + Tables.DATA + "." + Data._ID + "=?");
+        mActivitiesMimetypeQuery = db.compileStatement("SELECT " + MimetypesColumns.MIMETYPE
+                + " FROM " + Tables.ACTIVITIES_JOIN_MIMETYPES + " WHERE " + Tables.ACTIVITIES + "."
+                + Activities._ID + "=?");
+        mNameLookupInsert = db.compileStatement("INSERT INTO " + Tables.NAME_LOOKUP + "("
+                + NameLookupColumns.CONTACT_ID + "," + NameLookupColumns.NAME_TYPE + ","
+                + NameLookupColumns.NORMALIZED_NAME + ") VALUES (?,?,?)");
+
+        final String visibleUpdate = "UPDATE " + Tables.AGGREGATES + " SET "
+                + Aggregates.IN_VISIBLE_GROUP + "= (" + Clauses.IN_VISIBLE_GROUP + ")";
+
+        mVisibleAllUpdate = db.compileStatement(visibleUpdate);
+        mVisibleSpecificUpdate = db.compileStatement(visibleUpdate + " WHERE "
+                + AggregatesColumns.CONCRETE_ID + "=?");
+
+        // Make sure we have an in-memory presence table
+        final String tableName = DATABASE_PRESENCE + "." + Tables.PRESENCE;
+        final String indexName = DATABASE_PRESENCE + ".presenceIndex";
+
+        db.execSQL("ATTACH DATABASE ':memory:' AS " + DATABASE_PRESENCE + ";");
+        db.execSQL("CREATE TABLE IF NOT EXISTS " + tableName + " ("+
+                BaseColumns._ID + " INTEGER PRIMARY KEY," +
+                Presence.AGGREGATE_ID + " INTEGER REFERENCES aggregates(_id)," +
+                Presence.DATA_ID + " INTEGER REFERENCES data(_id)," +
+                Presence.IM_PROTOCOL + " TEXT," +
+                Presence.IM_HANDLE + " TEXT," +
+                Presence.IM_ACCOUNT + " TEXT," +
+                Presence.PRESENCE_STATUS + " INTEGER," +
+                Presence.PRESENCE_CUSTOM_STATUS + " TEXT," +
+                "UNIQUE(" + Presence.IM_PROTOCOL + ", " + Presence.IM_HANDLE + ", " + Presence.IM_ACCOUNT + ")" +
+        ");");
+
+        db.execSQL("CREATE INDEX IF NOT EXISTS " + indexName + " ON " + Tables.PRESENCE + " ("
+                + Presence.AGGREGATE_ID + ");");
+    }
+
+    @Override
+    public void onCreate(SQLiteDatabase db) {
+        Log.i(TAG, "Bootstrapping database");
+
+        db.execSQL("CREATE TABLE " + Tables.ACCOUNTS + " (" +
+                BaseColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
+                Accounts.NAME + " TEXT," +
+                Accounts.TYPE + " TEXT," +
+                Accounts.DATA1 + " TEXT," +
+                Accounts.DATA2 + " TEXT, " +
+                Accounts.DATA3 + " TEXT, " +
+                Accounts.DATA4 + " TEXT, " +
+                Accounts.DATA5 + " TEXT, " +
+                " UNIQUE(" + Accounts.NAME + ", " + Accounts.TYPE + ") " +
+        ");");
+
+        // One row per group of contacts corresponding to the same person
+        db.execSQL("CREATE TABLE " + Tables.AGGREGATES + " (" +
+                BaseColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
+                Aggregates.DISPLAY_NAME + " TEXT," +
+                Aggregates.TIMES_CONTACTED + " INTEGER," +
+                Aggregates.LAST_TIME_CONTACTED + " INTEGER," +
+                Aggregates.STARRED + " INTEGER," +
+                AggregatesColumns.OPTIMAL_PRIMARY_PHONE_ID + " INTEGER REFERENCES data(_id)," +
+                AggregatesColumns.OPTIMAL_PRIMARY_PHONE_PACKAGE_ID + " INTEGER REFERENCES package(_id)," +
+                AggregatesColumns.FALLBACK_PRIMARY_PHONE_ID + " INTEGER REFERENCES data(_id)," +
+                AggregatesColumns.OPTIMAL_PRIMARY_EMAIL_ID + " INTEGER REFERENCES data(_id)," +
+                AggregatesColumns.OPTIMAL_PRIMARY_EMAIL_PACKAGE_ID + " INTEGER REFERENCES package(_id)," +
+                AggregatesColumns.FALLBACK_PRIMARY_EMAIL_ID + " INTEGER REFERENCES data(_id)," +
+                AggregatesColumns.SINGLE_RESTRICTED_PACKAGE_ID + " INTEGER REFERENCES package(_id)," +
+                Aggregates.PHOTO_ID + " INTEGER REFERENCES data(_id)," +
+                Aggregates.CUSTOM_RINGTONE + " TEXT," +
+                Aggregates.SEND_TO_VOICEMAIL + " INTEGER NOT NULL DEFAULT 0," +
+                Aggregates.IN_VISIBLE_GROUP + " INTEGER NOT NULL DEFAULT 1" +
+        ");");
+
+        // Contacts table
+        db.execSQL("CREATE TABLE " + Tables.CONTACTS + " (" +
+                Contacts._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
+                ContactsColumns.PACKAGE_ID + " INTEGER REFERENCES package(_id) NOT NULL," +
+                Contacts.IS_RESTRICTED + " INTEGER NOT NULL DEFAULT 0," +
+                Contacts.ACCOUNTS_ID + " INTEGER REFERENCES accounts(_id)," +
+                Contacts.SOURCE_ID + " TEXT," +
+                Contacts.VERSION + " INTEGER NOT NULL DEFAULT 1," +
+                Contacts.DIRTY + " INTEGER NOT NULL DEFAULT 1," +
+                Contacts.AGGREGATE_ID + " INTEGER " +
+        ");");
+
+        // Contact options table. It has the same primary key as the corresponding contact.
+        db.execSQL("CREATE TABLE " + Tables.CONTACT_OPTIONS + " (" +
+                ContactOptionsColumns._ID + " INTEGER PRIMARY KEY," +
+                ContactOptionsColumns.CUSTOM_RINGTONE + " TEXT," +
+                ContactOptionsColumns.SEND_TO_VOICEMAIL + " INTEGER NOT NULL DEFAULT 0" +
+       ");");
+
+        // Package name mapping table
+        db.execSQL("CREATE TABLE " + Tables.PACKAGES + " (" +
+                PackagesColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
+                PackagesColumns.PACKAGE + " TEXT NOT NULL" +
+        ");");
+
+        // Mimetype mapping table
+        db.execSQL("CREATE TABLE " + Tables.MIMETYPES + " (" +
+                MimetypesColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
+                MimetypesColumns.MIMETYPE + " TEXT NOT NULL" +
+        ");");
+
+        // Public generic data table
+        db.execSQL("CREATE TABLE " + Tables.DATA + " (" +
+                Data._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
+                DataColumns.MIMETYPE_ID + " INTEGER REFERENCES mimetype(_id) NOT NULL," +
+                Data.CONTACT_ID + " INTEGER NOT NULL," +
+                Data.IS_PRIMARY + " INTEGER NOT NULL DEFAULT 0," +
+                Data.IS_SUPER_PRIMARY + " INTEGER NOT NULL DEFAULT 0," +
+                Data.DATA_VERSION + " INTEGER NOT NULL DEFAULT 0," +
+                Data.DATA1 + " TEXT," +
+                Data.DATA2 + " TEXT," +
+                Data.DATA3 + " TEXT," +
+                Data.DATA4 + " TEXT," +
+                Data.DATA5 + " TEXT," +
+                Data.DATA6 + " TEXT," +
+                Data.DATA7 + " TEXT," +
+                Data.DATA8 + " TEXT," +
+                Data.DATA9 + " TEXT," +
+                Data.DATA10 + " TEXT" +
+        ");");
+
+        /**
+         * set contact.dirty whenever the contact is updated and the new version does not explicity
+         * clear the dirty flag
+         *
+         * Want to have a data row that has the server version of the contact. Then when I save
+         * an entry from the server into the provider I will set the server version of the data
+         * while also clearing the dirty flag of the contact.
+         *
+         * increment the contact.version whenever the contact is updated
+         */
+        db.execSQL("CREATE TRIGGER " + Tables.CONTACTS + "_updated1 "
+                + "   BEFORE UPDATE ON " + Tables.CONTACTS
+                + " BEGIN "
+                + "   UPDATE " + Tables.CONTACTS
+                + "     SET "
+                +         Contacts.VERSION + "=OLD." + Contacts.VERSION + "+1, "
+                +         Contacts.DIRTY + "=1"
+                + "     WHERE " + Contacts._ID + "=OLD." + Contacts._ID + ";"
+                + " END");
+
+        db.execSQL("CREATE TRIGGER " + Tables.CONTACTS + "_deleted "
+                + "   BEFORE DELETE ON " + Tables.CONTACTS
+                + " BEGIN "
+                + "   DELETE FROM " + Tables.DATA
+                + "     WHERE " + Data.CONTACT_ID + "=OLD." + Contacts._ID + ";"
+                + "   DELETE FROM " + Tables.PHONE_LOOKUP
+                + "     WHERE " + PhoneLookupColumns.CONTACT_ID + "=OLD." + Contacts._ID + ";"
+                + " END");
+
+        db.execSQL("CREATE TRIGGER " + Tables.DATA + "_updated AFTER UPDATE ON " + Tables.DATA
+                + " BEGIN "
+                + "   UPDATE " + Tables.DATA
+                + "     SET " + Data.DATA_VERSION + "=OLD." + Data.DATA_VERSION + "+1 "
+                + "     WHERE " + Data._ID + "=OLD." + Data._ID + ";"
+                + "   UPDATE " + Tables.CONTACTS
+                + "     SET " + Contacts.DIRTY + "=1"
+                + "     WHERE " + Contacts._ID + "=OLD." + Contacts._ID + ";"
+                + " END");
+
+        db.execSQL("CREATE TRIGGER " + Tables.DATA + "_deleted BEFORE DELETE ON " + Tables.DATA
+                + " BEGIN "
+                + "   UPDATE " + Tables.CONTACTS
+                + "     SET " + Contacts.DIRTY + "=1"
+                + "     WHERE " + Contacts._ID + "=OLD." + Contacts._ID + ";"
+                + "   DELETE FROM " + Tables.PHONE_LOOKUP
+                + "     WHERE " + PhoneLookupColumns.DATA_ID + "=OLD." + Data._ID + ";"
+                + " END");
+
+        // Private phone numbers table used for lookup
+        db.execSQL("CREATE TABLE " + Tables.PHONE_LOOKUP + " (" +
+                PhoneLookupColumns._ID + " INTEGER PRIMARY KEY," +
+                PhoneLookupColumns.DATA_ID + " INTEGER REFERENCES data(_id) NOT NULL," +
+                PhoneLookupColumns.CONTACT_ID + " INTEGER REFERENCES contacts(_id) NOT NULL," +
+                PhoneLookupColumns.NORMALIZED_NUMBER + " TEXT NOT NULL" +
+        ");");
+
+        db.execSQL("CREATE INDEX phone_lookup_index ON " + Tables.PHONE_LOOKUP + " (" +
+                PhoneLookupColumns.NORMALIZED_NUMBER + " ASC, " +
+                PhoneLookupColumns.CONTACT_ID + ", " +
+                PhoneLookupColumns.DATA_ID +
+        ");");
+
+        // Private name/nickname table used for lookup
+        db.execSQL("CREATE TABLE " + Tables.NAME_LOOKUP + " (" +
+                NameLookupColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
+                NameLookupColumns.CONTACT_ID + " INTEGER REFERENCES contacts(_id) NOT NULL," +
+                NameLookupColumns.NORMALIZED_NAME + " TEXT," +
+                NameLookupColumns.NAME_TYPE + " INTEGER" +
+        ");");
+
+        db.execSQL("CREATE INDEX name_lookup_index ON " + Tables.NAME_LOOKUP + " (" +
+                NameLookupColumns.NORMALIZED_NAME + " ASC, " +
+                NameLookupColumns.NAME_TYPE + " ASC, " +
+                NameLookupColumns.CONTACT_ID +
+        ");");
+
+        db.execSQL("CREATE TABLE " + Tables.NICKNAME_LOOKUP + " (" +
+                NicknameLookupColumns.NAME + " TEXT," +
+                NicknameLookupColumns.CLUSTER + " TEXT" +
+        ");");
+
+        db.execSQL("CREATE UNIQUE INDEX nickname_lookup_index ON " + Tables.NICKNAME_LOOKUP + " (" +
+                NicknameLookupColumns.NAME + ", " +
+                NicknameLookupColumns.CLUSTER +
+        ");");
+
+        // Groups table
+        db.execSQL("CREATE TABLE " + Tables.GROUPS + " (" +
+                Groups._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
+                Groups.PACKAGE_ID + " INTEGER REFERENCES package(_id) NOT NULL," +
+                Groups.ACCOUNTS_ID + " INTEGER REFERENCES accounts(_id)," +
+                Groups.SOURCE_ID + " TEXT," +
+                Groups.TITLE + " TEXT," +
+                Groups.TITLE_RESOURCE + " INTEGER," +
+                Groups.GROUP_VISIBLE + " INTEGER" +
+        ");");
+
+        db.execSQL("CREATE TABLE IF NOT EXISTS " + Tables.AGGREGATION_EXCEPTIONS + " (" +
+                AggregationExceptionColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
+                AggregationExceptions.TYPE + " INTEGER NOT NULL, " +
+                AggregationExceptionColumns.CONTACT_ID1 + " INTEGER REFERENCES contacts(_id), " +
+                AggregationExceptionColumns.CONTACT_ID2 + " INTEGER REFERENCES contacts(_id)" +
+		");");
+
+        db.execSQL("CREATE UNIQUE INDEX IF NOT EXISTS aggregation_exception_index1 ON " +
+                Tables.AGGREGATION_EXCEPTIONS + " (" +
+                AggregationExceptionColumns.CONTACT_ID1 + ", " +
+                AggregationExceptionColumns.CONTACT_ID2 +
+        ");");
+
+        db.execSQL("CREATE UNIQUE INDEX IF NOT EXISTS aggregation_exception_index2 ON " +
+                Tables.AGGREGATION_EXCEPTIONS + " (" +
+                AggregationExceptionColumns.CONTACT_ID2 + ", " +
+                AggregationExceptionColumns.CONTACT_ID1 +
+        ");");
+
+        // Restriction exceptions table
+        db.execSQL("CREATE TABLE " + Tables.RESTRICTION_EXCEPTIONS + " (" +
+                BaseColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
+                RestrictionExceptions.PACKAGE_PROVIDER + " TEXT NOT NULL, " +
+                RestrictionExceptions.PACKAGE_CLIENT + " TEXT NOT NULL, " +
+                RestrictionExceptionsColumns.PACKAGE_PROVIDER_ID + " INTEGER NOT NULL, " +
+                RestrictionExceptionsColumns.PACKAGE_CLIENT_ID + " INTEGER NOT NULL" +
+        ");");
+
+        // Activities table
+        db.execSQL("CREATE TABLE " + Tables.ACTIVITIES + " (" +
+                Activities._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
+                ActivitiesColumns.PACKAGE_ID + " INTEGER REFERENCES package(_id) NOT NULL," +
+                ActivitiesColumns.MIMETYPE_ID + " INTEGER REFERENCES mimetype(_id) NOT NULL," +
+                Activities.RAW_ID + " TEXT," +
+                Activities.IN_REPLY_TO + " TEXT," +
+                Activities.AUTHOR_CONTACT_ID +  " INTEGER REFERENCES contacts(_id)," +
+                Activities.TARGET_CONTACT_ID + " INTEGER REFERENCES contacts(_id)," +
+                Activities.PUBLISHED + " INTEGER NOT NULL," +
+                Activities.THREAD_PUBLISHED + " INTEGER NOT NULL," +
+                Activities.TITLE + " TEXT NOT NULL," +
+                Activities.SUMMARY + " TEXT," +
+                Activities.LINK + " TEXT, " +
+                Activities.THUMBNAIL + " BLOB" +
+        ");");
+
+        loadNicknameLookupTable(db);
+    }
+
+    @Override
+    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+        Log.i(TAG, "Upgrading from version " + oldVersion + " to " + newVersion
+                + ", data will be lost!");
+
+        db.execSQL("DROP TABLE IF EXISTS " + Tables.ACCOUNTS + ";");
+        db.execSQL("DROP TABLE IF EXISTS " + Tables.AGGREGATES + ";");
+        db.execSQL("DROP TABLE IF EXISTS " + Tables.CONTACTS + ";");
+        db.execSQL("DROP TABLE IF EXISTS " + Tables.PACKAGES + ";");
+        db.execSQL("DROP TABLE IF EXISTS " + Tables.MIMETYPES + ";");
+        db.execSQL("DROP TABLE IF EXISTS " + Tables.DATA + ";");
+        db.execSQL("DROP TABLE IF EXISTS " + Tables.PHONE_LOOKUP + ";");
+        db.execSQL("DROP TABLE IF EXISTS " + Tables.NAME_LOOKUP + ";");
+        db.execSQL("DROP TABLE IF EXISTS " + Tables.NICKNAME_LOOKUP + ";");
+        db.execSQL("DROP TABLE IF EXISTS " + Tables.GROUPS + ";");
+        db.execSQL("DROP TABLE IF EXISTS " + Tables.RESTRICTION_EXCEPTIONS + ";");
+        db.execSQL("DROP TABLE IF EXISTS " + Tables.ACTIVITIES + ";");
+
+        // TODO: we should not be dropping agg_exceptions and contact_options. In case that table's
+        // schema changes, we should try to preserve the data, because it was entered by the user
+        // and has never been synched to the server.
+        db.execSQL("DROP TABLE IF EXISTS " + Tables.AGGREGATION_EXCEPTIONS + ";");
+        db.execSQL("DROP TABLE IF EXISTS " + Tables.CONTACT_OPTIONS + ";");
+
+        onCreate(db);
+    }
+
+    /**
+     * Wipes all data except mime type and package lookup tables.
+     */
+    public void wipeData() {
+        SQLiteDatabase db = getWritableDatabase();
+        db.execSQL("DELETE FROM " + Tables.AGGREGATES + ";");
+        db.execSQL("DELETE FROM " + Tables.CONTACTS + ";");
+        db.execSQL("DELETE FROM " + Tables.CONTACT_OPTIONS + ";");
+        db.execSQL("DELETE FROM " + Tables.DATA + ";");
+        db.execSQL("DELETE FROM " + Tables.PHONE_LOOKUP + ";");
+        db.execSQL("DELETE FROM " + Tables.NAME_LOOKUP + ";");
+        db.execSQL("DELETE FROM " + Tables.GROUPS + ";");
+        db.execSQL("DELETE FROM " + Tables.AGGREGATION_EXCEPTIONS + ";");
+        db.execSQL("DELETE FROM " + Tables.RESTRICTION_EXCEPTIONS + ";");
+        db.execSQL("DELETE FROM " + Tables.ACTIVITIES + ";");
+
+        // Note: we are not removing reference data from Tables.NICKNAME_LOOKUP
+
+        db.execSQL("VACUUM;");
+    }
+
+    /**
+     * Return the {@link ApplicationInfo#uid} for the given package name.
+     */
+    public static int getUidForPackageName(PackageManager pm, String packageName) {
+        try {
+            ApplicationInfo clientInfo = pm.getApplicationInfo(packageName, 0 /* no flags */);
+            return clientInfo.uid;
+        } catch (NameNotFoundException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * Perform an internal string-to-integer lookup using the compiled
+     * {@link SQLiteStatement} provided, using the in-memory cache to speed up
+     * lookups. If a mapping isn't found in cache or database, it will be
+     * created. All new, uncached answers are added to the cache automatically.
+     *
+     * @param query Compiled statement used to query for the mapping.
+     * @param insert Compiled statement used to insert a new mapping when no
+     *            existing one is found in cache or from query.
+     * @param value Value to find mapping for.
+     * @param cache In-memory cache of previous answers.
+     * @return An unique integer mapping for the given value.
+     */
+    private synchronized long getCachedId(SQLiteStatement query, SQLiteStatement insert,
+            String value, HashMap<String, Long> cache) {
+        // Try an in-memory cache lookup
+        if (cache.containsKey(value)) {
+            return cache.get(value);
+        }
+
+        long id = -1;
+        try {
+            // Try searching database for mapping
+            DatabaseUtils.bindObjectToProgram(query, 1, value);
+            id = query.simpleQueryForLong();
+        } catch (SQLiteDoneException e) {
+            // Nothing found, so try inserting new mapping
+            DatabaseUtils.bindObjectToProgram(insert, 1, value);
+            id = insert.executeInsert();
+        }
+
+        if (id != -1) {
+            // Cache and return the new answer
+            cache.put(value, id);
+            return id;
+        } else {
+            // Otherwise throw if no mapping found or created
+            throw new IllegalStateException("Couldn't find or create internal "
+                    + "lookup table entry for value " + value);
+        }
+    }
+
+    /**
+     * Convert a package name into an integer, using {@link Tables#PACKAGES} for
+     * lookups and possible allocation of new IDs as needed.
+     */
+    public long getPackageId(String packageName) {
+        // Make sure compiled statements are ready by opening database
+        getReadableDatabase();
+        return getCachedId(mPackageQuery, mPackageInsert, packageName, mPackageCache);
+    }
+
+    /**
+     * Convert a mimetype into an integer, using {@link Tables#MIMETYPES} for
+     * lookups and possible allocation of new IDs as needed.
+     */
+    public long getMimeTypeId(String mimetype) {
+        // Make sure compiled statements are ready by opening database
+        getReadableDatabase();
+        return getCachedId(mMimetypeQuery, mMimetypeInsert, mimetype, mMimetypeCache);
+    }
+
+    /**
+     * Find the mimetype for the given {@link Data#_ID}.
+     */
+    public String getDataMimeType(long dataId) {
+        // Make sure compiled statements are ready by opening database
+        getReadableDatabase();
+        try {
+            // Try database query to find mimetype
+            DatabaseUtils.bindObjectToProgram(mDataMimetypeQuery, 1, dataId);
+            String mimetype = mDataMimetypeQuery.simpleQueryForString();
+            return mimetype;
+        } catch (SQLiteDoneException e) {
+            // No valid mapping found, so return null
+            return null;
+        }
+    }
+
+    /**
+     * Find the mime-type for the given {@link Activities#_ID}.
+     */
+    public String getActivityMimeType(long activityId) {
+        // Make sure compiled statements are ready by opening database
+        getReadableDatabase();
+        try {
+            // Try database query to find mimetype
+            DatabaseUtils.bindObjectToProgram(mActivitiesMimetypeQuery, 1, activityId);
+            String mimetype = mActivitiesMimetypeQuery.simpleQueryForString();
+            return mimetype;
+        } catch (SQLiteDoneException e) {
+            // No valid mapping found, so return null
+            return null;
+        }
+    }
+
+    /**
+     * Update {@link Aggregates#IN_VISIBLE_GROUP} for all aggregates.
+     */
+    public void updateAllVisible() {
+        final long groupMembershipMimetypeId = getMimeTypeId(GroupMembership.CONTENT_ITEM_TYPE);
+        mVisibleAllUpdate.bindLong(1, groupMembershipMimetypeId);
+        mVisibleAllUpdate.execute();
+    }
+
+    /**
+     * Update {@link Aggregates#IN_VISIBLE_GROUP} for a specific aggregate.
+     */
+    public void updateAggregateVisible(long aggId) {
+        final long groupMembershipMimetypeId = getMimeTypeId(GroupMembership.CONTENT_ITEM_TYPE);
+        mVisibleSpecificUpdate.bindLong(1, groupMembershipMimetypeId);
+        mVisibleSpecificUpdate.bindLong(2, aggId);
+        mVisibleSpecificUpdate.execute();
+    }
+
+    /**
+     * Updates the aggregate ID for the specified contact.
+     */
+    public void setAggregateId(long contactId, long aggregateId) {
+        getWritableDatabase();
+        DatabaseUtils.bindObjectToProgram(mAggregateIdUpdate, 1, aggregateId);
+        DatabaseUtils.bindObjectToProgram(mAggregateIdUpdate, 2, contactId);
+        mAggregateIdUpdate.execute();
+    }
+
+    /**
+     * Returns aggregate ID for the given contact or zero if it is NULL.
+     */
+    public long getAggregateId(long contactId) {
+        getReadableDatabase();
+        try {
+            DatabaseUtils.bindObjectToProgram(mAggregateIdQuery, 1, contactId);
+            return mAggregateIdQuery.simpleQueryForLong();
+        } catch (SQLiteDoneException e) {
+            // No valid mapping found, so return -1
+            return 0;
+        }
+    }
+
+    /**
+     * Inserts a record in the {@link Tables#NAME_LOOKUP} table.
+     */
+    public void insertNameLookup(long contactId, int lookupType, String name) {
+        getWritableDatabase();
+        DatabaseUtils.bindObjectToProgram(mNameLookupInsert, 1, contactId);
+        DatabaseUtils.bindObjectToProgram(mNameLookupInsert, 2, lookupType);
+        DatabaseUtils.bindObjectToProgram(mNameLookupInsert, 3, name);
+        mNameLookupInsert.executeInsert();
+    }
+
+    public static void buildPhoneLookupQuery(SQLiteQueryBuilder qb, final String number) {
+        final String normalizedNumber = PhoneNumberUtils.toCallerIDMinMatch(number);
+        final StringBuilder tables = new StringBuilder();
+        tables.append("contacts, (SELECT data_id FROM phone_lookup "
+                + "WHERE (phone_lookup.normalized_number GLOB '");
+        tables.append(normalizedNumber);
+        tables.append("*')) AS lookup, " + Tables.DATA_JOIN_MIMETYPES);
+        qb.setTables(tables.toString());
+        qb.appendWhere("lookup.data_id=data._id AND data.contact_id=contacts._id AND ");
+        qb.appendWhere("PHONE_NUMBERS_EQUAL(data." + Phone.NUMBER + ", ");
+        qb.appendWhereEscapeString(number);
+        qb.appendWhere(")");
+    }
+
+
+    /**
+     * Loads common nickname mappings into the database.
+     */
+    private void loadNicknameLookupTable(SQLiteDatabase db) {
+        String[] strings = mContext.getResources().getStringArray(
+                com.android.internal.R.array.common_nicknames);
+        if (strings == null || strings.length == 0) {
+            return;
+        }
+
+        SQLiteStatement nicknameLookupInsert = db.compileStatement("INSERT INTO "
+                + Tables.NICKNAME_LOOKUP + "(" + NicknameLookupColumns.NAME + ","
+                + NicknameLookupColumns.CLUSTER + ") VALUES (?,?)");
+
+        for (int clusterId = 0; clusterId < strings.length; clusterId++) {
+            String[] names = strings[clusterId].split(",");
+            for (int j = 0; j < names.length; j++) {
+                String name = NameNormalizer.normalize(names[j]);
+                try {
+                    DatabaseUtils.bindObjectToProgram(nicknameLookupInsert, 1, name);
+                    DatabaseUtils.bindObjectToProgram(nicknameLookupInsert, 2,
+                            String.valueOf(clusterId));
+                    nicknameLookupInsert.executeInsert();
+                } catch (SQLiteException e) {
+
+                    // Print the exception and keep going - this is not a fatal error
+                    Log.e(TAG, "Cannot insert nickname: " + names[j], e);
+                }
+            }
+        }
+    }
+
+    /**
+     * Returns common nickname cluster IDs for a given name. For example, it
+     * will return the same value for "Robert", "Bob" and "Rob". Some names belong to multiple
+     * clusters, e.g. Leo could be Leonard or Leopold.
+     *
+     * May return null.
+     *
+     * @param normalizedName A normalized first name, see {@link NameNormalizer#normalize}.
+     */
+    public String[] getCommonNicknameClusters(String normalizedName) {
+        if (mNicknameClusterCache == null) {
+            mNicknameClusterCache = new HashMap<String, String[]>();
+        }
+
+        synchronized (mNicknameClusterCache) {
+            if (mNicknameClusterCache.containsKey(normalizedName)) {
+                return mNicknameClusterCache.get(normalizedName);
+            }
+        }
+
+        String[] clusters = null;
+        SQLiteDatabase db = getReadableDatabase();
+
+        Cursor cursor = db.query(Tables.NICKNAME_LOOKUP, NICKNAME_LOOKUP_COLUMNS,
+                NicknameLookupColumns.NAME + "=?", new String[] { normalizedName },
+                null, null, null);
+        try {
+            int count = cursor.getCount();
+            if (count > 0) {
+                clusters = new String[count];
+                for (int i = 0; i < count; i++) {
+                    cursor.moveToNext();
+                    clusters[i] = cursor.getString(COL_NICKNAME_LOOKUP_CLUSTER);
+                }
+            }
+        } finally {
+            cursor.close();
+        }
+
+        synchronized (mNicknameClusterCache) {
+            mNicknameClusterCache.put(normalizedName, clusters);
+        }
+
+        return clusters;
+    }
+
+    /**
+     * Add a {@link RestrictionExceptions} record. This will update the
+     * in-memory lookup table, and write to the database when needed. Any
+     * callers should enforce that the {@link Binder#getCallingUid()} has the
+     * authority to grant exceptions.
+     */
+    public void addRestrictionException(Context context, ContentValues values) {
+        final PackageManager pm = context.getPackageManager();
+        final SQLiteDatabase db = this.getWritableDatabase();
+
+        // Read incoming package values and find lookup values
+        final String packageProvider = values.getAsString(RestrictionExceptions.PACKAGE_PROVIDER);
+        final String packageClient = values.getAsString(RestrictionExceptions.PACKAGE_CLIENT);
+        final long packageProviderId = getPackageId(packageProvider);
+        final long packageClientId = getPackageId(packageClient);
+
+        // Find the client UID to update our internal lookup table and write the
+        // exception to our database if we changed the in-memory cache.
+        final int clientUid = getUidForPackageName(pm, packageClient);
+        boolean cacheChanged = mCache.addException(packageProviderId, clientUid);
+        if (cacheChanged) {
+            values.put(RestrictionExceptionsColumns.PACKAGE_PROVIDER_ID, packageProviderId);
+            values.put(RestrictionExceptionsColumns.PACKAGE_CLIENT_ID, packageClientId);
+            values.remove(RestrictionExceptions.ALLOW_ACCESS);
+            db.insert(Tables.RESTRICTION_EXCEPTIONS, null, values);
+        }
+
+    }
+
+    /**
+     * Remove a {@link RestrictionExceptions} record. This will update the
+     * in-memory lookup table, and write to the database when needed. Any
+     * callers should enforce that the {@link Binder#getCallingUid()} has the
+     * authority to revoke exceptions.
+     */
+    public void removeRestrictionException(Context context, ContentValues values) {
+        final PackageManager pm = context.getPackageManager();
+        final SQLiteDatabase db = this.getWritableDatabase();
+
+        // Read incoming package values and find lookup values
+        final String packageProvider = values.getAsString(RestrictionExceptions.PACKAGE_PROVIDER);
+        final String packageClient = values.getAsString(RestrictionExceptions.PACKAGE_CLIENT);
+        final long packageProviderId = getPackageId(packageProvider);
+        final long packageClientId = getPackageId(packageClient);
+
+        // Find the client UID to update our internal lookup table and remove
+        // the exception from our database if we changed the in-memory cache.
+        final int clientUid = getUidForPackageName(pm, packageClient);
+        final boolean cacheChanged = mCache.removeException(packageProviderId, clientUid);
+        if (cacheChanged) {
+            db.delete(Tables.RESTRICTION_EXCEPTIONS,
+                    RestrictionExceptionsColumns.PACKAGE_PROVIDER_ID + "=" + packageProviderId
+                            + " AND " + RestrictionExceptionsColumns.PACKAGE_CLIENT_ID + "="
+                            + packageClientId, null);
+        }
+
+    }
+
+    /**
+     * Return the exception clause that should be used when running {@link Data}
+     * queries that may be impacted by {@link Contacts#IS_RESTRICTED}. Will
+     * return a clause of all of the provider packages that have granted
+     * exceptions to the requested client UID.
+     */
+    public String getRestrictionExceptionClause(int clientUid, String column) {
+        return mCache.getExceptionQueryClause(clientUid, column);
+    }
+
+    /**
+     * Utility class to build a selection query clause that matches a specific
+     * column against any one of the contained values. You must provide any
+     * escaping of the field values yourself.
+     */
+    private static class MatchesClause<T> extends LinkedList<T> {
+        private final HashMap<String, String> mCache = new HashMap<String, String>();
+
+        private static final String JOIN_OR = " OR ";
+
+        public synchronized boolean addMatch(T object) {
+            mCache.clear();
+            return super.add(object);
+        }
+
+        public synchronized void removeMatch(T object) {
+            mCache.clear();
+            super.remove(object);
+        }
+
+        /**
+         * Return the query clause that would match the given column string to
+         * any values added through {@link #addMatch(Object)}.
+         */
+        public synchronized String getQueryClause(String column, StringBuilder recycle) {
+            // We maintain an internal cache for each requested column, and only
+            // build the actual value when needed.
+            String queryClause = mCache.get(column);
+            final int size = this.size();
+            if (queryClause == null && size > 0) {
+                recycle.setLength(0);
+                for (int i = 0; i < size; i++) {
+                    recycle.append(column);
+                    recycle.append("=");
+                    recycle.append(this.get(i));
+                    recycle.append(JOIN_OR);
+                }
+
+                // Trim off the last "OR" clause and store cached value.
+                final int length = recycle.length();
+                recycle.delete(length - JOIN_OR.length(), length);
+                queryClause = recycle.toString();
+                mCache.put(column, queryClause);
+            }
+            return queryClause;
+        }
+    }
+
+    /**
+     * Optimized in-memory cache for storing {@link RestrictionExceptions} that
+     * have been read up from database. Helper methods indicate when an
+     * exception change require writing to disk, and build query clauses for a
+     * specific {@link RestrictionExceptions#PACKAGE_CLIENT}.
+     */
+    private static class RestrictionExceptionsCache extends HashMap<Integer, MatchesClause<Long>> {
+        private final StringBuilder mBuilder = new StringBuilder();
+
+        private static final String[] PROJ_RESTRICTION_EXCEPTIONS = new String[] {
+                RestrictionExceptionsColumns.PACKAGE_PROVIDER_ID,
+                RestrictionExceptions.PACKAGE_CLIENT,
+        };
+
+        private static final int COL_PACKAGE_PROVIDER_ID = 0;
+        private static final int COL_PACKAGE_CLIENT = 1;
+
+        public void loadFromDatabase(Context context, SQLiteDatabase db) {
+            final PackageManager pm = context.getPackageManager();
+
+            // Load all existing exceptions from our database.
+            Cursor cursor = null;
+            try {
+                cursor = db.query(Tables.RESTRICTION_EXCEPTIONS, PROJ_RESTRICTION_EXCEPTIONS, null,
+                        null, null, null, null);
+                while (cursor.moveToNext()) {
+                    // Read provider and client package details from database
+                    final long packageProviderId = cursor.getLong(COL_PACKAGE_PROVIDER_ID);
+                    final String clientPackage = cursor.getString(COL_PACKAGE_CLIENT);
+
+                    try {
+                        // Create exception entry for this client
+                        final int clientUid = getUidForPackageName(pm, clientPackage);
+                        addException(packageProviderId, clientUid);
+                    } catch (RuntimeException e) {
+                        Log.w(TAG, "Failed to grant restriction exception to " + clientPackage);
+                        continue;
+                    }
+
+                }
+            } finally {
+                if (cursor != null) {
+                    cursor.close();
+                }
+            }
+        }
+
+        /**
+         * Lazily fetch a {@link MatchesClause} instance, creating a new one if
+         * both needed and requested.
+         */
+        private MatchesClause<Long> getLazy(int clientUid, boolean create) {
+            MatchesClause<Long> matchesClause = get(clientUid);
+            if (matchesClause == null && create) {
+                matchesClause = new MatchesClause<Long>();
+                put(clientUid, matchesClause);
+            }
+            return matchesClause;
+        }
+
+        /**
+         * Build a query clause that will allow the restriction exceptions
+         * granted to a specific {@link Binder#getCallingUid()}.
+         */
+        public String getExceptionQueryClause(int clientUid, String column) {
+            MatchesClause<Long> matchesClause = getLazy(clientUid, false);
+            if (matchesClause != null) {
+                return matchesClause.getQueryClause(column, mBuilder);
+            } else {
+                // When no matching clause found, return 0 to provide a false
+                // value for the query string.
+                return "0";
+            }
+        }
+
+        /**
+         * Add a {@link RestrictionExceptions} into the cache. Returns true if
+         * this action resulted in the cache being changed.
+         */
+        public boolean addException(long packageProviderId, int clientUid) {
+            MatchesClause<Long> matchesClause = getLazy(clientUid, true);
+            if (matchesClause.contains(packageProviderId)) {
+                return false;
+            } else {
+                matchesClause.addMatch(packageProviderId);
+                return true;
+            }
+        }
+
+        /**
+         * Remove a {@link RestrictionExceptions} from the cache. Returns true if
+         * this action resulted in the cache being changed.
+         */
+        public boolean removeException(long packageProviderId, int clientUid) {
+            MatchesClause<Long> matchesClause = getLazy(clientUid, false);
+            if (matchesClause == null || !matchesClause.contains(packageProviderId)) {
+                return false;
+            } else {
+                matchesClause.removeMatch(packageProviderId);
+                return true;
+            }
+        }
+    }
+
+}
diff --git a/src/com/android/providers/contacts/ReorderingCursorWrapper.java b/src/com/android/providers/contacts/ReorderingCursorWrapper.java
new file mode 100644
index 0000000..5d7983a
--- /dev/null
+++ b/src/com/android/providers/contacts/ReorderingCursorWrapper.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2009 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;
+
+import android.database.AbstractCursor;
+import android.database.Cursor;
+
+/**
+ * Cursor wrapper that reorders rows according to supplied specific position mapping.
+ */
+public class ReorderingCursorWrapper extends AbstractCursor {
+
+    private final Cursor mCursor;
+    private final int[] mPositionMap;
+
+    /**
+     * Constructor.
+     *
+     * @param cursor wrapped cursor
+     * @param positionMap maps wrapper cursor positions to wrapped cursor positions
+     *            so that positionMap[wrapperPosition] == wrappedPosition
+     */
+    public ReorderingCursorWrapper(Cursor cursor, int[] positionMap) {
+        if (cursor.getCount() != positionMap.length) {
+            throw new IllegalArgumentException("Cursor and position map have different sizes.");
+        }
+
+        mCursor = cursor;
+        mPositionMap = positionMap;
+    }
+
+    @Override
+    public boolean onMove(int oldPosition, int newPosition) {
+        return mCursor.moveToPosition(mPositionMap[newPosition]);
+    }
+
+    @Override
+    public String[] getColumnNames() {
+        return mCursor.getColumnNames();
+    }
+
+    @Override
+    public int getCount() {
+        return mCursor.getCount();
+    }
+
+    @Override
+    public double getDouble(int column) {
+        return mCursor.getDouble(column);
+    }
+
+    @Override
+    public float getFloat(int column) {
+        return mCursor.getFloat(column);
+    }
+
+    @Override
+    public int getInt(int column) {
+        return mCursor.getInt(column);
+    }
+
+    @Override
+    public long getLong(int column) {
+        return mCursor.getLong(column);
+    }
+
+    @Override
+    public short getShort(int column) {
+        return mCursor.getShort(column);
+    }
+
+    @Override
+    public String getString(int column) {
+        return mCursor.getString(column);
+    }
+
+    @Override
+    public boolean isNull(int column) {
+        return mCursor.isNull(column);
+    }
+}
\ No newline at end of file
diff --git a/src/com/android/providers/contacts/SocialProvider.java b/src/com/android/providers/contacts/SocialProvider.java
new file mode 100644
index 0000000..50622b2
--- /dev/null
+++ b/src/com/android/providers/contacts/SocialProvider.java
@@ -0,0 +1,400 @@
+/*
+ * Copyright (C) 2009 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;
+
+import com.android.providers.contacts.OpenHelper.ActivitiesColumns;
+import com.android.providers.contacts.OpenHelper.Tables;
+
+import android.content.ContentProvider;
+import android.content.ContentUris;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.UriMatcher;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteQueryBuilder;
+import android.provider.BaseColumns;
+import android.provider.ContactsContract;
+import android.provider.ContactsContract.Aggregates;
+import android.provider.ContactsContract.Contacts;
+import android.provider.SocialContract;
+import android.provider.SocialContract.Activities;
+
+import android.net.Uri;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+
+/**
+ * Social activity content provider. The contract between this provider and
+ * applications is defined in {@link SocialContract}.
+ */
+public class SocialProvider extends ContentProvider {
+    // TODO: clean up debug tag
+    private static final String TAG = "SocialProvider ~~~~";
+
+    private static final UriMatcher sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
+
+    private static final int ACTIVITIES = 1000;
+    private static final int ACTIVITIES_ID = 1001;
+    private static final int ACTIVITIES_AUTHORED_BY = 1002;
+
+    private static final int AGGREGATE_STATUS_ID = 3000;
+
+    private static final String DEFAULT_SORT_ORDER = Activities.THREAD_PUBLISHED + " DESC, "
+            + Activities.PUBLISHED + " ASC";
+
+    /** Contains just the contacts columns */
+    private static final HashMap<String, String> sAggregatesProjectionMap;
+    /** Contains just the contacts columns */
+    private static final HashMap<String, String> sContactsProjectionMap;
+    /** Contains just the activities columns */
+    private static final HashMap<String, String> sActivitiesProjectionMap;
+
+    /** Contains the activities, contacts, and aggregates columns, for joined tables */
+    private static final HashMap<String, String> sActivitiesAggregatesProjectionMap;
+
+    static {
+        // Contacts URI matching table
+        final UriMatcher matcher = sUriMatcher;
+
+        matcher.addURI(SocialContract.AUTHORITY, "activities", ACTIVITIES);
+        matcher.addURI(SocialContract.AUTHORITY, "activities/#", ACTIVITIES_ID);
+        matcher.addURI(SocialContract.AUTHORITY, "activities/authored_by/#", ACTIVITIES_AUTHORED_BY);
+
+        matcher.addURI(SocialContract.AUTHORITY, "aggregate_status/#", AGGREGATE_STATUS_ID);
+
+        HashMap<String, String> columns;
+
+        // Aggregates projection map
+        columns = new HashMap<String, String>();
+        columns.put(Aggregates.DISPLAY_NAME, Aggregates.DISPLAY_NAME);
+        sAggregatesProjectionMap = columns;
+
+        // Contacts projection map
+        columns = new HashMap<String, String>();
+        columns.put(Contacts._ID, "contacts._id AS _id");
+        columns.put(Contacts.AGGREGATE_ID, Contacts.AGGREGATE_ID);
+        sContactsProjectionMap = columns;
+
+        // Activities projection map
+        columns = new HashMap<String, String>();
+        columns.put(Activities._ID, "activities._id AS _id");
+        columns.put(Activities.PACKAGE, Activities.PACKAGE);
+        columns.put(Activities.MIMETYPE, Activities.MIMETYPE);
+        columns.put(Activities.RAW_ID, Activities.RAW_ID);
+        columns.put(Activities.IN_REPLY_TO, Activities.IN_REPLY_TO);
+        columns.put(Activities.AUTHOR_CONTACT_ID, Activities.AUTHOR_CONTACT_ID);
+        columns.put(Activities.TARGET_CONTACT_ID, Activities.TARGET_CONTACT_ID);
+        columns.put(Activities.PUBLISHED, Activities.PUBLISHED);
+        columns.put(Activities.THREAD_PUBLISHED, Activities.THREAD_PUBLISHED);
+        columns.put(Activities.TITLE, Activities.TITLE);
+        columns.put(Activities.SUMMARY, Activities.SUMMARY);
+        columns.put(Activities.LINK, Activities.LINK);
+        columns.put(Activities.THUMBNAIL, Activities.THUMBNAIL);
+        sActivitiesProjectionMap = columns;
+
+        // Activities, contacts, and aggregates projection map for joins
+        columns = new HashMap<String, String>();
+        columns.putAll(sAggregatesProjectionMap);
+        columns.putAll(sContactsProjectionMap);
+        columns.putAll(sActivitiesProjectionMap); // Final _id will be from Activities
+        sActivitiesAggregatesProjectionMap = columns;
+
+    }
+
+    private OpenHelper mOpenHelper;
+
+    /** {@inheritDoc} */
+    @Override
+    public boolean onCreate() {
+        final Context context = getContext();
+        mOpenHelper = OpenHelper.getInstance(context);
+
+        // TODO remove this, it's here to force opening the database on boot for testing
+        mOpenHelper.getReadableDatabase();
+
+        return true;
+    }
+
+    /**
+     * Called when a change has been made.
+     *
+     * @param uri the uri that the change was made to
+     */
+    private void onChange(Uri uri) {
+        getContext().getContentResolver().notifyChange(ContactsContract.AUTHORITY_URI, null);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public boolean isTemporary() {
+        return false;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public Uri insert(Uri uri, ContentValues values) {
+        final int match = sUriMatcher.match(uri);
+        long id = 0;
+        switch (match) {
+            case ACTIVITIES: {
+                id = insertActivity(values);
+                break;
+            }
+
+            default:
+                throw new UnsupportedOperationException("Unknown uri: " + uri);
+        }
+
+        final Uri result = ContentUris.withAppendedId(Activities.CONTENT_URI, id);
+        onChange(result);
+        return result;
+    }
+
+    /**
+     * Inserts an item into the {@link Tables#ACTIVITIES} table.
+     *
+     * @param values the values for the new row
+     * @return the row ID of the newly created row
+     */
+    private long insertActivity(ContentValues values) {
+
+        // TODO verify that IN_REPLY_TO != RAW_ID
+
+        final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+        long id = 0;
+        db.beginTransaction();
+        try {
+            // TODO: Consider enforcing Binder.getCallingUid() for package name
+            // requested by this insert.
+
+            // Replace package name and mime-type with internal mappings
+            final String packageName = values.getAsString(Activities.PACKAGE);
+            values.put(ActivitiesColumns.PACKAGE_ID, mOpenHelper.getPackageId(packageName));
+            values.remove(Activities.PACKAGE);
+
+            final String mimeType = values.getAsString(Activities.MIMETYPE);
+            values.put(ActivitiesColumns.MIMETYPE_ID, mOpenHelper.getMimeTypeId(mimeType));
+            values.remove(Activities.MIMETYPE);
+
+            long published = values.getAsLong(Activities.PUBLISHED);
+            long threadPublished = published;
+
+            String inReplyTo = values.getAsString(Activities.IN_REPLY_TO);
+            if (inReplyTo != null) {
+                threadPublished = getThreadPublished(db, inReplyTo, published);
+            }
+
+            values.put(Activities.THREAD_PUBLISHED, threadPublished);
+
+            // Insert the data row itself
+            id = db.insert(Tables.ACTIVITIES, Activities.RAW_ID, values);
+
+            // Adjust thread timestamps on replies that have already been inserted
+            if (values.containsKey(Activities.RAW_ID)) {
+                adjustReplyTimestamps(db, values.getAsString(Activities.RAW_ID), published);
+            }
+
+            db.setTransactionSuccessful();
+        } finally {
+            db.endTransaction();
+        }
+        return id;
+    }
+
+    /**
+     * Finds the timestamp of the original message in the thread. If not found, returns
+     * {@code defaultValue}.
+     */
+    private long getThreadPublished(SQLiteDatabase db, String rawId, long defaultValue) {
+        String inReplyTo = null;
+        long threadPublished = defaultValue;
+
+        final Cursor c = db.query(Tables.ACTIVITIES,
+                new String[]{Activities.IN_REPLY_TO, Activities.PUBLISHED},
+                Activities.RAW_ID + " = ?", new String[]{rawId}, null, null, null);
+        try {
+            if (c.moveToFirst()) {
+                inReplyTo = c.getString(0);
+                threadPublished = c.getLong(1);
+            }
+        } finally {
+            c.close();
+        }
+
+        if (inReplyTo != null) {
+
+            // Call recursively to obtain the original timestamp of the entire thread
+            return getThreadPublished(db, inReplyTo, threadPublished);
+        }
+
+        return threadPublished;
+    }
+
+    /**
+     * In case the original message of a thread arrives after its reply messages, we need
+     * to check if there are any replies in the database and if so adjust their thread_published.
+     */
+    private void adjustReplyTimestamps(SQLiteDatabase db, String inReplyTo, long threadPublished) {
+
+        ContentValues values = new ContentValues();
+        values.put(Activities.THREAD_PUBLISHED, threadPublished);
+
+        /*
+         * Issuing an exploratory update. If it updates nothing, we are done.  Otherwise,
+         * we will run a query to find the updated records again and repeat recursively.
+         */
+        int replies = db.update(Tables.ACTIVITIES, values,
+                Activities.IN_REPLY_TO + "= ?", new String[] {inReplyTo});
+
+        if (replies == 0) {
+            return;
+        }
+
+        /*
+         * Presumably this code will be executed very infrequently since messages tend to arrive
+         * in the order they get sent.
+         */
+        ArrayList<String> rawIds = new ArrayList<String>(replies);
+        final Cursor c = db.query(Tables.ACTIVITIES,
+                new String[]{Activities.RAW_ID},
+                Activities.IN_REPLY_TO + " = ?", new String[] {inReplyTo}, null, null, null);
+        try {
+            while (c.moveToNext()) {
+                rawIds.add(c.getString(0));
+            }
+        } finally {
+            c.close();
+        }
+
+        for (String rawId : rawIds) {
+            adjustReplyTimestamps(db, rawId, threadPublished);
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public int delete(Uri uri, String selection, String[] selectionArgs) {
+        final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+
+        final int match = sUriMatcher.match(uri);
+        switch (match) {
+            case ACTIVITIES_ID: {
+                final long activityId = ContentUris.parseId(uri);
+                return db.delete(Tables.ACTIVITIES, Activities._ID + "=" + activityId, null);
+            }
+
+            case ACTIVITIES_AUTHORED_BY: {
+                final long contactId = ContentUris.parseId(uri);
+                return db.delete(Tables.ACTIVITIES, Activities.AUTHOR_CONTACT_ID + "=" + contactId, null);
+            }
+
+            default:
+                throw new UnsupportedOperationException("Unknown uri: " + uri);
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
+            String sortOrder) {
+        final SQLiteDatabase db = mOpenHelper.getReadableDatabase();
+        final SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
+        String limit = null;
+
+        final int match = sUriMatcher.match(uri);
+        switch (match) {
+            case ACTIVITIES: {
+                qb.setTables(Tables.ACTIVITIES_JOIN_MIMETYPES_CONTACTS_PACKAGES_AGGREGATES);
+                qb.setProjectionMap(sActivitiesAggregatesProjectionMap);
+                break;
+            }
+
+            case ACTIVITIES_ID: {
+                // TODO: enforce that caller has read access to this data
+                long activityId = ContentUris.parseId(uri);
+                qb.setTables(Tables.ACTIVITIES_JOIN_MIMETYPES_CONTACTS_PACKAGES_AGGREGATES);
+                qb.setProjectionMap(sActivitiesAggregatesProjectionMap);
+                qb.appendWhere(Activities._ID + "=" + activityId);
+                break;
+            }
+
+            case ACTIVITIES_AUTHORED_BY: {
+                long contactId = ContentUris.parseId(uri);
+                qb.setTables(Tables.ACTIVITIES_JOIN_MIMETYPES_CONTACTS_PACKAGES_AGGREGATES);
+                qb.setProjectionMap(sActivitiesAggregatesProjectionMap);
+                qb.appendWhere(Activities.AUTHOR_CONTACT_ID + "=" + contactId);
+                break;
+            }
+
+            case AGGREGATE_STATUS_ID: {
+                long aggId = ContentUris.parseId(uri);
+                qb.setTables(Tables.ACTIVITIES_JOIN_MIMETYPES_CONTACTS_PACKAGES_AGGREGATES);
+                qb.setProjectionMap(sActivitiesAggregatesProjectionMap);
+
+                // Latest status of an aggregate is any top-level status
+                // authored by one of its children contacts.
+                qb.appendWhere(Activities.IN_REPLY_TO + " IS NULL AND ");
+                qb.appendWhere(Activities.AUTHOR_CONTACT_ID + " IN (SELECT " + BaseColumns._ID
+                        + " FROM " + Tables.CONTACTS + " WHERE " + Contacts.AGGREGATE_ID + "="
+                        + aggId + ")");
+                sortOrder = Activities.PUBLISHED + " DESC";
+                limit = "1";
+                break;
+            }
+
+            default:
+                throw new UnsupportedOperationException("Unknown uri: " + uri);
+        }
+
+        // Default to reverse-chronological sort if nothing requested
+        if (sortOrder == null) {
+            sortOrder = DEFAULT_SORT_ORDER;
+        }
+
+        // Perform the query and set the notification uri
+        final Cursor c = qb.query(db, projection, selection, selectionArgs, null, null, sortOrder, limit);
+        if (c != null) {
+            c.setNotificationUri(getContext().getContentResolver(), ContactsContract.AUTHORITY_URI);
+        }
+        return c;
+    }
+
+    @Override
+    public String getType(Uri uri) {
+        final int match = sUriMatcher.match(uri);
+        switch (match) {
+            case ACTIVITIES:
+            case ACTIVITIES_AUTHORED_BY:
+                return Activities.CONTENT_TYPE;
+            case ACTIVITIES_ID:
+                final SQLiteDatabase db = mOpenHelper.getReadableDatabase();
+                long activityId = ContentUris.parseId(uri);
+                return mOpenHelper.getActivityMimeType(activityId);
+            case AGGREGATE_STATUS_ID:
+                return Aggregates.CONTENT_ITEM_TYPE;
+        }
+        throw new UnsupportedOperationException("Unknown uri: " + uri);
+    }
+}
diff --git a/tests/Android.mk b/tests/Android.mk
new file mode 100644
index 0000000..96ae80f
--- /dev/null
+++ b/tests/Android.mk
@@ -0,0 +1,17 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+# We only want this apk build for tests.
+LOCAL_MODULE_TAGS := tests
+
+# Only compile source java files in this apk.
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := ContactsProvider2Tests
+
+LOCAL_JAVA_LIBRARIES := android.test.runner
+
+LOCAL_INSTRUMENTATION_FOR := ContactsProvider
+LOCAL_CERTIFICATE := shared
+
+include $(BUILD_PACKAGE)
diff --git a/tests/AndroidManifest.xml b/tests/AndroidManifest.xml
new file mode 100644
index 0000000..d662b53
--- /dev/null
+++ b/tests/AndroidManifest.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+        package="com.android.providers.contacts.tests"
+        android:sharedUserId="android.uid.shared">
+
+    <uses-permission android:name="android.permission.READ_CONTACTS" />
+    <uses-permission android:name="android.permission.WRITE_CONTACTS" />
+
+    <application>
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+    <!--
+    The test delcared in this instrumentation will be run along with tests declared by
+    all other applications via the command: "adb shell itr".
+    The "itr" command will find all tests declared by all applications. If you want to run just these
+    tests on their own then use the command:
+    "adb shell am instrument -w com.android.providers.contacts.tests/android.test.InstrumentationTestRunner"
+    -->
+    <instrumentation android:name="android.test.InstrumentationTestRunner"
+        android:targetPackage="com.android.providers.contacts"
+        android:label="Contacts2 provider tests">
+    </instrumentation>
+
+</manifest>
diff --git a/tests/src/com/android/providers/contacts/BaseContactsProvider2Test.java b/tests/src/com/android/providers/contacts/BaseContactsProvider2Test.java
new file mode 100644
index 0000000..aa2b2ef
--- /dev/null
+++ b/tests/src/com/android/providers/contacts/BaseContactsProvider2Test.java
@@ -0,0 +1,228 @@
+/*
+ * Copyright (C) 2009 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;
+
+import static com.android.providers.contacts.ContactsActor.PACKAGE_GREY;
+
+import com.android.providers.contacts.ContactsActor;
+
+import android.content.ContentUris;
+import android.content.ContentValues;
+import android.database.Cursor;
+import android.net.Uri;
+import android.provider.ContactsContract.Aggregates;
+import android.provider.ContactsContract.AggregationExceptions;
+import android.provider.ContactsContract.Contacts;
+import android.provider.ContactsContract.Data;
+import android.provider.ContactsContract.Presence;
+import android.provider.ContactsContract.CommonDataKinds.Im;
+import android.provider.ContactsContract.CommonDataKinds.StructuredName;
+import android.provider.ContactsContract.CommonDataKinds.Email;
+import android.provider.ContactsContract.CommonDataKinds.Nickname;
+import android.provider.ContactsContract.CommonDataKinds.Phone;
+import android.test.AndroidTestCase;
+import android.test.mock.MockContentResolver;
+import android.test.suitebuilder.annotation.LargeTest;
+
+/**
+ * A common superclass for {@link ContactsProvider2}-related tests.
+ */
+@LargeTest
+public abstract class BaseContactsProvider2Test extends AndroidTestCase {
+
+    protected static final String PACKAGE = "ContactsProvider2Test";
+
+    private ContactsActor mActor;
+    protected MockContentResolver mResolver;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        mActor = new ContactsActor(getContext(), PACKAGE_GREY);
+        mResolver = mActor.resolver;
+    }
+
+    protected long createContact() {
+        ContentValues values = new ContentValues();
+        values.put(Contacts.PACKAGE, mActor.packageName);
+        Uri contactUri = mResolver.insert(Contacts.CONTENT_URI, values);
+        return ContentUris.parseId(contactUri);
+    }
+
+    protected Uri insertStructuredName(long contactId, String givenName, String familyName) {
+        ContentValues values = new ContentValues();
+        StringBuilder sb = new StringBuilder();
+        if (givenName != null) {
+            sb.append(givenName);
+        }
+        if (givenName != null && familyName != null) {
+            sb.append(" ");
+        }
+        if (familyName != null) {
+            sb.append(familyName);
+        }
+        values.put(StructuredName.DISPLAY_NAME, sb.toString());
+        values.put(StructuredName.GIVEN_NAME, givenName);
+        values.put(StructuredName.FAMILY_NAME, familyName);
+
+        return insertStructuredName(contactId, values);
+    }
+
+    protected Uri insertStructuredName(long contactId, ContentValues values) {
+        values.put(Data.CONTACT_ID, contactId);
+        values.put(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE);
+        Uri resultUri = mResolver.insert(Data.CONTENT_URI, values);
+        return resultUri;
+    }
+
+    protected Uri insertPhoneNumber(long contactId, String phoneNumber) {
+        ContentValues values = new ContentValues();
+        values.put(Data.CONTACT_ID, contactId);
+        values.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
+        values.put(Phone.NUMBER, phoneNumber);
+
+        Uri resultUri = mResolver.insert(Data.CONTENT_URI, values);
+        return resultUri;
+    }
+
+    protected Uri insertEmail(long contactId, String email) {
+        ContentValues values = new ContentValues();
+        values.put(Data.CONTACT_ID, contactId);
+        values.put(Data.MIMETYPE, Email.CONTENT_ITEM_TYPE);
+        values.put(Email.DATA, email);
+
+        Uri resultUri = mResolver.insert(Data.CONTENT_URI, values);
+        return resultUri;
+    }
+
+    protected Uri insertNickname(long contactId, String nickname) {
+        ContentValues values = new ContentValues();
+        values.put(Data.CONTACT_ID, contactId);
+        values.put(Data.MIMETYPE, Nickname.CONTENT_ITEM_TYPE);
+        values.put(Nickname.NAME, nickname);
+
+        Uri resultUri = mResolver.insert(Data.CONTENT_URI, values);
+        return resultUri;
+    }
+
+    protected Uri insertPresence(int protocol, String handle, int presence) {
+        ContentValues values = new ContentValues();
+        values.put(Presence.IM_PROTOCOL, protocol);
+        values.put(Presence.IM_HANDLE, handle);
+        values.put(Presence.PRESENCE_STATUS, presence);
+
+        Uri resultUri = mResolver.insert(Presence.CONTENT_URI, values);
+        return resultUri;
+    }
+
+    protected Uri insertImHandle(long contactId, int protocol, String handle) {
+        ContentValues values = new ContentValues();
+        values.put(Data.CONTACT_ID, contactId);
+        values.put(Data.MIMETYPE, Im.CONTENT_ITEM_TYPE);
+        values.put(Im.PROTOCOL, protocol);
+        values.put(Im.DATA, handle);
+
+        Uri resultUri = mResolver.insert(Data.CONTENT_URI, values);
+        return resultUri;
+    }
+
+    protected void setAggregationException(int type, long aggregateId, long contactId) {
+        ContentValues values = new ContentValues();
+        values.put(AggregationExceptions.AGGREGATE_ID, aggregateId);
+        values.put(AggregationExceptions.CONTACT_ID, contactId);
+        values.put(AggregationExceptions.TYPE, type);
+        mResolver.update(AggregationExceptions.CONTENT_URI, values, null, null);
+    }
+
+    protected Cursor queryContact(long contactId) {
+        return mResolver.query(ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId), null,
+                null, null, null);
+    }
+
+    protected Cursor queryAggregate(long aggregateId) {
+        return mResolver.query(ContentUris.withAppendedId(Aggregates.CONTENT_URI, aggregateId),
+                null, null, null, null);
+    }
+
+    protected Cursor queryAggregateSummary(long aggregateId, String[] projection) {
+        return mResolver.query(ContentUris.withAppendedId(Aggregates.CONTENT_SUMMARY_URI,
+                aggregateId), projection, null, null, null);
+    }
+
+    protected Cursor queryAggregateSummary() {
+        return mResolver.query(Aggregates.CONTENT_SUMMARY_URI, null, null, null, null);
+    }
+
+    protected long queryAggregateId(long contactId) {
+        Cursor c = queryContact(contactId);
+        assertTrue(c.moveToFirst());
+        long aggregateId = c.getLong(c.getColumnIndex(Contacts.AGGREGATE_ID));
+        c.close();
+        return aggregateId;
+    }
+
+    protected String queryDisplayName(long aggregateId) {
+        Cursor c = queryAggregate(aggregateId);
+        assertTrue(c.moveToFirst());
+        String displayName = c.getString(c.getColumnIndex(Aggregates.DISPLAY_NAME));
+        c.close();
+        return displayName;
+    }
+
+    protected void assertAggregated(long contactId1, long contactId2) {
+        long aggregateId1 = queryAggregateId(contactId1);
+        long aggregateId2 = queryAggregateId(contactId2);
+        assertTrue(aggregateId1 == aggregateId2);
+    }
+
+    protected void assertAggregated(long contactId1, long contactId2, String expectedDisplayName) {
+        long aggregateId1 = queryAggregateId(contactId1);
+        long aggregateId2 = queryAggregateId(contactId2);
+        assertTrue(aggregateId1 == aggregateId2);
+
+        String displayName = queryDisplayName(aggregateId1);
+        assertEquals(expectedDisplayName, displayName);
+    }
+
+    protected void assertNotAggregated(long contactId1, long contactId2) {
+        long aggregateId1 = queryAggregateId(contactId1);
+        long aggregateId2 = queryAggregateId(contactId2);
+        assertTrue(aggregateId1 != aggregateId2);
+    }
+
+    protected void assertStructuredName(long contactId, String prefix, String givenName,
+            String middleName, String familyName, String suffix) {
+        Uri uri = Uri.withAppendedPath(ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
+                Contacts.Data.CONTENT_DIRECTORY);
+
+        final String[] projection = new String[] {
+                StructuredName.PREFIX, StructuredName.GIVEN_NAME, StructuredName.MIDDLE_NAME,
+                StructuredName.FAMILY_NAME, StructuredName.SUFFIX
+        };
+
+        Cursor c = mResolver.query(uri, projection, Data.MIMETYPE + "='"
+                + StructuredName.CONTENT_ITEM_TYPE + "'", null, null);
+
+        assertTrue(c.moveToFirst());
+        assertEquals(prefix, c.getString(0));
+        assertEquals(givenName, c.getString(1));
+        assertEquals(middleName, c.getString(2));
+        assertEquals(familyName, c.getString(3));
+        assertEquals(suffix, c.getString(4));
+        c.close();
+    }
+}
diff --git a/tests/src/com/android/providers/contacts/ContactAggregationSchedulerTest.java b/tests/src/com/android/providers/contacts/ContactAggregationSchedulerTest.java
new file mode 100644
index 0000000..1a98d2a
--- /dev/null
+++ b/tests/src/com/android/providers/contacts/ContactAggregationSchedulerTest.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2009 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;
+
+import android.test.suitebuilder.annotation.SmallTest;
+
+import junit.framework.TestCase;
+
+/**
+ * Tests from {@link ContactAggregationScheduler}.
+ */
+@SmallTest
+public class ContactAggregationSchedulerTest extends TestCase {
+
+    private TestContactAggregationScheduler mScheduler;
+
+    @Override
+    protected void setUp() throws Exception {
+        mScheduler = new TestContactAggregationScheduler();
+    }
+
+    public void testScheduleInitial() {
+        mScheduler.schedule();
+        assertEquals(1, mScheduler.mRunDelayed);
+    }
+
+    public void testScheduleTwiceRapidly() {
+        mScheduler.schedule();
+
+        mScheduler.mTime += ContactAggregationScheduler.AGGREGATION_DELAY / 2;
+        mScheduler.schedule();
+        assertEquals(2, mScheduler.mRunDelayed);
+    }
+
+    public void testScheduleTwiceExceedingMaxDelay() {
+        mScheduler.schedule();
+
+        mScheduler.mTime += ContactAggregationScheduler.MAX_AGGREGATION_DELAY + 100;
+        mScheduler.schedule();
+        assertEquals(1, mScheduler.mRunDelayed);
+    }
+
+    public void testScheduleWhileRunning() {
+        mScheduler.setAggregator(new ContactAggregationScheduler.Aggregator() {
+            boolean mInterruptCalled;
+
+            public void interrupt() {
+                mInterruptCalled = true;
+            }
+
+            public void run() {
+                mScheduler.schedule();
+                assertTrue(mInterruptCalled);
+            }
+        });
+
+        mScheduler.run();
+        assertEquals(1, mScheduler.mRunDelayed);
+    }
+
+    public void testScheduleWhileRunningExceedingMaxDelay() {
+        mScheduler.schedule();
+
+        mScheduler.mTime += ContactAggregationScheduler.MAX_AGGREGATION_DELAY + 100;
+
+        mScheduler.setAggregator(new ContactAggregationScheduler.Aggregator() {
+            boolean mInterruptCalled;
+
+            public void interrupt() {
+                mInterruptCalled = true;
+            }
+
+            public void run() {
+                mScheduler.schedule();
+                assertFalse(mInterruptCalled);
+            }
+        });
+
+        mScheduler.run();
+        assertEquals(2, mScheduler.mRunDelayed);
+    }
+
+    private static class TestContactAggregationScheduler extends ContactAggregationScheduler {
+
+        long mTime = 1000;
+        int mRunDelayed;
+
+        @Override
+        public void start() {
+        }
+
+        @Override
+        public void stop() {
+        }
+
+        @Override
+        long currentTime() {
+            return mTime;
+        }
+
+        @Override
+        void runDelayed() {
+            mRunDelayed++;
+        }
+    }
+}
diff --git a/tests/src/com/android/providers/contacts/ContactAggregatorTest.java b/tests/src/com/android/providers/contacts/ContactAggregatorTest.java
new file mode 100644
index 0000000..daff7f0
--- /dev/null
+++ b/tests/src/com/android/providers/contacts/ContactAggregatorTest.java
@@ -0,0 +1,544 @@
+/*
+ * Copyright (C) 2009 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;
+
+import android.content.ContentUris;
+import android.database.Cursor;
+import android.net.Uri;
+import android.provider.ContactsContract.Aggregates;
+import android.provider.ContactsContract.AggregationExceptions;
+import android.test.suitebuilder.annotation.LargeTest;
+
+/**
+ * Unit tests for {@link ContactAggregator}.
+ *
+ * Run the test like this:
+ * <code>
+ * adb shell am instrument -w \
+ *         com.android.providers.contacts.tests/android.test.InstrumentationTestRunner
+ * </code>
+ */
+@LargeTest
+public class ContactAggregatorTest extends BaseContactsProvider2Test {
+
+    private static final String[] AGGREGATION_EXCEPTION_PROJECTION = new String[] {
+            AggregationExceptions.TYPE,
+            AggregationExceptions.AGGREGATE_ID,
+            AggregationExceptions.CONTACT_ID
+    };
+
+    public void testCrudAggregationExceptions() throws Exception {
+        long contactId1 = createContact();
+        long aggregateId = queryAggregateId(contactId1);
+        long contactId2 = createContact();
+
+        setAggregationException(AggregationExceptions.TYPE_KEEP_IN, aggregateId, contactId2);
+
+        // Refetch the row we have just inserted
+        Cursor c = mResolver.query(AggregationExceptions.CONTENT_URI,
+                AGGREGATION_EXCEPTION_PROJECTION, AggregationExceptions.AGGREGATE_ID + "="
+                        + aggregateId, null, null);
+
+        assertTrue(c.moveToFirst());
+        assertEquals(AggregationExceptions.TYPE_KEEP_IN, c.getInt(0));
+        assertEquals(aggregateId, c.getLong(1));
+        assertEquals(contactId2, c.getLong(2));
+        assertFalse(c.moveToNext());
+        c.close();
+
+        // Change from TYPE_KEEP_IN to TYPE_KEEP_OUT
+        setAggregationException(AggregationExceptions.TYPE_KEEP_OUT, aggregateId, contactId2);
+
+        c = mResolver.query(AggregationExceptions.CONTENT_URI,
+                AGGREGATION_EXCEPTION_PROJECTION, AggregationExceptions.AGGREGATE_ID + "="
+                        + aggregateId, null, null);
+
+        assertTrue(c.moveToFirst());
+        assertEquals(AggregationExceptions.TYPE_KEEP_OUT, c.getInt(0));
+        assertEquals(aggregateId, c.getLong(1));
+        assertEquals(contactId2, c.getLong(2));
+        assertFalse(c.moveToNext());
+        c.close();
+
+        // Delete the rule
+        setAggregationException(AggregationExceptions.TYPE_AUTOMATIC, aggregateId, contactId2);
+
+        // Verify that the row is gone
+        c = mResolver.query(AggregationExceptions.CONTENT_URI,
+                AGGREGATION_EXCEPTION_PROJECTION, AggregationExceptions.AGGREGATE_ID + "="
+                        + aggregateId, null, null);
+        assertFalse(c.moveToFirst());
+        c.close();
+    }
+
+    public void testAggregationCreatesNewAggregate() {
+        long contactId = createContact();
+
+        Uri resultUri = insertStructuredName(contactId, "Johna", "Smitha");
+
+        // Parse the URI and confirm that it contains an ID
+        assertTrue(ContentUris.parseId(resultUri) != 0);
+
+        long aggregateId = queryAggregateId(contactId);
+        assertTrue(aggregateId != 0);
+
+        String displayName = queryDisplayName(aggregateId);
+        assertEquals("Johna Smitha", displayName);
+    }
+
+    public void testAggregationOfExactFullNameMatch() {
+        long contactId1 = createContact();
+        insertStructuredName(contactId1, "Johnb", "Smithb");
+
+        long contactId2 = createContact();
+        insertStructuredName(contactId2, "Johnb", "Smithb");
+
+        assertAggregated(contactId1, contactId2, "Johnb Smithb");
+    }
+
+    public void testAggregationOfCaseInsensitiveFullNameMatch() {
+        long contactId1 = createContact();
+        insertStructuredName(contactId1, "Johnc", "Smithc");
+
+        long contactId2 = createContact();
+        insertStructuredName(contactId2, "Johnc", "smithc");
+
+        assertAggregated(contactId1, contactId2, "Johnc Smithc");
+    }
+
+    public void testAggregationOfLastNameMatch() {
+        long contactId1 = createContact();
+        insertStructuredName(contactId1, null, "Johnd");
+
+        long contactId2 = createContact();
+        insertStructuredName(contactId2, null, "johnd");
+
+        assertAggregated(contactId1, contactId2, "Johnd");
+    }
+
+    public void testNonAggregationOfFirstNameMatch() {
+        long contactId1 = createContact();
+        insertStructuredName(contactId1, "Johne", "Smithe");
+
+        long contactId2 = createContact();
+        insertStructuredName(contactId2, "Johne", null);
+
+        assertNotAggregated(contactId1, contactId2);
+    }
+
+    // TODO: should this be allowed to match?
+    public void testNonAggregationOfLastNameMatch() {
+        long contactId1 = createContact();
+        insertStructuredName(contactId1, "Johnf", "Smithf");
+
+        long contactId2 = createContact();
+        insertStructuredName(contactId2, null, "Smithf");
+
+        assertNotAggregated(contactId1, contactId2);
+    }
+
+    public void testAggregationOfConcatenatedFullNameMatch() {
+        long contactId1 = createContact();
+        insertStructuredName(contactId1, "Johng", "Smithg");
+
+        long contactId2 = createContact();
+        insertStructuredName(contactId2, "johngsmithg", null);
+
+        assertAggregated(contactId1, contactId2, "Johng Smithg");
+    }
+
+    public void testAggregationOfNormalizedFullNameMatch() {
+        long contactId1 = createContact();
+        insertStructuredName(contactId1, "H\u00e9l\u00e8ne", "Bj\u00f8rn");
+
+        long contactId2 = createContact();
+        insertStructuredName(contactId2, "helene bjorn", null);
+
+        assertAggregated(contactId1, contactId2, "H\u00e9l\u00e8ne Bj\u00f8rn");
+    }
+
+    public void testAggregationBasedOnPhoneNumberNoNameData() {
+        long contactId1 = createContact();
+        insertPhoneNumber(contactId1, "(888)555-1231");
+
+        long contactId2 = createContact();
+        insertPhoneNumber(contactId2, "1(888)555-1231");
+
+        assertAggregated(contactId1, contactId2);
+    }
+
+    public void testAggregationBasedOnPhoneNumberWhenTargetAggregateHasNoName() {
+        long contactId1 = createContact();
+        insertPhoneNumber(contactId1, "(888)555-1232");
+
+        long contactId2 = createContact();
+        insertStructuredName(contactId2, "Johnl", "Smithl");
+        insertPhoneNumber(contactId2, "1(888)555-1232");
+
+        assertAggregated(contactId1, contactId2);
+    }
+
+    public void testAggregationBasedOnPhoneNumberWhenNewContactHasNoName() {
+        long contactId1 = createContact();
+        insertStructuredName(contactId1, "Johnm", "Smithm");
+        insertPhoneNumber(contactId1, "(888)555-1233");
+
+        long contactId2 = createContact();
+        insertPhoneNumber(contactId2, "1(888)555-1233");
+
+        assertAggregated(contactId1, contactId2);
+    }
+
+    public void testAggregationBasedOnPhoneNumberWithSimilarNames() {
+        long contactId1 = createContact();
+        insertStructuredName(contactId1, "Ogre", "Hunter");
+        insertPhoneNumber(contactId1, "(888)555-1234");
+
+        long contactId2 = createContact();
+        insertStructuredName(contactId2, "Opra", "Humper");
+        insertPhoneNumber(contactId2, "1(888)555-1234");
+
+        assertAggregated(contactId1, contactId2);
+    }
+
+    public void testAggregationBasedOnPhoneNumberWithDifferentNames() {
+        long contactId1 = createContact();
+        insertStructuredName(contactId1, "Baby", "Bear");
+        insertPhoneNumber(contactId1, "(888)555-1235");
+
+        long contactId2 = createContact();
+        insertStructuredName(contactId2, "Blind", "Mouse");
+        insertPhoneNumber(contactId2, "1(888)555-1235");
+
+        assertNotAggregated(contactId1, contactId2);
+    }
+
+    public void testAggregationBasedOnEmailNoNameData() {
+        long contactId1 = createContact();
+        insertEmail(contactId1, "lightning@android.com");
+
+        long contactId2 = createContact();
+        insertEmail(contactId2, "lightning@android.com");
+
+        assertAggregated(contactId1, contactId2);
+    }
+
+    public void testAggregationBasedOnEmailWhenTargetAggregateHasNoName() {
+        long contactId1 = createContact();
+        insertEmail(contactId1, "mcqueen@android.com");
+
+        long contactId2 = createContact();
+        insertStructuredName(contactId2, "Lightning", "McQueen");
+        insertEmail(contactId2, "mcqueen@android.com");
+
+        assertAggregated(contactId1, contactId2);
+    }
+
+    public void testAggregationBasedOnEmailWhenNewContactHasNoName() {
+        long contactId1 = createContact();
+        insertStructuredName(contactId1, "Doc", "Hudson");
+        insertEmail(contactId1, "doc@android.com");
+
+        long contactId2 = createContact();
+        insertEmail(contactId2, "doc@android.com");
+
+        assertAggregated(contactId1, contactId2);
+    }
+
+    public void testAggregationBasedOnEmailWithSimilarNames() {
+        long contactId1 = createContact();
+        insertStructuredName(contactId1, "Sally", "Carrera");
+        insertEmail(contactId1, "sally@android.com");
+
+        long contactId2 = createContact();
+        insertStructuredName(contactId2, "Sallie", "Carerra");
+        insertEmail(contactId2, "sally@android.com");
+
+        assertAggregated(contactId1, contactId2);
+    }
+
+    public void testAggregationBasedOnEmailWithDifferentNames() {
+        long contactId1 = createContact();
+        insertStructuredName(contactId1, "Chick", "Hicks");
+        insertEmail(contactId1, "hicky@android.com");
+
+        long contactId2 = createContact();
+        insertStructuredName(contactId2, "Luigi", "Guido");
+        insertEmail(contactId2, "hicky@android.com");
+
+        assertNotAggregated(contactId1, contactId2);
+    }
+
+    public void testAggregationByCommonNicknameWithLastName() {
+        long contactId1 = createContact();
+        insertStructuredName(contactId1, "Bill", "Gore");
+
+        long contactId2 = createContact();
+        insertStructuredName(contactId2, "William", "Gore");
+
+        assertAggregated(contactId1, contactId2, "William Gore");
+    }
+
+    public void testAggregationByCommonNicknameOnly() {
+        long contactId1 = createContact();
+        insertStructuredName(contactId1, "Lawrence", null);
+
+        long contactId2 = createContact();
+        insertStructuredName(contactId2, "Larry", null);
+
+        assertAggregated(contactId1, contactId2, "Lawrence");
+    }
+
+    public void testAggregationByNicknameNoStructuredName() {
+        long contactId1 = createContact();
+        insertNickname(contactId1, "Frozone");
+
+        long contactId2 = createContact();
+        insertNickname(contactId2, "Frozone");
+
+        assertAggregated(contactId1, contactId2);
+    }
+
+    public void testAggregationByNicknameWithSimilarNames() {
+        long contactId1 = createContact();
+        insertStructuredName(contactId1, "Buddy", "Pine");
+        insertNickname(contactId1, "Syndrome");
+
+        long contactId2 = createContact();
+        insertStructuredName(contactId2, "Body", "Pane");
+        insertNickname(contactId2, "Syndrome");
+
+        assertAggregated(contactId1, contactId2);
+    }
+
+    public void testAggregationByNicknameWithDifferentNames() {
+        long contactId1 = createContact();
+        insertStructuredName(contactId1, "Helen", "Parr");
+        insertNickname(contactId1, "Elastigirl");
+
+        long contactId2 = createContact();
+        insertStructuredName(contactId2, "Shawn", "Johnson");
+        insertNickname(contactId2, "Elastigirl");
+
+        assertNotAggregated(contactId1, contactId2);
+    }
+
+    public void testAggregationExceptionKeepIn() {
+        long contactId1 = createContact();
+        insertStructuredName(contactId1, "Johnk", "Smithk");
+
+        long contactId2 = createContact();
+        insertStructuredName(contactId2, "Johnkx", "Smithkx");
+
+        long aggregateId1 = queryAggregateId(contactId1);
+        long aggregateId2 = queryAggregateId(contactId2);
+
+        setAggregationException(AggregationExceptions.TYPE_KEEP_IN,
+                queryAggregateId(contactId1), contactId2);
+
+        assertAggregated(contactId1, contactId2, "Johnkx Smithkx");
+
+        // Assert that the empty aggregate got removed
+        long newAggregateId1 = queryAggregateId(contactId1);
+        if (aggregateId1 != newAggregateId1) {
+            Cursor cursor = queryAggregate(aggregateId1);
+            assertFalse(cursor.moveToFirst());
+            cursor.close();
+        } else {
+            Cursor cursor = queryAggregate(aggregateId2);
+            assertFalse(cursor.moveToFirst());
+            cursor.close();
+        }
+    }
+
+    public void testAggregationExceptionKeepOut() {
+        long contactId1 = createContact();
+        insertStructuredName(contactId1, "Johnh", "Smithh");
+
+        long contactId2 = createContact();
+        insertStructuredName(contactId2, "Johnh", "Smithh");
+
+        setAggregationException(AggregationExceptions.TYPE_KEEP_OUT,
+                queryAggregateId(contactId1), contactId2);
+
+        assertNotAggregated(contactId1, contactId2);
+    }
+
+    public void testAggregationExceptionKeepOutCheckUpdatesDisplayName() {
+        long contactId1 = createContact();
+        insertStructuredName(contactId1, "Johni", "Smithi");
+
+        long contactId2 = createContact();
+        insertStructuredName(contactId2, "Johnj", "Smithj");
+
+        setAggregationException(AggregationExceptions.TYPE_KEEP_IN,
+                queryAggregateId(contactId1), contactId2);
+
+        assertAggregated(contactId1, contactId2, "Johnj Smithj");
+
+        setAggregationException(AggregationExceptions.TYPE_KEEP_OUT,
+                queryAggregateId(contactId1), contactId2);
+
+        assertNotAggregated(contactId1, contactId2);
+
+        String displayName1 = queryDisplayName(queryAggregateId(contactId1));
+        assertEquals("Johni Smithi", displayName1);
+
+        String displayName2 = queryDisplayName(queryAggregateId(contactId2));
+        assertEquals("Johnj Smithj", displayName2);
+    }
+
+    public void testAggregationSuggestionsBasedOnName() {
+        long contactId1 = createContact();
+        insertStructuredName(contactId1, "Duane", null);
+
+        // Exact name match
+        long contactId2 = createContact();
+        insertStructuredName(contactId2, "Duane", null);
+        setAggregationException(AggregationExceptions.TYPE_KEEP_OUT,
+                queryAggregateId(contactId1), contactId2);
+
+        // Edit distance == 0.84
+        long contactId3 = createContact();
+        insertStructuredName(contactId3, "Dwayne", null);
+
+        // Edit distance == 0.6
+        long contactId4 = createContact();
+        insertStructuredName(contactId4, "Donny", null);
+
+        long aggregateId1 = queryAggregateId(contactId1);
+        long aggregateId2 = queryAggregateId(contactId2);
+        long aggregateId3 = queryAggregateId(contactId3);
+
+        assertSuggestions(aggregateId1, aggregateId2, aggregateId3);
+    }
+
+    public void testAggregationSuggestionsBasedOnPhoneNumber() {
+
+        // Create two contacts that would not be aggregated because of name mismatch
+        long contactId1 = createContact();
+        insertStructuredName(contactId1, "Lord", "Farquaad");
+        insertPhoneNumber(contactId1, "(888)555-1236");
+
+        long contactId2 = createContact();
+        insertStructuredName(contactId2, "Talking", "Donkey");
+        insertPhoneNumber(contactId2, "1(888)555-1236");
+
+        long aggregateId1 = queryAggregateId(contactId1);
+        long aggregateId2 = queryAggregateId(contactId2);
+        assertTrue(aggregateId1 != aggregateId2);
+
+        assertSuggestions(aggregateId1, aggregateId2);
+    }
+
+    public void testAggregationSuggestionsBasedOnEmailAddress() {
+
+        // Create two contacts that would not be aggregated because of name mismatch
+        long contactId1 = createContact();
+        insertStructuredName(contactId1, "Carl", "Fredricksen");
+        insertEmail(contactId1, "up@android.com");
+
+        long contactId2 = createContact();
+        insertStructuredName(contactId2, "Charles", "Muntz");
+        insertEmail(contactId2, "up@android.com");
+
+        long aggregateId1 = queryAggregateId(contactId1);
+        long aggregateId2 = queryAggregateId(contactId2);
+        assertTrue(aggregateId1 != aggregateId2);
+
+        assertSuggestions(aggregateId1, aggregateId2);
+    }
+
+    public void testAggregationSuggestionsBasedOnEmailAddressApproximateMatch() {
+
+        // Create two contacts that would not be aggregated because of name mismatch
+        long contactId1 = createContact();
+        insertStructuredName(contactId1, "Bob", null);
+        insertEmail(contactId1, "incredible2004@android.com");
+
+        long contactId2 = createContact();
+        insertStructuredName(contactId2, "Lucius", "Best");
+        insertEmail(contactId2, "incrediball@androidd.com");
+
+        long aggregateId1 = queryAggregateId(contactId1);
+        long aggregateId2 = queryAggregateId(contactId2);
+        assertTrue(aggregateId1 != aggregateId2);
+
+        assertSuggestions(aggregateId1, aggregateId2);
+    }
+
+    public void testAggregationSuggestionsBasedOnNickname() {
+        long contactId1 = createContact();
+        insertStructuredName(contactId1, "Peter", "Parker");
+        insertNickname(contactId1, "Spider-Man");
+
+        long contactId2 = createContact();
+        insertStructuredName(contactId2, "Manny", "Spider");
+
+        long aggregateId1 = queryAggregateId(contactId1);
+        setAggregationException(AggregationExceptions.TYPE_KEEP_OUT, aggregateId1, contactId2);
+
+        long aggregateId2 = queryAggregateId(contactId2);
+        assertSuggestions(aggregateId1, aggregateId2);
+    }
+
+    public void testAggregationSuggestionsBasedOnNicknameMatchingName() {
+        long contactId1 = createContact();
+        insertStructuredName(contactId1, "Clark", "Kent");
+        insertNickname(contactId1, "Superman");
+
+        long contactId2 = createContact();
+        insertStructuredName(contactId2, "Roy", "Williams");
+        insertNickname(contactId2, "superman");
+
+        long aggregateId1 = queryAggregateId(contactId1);
+        setAggregationException(AggregationExceptions.TYPE_KEEP_OUT, aggregateId1, contactId2);
+
+        long aggregateId2 = queryAggregateId(contactId2);
+        assertSuggestions(aggregateId1, aggregateId2);
+    }
+
+    public void testAggregationSuggestionsBasedOnCommonNickname() {
+        long contactId1 = createContact();
+        insertStructuredName(contactId1, "Dick", "Cherry");
+
+        long contactId2 = createContact();
+        insertStructuredName(contactId2, "Richard", "Cherry");
+
+        long aggregateId1 = queryAggregateId(contactId1);
+        setAggregationException(AggregationExceptions.TYPE_KEEP_OUT, aggregateId1, contactId2);
+
+        long aggregateId2 = queryAggregateId(contactId2);
+        assertSuggestions(aggregateId1, aggregateId2);
+    }
+
+    private void assertSuggestions(long aggregateId, long... suggestions) {
+        final Uri aggregateUri = ContentUris.withAppendedId(Aggregates.CONTENT_URI, aggregateId);
+        Uri uri = Uri.withAppendedPath(aggregateUri,
+                Aggregates.AggregationSuggestions.CONTENT_DIRECTORY);
+        final Cursor cursor = mResolver.query(uri, new String[] { Aggregates._ID },
+                null, null, null);
+
+        assertEquals(suggestions.length, cursor.getCount());
+
+        for (int i = 0; i < suggestions.length; i++) {
+            cursor.moveToNext();
+            assertEquals(suggestions[i], cursor.getLong(0));
+        }
+
+        cursor.close();
+    }
+}
diff --git a/tests/src/com/android/providers/contacts/ContactsActor.java b/tests/src/com/android/providers/contacts/ContactsActor.java
new file mode 100644
index 0000000..5936f8f
--- /dev/null
+++ b/tests/src/com/android/providers/contacts/ContactsActor.java
@@ -0,0 +1,296 @@
+/*
+ * Copyright (C) 2009 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;
+
+import android.content.ContentUris;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.res.Resources;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Binder;
+import android.provider.BaseColumns;
+import android.provider.ContactsContract;
+import android.provider.Contacts.Phones;
+import android.provider.ContactsContract.Aggregates;
+import android.provider.ContactsContract.CommonDataKinds;
+import android.provider.ContactsContract.Contacts;
+import android.provider.ContactsContract.Data;
+import android.provider.ContactsContract.RestrictionExceptions;
+import android.test.IsolatedContext;
+import android.test.RenamingDelegatingContext;
+import android.test.mock.MockContentResolver;
+import android.test.mock.MockContext;
+import android.test.mock.MockPackageManager;
+import android.util.Log;
+
+import java.util.HashMap;
+
+/**
+ * Helper class that encapsulates an "actor" which is owned by a specific
+ * package name. It correctly maintains a wrapped {@link Context} and an
+ * attached {@link MockContentResolver}. Multiple actors can be used to test
+ * security scenarios between multiple packages.
+ */
+public class ContactsActor {
+    private static final String FILENAME_PREFIX = "test.";
+
+    public static final String PACKAGE_GREY = "edu.example.grey";
+    public static final String PACKAGE_RED = "net.example.red";
+    public static final String PACKAGE_GREEN = "com.example.green";
+    public static final String PACKAGE_BLUE = "org.example.blue";
+
+    public Context context;
+    public String packageName;
+    public MockContentResolver resolver;
+    public SynchronousContactsProvider2 provider;
+
+    /**
+     * Create an "actor" using the given parent {@link Context} and the specific
+     * package name. Internally, all {@link Context} method calls are passed to
+     * a new instance of {@link RestrictionMockContext}, which stubs out the
+     * security infrastructure.
+     */
+    public ContactsActor(Context overallContext, String packageName) {
+        context = new RestrictionMockContext(overallContext, packageName);
+        this.packageName = packageName;
+        resolver = new MockContentResolver();
+
+        RenamingDelegatingContext targetContextWrapper = new RenamingDelegatingContext(
+                context, overallContext, FILENAME_PREFIX);
+        Context providerContext = new IsolatedContext(resolver, targetContextWrapper);
+
+        provider = new SynchronousContactsProvider2();
+        provider.attachInfo(providerContext, null);
+        resolver.addProvider(ContactsContract.AUTHORITY, provider);
+    }
+
+    /**
+     * Mock {@link Context} that reports specific well-known values for testing
+     * data protection. The creator can override the owner package name, and
+     * force the {@link PackageManager} to always return a well-known package
+     * list for any call to {@link PackageManager#getPackagesForUid(int)}.
+     * <p>
+     * For example, the creator could request that the {@link Context} lives in
+     * package name "com.example.red", and also cause the {@link PackageManager}
+     * to report that no UID contains that package name.
+     */
+    private static class RestrictionMockContext extends MockContext {
+        private final Context mOverallContext;
+        private final String mReportedPackageName;
+        private final RestrictionMockPackageManager mPackageManager;
+
+        /**
+         * Create a {@link Context} under the given package name.
+         */
+        public RestrictionMockContext(Context overallContext, String reportedPackageName) {
+            mOverallContext = overallContext;
+            mReportedPackageName = reportedPackageName;
+            mPackageManager = new RestrictionMockPackageManager();
+            mPackageManager.addPackage(1000, PACKAGE_GREY);
+            mPackageManager.addPackage(2000, PACKAGE_RED);
+            mPackageManager.addPackage(3000, PACKAGE_GREEN);
+            mPackageManager.addPackage(4000, PACKAGE_BLUE);
+        }
+
+        @Override
+        public String getPackageName() {
+            return mReportedPackageName;
+        }
+
+        @Override
+        public PackageManager getPackageManager() {
+            return mPackageManager;
+        }
+
+        @Override
+        public Resources getResources() {
+            return mOverallContext.getResources();
+        }
+    }
+
+    /**
+     * Mock {@link PackageManager} that knows about a specific set of packages
+     * to help test security models. Because {@link Binder#getCallingUid()}
+     * can't be mocked, you'll have to find your mock-UID manually using your
+     * {@link Context#getPackageName()}.
+     */
+    private static class RestrictionMockPackageManager extends MockPackageManager {
+        private final HashMap<Integer, String> mForward = new HashMap<Integer, String>();
+        private final HashMap<String, Integer> mReverse = new HashMap<String, Integer>();
+
+        /**
+         * Add a UID-to-package mapping, which is then stored internally.
+         */
+        public void addPackage(int packageUid, String packageName) {
+            mForward.put(packageUid, packageName);
+            mReverse.put(packageName, packageUid);
+        }
+
+        @Override
+        public String[] getPackagesForUid(int uid) {
+            return new String[] { mForward.get(uid) };
+        }
+
+        @Override
+        public ApplicationInfo getApplicationInfo(String packageName, int flags) {
+            ApplicationInfo info = new ApplicationInfo();
+            Integer uid = mReverse.get(packageName);
+            info.uid = (uid != null) ? uid : -1;
+            return info;
+        }
+    }
+
+    public long createContact(boolean isRestricted, String name) {
+        long contactId = createContact(isRestricted);
+        createName(contactId, name);
+        return contactId;
+    }
+
+    public long createContact(boolean isRestricted) {
+        final ContentValues values = new ContentValues();
+        values.put(Contacts.PACKAGE, packageName);
+        if (isRestricted) {
+            values.put(Contacts.IS_RESTRICTED, 1);
+        }
+
+        Uri contactUri = resolver.insert(Contacts.CONTENT_URI, values);
+        return ContentUris.parseId(contactUri);
+    }
+
+    public long createName(long contactId, String name) {
+        final ContentValues values = new ContentValues();
+        values.put(Data.CONTACT_ID, contactId);
+        values.put(Data.IS_PRIMARY, 1);
+        values.put(Data.IS_SUPER_PRIMARY, 1);
+        values.put(Data.MIMETYPE, CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE);
+        values.put(CommonDataKinds.StructuredName.FAMILY_NAME, name);
+        Uri insertUri = Uri.withAppendedPath(ContentUris.withAppendedId(Contacts.CONTENT_URI,
+                contactId), Contacts.Data.CONTENT_DIRECTORY);
+        Uri dataUri = resolver.insert(insertUri, values);
+        return ContentUris.parseId(dataUri);
+    }
+
+    public long createPhone(long contactId, String phoneNumber) {
+        final ContentValues values = new ContentValues();
+        values.put(Data.CONTACT_ID, contactId);
+        values.put(Data.IS_PRIMARY, 1);
+        values.put(Data.IS_SUPER_PRIMARY, 1);
+        values.put(Data.MIMETYPE, Phones.CONTENT_ITEM_TYPE);
+        values.put(ContactsContract.CommonDataKinds.Phone.NUMBER, phoneNumber);
+        Uri insertUri = Uri.withAppendedPath(ContentUris.withAppendedId(Contacts.CONTENT_URI,
+                contactId), Contacts.Data.CONTENT_DIRECTORY);
+        Uri dataUri = resolver.insert(insertUri, values);
+        return ContentUris.parseId(dataUri);
+    }
+
+    public void updateException(String packageProvider, String packageClient, boolean allowAccess) {
+        final ContentValues values = new ContentValues();
+        values.put(RestrictionExceptions.PACKAGE_PROVIDER, packageProvider);
+        values.put(RestrictionExceptions.PACKAGE_CLIENT, packageClient);
+        values.put(RestrictionExceptions.ALLOW_ACCESS, allowAccess ? 1 : 0);
+        resolver.update(RestrictionExceptions.CONTENT_URI, values, null, null);
+    }
+
+    public long getAggregateForContact(long contactId) {
+        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
+        final Cursor cursor = resolver.query(contactUri, Projections.PROJ_CONTACTS, null,
+                null, null);
+        if (!cursor.moveToFirst()) {
+            cursor.close();
+            throw new RuntimeException("Contact didn't have an aggregate");
+        }
+        final long aggId = cursor.getLong(Projections.COL_CONTACTS_AGGREGATE);
+        cursor.close();
+        return aggId;
+    }
+
+    public int getDataCountForAggregate(long aggId) {
+        Uri contactUri = Uri.withAppendedPath(ContentUris.withAppendedId(Aggregates.CONTENT_URI,
+                aggId), Aggregates.Data.CONTENT_DIRECTORY);
+        final Cursor cursor = resolver.query(contactUri, Projections.PROJ_ID, null, null,
+                null);
+        final int count = cursor.getCount();
+        cursor.close();
+        return count;
+    }
+
+    public void setSuperPrimaryPhone(long dataId) {
+        final ContentValues values = new ContentValues();
+        values.put(Data.IS_PRIMARY, 1);
+        values.put(Data.IS_SUPER_PRIMARY, 1);
+        Uri updateUri = ContentUris.withAppendedId(Data.CONTENT_URI, dataId);
+        resolver.update(updateUri, values, null, null);
+    }
+
+    public long getPrimaryPhoneId(long aggId) {
+        Uri aggUri = ContentUris.withAppendedId(Aggregates.CONTENT_URI, aggId);
+        final Cursor cursor = resolver.query(aggUri, Projections.PROJ_AGGREGATES, null,
+                null, null);
+        long primaryPhoneId = -1;
+        if (cursor.moveToFirst()) {
+            primaryPhoneId = cursor.getLong(Projections.COL_AGGREGATES_PRIMARY_PHONE_ID);
+        }
+        cursor.close();
+        return primaryPhoneId;
+    }
+
+    public long createGroup(String groupName) {
+        final ContentValues values = new ContentValues();
+        values.put(ContactsContract.Groups.PACKAGE, packageName);
+        values.put(ContactsContract.Groups.TITLE, groupName);
+        Uri groupUri = resolver.insert(ContactsContract.Groups.CONTENT_URI, values);
+        return ContentUris.parseId(groupUri);
+    }
+
+    public long createGroupMembership(long contactId, long groupId) {
+        final ContentValues values = new ContentValues();
+        values.put(Data.CONTACT_ID, contactId);
+        values.put(Data.MIMETYPE, CommonDataKinds.GroupMembership.CONTENT_ITEM_TYPE);
+        values.put(CommonDataKinds.GroupMembership.GROUP_ROW_ID, groupId);
+        Uri insertUri = Uri.withAppendedPath(ContentUris.withAppendedId(Contacts.CONTENT_URI,
+                contactId), Contacts.Data.CONTENT_DIRECTORY);
+        Uri dataUri = resolver.insert(insertUri, values);
+        return ContentUris.parseId(dataUri);
+    }
+
+    /**
+     * Various internal database projections.
+     */
+    private interface Projections {
+        static final String[] PROJ_ID = new String[] {
+                BaseColumns._ID,
+        };
+
+        static final int COL_ID = 0;
+
+        static final String[] PROJ_CONTACTS = new String[] {
+                Contacts.AGGREGATE_ID
+        };
+
+        static final int COL_CONTACTS_AGGREGATE = 0;
+
+        static final String[] PROJ_AGGREGATES = new String[] {
+                Aggregates.PRIMARY_PHONE_ID
+        };
+
+        static final int COL_AGGREGATES_PRIMARY_PHONE_ID = 0;
+
+    }
+}
diff --git a/tests/src/com/android/providers/contacts/ContactsProvider2Test.java b/tests/src/com/android/providers/contacts/ContactsProvider2Test.java
new file mode 100644
index 0000000..fc7beb3
--- /dev/null
+++ b/tests/src/com/android/providers/contacts/ContactsProvider2Test.java
@@ -0,0 +1,183 @@
+/*
+ * Copyright (C) 2009 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;
+
+import com.android.internal.util.ArrayUtils;
+import com.android.providers.contacts.BaseContactsProvider2Test;
+
+import android.content.ContentUris;
+import android.content.ContentValues;
+import android.database.Cursor;
+import android.net.Uri;
+import android.provider.ContactsContract.Aggregates;
+import android.provider.ContactsContract.AggregationExceptions;
+import android.provider.ContactsContract.Contacts;
+import android.provider.ContactsContract.Presence;
+import android.provider.ContactsContract.CommonDataKinds.Im;
+import android.provider.ContactsContract.CommonDataKinds.StructuredName;
+import android.test.suitebuilder.annotation.LargeTest;
+import android.util.Log;
+
+/**
+ * Unit tests for {@link ContactsProvider2}.
+ *
+ * Run the test like this:
+ * <code>
+ * adb shell am instrument -w \
+ *         com.android.providers.contacts.tests/android.test.InstrumentationTestRunner
+ * </code>
+ */
+@LargeTest
+public class ContactsProvider2Test extends BaseContactsProvider2Test {
+
+    public void testDisplayNameParsingWhenPartsUnspecified() {
+        long contactId = createContact();
+        ContentValues values = new ContentValues();
+        values.put(StructuredName.DISPLAY_NAME, "Mr.John Kevin von Smith, Jr.");
+        insertStructuredName(contactId, values);
+
+        assertStructuredName(contactId, "Mr", "John", "Kevin", "von Smith", "Jr");
+    }
+
+    public void testDisplayNameParsingWhenPartsSpecified() {
+        long contactId = createContact();
+        ContentValues values = new ContentValues();
+        values.put(StructuredName.DISPLAY_NAME, "Mr.John Kevin von Smith, Jr.");
+        values.put(StructuredName.FAMILY_NAME, "Johnson");
+        insertStructuredName(contactId, values);
+
+        assertStructuredName(contactId, null, null, null, "Johnson", null);
+    }
+
+    public void testSendToVoicemailDefault() {
+        long contactId = createContact();
+        long aggregateId = queryAggregateId(contactId);
+
+        Cursor c = queryAggregate(aggregateId);
+        assertTrue(c.moveToNext());
+        int sendToVoicemail = c.getInt(c.getColumnIndex(Aggregates.SEND_TO_VOICEMAIL));
+        assertEquals(0, sendToVoicemail);
+        c.close();
+    }
+
+    public void testSetSendToVoicemailAndRingtone() {
+        long contactId = createContact();
+        long aggregateId = queryAggregateId(contactId);
+
+        updateSendToVoicemailAndRingtone(aggregateId, true, "foo");
+        assertSendToVoicemailAndRingtone(aggregateId, true, "foo");
+    }
+
+    public void testSendToVoicemailAndRingtoneAfterAggregation() {
+        long contactId1 = createContact();
+        long aggregateId1 = queryAggregateId(contactId1);
+        updateSendToVoicemailAndRingtone(aggregateId1, true, "foo");
+
+        long contactId2 = createContact();
+        long aggregateId2 = queryAggregateId(contactId2);
+        updateSendToVoicemailAndRingtone(aggregateId2, true, "bar");
+
+        // Aggregate them
+        setAggregationException(AggregationExceptions.TYPE_KEEP_IN, aggregateId1, contactId2);
+
+        // Both contacts had "send to VM", the aggregate now has the same value
+        assertSendToVoicemailAndRingtone(aggregateId1, true, "foo,bar"); // Either foo or bar
+    }
+
+    public void testDoNotSendToVoicemailAfterAggregation() {
+        long contactId1 = createContact();
+        long aggregateId1 = queryAggregateId(contactId1);
+        updateSendToVoicemailAndRingtone(aggregateId1, true, null);
+
+        long contactId2 = createContact();
+        long aggregateId2 = queryAggregateId(contactId2);
+        updateSendToVoicemailAndRingtone(aggregateId2, false, null);
+
+        // Aggregate them
+        setAggregationException(AggregationExceptions.TYPE_KEEP_IN, aggregateId1, contactId2);
+
+        // Since one of the contacts had "don't send to VM" that setting wins for the aggregate
+        assertSendToVoicemailAndRingtone(aggregateId1, false, null);
+    }
+
+    public void testSetSendToVoicemailAndRingtonePreservedAfterJoinAndSplit() {
+        long contactId1 = createContact();
+        long aggregateId1 = queryAggregateId(contactId1);
+        updateSendToVoicemailAndRingtone(aggregateId1, true, "foo");
+
+        long contactId2 = createContact();
+        long aggregateId2 = queryAggregateId(contactId2);
+        updateSendToVoicemailAndRingtone(aggregateId2, false, "bar");
+
+        // Aggregate them
+        setAggregationException(AggregationExceptions.TYPE_KEEP_IN, aggregateId1, contactId2);
+
+        // Split them
+        setAggregationException(AggregationExceptions.TYPE_KEEP_OUT, aggregateId1, contactId2);
+
+        assertSendToVoicemailAndRingtone(aggregateId1, true, "foo");
+        assertSendToVoicemailAndRingtone(queryAggregateId(contactId2), false, "bar");
+    }
+
+    public void testSinglePresenceRowPerAggregate() {
+        int protocol1 = Im.PROTOCOL_GOOGLE_TALK;
+        String handle1 = "test@gmail.com";
+
+        long contactId1 = createContact();
+        insertImHandle(contactId1, protocol1, handle1);
+
+        insertPresence(protocol1, handle1, Presence.AVAILABLE);
+        insertPresence(protocol1, handle1, Presence.AWAY);
+        insertPresence(protocol1, handle1, Presence.INVISIBLE);
+
+        Cursor c = queryAggregateSummary(queryAggregateId(contactId1),
+                new String[] {Presence.PRESENCE_STATUS});
+        assertEquals(c.getCount(), 1);
+
+        c.moveToFirst();
+        assertEquals(c.getInt(0), Presence.AVAILABLE);
+
+    }
+
+    private void updateSendToVoicemailAndRingtone(long aggregateId, boolean sendToVoicemail,
+            String ringtone) {
+        ContentValues values = new ContentValues();
+        values.put(Aggregates.SEND_TO_VOICEMAIL, sendToVoicemail);
+        if (ringtone != null) {
+            values.put(Aggregates.CUSTOM_RINGTONE, ringtone);
+        }
+
+        final Uri uri = ContentUris.withAppendedId(Aggregates.CONTENT_URI, aggregateId);
+        int count = mResolver.update(uri, values, null, null);
+        assertEquals(1, count);
+    }
+
+    private void assertSendToVoicemailAndRingtone(long aggregateId, boolean expectedSendToVoicemail,
+            String expectedRingtone) {
+        Cursor c = queryAggregate(aggregateId);
+        assertTrue(c.moveToNext());
+        int sendToVoicemail = c.getInt(c.getColumnIndex(Aggregates.SEND_TO_VOICEMAIL));
+        assertEquals(expectedSendToVoicemail ? 1 : 0, sendToVoicemail);
+        String ringtone = c.getString(c.getColumnIndex(Aggregates.CUSTOM_RINGTONE));
+        if (expectedRingtone == null) {
+            assertNull(ringtone);
+        } else {
+            assertTrue(ArrayUtils.contains(expectedRingtone.split(","), ringtone));
+        }
+        c.close();
+    }
+}
+
diff --git a/tests/src/com/android/providers/contacts/GroupsTest.java b/tests/src/com/android/providers/contacts/GroupsTest.java
new file mode 100644
index 0000000..a9428ae
--- /dev/null
+++ b/tests/src/com/android/providers/contacts/GroupsTest.java
@@ -0,0 +1,164 @@
+/*
+ * Copyright (C) 2009 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;
+
+import static com.android.providers.contacts.ContactsActor.PACKAGE_GREY;
+
+import android.database.Cursor;
+import android.provider.ContactsContract.Groups;
+import android.provider.ContactsContract.CommonDataKinds.GroupMembership;
+import android.test.AndroidTestCase;
+import android.test.mock.MockContentResolver;
+import android.test.suitebuilder.annotation.LargeTest;
+
+/**
+ * Unit tests for {@link Groups} and {@link GroupMembership}.
+ *
+ * Run the test like this:
+ * <code>
+ * adb shell am instrument -w \
+ *         com.android.providers.contacts.tests/android.test.InstrumentationTestRunner
+ * </code>
+ */
+@LargeTest
+public class GroupsTest extends AndroidTestCase {
+
+    private ContactsActor mActor;
+    private MockContentResolver mResolver;
+
+    public GroupsTest() {
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        mActor = new ContactsActor(getContext(), PACKAGE_GREY);
+        mResolver = mActor.resolver;
+    }
+
+    private static final String GROUP_GREY = "Grey";
+    private static final String GROUP_RED = "Red";
+    private static final String GROUP_GREEN = "Green";
+    private static final String GROUP_BLUE = "Blue";
+
+    private static final String PERSON_ALPHA = "Alpha";
+    private static final String PERSON_BRAVO = "Bravo";
+    private static final String PERSON_CHARLIE = "Charlie";
+    private static final String PERSON_DELTA = "Delta";
+
+    private static final String PHONE_ALPHA = "555-1111";
+    private static final String PHONE_BRAVO_1 = "555-2222";
+    private static final String PHONE_BRAVO_2 = "555-3333";
+    private static final String PHONE_CHARLIE_1 = "555-4444";
+    private static final String PHONE_CHARLIE_2 = "555-5555";
+
+    public void testGroupSummary() {
+
+        // Clear any existing data before starting
+        mActor.provider.wipeData();
+
+        // Create a handful of groups
+        long groupGrey = mActor.createGroup(GROUP_GREY);
+        long groupRed = mActor.createGroup(GROUP_RED);
+        long groupGreen = mActor.createGroup(GROUP_GREEN);
+        long groupBlue = mActor.createGroup(GROUP_BLUE);
+
+        // Create a handful of contacts
+        long contactAlpha = mActor.createContact(false, PERSON_ALPHA);
+        long contactBravo = mActor.createContact(false, PERSON_BRAVO);
+        long contactCharlie = mActor.createContact(false, PERSON_CHARLIE);
+        long contactCharlieDupe = mActor.createContact(false, PERSON_CHARLIE);
+        long contactDelta = mActor.createContact(false, PERSON_DELTA);
+
+        // Make sure that Charlie was aggregated
+        {
+            long aggCharlie = mActor.getAggregateForContact(contactCharlie);
+            long aggCharlieDupe = mActor.getAggregateForContact(contactCharlieDupe);
+            assertTrue("Didn't aggregate two contacts with identical names",
+                    (aggCharlie == aggCharlieDupe));
+        }
+
+        // Add phone numbers to specific contacts
+        mActor.createPhone(contactAlpha, PHONE_ALPHA);
+        mActor.createPhone(contactBravo, PHONE_BRAVO_1);
+        mActor.createPhone(contactBravo, PHONE_BRAVO_2);
+        mActor.createPhone(contactCharlie, PHONE_CHARLIE_1);
+        mActor.createPhone(contactCharlieDupe, PHONE_CHARLIE_2);
+
+        // Add contacts to various mixture of groups. Grey will have all
+        // contacts, Red only with phone numbers, Green with no phones, and Blue
+        // with no contacts at all.
+        mActor.createGroupMembership(contactAlpha, groupGrey);
+        mActor.createGroupMembership(contactBravo, groupGrey);
+        mActor.createGroupMembership(contactCharlie, groupGrey);
+        mActor.createGroupMembership(contactDelta, groupGrey);
+
+        mActor.createGroupMembership(contactAlpha, groupRed);
+        mActor.createGroupMembership(contactBravo, groupRed);
+        mActor.createGroupMembership(contactCharlie, groupRed);
+
+        mActor.createGroupMembership(contactDelta, groupGreen);
+
+        // Walk across groups summary cursor and verify returned counts.
+        final Cursor cursor = mActor.resolver.query(Groups.CONTENT_SUMMARY_URI,
+                Projections.PROJ_SUMMARY, null, null, null);
+
+        // Require that each group has a summary row
+        assertTrue("Didn't return summary for all groups", (cursor.getCount() == 4));
+
+        while (cursor.moveToNext()) {
+            final long groupId = cursor.getLong(Projections.COL_ID);
+            final int summaryCount = cursor.getInt(Projections.COL_SUMMARY_COUNT);
+            final int summaryWithPhones = cursor.getInt(Projections.COL_SUMMARY_WITH_PHONES);
+
+            if (groupId == groupGrey) {
+                // Grey should have four aggregates, three with phones.
+                assertTrue("Incorrect Grey count", (summaryCount == 4));
+                assertTrue("Incorrect Grey with phones count", (summaryWithPhones == 3));
+            } else if (groupId == groupRed) {
+                // Red should have 3 aggregates, all with phones.
+                assertTrue("Incorrect Red count", (summaryCount == 3));
+                assertTrue("Incorrect Red with phones count", (summaryWithPhones == 3));
+            } else if (groupId == groupGreen) {
+                // Green should have 1 aggregate, none with phones.
+                assertTrue("Incorrect Green count", (summaryCount == 1));
+                assertTrue("Incorrect Green with phones count", (summaryWithPhones == 0));
+            } else if (groupId == groupBlue) {
+                // Blue should have no contacts.
+                assertTrue("Incorrect Blue count", (summaryCount == 0));
+                assertTrue("Incorrect Blue with phones count", (summaryWithPhones == 0));
+            } else {
+                fail("Unrecognized group in summary cursor");
+            }
+        }
+
+    }
+
+    private interface Projections {
+        public static final String[] PROJ_SUMMARY = new String[] {
+            Groups._ID,
+            Groups.SUMMARY_COUNT,
+            Groups.SUMMARY_WITH_PHONES,
+        };
+
+        public static final int COL_ID = 0;
+        public static final int COL_SUMMARY_COUNT = 1;
+        public static final int COL_SUMMARY_WITH_PHONES = 2;
+    }
+
+}
diff --git a/tests/src/com/android/providers/contacts/JaroWinklerDistanceTest.java b/tests/src/com/android/providers/contacts/JaroWinklerDistanceTest.java
new file mode 100644
index 0000000..ad34bba
--- /dev/null
+++ b/tests/src/com/android/providers/contacts/JaroWinklerDistanceTest.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2009 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;
+
+import android.test.suitebuilder.annotation.SmallTest;
+
+import junit.framework.TestCase;
+
+@SmallTest
+public class JaroWinklerDistanceTest extends TestCase {
+
+    private JaroWinklerDistance mJaroWinklerDistance;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        mJaroWinklerDistance = new JaroWinklerDistance(10);
+    }
+
+    public void testExactMatch() {
+        assertFloat(1, "Dwayne", "Dwayne");
+    }
+
+    public void testWinklerBonus() {
+        assertFloat(0.961f, "Martha", "Marhta");
+        assertFloat(0.840f, "Dwayne", "Duane");
+        assertFloat(0.813f, "DIXON", "DICKSONX");
+    }
+
+    public void testJaroDistance() {
+        assertFloat(0.600f, "Donny", "Duane");
+    }
+
+    public void testPoorMatch() {
+        assertFloat(0.467f, "Johny", "Duane");
+    }
+
+    public void testNoMatches() {
+        assertFloat(0, "Abcd", "Efgh");
+    }
+
+    private void assertFloat(float expected, String name1, String name2) {
+        byte[] s1 = Hex.decodeHex(NameNormalizer.normalize(name1));
+        byte[] s2 = Hex.decodeHex(NameNormalizer.normalize(name2));
+
+        float actual = mJaroWinklerDistance.getDistance(s1, s2);
+        assertTrue("Expected Jaro-Winkler distance: " + expected + ", actual: " + actual,
+                Math.abs(actual - expected) < 0.001);
+    }
+}
diff --git a/tests/src/com/android/providers/contacts/NameNormalizerTest.java b/tests/src/com/android/providers/contacts/NameNormalizerTest.java
new file mode 100644
index 0000000..08d873f
--- /dev/null
+++ b/tests/src/com/android/providers/contacts/NameNormalizerTest.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2009 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;
+
+import android.test.suitebuilder.annotation.SmallTest;
+
+import junit.framework.TestCase;
+
+/**
+ * Unit tests for {@link NameNormalizer}.
+ */
+@SmallTest
+public class NameNormalizerTest extends TestCase {
+
+    public void testDifferent() {
+        final String name1 = NameNormalizer.normalize("Helene");
+        final String name2 = NameNormalizer.normalize("Francesca");
+        assertFalse(name2.equals(name1));
+    }
+
+    public void testAccents() {
+        final String name1 = NameNormalizer.normalize("Helene");
+        final String name2 = NameNormalizer.normalize("H\u00e9l\u00e8ne");
+        assertTrue(name2.equals(name1));
+    }
+
+    public void testMixedCase() {
+        final String name1 = NameNormalizer.normalize("Helene");
+        final String name2 = NameNormalizer.normalize("hELENE");
+        assertTrue(name2.equals(name1));
+    }
+
+    public void testNonLetters() {
+        final String name1 = NameNormalizer.normalize("h-e?l e+n=e");
+        final String name2 = NameNormalizer.normalize("helene");
+        assertTrue(name2.equals(name1));
+    }
+
+    public void testComplexityCase() {
+        assertTrue(NameNormalizer.compareComplexity("Helene", "helene") > 0);
+    }
+
+    public void testComplexityAccent() {
+        assertTrue(NameNormalizer.compareComplexity("H\u00e9lene", "Helene") > 0);
+    }
+
+    public void testComplexityLength() {
+        assertTrue(NameNormalizer.compareComplexity("helene2009", "helene") > 0);
+    }
+}
diff --git a/tests/src/com/android/providers/contacts/NameSplitterTest.java b/tests/src/com/android/providers/contacts/NameSplitterTest.java
new file mode 100644
index 0000000..91ce025
--- /dev/null
+++ b/tests/src/com/android/providers/contacts/NameSplitterTest.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2009 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;
+
+import junit.framework.TestCase;
+
+import com.android.providers.contacts.NameSplitter.Name;
+
+import android.test.suitebuilder.annotation.SmallTest;
+
+/**
+ * Tests for {@link NameSplitter}.
+ */
+@SmallTest
+public class NameSplitterTest extends TestCase {
+    private NameSplitter mNameSplitter;
+    private Name mName;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        mNameSplitter = new NameSplitter("Mr, Ms, Mrs", "d', st, st., von", "Jr, M.D., MD, D.D.S.",
+                "&, AND");
+        mName = new Name();
+    }
+
+    public void testNull() {
+        assertSplitName(null, null, null, null, null, null);
+    }
+
+    public void testEmpty() {
+        assertSplitName("", null, null, null, null, null);
+    }
+
+    public void testSpaces() {
+        assertSplitName(" ", null, null, null, null, null);
+    }
+
+    public void testLastName() {
+        assertSplitName("Smith", null, null, null, "Smith", null);
+    }
+
+    public void testFirstLastName() {
+        assertSplitName("John Smith", null, "John", null, "Smith", null);
+    }
+
+    public void testFirstMiddleLastName() {
+        assertSplitName("John Edward Smith", null, "John", "Edward", "Smith", null);
+    }
+
+    public void testThreeNamesAndLastName() {
+        assertSplitName("John Edward Kevin Smith", null, "John Edward", "Kevin", "Smith", null);
+    }
+
+    public void testPrefixFirstLastName() {
+        assertSplitName("Mr. John Smith", "Mr", "John", null, "Smith", null);
+        assertSplitName("Mr.John Smith", "Mr", "John", null, "Smith", null);
+    }
+
+    public void testFirstLastNameSuffix() {
+        assertSplitName("John Smith Jr.", null, "John", null, "Smith", "Jr");
+    }
+
+    public void testFirstLastNameSuffixWithDot() {
+        assertSplitName("John Smith M.D.", null, "John", null, "Smith", "M.D.");
+        assertSplitName("John Smith D D S", null, "John", null, "Smith", "D D S");
+    }
+
+    public void testFirstSuffixLastName() {
+        assertSplitName("John von Smith", null, "John", null, "von Smith", null);
+    }
+
+    public void testFirstSuffixLastNameWithDot() {
+        assertSplitName("John St.Smith", null, "John", null, "St. Smith", null);
+    }
+
+    public void testPrefixFirstMiddleLast() {
+        assertSplitName("Mr. John Kevin Smith", "Mr", "John", "Kevin", "Smith", null);
+        assertSplitName("Mr.John Kevin Smith", "Mr", "John", "Kevin", "Smith", null);
+    }
+
+    public void testPrefixFirstMiddleLastSuffix() {
+        assertSplitName("Mr. John Kevin Smith Jr.", "Mr", "John", "Kevin", "Smith", "Jr");
+    }
+
+    public void testPrefixFirstMiddlePrefixLastSuffixWrongCapitalization() {
+        assertSplitName("MR. john keVin VON SmiTh JR.", "MR", "john", "keVin", "VON SmiTh", "JR");
+    }
+
+    public void testPrefixLastSuffix() {
+        assertSplitName("von Smith Jr.", null, null, null, "von Smith", "Jr");
+    }
+
+    public void testTwoNamesAndLastNameWithAmpersand() {
+        assertSplitName("John & Edward Smith", null, "John & Edward", null, "Smith", null);
+        assertSplitName("John and Edward Smith", null, "John and Edward", null, "Smith", null);
+    }
+
+    public void testWithMiddleInitialAndNoDot() {
+        assertSplitName("John E. Smith", null, "John", "E", "Smith", null);
+    }
+
+    public void testWithLongFirstNameAndDot() {
+        assertSplitName("John Ed. K. Smith", null, "John Ed.", "K", "Smith", null);
+      }
+
+    private void assertSplitName(String fullName, String prefix, String givenNames,
+            String middleName, String lastName, String suffix) {
+        mNameSplitter.split(mName, fullName);
+        assertEquals(prefix, mName.getPrefix());
+        assertEquals(givenNames, mName.getGivenNames());
+        assertEquals(middleName, mName.getMiddleName());
+        assertEquals(lastName, mName.getFamilyName());
+        assertEquals(suffix, mName.getSuffix());
+    }
+}
diff --git a/tests/src/com/android/providers/contacts/RestrictionExceptionsTest.java b/tests/src/com/android/providers/contacts/RestrictionExceptionsTest.java
new file mode 100644
index 0000000..aad267f
--- /dev/null
+++ b/tests/src/com/android/providers/contacts/RestrictionExceptionsTest.java
@@ -0,0 +1,346 @@
+/*
+ * Copyright (C) 2009 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;
+
+import static com.android.providers.contacts.ContactsActor.PACKAGE_BLUE;
+import static com.android.providers.contacts.ContactsActor.PACKAGE_GREEN;
+import static com.android.providers.contacts.ContactsActor.PACKAGE_GREY;
+import static com.android.providers.contacts.ContactsActor.PACKAGE_RED;
+
+import android.content.ContentUris;
+import android.content.Context;
+import android.database.Cursor;
+import android.net.Uri;
+import android.provider.BaseColumns;
+import android.provider.ContactsContract.Aggregates;
+import android.provider.ContactsContract.Contacts;
+import android.provider.ContactsContract.Data;
+import android.provider.ContactsContract.RestrictionExceptions;
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.LargeTest;
+
+/**
+ * Unit tests for {@link RestrictionExceptions}.
+ *
+ * Run the test like this:
+ * <code>
+ * adb shell am instrument -w \
+ *         com.android.providers.contacts.tests/android.test.InstrumentationTestRunner
+ * </code>
+ */
+@LargeTest
+public class RestrictionExceptionsTest extends AndroidTestCase {
+    private static final String TAG = "RestrictionExceptionsTest";
+
+    private static ContactsActor mGrey;
+    private static ContactsActor mRed;
+    private static ContactsActor mGreen;
+    private static ContactsActor mBlue;
+
+    private static final String PHONE_GREY = "555-1111";
+    private static final String PHONE_RED = "555-2222";
+    private static final String PHONE_GREEN = "555-3333";
+    private static final String PHONE_BLUE = "555-4444";
+
+    private static final String GENERIC_NAME = "Smith";
+
+    public RestrictionExceptionsTest() {
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        final Context overallContext = this.getContext();
+
+        // Build each of our specific actors in their own Contexts
+        mGrey = new ContactsActor(overallContext, PACKAGE_GREY);
+        mRed = new ContactsActor(overallContext, PACKAGE_RED);
+        mGreen = new ContactsActor(overallContext, PACKAGE_GREEN);
+        mBlue = new ContactsActor(overallContext, PACKAGE_BLUE);
+    }
+
+    /**
+     * Create various contacts that are both open and restricted, and assert
+     * that both {@link Contacts#IS_RESTRICTED} and
+     * {@link RestrictionExceptions} are being applied correctly.
+     */
+    public void testDataRestriction() {
+
+        // Clear all previous data before starting this test
+        mGrey.provider.wipeData();
+
+        // Grey creates an unprotected contact
+        long greyContact = mGrey.createContact(false);
+        long greyData = mGrey.createPhone(greyContact, PHONE_GREY);
+        long greyAgg = mGrey.getAggregateForContact(greyContact);
+
+        // Assert that both Grey and Blue can read contact
+        assertTrue("Owner of unrestricted contact unable to read",
+                (mGrey.getDataCountForAggregate(greyAgg) == 1));
+        assertTrue("Non-owner of unrestricted contact unable to read",
+                (mBlue.getDataCountForAggregate(greyAgg) == 1));
+
+        // Red grants protected access to itself
+        mRed.updateException(PACKAGE_RED, PACKAGE_RED, true);
+
+        // Red creates a protected contact
+        long redContact = mRed.createContact(true);
+        long redData = mRed.createPhone(redContact, PHONE_RED);
+        long redAgg = mRed.getAggregateForContact(redContact);
+
+        // Assert that only Red can read contact
+        assertTrue("Owner of restricted contact unable to read",
+                (mRed.getDataCountForAggregate(redAgg) == 1));
+        assertTrue("Non-owner of restricted contact able to read",
+                (mBlue.getDataCountForAggregate(redAgg) == 0));
+        assertTrue("Non-owner of restricted contact able to read",
+                (mGreen.getDataCountForAggregate(redAgg) == 0));
+
+        try {
+            // Blue tries to grant an exception for Red data, which should throw
+            // exception. If it somehow worked, fail this test.
+            mBlue.updateException(PACKAGE_RED, PACKAGE_BLUE, true);
+            fail("Non-owner able to grant restriction exception");
+
+        } catch (RuntimeException e) {
+        }
+
+        // Red grants exception to Blue for contact
+        mRed.updateException(PACKAGE_RED, PACKAGE_BLUE, true);
+
+        // Both Blue and Red can read Red contact, but still not Green
+        assertTrue("Owner of restricted contact unable to read",
+                (mRed.getDataCountForAggregate(redAgg) == 1));
+        assertTrue("Non-owner with restriction exception unable to read",
+                (mBlue.getDataCountForAggregate(redAgg) == 1));
+        assertTrue("Non-owner of restricted contact able to read",
+                (mGreen.getDataCountForAggregate(redAgg) == 0));
+
+        // Red revokes exception to Blue
+        mRed.updateException(PACKAGE_RED, PACKAGE_BLUE, false);
+
+        // Assert that only Red can read contact
+        assertTrue("Owner of restricted contact unable to read",
+                (mRed.getDataCountForAggregate(redAgg) == 1));
+        assertTrue("Non-owner of restricted contact able to read",
+                (mBlue.getDataCountForAggregate(redAgg) == 0));
+        assertTrue("Non-owner of restricted contact able to read",
+                (mGreen.getDataCountForAggregate(redAgg) == 0));
+
+    }
+
+    /**
+     * Create an aggregate that has multiple contacts with various levels of
+     * protected data, and ensure that {@link Aggregates#CONTENT_SUMMARY_URI}
+     * details don't expose {@link Contacts#IS_RESTRICTED} data.
+     */
+    public void testAggregateSummary() {
+
+        // Clear all previous data before starting this test
+        mGrey.provider.wipeData();
+
+        // Red grants exceptions to itself and Grey
+        mRed.updateException(PACKAGE_RED, PACKAGE_RED, true);
+        mRed.updateException(PACKAGE_RED, PACKAGE_GREY, true);
+
+        // Red creates a protected contact
+        long redContact = mRed.createContact(true);
+        long redName = mRed.createName(redContact, GENERIC_NAME);
+        long redPhone = mRed.createPhone(redContact, PHONE_RED);
+
+        // Blue grants exceptions to itself and Grey
+        mBlue.updateException(PACKAGE_BLUE, PACKAGE_BLUE, true);
+        mBlue.updateException(PACKAGE_BLUE, PACKAGE_GREY, true);
+
+        // Blue creates a protected contact
+        long blueContact = mBlue.createContact(true);
+        long blueName = mBlue.createName(blueContact, GENERIC_NAME);
+        long bluePhone = mBlue.createPhone(blueContact, PHONE_BLUE);
+
+        // Set the super-primary phone number to Red
+        mRed.setSuperPrimaryPhone(redPhone);
+
+        // Make sure both aggregates were joined
+        long singleAgg;
+        {
+            long redAgg = mRed.getAggregateForContact(redContact);
+            long blueAgg = mBlue.getAggregateForContact(blueContact);
+            assertTrue("Two contacts with identical name not aggregated correctly",
+                    (redAgg == blueAgg));
+            singleAgg = redAgg;
+        }
+
+        // Grey and Red querying summary should see Red phone. Blue shouldn't
+        // see any summary data, since it's own data is protected and it's not
+        // the super-primary. Green shouldn't know this aggregate exists.
+        assertTrue("Participant with restriction exception reading incorrect summary",
+                (mGrey.getPrimaryPhoneId(singleAgg) == redPhone));
+        assertTrue("Participant with super-primary restricted data reading incorrect summary",
+                (mRed.getPrimaryPhoneId(singleAgg) == redPhone));
+        assertTrue("Participant with non-super-primary restricted data reading incorrect summary",
+                (mBlue.getPrimaryPhoneId(singleAgg) == 0));
+        assertTrue("Non-participant able to discover aggregate existance",
+                (mGreen.getPrimaryPhoneId(singleAgg) == 0));
+
+        // Add an unprotected Grey contact into the mix
+        long greyContact = mGrey.createContact(false);
+        long greyName = mGrey.createName(greyContact, GENERIC_NAME);
+        long greyPhone = mGrey.createPhone(greyContact, PHONE_GREY);
+
+        // Set the super-primary phone number to Blue
+        mBlue.setSuperPrimaryPhone(bluePhone);
+
+        // Make sure all three aggregates were joined
+        {
+            long redAgg = mRed.getAggregateForContact(redContact);
+            long blueAgg = mBlue.getAggregateForContact(blueContact);
+            long greyAgg = mGrey.getAggregateForContact(greyContact);
+            assertTrue("Three contacts with identical name not aggregated correctly",
+                    (redAgg == blueAgg) && (blueAgg == greyAgg));
+            singleAgg = redAgg;
+        }
+
+        // Grey and Blue querying summary should see Blue phone. Red should see
+        // the Grey phone in its summary, since it's the unprotected fallback.
+        // Red doesn't see its own phone number because it's not super-primary,
+        // and is protected. Again, green shouldn't know this exists.
+        assertTrue("Participant with restriction exception reading incorrect summary",
+                (mGrey.getPrimaryPhoneId(singleAgg) == bluePhone));
+        assertTrue("Participant with non-super-primary restricted data reading incorrect summary",
+                (mRed.getPrimaryPhoneId(singleAgg) == greyPhone));
+        assertTrue("Participant with super-primary restricted data reading incorrect summary",
+                (mBlue.getPrimaryPhoneId(singleAgg) == bluePhone));
+        assertTrue("Non-participant couldn't find unrestricted primary through summary",
+                (mGreen.getPrimaryPhoneId(singleAgg) == greyPhone));
+
+    }
+
+    /**
+     * Create a contact that is completely restricted and isolated in its own
+     * aggregate, and make sure that another actor can't detect its existence.
+     */
+    public void testRestrictionSilence() {
+        Cursor cursor;
+
+        // Clear all previous data before starting this test
+        mGrey.provider.wipeData();
+
+        // Green grants exception to itself
+        mGreen.updateException(PACKAGE_GREEN, PACKAGE_GREEN, true);
+
+        // Green creates a protected contact
+        long greenContact = mGreen.createContact(true);
+        long greenData = mGreen.createPhone(greenContact, PHONE_GREEN);
+        long greenAgg = mGreen.getAggregateForContact(greenContact);
+
+        // AGGREGATES
+        cursor = mRed.resolver
+                .query(Aggregates.CONTENT_URI, Projections.PROJ_ID, null, null, null);
+        while (cursor.moveToNext()) {
+            assertTrue("Discovered restricted contact",
+                    (cursor.getLong(Projections.COL_ID) != greenAgg));
+        }
+        cursor.close();
+
+        // AGGREGATES_ID
+        cursor = mRed.resolver.query(ContentUris.withAppendedId(Aggregates.CONTENT_URI, greenAgg),
+                Projections.PROJ_ID, null, null, null);
+        assertTrue("Discovered restricted contact", (cursor.getCount() == 0));
+        cursor.close();
+
+        // AGGREGATES_DATA
+        cursor = mRed.resolver.query(Uri.withAppendedPath(ContentUris.withAppendedId(
+                Aggregates.CONTENT_URI, greenAgg), Aggregates.Data.CONTENT_DIRECTORY),
+                Projections.PROJ_ID, null, null, null);
+        assertTrue("Discovered restricted contact", (cursor.getCount() == 0));
+        cursor.close();
+
+        // AGGREGATES_SUMMARY
+        cursor = mRed.resolver.query(Aggregates.CONTENT_SUMMARY_URI, Projections.PROJ_ID, null,
+                null, null);
+        while (cursor.moveToNext()) {
+            assertTrue("Discovered restricted contact",
+                    (cursor.getLong(Projections.COL_ID) != greenAgg));
+        }
+        cursor.close();
+
+        // AGGREGATES_SUMMARY_ID
+        cursor = mRed.resolver.query(ContentUris.withAppendedId(Aggregates.CONTENT_SUMMARY_URI,
+                greenAgg), Projections.PROJ_ID, null, null, null);
+        assertTrue("Discovered restricted contact", (cursor.getCount() == 0));
+        cursor.close();
+
+        // TODO: AGGREGATES_SUMMARY_FILTER
+        // TODO: =========================
+
+        // TODO: AGGREGATION_SUGGESTIONS
+        // TODO: =======================
+
+        // CONTACTS
+        cursor = mRed.resolver.query(Contacts.CONTENT_URI, Projections.PROJ_ID, null, null, null);
+        while (cursor.moveToNext()) {
+            assertTrue("Discovered restricted contact",
+                    (cursor.getLong(Projections.COL_ID) != greenContact));
+        }
+        cursor.close();
+
+        // CONTACTS_ID
+        cursor = mRed.resolver.query(ContentUris
+                .withAppendedId(Contacts.CONTENT_URI, greenContact), Projections.PROJ_ID, null,
+                null, null);
+        assertTrue("Discovered restricted contact", (cursor.getCount() == 0));
+        cursor.close();
+
+        // CONTACTS_DATA
+        cursor = mRed.resolver.query(Uri.withAppendedPath(ContentUris.withAppendedId(
+                Contacts.CONTENT_URI, greenContact), Contacts.Data.CONTENT_DIRECTORY),
+                Projections.PROJ_ID, null, null, null);
+        assertTrue("Discovered restricted contact", (cursor.getCount() == 0));
+        cursor.close();
+
+        // TODO: CONTACTS_FILTER_EMAIL
+        // TODO: =====================
+
+        // DATA
+        cursor = mRed.resolver.query(Data.CONTENT_URI, Projections.PROJ_ID, null, null, null);
+        while (cursor.moveToNext()) {
+            assertTrue("Discovered restricted contact",
+                    (cursor.getLong(Projections.COL_ID) != greenData));
+        }
+        cursor.close();
+
+        // DATA_ID
+        cursor = mRed.resolver.query(ContentUris.withAppendedId(Data.CONTENT_URI, greenData),
+                Projections.PROJ_ID, null, null, null);
+        assertTrue("Discovered restricted contact", (cursor.getCount() == 0));
+        cursor.close();
+
+        // TODO: PHONE_LOOKUP
+        // TODO: ============
+
+    }
+
+    private interface Projections {
+        static final String[] PROJ_ID = new String[] {
+                BaseColumns._ID,
+        };
+
+        static final int COL_ID = 0;
+    }
+
+}
diff --git a/tests/src/com/android/providers/contacts/SynchronousContactsProvider2.java b/tests/src/com/android/providers/contacts/SynchronousContactsProvider2.java
new file mode 100644
index 0000000..fa3c2a6
--- /dev/null
+++ b/tests/src/com/android/providers/contacts/SynchronousContactsProvider2.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2009 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;
+
+import android.content.Context;
+
+/**
+ * A version of {@link ContactsProvider2} class that performs aggregation
+ * synchronously and wipes all data at construction time.
+ */
+public class SynchronousContactsProvider2 extends ContactsProvider2 {
+    private static Boolean sDataWiped = false;
+    private static OpenHelper mOpenHelper;
+
+    public SynchronousContactsProvider2() {
+        super(new SynchronousAggregationScheduler());
+    }
+
+    @Override
+    protected OpenHelper getOpenHelper(final Context context) {
+        if (mOpenHelper == null) {
+            mOpenHelper = new OpenHelper(context);
+        }
+        return mOpenHelper;
+    }
+
+    @Override
+    public boolean onCreate() {
+        boolean created = super.onCreate();
+        synchronized (sDataWiped) {
+            if (!sDataWiped) {
+                sDataWiped = true;
+                wipeData();
+            }
+        }
+        return created;
+    }
+
+    private static class SynchronousAggregationScheduler extends ContactAggregationScheduler {
+
+        @Override
+        public void start() {
+        }
+
+        @Override
+        public void stop() {
+        }
+
+        @Override
+        long currentTime() {
+            return 0;
+        }
+
+        @Override
+        void runDelayed() {
+            super.run();
+        }
+
+    }
+}
