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 8f967d2..d7de1fb 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -7,20 +7,50 @@
     <uses-permission android:name="android.permission.GET_ACCOUNTS" />
     <uses-permission android:name="android.permission.READ_SYNC_STATS" />
     <uses-permission android:name="android.permission.INTERNET" />
+    <uses-permission android:name="android.permission.USE_CREDENTIALS" />
     <uses-permission android:name="com.google.android.googleapps.permission.GOOGLE_AUTH" />
     <uses-permission android:name="com.google.android.googleapps.permission.GOOGLE_AUTH.cp" />
     <uses-permission android:name="android.permission.SUBSCRIBED_FEEDS_READ" />
     <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">
-            <path-permission android:path="/people/search_suggest_query"
+        android:label="@string/app_label"
+        android:icon="@drawable/app_icon">
+
+        <provider android:name="ContactsProvider" 
+            android:authorities="contacts"
+            android:syncable="false" android:multiprocess="false"
+            android:readPermission="android.permission.READ_CONTACTS"
+            android:writePermission="android.permission.WRITE_CONTACTS">
+            <path-permission
+                    android:path="/people/search_suggest_query"
                     android:readPermission="android.permission.GLOBAL_SEARCH" />
         </provider>
+
+        <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">
+            <path-permission
+                    android:path="/contacts/search_suggest_query"
+                    android:readPermission="android.permission.GLOBAL_SEARCH" />
+        </provider>
+
+        <provider android:name="CallLogProvider"
+            android:authorities="call_log"
+            android:syncable="false" android:multiprocess="false"
+            android:readPermission="android.permission.READ_CONTACTS"
+            android:writePermission="android.permission.WRITE_CONTACTS">
+        </provider>
+
+        <!-- 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/CallLogProvider.java b/src/com/android/providers/contacts/CallLogProvider.java
new file mode 100644
index 0000000..fbda970
--- /dev/null
+++ b/src/com/android/providers/contacts/CallLogProvider.java
@@ -0,0 +1,190 @@
+/*
+ * 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.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.DatabaseUtils;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteQueryBuilder;
+import android.net.Uri;
+import android.provider.CallLog;
+import android.provider.CallLog.Calls;
+
+import java.util.HashMap;
+
+/**
+ * Call log content provider.
+ */
+public class CallLogProvider extends ContentProvider {
+
+    private static final int CALLS = 1;
+
+    private static final int CALLS_ID = 2;
+
+    private static final int CALLS_FILTER = 3;
+
+    private static final UriMatcher sURIMatcher = new UriMatcher(UriMatcher.NO_MATCH);
+    static {
+        sURIMatcher.addURI(CallLog.AUTHORITY, "calls", CALLS);
+        sURIMatcher.addURI(CallLog.AUTHORITY, "calls/#", CALLS_ID);
+        sURIMatcher.addURI(CallLog.AUTHORITY, "calls/filter/*", CALLS_FILTER);
+    }
+
+    private static final HashMap<String, String> sCallsProjectionMap;
+    static {
+
+        // Calls projection map
+        sCallsProjectionMap = new HashMap<String, String>();
+        sCallsProjectionMap.put(Calls._ID, Calls._ID);
+        sCallsProjectionMap.put(Calls.NUMBER, Calls.NUMBER);
+        sCallsProjectionMap.put(Calls.DATE, Calls.DATE);
+        sCallsProjectionMap.put(Calls.DURATION, Calls.DURATION);
+        sCallsProjectionMap.put(Calls.TYPE, Calls.TYPE);
+        sCallsProjectionMap.put(Calls.NEW, Calls.NEW);
+        sCallsProjectionMap.put(Calls.CACHED_NAME, Calls.CACHED_NAME);
+        sCallsProjectionMap.put(Calls.CACHED_NUMBER_TYPE, Calls.CACHED_NUMBER_TYPE);
+        sCallsProjectionMap.put(Calls.CACHED_NUMBER_LABEL, Calls.CACHED_NUMBER_LABEL);
+    }
+
+    private OpenHelper mOpenHelper;
+    private DatabaseUtils.InsertHelper mCallsInserter;
+
+    @Override
+    public boolean onCreate() {
+        final Context context = getContext();
+
+        mOpenHelper = getOpenHelper(context);
+        SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+        mCallsInserter = new DatabaseUtils.InsertHelper(db, Tables.CALLS);
+
+        return true;
+    }
+
+    /* Visible for testing */
+    protected OpenHelper getOpenHelper(final Context context) {
+        return OpenHelper.getInstance(context);
+    }
+
+    @Override
+    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
+            String sortOrder) {
+        SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
+        int match = sURIMatcher.match(uri);
+        switch (match) {
+            case CALLS: {
+                qb.setTables("calls");
+                qb.setProjectionMap(sCallsProjectionMap);
+                break;
+            }
+
+            case CALLS_ID: {
+                qb.setTables("calls");
+                qb.setProjectionMap(sCallsProjectionMap);
+                qb.appendWhere("calls._id=");
+                qb.appendWhere(uri.getPathSegments().get(1));
+                break;
+            }
+
+            case CALLS_FILTER: {
+                qb.setTables("calls");
+                qb.setProjectionMap(sCallsProjectionMap);
+                String phoneNumber = uri.getPathSegments().get(2);
+                qb.appendWhere("PHONE_NUMBERS_EQUAL(number, ");
+                qb.appendWhereEscapeString(phoneNumber);
+                qb.appendWhere(")");
+                break;
+            }
+
+            default:
+                throw new IllegalArgumentException("Unknown URL " + uri);
+        }
+
+        final SQLiteDatabase db = mOpenHelper.getReadableDatabase();
+        Cursor c = qb.query(db, projection, selection, selectionArgs, null, null, sortOrder, null);
+        if (c != null) {
+            c.setNotificationUri(getContext().getContentResolver(), CallLog.CONTENT_URI);
+        }
+        return c;
+    }
+
+    @Override
+    public String getType(Uri uri) {
+        int match = sURIMatcher.match(uri);
+        switch (match) {
+            case CALLS:
+                return Calls.CONTENT_TYPE;
+            case CALLS_ID:
+                return Calls.CONTENT_ITEM_TYPE;
+            case CALLS_FILTER:
+                return Calls.CONTENT_TYPE;
+            default:
+                throw new IllegalArgumentException("Unknown URI: " + uri);
+        }
+    }
+
+    @Override
+    public Uri insert(Uri uri, ContentValues values) {
+        long rowId = mCallsInserter.insert(values);
+        if (rowId > 0) {
+            return ContentUris.withAppendedId(uri, rowId);
+        }
+        return null;
+    }
+
+    @Override
+    public int update(Uri url, ContentValues values, String selection, String[] selectionArgs) {
+        final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+        String where;
+        final int matchedUriId = sURIMatcher.match(url);
+        switch (matchedUriId) {
+            case CALLS:
+                where = selection;
+                break;
+
+            case CALLS_ID:
+                where = DatabaseUtils.concatenateWhere(selection, Calls._ID + "="
+                        + url.getPathSegments().get(1));
+                break;
+
+            default:
+                throw new UnsupportedOperationException("Cannot update URL: " + url);
+        }
+
+        return db.update(Tables.CALLS, values, where, selectionArgs);
+    }
+
+    @Override
+    public int delete(Uri uri, String selection, String[] selectionArgs) {
+        final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+
+        final int matchedUriId = sURIMatcher.match(uri);
+        switch (matchedUriId) {
+            case CALLS:
+                return db.delete(Tables.CALLS, selection, selectionArgs);
+
+            default:
+                throw new UnsupportedOperationException("Cannot delete that URL: " + uri);
+        }
+    }
+}
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..ad70640
--- /dev/null
+++ b/src/com/android/providers/contacts/ContactAggregator.java
@@ -0,0 +1,1226 @@
+/*
+ * 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.AggregationExceptionColumns;
+import com.android.providers.contacts.OpenHelper.Clauses;
+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.RawContactsColumns;
+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.provider.ContactsContract.AggregationExceptions;
+import android.provider.ContactsContract.CommonDataKinds;
+import android.provider.ContactsContract.Contacts;
+import android.provider.ContactsContract.Data;
+import android.provider.ContactsContract.RawContacts;
+import android.provider.ContactsContract.CommonDataKinds.Email;
+import android.provider.ContactsContract.CommonDataKinds.Nickname;
+import android.provider.ContactsContract.CommonDataKinds.Phone;
+import android.provider.ContactsContract.CommonDataKinds.Photo;
+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, RawContacts.CONTACT_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_CONTACT_ID = 2;
+
+    private static final String[] NAME_LOOKUP_COLUMNS = new String[] {
+            RawContacts.CONTACT_ID, NameLookupColumns.NORMALIZED_NAME, NameLookupColumns.NAME_TYPE
+    };
+
+    private static final int COL_NAME_LOOKUP_CONTACT_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.RAW_CONTACT_ID1,
+            "raw_contacts1." + RawContacts.CONTACT_ID,
+            "raw_contacts2." + RawContacts.CONTACT_ID
+    };
+
+    private static final int COL_TYPE = 0;
+    private static final int COL_RAW_CONTACT_ID1 = 1;
+    private static final int COL_CONTACT_ID1 = 2;
+    private static final int COL_CONTACT_ID2 = 3;
+
+    private static final String[] CONTACT_ID_COLUMN = new String[] { RawContacts._ID };
+
+    private static final String[] CONTACT_OPTIONS_COLUMNS = new String[] {
+            RawContacts.CUSTOM_RINGTONE,
+            RawContacts.SEND_TO_VOICEMAIL,
+            RawContacts.LAST_TIME_CONTACTED,
+            RawContacts.TIMES_CONTACTED,
+            RawContacts.STARRED,
+    };
+
+    private static final int COL_CUSTOM_RINGTONE = 0;
+    private static final int COL_SEND_TO_VOICEMAIL = 1;
+    private static final int COL_LAST_TIME_CONTACTED = 2;
+    private static final int COL_TIMES_CONTACTED = 3;
+    private static final int COL_STARRED = 4;
+
+    private static final String[] CONTACT_ID_COLUMNS = new String[]{ RawContacts.CONTACT_ID };
+    private static final int COL_CONTACT_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;
+
+    /**
+     * 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 RawContacts#CONTACT_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.RAW_CONTACTS, new String[]{RawContacts._ID},
+                RawContacts.CONTACT_ID + " IS NULL AND "
+                        + RawContacts.AGGREGATION_MODE + "=" + RawContacts.AGGREGATION_MODE_DEFAULT,
+                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 rawContactId) {
+        final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+        db.beginTransaction();
+        try {
+            aggregateContact(db, rawContactId);
+            db.setTransactionSuccessful();
+        } finally {
+            db.endTransaction();
+        }
+    }
+
+    /**
+     * Synchronously aggregate the specified contact assuming an open transaction.
+     */
+    public void aggregateContact(SQLiteDatabase db, long rawContactId) {
+        MatchCandidateList candidates = new MatchCandidateList();
+        ContactMatcher matcher = new ContactMatcher();
+        ContentValues values = new ContentValues();
+        aggregateContact(db, rawContactId, candidates, matcher, values);
+    }
+
+    /**
+     * Marks the specified contact for (re)aggregation.
+     *
+     * @param rawContactId contact ID that needs to be (re)aggregated
+     * @return The contact aggregation mode:
+     *         {@link RawContacts#AGGREGATION_MODE_DEFAULT},
+     *         {@link RawContacts#AGGREGATION_MODE_IMMEDIATE} or
+     *         {@link RawContacts#AGGREGATION_MODE_DISABLED}.
+     */
+    public int markContactForAggregation(long rawContactId) {
+        final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+
+        int aggregationMode = mOpenHelper.getAggregationMode(rawContactId);
+        if (aggregationMode == RawContacts.AGGREGATION_MODE_DISABLED) {
+            return aggregationMode;
+        }
+
+        long contactId = mOpenHelper.getContactId(rawContactId);
+        if (contactId == 0) {
+            // Not aggregated
+            return aggregationMode;
+        }
+
+        mOpenHelper.removeContactIfSingleton(rawContactId);
+
+        // TODO compiled statements
+
+        // Clear out data used for aggregation - we will recreate it during aggregation
+        db.execSQL("DELETE FROM " + Tables.NAME_LOOKUP + " WHERE "
+                + NameLookupColumns.RAW_CONTACT_ID + "=" + rawContactId);
+
+        // Clear out the contact ID field on the contact
+        ContentValues values = new ContentValues();
+        values.putNull(RawContacts.CONTACT_ID);
+        db.update(Tables.RAW_CONTACTS, values, RawContacts._ID + "=" + rawContactId, null);
+
+        return aggregationMode;
+    }
+
+    public void updateAggregateData(long contactId) {
+        final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+        final ContentValues values = new ContentValues();
+        updateAggregateData(db, contactId, values);
+    }
+
+    /**
+     * Given a specific raw contact, finds all matching aggregate contacts and chooses the one
+     * with the highest match score.  If no such contact is found, creates a new contact.
+     */
+    /* package */ synchronized void aggregateContact(SQLiteDatabase db, long rawContactId,
+            MatchCandidateList candidates, ContactMatcher matcher, ContentValues values) {
+        candidates.clear();
+        matcher.clear();
+
+        long contactId = pickBestMatchBasedOnExceptions(db, rawContactId, matcher);
+        if (contactId == -1) {
+            contactId = pickBestMatchBasedOnData(db, rawContactId, candidates, matcher);
+        }
+
+        boolean newAgg = false;
+
+        if (contactId == -1) {
+            newAgg = true;
+            ContentValues contactValues = new ContentValues();
+            contactValues.put(Contacts.DISPLAY_NAME, "");
+            contactId = db.insert(Tables.CONTACTS, Contacts.DISPLAY_NAME, contactValues);
+        }
+
+        updateContactAggregationData(db, rawContactId, candidates, values);
+        mOpenHelper.setContactId(rawContactId, contactId);
+
+        updateAggregateData(db, contactId, values);
+        updatePrimaries(db, contactId, rawContactId, newAgg);
+        mOpenHelper.updateContactVisible(contactId);
+
+    }
+
+    /**
+     * Computes match scores based on exceptions entered by the user: always match and never match.
+     * Returns the aggregate contact with the always match exception if any.
+     */
+    private long pickBestMatchBasedOnExceptions(SQLiteDatabase db, long rawContactId,
+            ContactMatcher matcher) {
+        final Cursor c = db.query(Tables.AGGREGATION_EXCEPTIONS_JOIN_RAW_CONTACTS_TWICE,
+                AGGREGATE_EXCEPTION_JOIN_CONTACT_TWICE_COLUMNS,
+                AggregationExceptionColumns.RAW_CONTACT_ID1 + "=" + rawContactId
+                        + " OR " + AggregationExceptionColumns.RAW_CONTACT_ID2 + "=" + rawContactId,
+                null, null, null, null);
+
+        try {
+            while (c.moveToNext()) {
+                int type = c.getInt(COL_TYPE);
+                long rawContactId1 = c.getLong(COL_RAW_CONTACT_ID1);
+                long contactId = -1;
+                if (rawContactId == rawContactId1) {
+                    if (!c.isNull(COL_CONTACT_ID2)) {
+                        contactId = c.getLong(COL_CONTACT_ID2);
+                    }
+                } else {
+                    if (!c.isNull(COL_CONTACT_ID1)) {
+                        contactId = c.getLong(COL_CONTACT_ID1);
+                    }
+                }
+                if (contactId != -1) {
+                    if (type == AggregationExceptions.TYPE_KEEP_IN) {
+                        return contactId;
+                    } else {
+                        matcher.keepOut(contactId);
+                    }
+                }
+            }
+        } finally {
+            c.close();
+        }
+
+        return -1;
+    }
+
+    /**
+     * Picks the best matching contact based on matches between data elements.  It considers
+     * name match to be primary and phone, email etc matches to be secondary.  A good primary
+     * match triggers aggregation, while a good secondary match only triggers aggregation in
+     * the absence of a strong primary mismatch.
+     * <p>
+     * Consider these examples:
+     * <p>
+     * John Doe with phone number 111-111-1111 and Jon Doe with phone number 111-111-1111 should
+     * be aggregated (same number, similar names).
+     * <p>
+     * John Doe with phone number 111-111-1111 and Deborah Doe with phone number 111-111-1111 should
+     * not be aggregated (same number, different names).
+     */
+    private long pickBestMatchBasedOnData(SQLiteDatabase db, long rawContactId,
+            MatchCandidateList candidates, ContactMatcher matcher) {
+
+        updateMatchScoresBasedOnDataMatches(db, rawContactId, 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 contact based on secondary data matches.  The method loads
+     * structured names for all candidate contacts and recomputes match scores using approximate
+     * matching.
+     */
+    private long pickBestMatchBasedOnSecondaryData(SQLiteDatabase db,
+            MatchCandidateList candidates, ContactMatcher matcher) {
+        List<Long> secondaryContactIds = matcher.prepareSecondaryMatchCandidates(
+                ContactMatcher.SCORE_THRESHOLD_PRIMARY);
+        if (secondaryContactIds == null) {
+            return -1;
+        }
+
+        StringBuilder selection = new StringBuilder();
+        selection.append(RawContacts.CONTACT_ID).append(" IN (");
+        for (int i = 0; i < secondaryContactIds.size(); i++) {
+            if (i != 0) {
+                selection.append(',');
+            }
+            selection.append(secondaryContactIds.get(i));
+        }
+        selection.append(") AND " + MimetypesColumns.MIMETYPE + "='"
+                + StructuredName.CONTENT_ITEM_TYPE + "'");
+
+        final Cursor c = db.query(Tables.DATA_JOIN_MIMETYPE_RAW_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 contactId = c.getLong(COL_DATA_CONTACT_CONTACT_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(contactId,
+                                    nameCandidate.mLookupType, nameCandidate.mName,
+                                    candidate.mLookupType, candidate.mName, true);
+                        }
+                    }
+                }
+            }
+        } finally {
+            c.close();
+        }
+
+        return matcher.pickBestMatch(ContactMatcher.SCORE_THRESHOLD_SECONDARY);
+    }
+
+    /**
+     * Computes scores for contacts that have matching data rows.
+     */
+    private void updateMatchScoresBasedOnDataMatches(SQLiteDatabase db, long rawContactId,
+            int mode, MatchCandidateList candidates, ContactMatcher matcher) {
+
+        final Cursor c = db.query(Tables.DATA_JOIN_MIMETYPE_RAW_CONTACTS,
+                DATA_JOIN_MIMETYPE_COLUMNS,
+                Data.RAW_CONTACT_ID + "=" + rawContactId + " AND ("
+                        + 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(RawContacts.CONTACT_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 " + RawContacts.CONTACT_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_RAW_CONTACTS, NAME_LOOKUP_COLUMNS,
+                selection, null, null, null, null);
+
+        try {
+            while (c.moveToNext()) {
+                Long contactId = c.getLong(COL_NAME_LOOKUP_CONTACT_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(contactId, 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, CONTACT_ID_COLUMNS,
+                RawContacts.CONTACT_ID + " NOT NULL", null, null, null, null);
+        try {
+            while (c.moveToNext()) {
+                long contactId = c.getLong(COL_CONTACT_ID);
+                matcher.updateScoreWithPhoneNumberMatch(contactId);
+            }
+        } 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_RAW_CONTACTS, CONTACT_ID_COLUMNS,
+                Clauses.WHERE_EMAIL_MATCHES + " AND " + RawContacts.CONTACT_ID + " NOT NULL",
+                new String[]{address}, null, null, null);
+        try {
+            while (c.moveToNext()) {
+                long contactId = c.getLong(COL_CONTACT_ID);
+                matcher.updateScoreWithEmailMatch(contactId);
+            }
+        } 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_RAW_CONTACTS, CONTACT_ID_COLUMNS,
+                NameLookupColumns.NAME_TYPE + "=" + NameLookupType.NICKNAME + " AND "
+                        + NameLookupColumns.NORMALIZED_NAME + "='" + normalized + "' AND "
+                        + RawContacts.CONTACT_ID + " NOT NULL",
+                null, null, null, null, null);
+        try {
+            while (c.moveToNext()) {
+                long contactId = c.getLong(COL_CONTACT_ID);
+                matcher.updateScoreWithNicknameMatch(contactId);
+            }
+        } finally {
+            c.close();
+        }
+    }
+
+    /**
+     * Prepares the supplied contact for aggregation with other contacts by (re)computing
+     * match lookup keys.
+     */
+    private void updateContactAggregationData(SQLiteDatabase db, long rawContactId,
+            MatchCandidateList candidates, ContentValues values) {
+        candidates.clear();
+
+        final Cursor c = db.query(Tables.DATA_JOIN_MIMETYPES,
+                DATA_JOIN_MIMETYPE_COLUMNS,
+                DatabaseUtils.concatenateWhere(Data.RAW_CONTACT_ID + "=" + rawContactId,
+                        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(rawContactId, candidate.mLookupType, candidate.mName);
+        }
+    }
+
+    /**
+     * Updates aggregate-level data from constituent contacts.
+     */
+    private void updateAggregateData(final SQLiteDatabase db, long contactId,
+            final ContentValues values) {
+        updateDisplayName(db, contactId, values);
+        updateSendToVoicemailAndRingtone(db, contactId);
+        updatePhotoId(db, contactId, values);
+    }
+
+    /**
+     * Updates the contact record's {@link Contacts#DISPLAY_NAME} field. If none of the
+     * constituent raw contacts has a suitable name, leaves the aggregate contact record unchanged.
+     */
+    private void updateDisplayName(SQLiteDatabase db, long contactId, ContentValues values) {
+        String displayName = getBestDisplayName(db, contactId);
+
+        // 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(Contacts.DISPLAY_NAME, displayName);
+        db.update(Tables.CONTACTS, values, Contacts._ID + "=" + contactId, null);
+    }
+
+    private void updatePhotoId(SQLiteDatabase db, long contactId, ContentValues values) {
+        int photoId = choosePhotoId(db, contactId);
+
+        if (photoId == -1) {
+            return;
+        }
+
+        values.clear();
+        values.put(Contacts.PHOTO_ID, photoId);
+        db.update(Tables.CONTACTS, values, Contacts._ID + "=" + contactId, null);
+    }
+
+    /**
+     * Updates the various {@link ContactsColumns} primary values based on the
+     * newly joined {@link RawContacts} 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 rawContactId, 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.CONTACTS, Projections.PROJ_CONTACT_PRIMARIES,
+                    Contacts._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;
+        boolean candidateIsRestricted = false;
+
+        // Find primary data items from newly-joined contact, returning one
+        // candidate for each mimetype.
+        try {
+            cursor = db.query(Tables.DATA_JOIN_PACKAGES_MIMETYPES_RAW_CONTACTS,
+                    Projections.PROJ_DATA,
+                    Data.RAW_CONTACT_ID + "=" + rawContactId + " 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);
+
+                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 contact, and single child is restricted, then mark
+        // contact as being protected by package. Otherwise set as null if
+        // multiple under contact or not restricted.
+        values.put(ContactsColumns.SINGLE_IS_RESTRICTED, (newAgg && candidateIsRestricted) ? 1
+                : 0);
+
+        // 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(ContactsColumns.OPTIMAL_PRIMARY_PHONE_ID, candidatePhone);
+                values.put(ContactsColumns.OPTIMAL_PRIMARY_PHONE_IS_RESTRICTED,
+                        candidateIsRestricted ? 1 : 0);
+            }
+
+            // Also promote to unrestricted value, if none provided yet.
+            if (!hasFallbackPhone && !candidateIsRestricted) {
+                values.put(ContactsColumns.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(ContactsColumns.OPTIMAL_PRIMARY_EMAIL_ID, candidateEmail);
+                values.put(ContactsColumns.OPTIMAL_PRIMARY_EMAIL_IS_RESTRICTED,
+                        candidateIsRestricted ? 1 : 0);
+            }
+
+            // Also promote to unrestricted value, if none provided yet.
+            if (!hasFallbackEmail && !candidateIsRestricted) {
+                values.put(ContactsColumns.FALLBACK_PRIMARY_EMAIL_ID, candidateEmail);
+            }
+        }
+
+        // Only write updated contact values if we made changes.
+        if (values.size() > 0) {
+            Log.d(TAG, "some sort of promotion is going on: " + values.toString());
+            db.update(Tables.CONTACTS, values, Contacts._ID + "=" + aggId, null);
+        }
+
+    }
+
+    /**
+     * Computes display name for the given contact.  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 contactId) {
+        String bestDisplayName = null;
+
+        final Cursor c = db.query(Tables.RAW_CONTACTS, new String[] {RawContactsColumns.DISPLAY_NAME},
+                RawContacts.CONTACT_ID + "=" + contactId, null, null, null, null);
+
+        try {
+            while (c.moveToNext()) {
+                String displayName = c.getString(0);
+                if (!TextUtils.isEmpty(displayName)) {
+                    if (bestDisplayName == null) {
+                        bestDisplayName = displayName;
+                    } else {
+                        if (NameNormalizer.compareComplexity(displayName, bestDisplayName) > 0) {
+                            bestDisplayName = displayName;
+                        }
+                    }
+                }
+            }
+        } finally {
+            c.close();
+        }
+        return bestDisplayName;
+    }
+
+    /**
+     * Iterates over the photos associated with contact defined by contactId, and chooses one
+     * to be associated with the contact. Initially this just chooses the first photo in a list
+     * sorted by account name.
+     */
+    private int choosePhotoId(SQLiteDatabase db, long contactId) {
+        int chosenPhotoId = -1;
+        String chosenAccount = null;
+
+        final Cursor c = db.query(Tables.DATA_JOIN_PACKAGES_MIMETYPES_RAW_CONTACTS_CONTACTS,
+                new String[] {"data._id AS _id", RawContacts.ACCOUNT_NAME},
+                DatabaseUtils.concatenateWhere(RawContacts.CONTACT_ID + "=" + contactId,
+                        Data.MIMETYPE + "='" + Photo.CONTENT_ITEM_TYPE + "'"),
+                null, null, null, null);
+
+        try {
+            while (c.moveToNext()) {
+                int photoId = c.getInt(0);
+                String account = c.getString(1);
+                if (chosenAccount == null) {
+                    chosenAccount = account;
+                    chosenPhotoId = photoId;
+                } else {
+                    if (account.compareToIgnoreCase(chosenAccount) < 0 ) {
+                        chosenAccount = account;
+                        chosenPhotoId = photoId;
+                    }
+                }
+            }
+        } finally {
+            c.close();
+        }
+        return chosenPhotoId;
+    }
+
+    /**
+     * Updates the contact's send-to-voicemail and custom-ringtone options based on
+     * constituent contacts' options.
+     */
+    private void updateSendToVoicemailAndRingtone(SQLiteDatabase db, long contactId) {
+        int totalContactCount = 0;
+        int contactSendToVoicemail = 0;
+        String contactCustomRingtone = null;
+        long contactLastTimeContacted = 0;
+        int contactTimesContacted = 0;
+        boolean contactStarred = false;
+
+        final Cursor c = db.query(Tables.RAW_CONTACTS, CONTACT_OPTIONS_COLUMNS,
+                RawContacts.CONTACT_ID + "=" + contactId, 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) {
+                        contactSendToVoicemail++;
+                    }
+                }
+
+                if (contactCustomRingtone == null && !c.isNull(COL_CUSTOM_RINGTONE)) {
+                    contactCustomRingtone = c.getString(COL_CUSTOM_RINGTONE);
+                }
+
+                long lastTimeContacted = c.getLong(COL_LAST_TIME_CONTACTED);
+                if (lastTimeContacted > contactLastTimeContacted) {
+                    contactLastTimeContacted = lastTimeContacted;
+                }
+
+                int timesContacted = c.getInt(COL_TIMES_CONTACTED);
+                if (timesContacted > contactTimesContacted) {
+                    contactTimesContacted = timesContacted;
+                }
+
+                contactStarred |= (c.getInt(COL_STARRED) != 0);
+            }
+        } finally {
+            c.close();
+        }
+
+        ContentValues values = new ContentValues(2);
+        values.put(Contacts.SEND_TO_VOICEMAIL, totalContactCount == contactSendToVoicemail);
+        values.put(Contacts.CUSTOM_RINGTONE, contactCustomRingtone);
+        values.put(Contacts.LAST_TIME_CONTACTED, contactLastTimeContacted);
+        values.put(Contacts.TIMES_CONTACTED, contactTimesContacted);
+        values.put(Contacts.STARRED, contactStarred);
+
+        db.update(Tables.CONTACTS, values, Contacts._ID + "=" + contactId, null);
+    }
+
+    /**
+     * Finds matching contacts and returns a cursor on those.
+     */
+    public Cursor queryAggregationSuggestions(long contactId, 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 = findMatchingContacts(db, contactId, maxSuggestions);
+            c = queryMatchingContacts(db, contactId, projection, projectionMap, bestMatches);
+            db.setTransactionSuccessful();
+        } finally {
+            db.endTransaction();
+        }
+        return c;
+    }
+
+    /**
+     * Loads contacts with specified IDs and returns them in the order of IDs in the
+     * supplied list.
+     */
+    private Cursor queryMatchingContacts(final SQLiteDatabase db, long contactId,
+            String[] projection, HashMap<String, String> projectionMap,
+            List<MatchScore> bestMatches) {
+
+        StringBuilder selection = new StringBuilder();
+        selection.append(Contacts._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.getContactId());
+        }
+        selection.append(")");
+
+        final SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
+        qb.setTables(Tables.CONTACTS);
+        qb.setProjectionMap(projectionMap);
+
+        final Cursor cursor = qb.query(db, projection, selection.toString(), null, null, null,
+                Contacts._ID);
+
+        ArrayList<Long> sortedContactIds = new ArrayList<Long>(bestMatches.size());
+        for (MatchScore matchScore : bestMatches) {
+            sortedContactIds.add(matchScore.getContactId());
+        }
+
+        Collections.sort(sortedContactIds);
+
+        int[] positionMap = new int[bestMatches.size()];
+        for (int i = 0; i < positionMap.length; i++) {
+            long id = bestMatches.get(i).getContactId();
+            positionMap[i] = sortedContactIds.indexOf(id);
+        }
+
+        return new ReorderingCursorWrapper(cursor, positionMap);
+    }
+
+    /**
+     * Finds contacts with data matches and returns a list of {@link MatchScore}'s in the
+     * descending order of match score.
+     */
+    private List<MatchScore> findMatchingContacts(final SQLiteDatabase db,
+            long contactId, int maxSuggestions) {
+
+        MatchCandidateList candidates = new MatchCandidateList();
+        ContactMatcher matcher = new ContactMatcher();
+
+        // Don't aggregate a contact with itself
+        matcher.keepOut(contactId);
+
+        final Cursor c = db.query(Tables.RAW_CONTACTS, CONTACT_ID_COLUMN,
+                RawContacts.CONTACT_ID + "=" + contactId, null, null, null, null);
+        try {
+            while (c.moveToNext()) {
+                long rawContactId = c.getLong(0);
+                updateMatchScoresBasedOnDataMatches(db, rawContactId, 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_CONTACT_PRIMARIES = new String[] {
+                ContactsColumns.OPTIMAL_PRIMARY_PHONE_ID,
+                ContactsColumns.FALLBACK_PRIMARY_PHONE_ID,
+                ContactsColumns.OPTIMAL_PRIMARY_EMAIL_ID,
+                ContactsColumns.FALLBACK_PRIMARY_EMAIL_ID,
+                ContactsColumns.SINGLE_IS_RESTRICTED,
+        };
+
+        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_IS_RESTRICTED = 4;
+
+        static final String[] PROJ_DATA = new String[] {
+                Tables.DATA + "." + Data._ID,
+                Data.MIMETYPE,
+                RawContacts.IS_RESTRICTED,
+        };
+
+        static final int COL_DATA_ID = 0;
+        static final int COL_DATA_MIMETYPE = 1;
+        static final int COL_IS_RESTRICTED = 2;
+
+        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..6ab98dd
--- /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 contact.  Used in an
+     * contactId - MatchScore map.
+     */
+    public static class MatchScore implements Comparable<MatchScore> {
+        private long mContactId;
+        private boolean mKeepIn;
+        private boolean mKeepOut;
+        private int mPrimaryScore;
+        private int mSecondaryScore;
+        private int mMatchCount;
+
+        public MatchScore(long contactId) {
+            this.mContactId = contactId;
+        }
+
+        public void reset(long contactId) {
+            this.mContactId = contactId;
+            mKeepIn = false;
+            mKeepOut = false;
+            mPrimaryScore = 0;
+            mSecondaryScore = 0;
+            mMatchCount = 0;
+        }
+
+        public long getContactId() {
+            return mContactId;
+        }
+
+        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 contacts 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 mContactId + ": " + 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 contactId) {
+        MatchScore matchingScore = mScores.get(contactId);
+        if (matchingScore == null) {
+            if (mScoreList.size() > mScoreCount) {
+                matchingScore = mScoreList.get(mScoreCount);
+                matchingScore.reset(contactId);
+            } else {
+                matchingScore = new MatchScore(contactId);
+                mScoreList.add(matchingScore);
+            }
+            mScoreCount++;
+            mScores.put(contactId, matchingScore);
+        }
+        return matchingScore;
+    }
+
+    /**
+     * Checks if there is a match and updates the overall score for the
+     * specified contact 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 contactId, int candidateNameType, String candidateName,
+            int nameType, String name, boolean approximate) {
+        int maxScore = getMaxScore(candidateNameType, nameType);
+        if (maxScore == 0) {
+            return;
+        }
+
+        if (candidateName.equals(name)) {
+            updatePrimaryScore(contactId, 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(contactId, score);
+    }
+
+    public void updateScoreWithPhoneNumberMatch(long contactId) {
+        updateSecondaryScore(contactId, PHONE_MATCH_SCORE);
+    }
+
+    public void updateScoreWithEmailMatch(long contactId) {
+        updateSecondaryScore(contactId, EMAIL_MATCH_SCORE);
+    }
+
+    public void updateScoreWithNicknameMatch(long contactId) {
+        updateSecondaryScore(contactId, NICKNAME_MATCH_SCORE);
+    }
+
+    private void updatePrimaryScore(long contactId, int score) {
+        getMatchingScore(contactId).updatePrimaryScore(score);
+    }
+
+    private void updateSecondaryScore(long contactId, int score) {
+        getMatchingScore(contactId).updateSecondaryScore(score);
+    }
+
+    public void keepIn(long contactId) {
+        getMatchingScore(contactId).keepIn();
+    }
+
+    public void keepOut(long contactId) {
+        getMatchingScore(contactId).keepOut();
+    }
+
+    public void clear() {
+        mScores.clear();
+        mScoreCount = 0;
+    }
+
+    /**
+     * Returns a list of IDs for contacts that are matched on secondary data elements
+     * (phone number, email address, nickname). We still need to obtain the approximate
+     * primary score for those contacts to determine if any of them should be contactd.
+     * <p>
+     * May return null.
+     */
+    public List<Long> prepareSecondaryMatchCandidates(int threshold) {
+        ArrayList<Long> contactIds = 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 (contactIds == null) {
+                    contactIds = new ArrayList<Long>();
+                }
+                contactIds.add(score.mContactId);
+                score.mPrimaryScore = NO_DATA_SCORE;
+            }
+        }
+        return contactIds;
+    }
+
+    /**
+     * Returns the contactId with the best match score over the specified threshold or -1
+     * if no such contact is found.
+     */
+    public long pickBestMatch(int threshold) {
+        long contactId = -1;
+        int maxScore = 0;
+        for (int i = 0; i < mScoreCount; i++) {
+            MatchScore score = mScoreList.get(i);
+            if (score.mKeepIn) {
+                return score.mContactId;
+            }
+
+            if (score.mKeepOut) {
+                continue;
+            }
+
+            int s = score.mPrimaryScore;
+            if (s == NO_DATA_SCORE) {
+                s = score.mSecondaryScore;
+            }
+
+            if (s >= threshold && s > maxScore) {
+                contactId = score.mContactId;
+                maxScore = s;
+            }
+        }
+        return contactId;
+    }
+
+    /**
+     * 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/ContactsProvider.java b/src/com/android/providers/contacts/ContactsProvider.java
index 777aa61..a89b6db 100644
--- a/src/com/android/providers/contacts/ContactsProvider.java
+++ b/src/com/android/providers/contacts/ContactsProvider.java
@@ -44,10 +44,8 @@
 import android.os.MemoryFile;
 import android.os.ParcelFileDescriptor;
 import android.provider.CallLog;
-import android.provider.Contacts;
-import android.provider.LiveFolders;
-import android.provider.SyncConstValue;
 import android.provider.CallLog.Calls;
+import android.provider.Contacts;
 import android.provider.Contacts.ContactMethods;
 import android.provider.Contacts.Extensions;
 import android.provider.Contacts.GroupMembership;
@@ -61,22 +59,24 @@
 import android.provider.Contacts.Photos;
 import android.provider.Contacts.Presence;
 import android.provider.Contacts.PresenceColumns;
+import android.provider.LiveFolders;
+import android.provider.SyncConstValue;
+import android.provider.Calendar;
 import android.telephony.PhoneNumberUtils;
 import android.text.TextUtils;
 import android.util.Config;
 import android.util.Log;
-
-import com.google.android.collect.Maps;
-import com.google.android.collect.Sets;
+import android.accounts.Account;
 
 import com.android.internal.database.ArrayListCursor;
+import com.google.android.collect.Maps;
+import com.google.android.collect.Sets;
 
 import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.HashSet;
-import java.util.Locale;
 import java.util.Map;
 import java.util.Set;
 
@@ -125,7 +125,7 @@
      * other methods (other than the DB layer) */
     private final ContentValues mValuesLocal = new ContentValues();
 
-    private String[] mAccounts = new String[0];
+    private Account[] mAccounts = new Account[0];
     private final Object mAccountsLock = new Object();
 
     private DatabaseUtils.InsertHelper mDeletedPeopleInserter;
@@ -134,7 +134,8 @@
     private int mIndexPeopleSyncTime;
     private int mIndexPeopleSyncVersion;
     private int mIndexPeopleSyncDirty;
-    private int mIndexPeopleSyncAccount;
+    private int mIndexPeopleSyncAccountName;
+    private int mIndexPeopleSyncAccountType;
     private int mIndexPeopleName;
     private int mIndexPeoplePhoneticName;
     private int mIndexPeopleNotes;
@@ -145,7 +146,8 @@
     private int mIndexPhotosSyncTime;
     private int mIndexPhotosSyncVersion;
     private int mIndexPhotosSyncDirty;
-    private int mIndexPhotosSyncAccount;
+    private int mIndexPhotosSyncAccountName;
+    private int mIndexPhotosSyncAccountType;
     private int mIndexPhotosExistsOnServer;
     private int mIndexPhotosSyncError;
     private DatabaseUtils.InsertHelper mContactMethodsInserter;
@@ -169,7 +171,8 @@
     private int mIndexExtensionsValue;
     private DatabaseUtils.InsertHelper mGroupMembershipInserter;
     private int mIndexGroupMembershipPersonId;
-    private int mIndexGroupMembershipGroupSyncAccount;
+    private int mIndexGroupMembershipGroupSyncAccountName;
+    private int mIndexGroupMembershipGroupSyncAccountType;
     private int mIndexGroupMembershipGroupSyncId;
     private DatabaseUtils.InsertHelper mCallsInserter;
     private DatabaseUtils.InsertHelper mPhonesInserter;
@@ -180,28 +183,8 @@
     private int mIndexPhonesNumberKey;
     private int mIndexPhonesIsPrimary;
 
-    private static HashMap<String, String> mSearchSuggestionsProjectionMap;
-    private static String mSearchSuggestionLanguage;
-    
     public ContactsProvider() {
         super(DATABASE_NAME, DATABASE_VERSION, Contacts.CONTENT_URI);
-        mSearchSuggestionLanguage = Locale.getDefault().getLanguage();
-        // Search suggestions projection map
-        mSearchSuggestionsProjectionMap = new HashMap<String, String>();
-        updateSuggestColumnTexts();
-        mSearchSuggestionsProjectionMap.put(SearchManager.SUGGEST_COLUMN_ICON_1,
-                "(CASE WHEN " + Photos.DATA + " IS NOT NULL"
-                + " THEN '" + People.CONTENT_URI + "/' || people._id ||"
-                        + " '/" + Photos.CONTENT_DIRECTORY + "/data'"
-                + " ELSE " + com.android.internal.R.drawable.ic_contact_picture
-                + " END) AS " + SearchManager.SUGGEST_COLUMN_ICON_1);
-        mSearchSuggestionsProjectionMap.put(SearchManager.SUGGEST_COLUMN_ICON_2,
-                PRESENCE_ICON_SQL + " AS " + SearchManager.SUGGEST_COLUMN_ICON_2);
-        mSearchSuggestionsProjectionMap.put(SearchManager.SUGGEST_COLUMN_INTENT_DATA_ID,
-                "people._id AS " + SearchManager.SUGGEST_COLUMN_INTENT_DATA_ID);
-        mSearchSuggestionsProjectionMap.put(SearchManager.SUGGEST_COLUMN_SHORTCUT_ID,
-                "people._id AS " + SearchManager.SUGGEST_COLUMN_SHORTCUT_ID);
-        mSearchSuggestionsProjectionMap.put(People._ID, "people._id AS " + People._ID);
     }
 
     @Override
@@ -223,7 +206,8 @@
         mIndexPeopleSyncTime = mPeopleInserter.getColumnIndex(People._SYNC_TIME);
         mIndexPeopleSyncVersion = mPeopleInserter.getColumnIndex(People._SYNC_VERSION);
         mIndexPeopleSyncDirty = mPeopleInserter.getColumnIndex(People._SYNC_DIRTY);
-        mIndexPeopleSyncAccount = mPeopleInserter.getColumnIndex(People._SYNC_ACCOUNT);
+        mIndexPeopleSyncAccountName = mPeopleInserter.getColumnIndex(People._SYNC_ACCOUNT);
+        mIndexPeopleSyncAccountType = mPeopleInserter.getColumnIndex(People._SYNC_ACCOUNT_TYPE);
         mIndexPeopleName = mPeopleInserter.getColumnIndex(People.NAME);
         mIndexPeoplePhoneticName = mPeopleInserter.getColumnIndex(People.PHONETIC_NAME);
         mIndexPeopleNotes = mPeopleInserter.getColumnIndex(People.NOTES);
@@ -236,26 +220,32 @@
         mIndexPhotosSyncTime = mPhotosInserter.getColumnIndex(Photos._SYNC_TIME);
         mIndexPhotosSyncVersion = mPhotosInserter.getColumnIndex(Photos._SYNC_VERSION);
         mIndexPhotosSyncDirty = mPhotosInserter.getColumnIndex(Photos._SYNC_DIRTY);
-        mIndexPhotosSyncAccount = mPhotosInserter.getColumnIndex(Photos._SYNC_ACCOUNT);
+        mIndexPhotosSyncAccountName = mPhotosInserter.getColumnIndex(Photos._SYNC_ACCOUNT);
+        mIndexPhotosSyncAccountType = mPhotosInserter.getColumnIndex(Photos._SYNC_ACCOUNT_TYPE);
         mIndexPhotosSyncError = mPhotosInserter.getColumnIndex(Photos.SYNC_ERROR);
         mIndexPhotosExistsOnServer = mPhotosInserter.getColumnIndex(Photos.EXISTS_ON_SERVER);
 
         mContactMethodsInserter = new DatabaseUtils.InsertHelper(db, sContactMethodsTable);
-        mIndexContactMethodsPersonId = mContactMethodsInserter.getColumnIndex(ContactMethods.PERSON_ID);
+        mIndexContactMethodsPersonId =
+                mContactMethodsInserter.getColumnIndex(ContactMethods.PERSON_ID);
         mIndexContactMethodsLabel = mContactMethodsInserter.getColumnIndex(ContactMethods.LABEL);
         mIndexContactMethodsKind = mContactMethodsInserter.getColumnIndex(ContactMethods.KIND);
         mIndexContactMethodsType = mContactMethodsInserter.getColumnIndex(ContactMethods.TYPE);
         mIndexContactMethodsData = mContactMethodsInserter.getColumnIndex(ContactMethods.DATA);
-        mIndexContactMethodsAuxData = mContactMethodsInserter.getColumnIndex(ContactMethods.AUX_DATA);
-        mIndexContactMethodsIsPrimary = mContactMethodsInserter.getColumnIndex(ContactMethods.ISPRIMARY);
+        mIndexContactMethodsAuxData =
+                mContactMethodsInserter.getColumnIndex(ContactMethods.AUX_DATA);
+        mIndexContactMethodsIsPrimary =
+                mContactMethodsInserter.getColumnIndex(ContactMethods.ISPRIMARY);
 
         mOrganizationsInserter = new DatabaseUtils.InsertHelper(db, sOrganizationsTable);
-        mIndexOrganizationsPersonId = mOrganizationsInserter.getColumnIndex(Organizations.PERSON_ID);
+        mIndexOrganizationsPersonId =
+                mOrganizationsInserter.getColumnIndex(Organizations.PERSON_ID);
         mIndexOrganizationsLabel = mOrganizationsInserter.getColumnIndex(Organizations.LABEL);
         mIndexOrganizationsType = mOrganizationsInserter.getColumnIndex(Organizations.TYPE);
         mIndexOrganizationsCompany = mOrganizationsInserter.getColumnIndex(Organizations.COMPANY);
         mIndexOrganizationsTitle = mOrganizationsInserter.getColumnIndex(Organizations.TITLE);
-        mIndexOrganizationsIsPrimary = mOrganizationsInserter.getColumnIndex(Organizations.ISPRIMARY);
+        mIndexOrganizationsIsPrimary =
+                mOrganizationsInserter.getColumnIndex(Organizations.ISPRIMARY);
 
         mExtensionsInserter = new DatabaseUtils.InsertHelper(db, sExtensionsTable);
         mIndexExtensionsPersonId = mExtensionsInserter.getColumnIndex(Extensions.PERSON_ID);
@@ -263,9 +253,14 @@
         mIndexExtensionsValue = mExtensionsInserter.getColumnIndex(Extensions.VALUE);
 
         mGroupMembershipInserter = new DatabaseUtils.InsertHelper(db, sGroupmembershipTable);
-        mIndexGroupMembershipPersonId = mGroupMembershipInserter.getColumnIndex(GroupMembership.PERSON_ID);
-        mIndexGroupMembershipGroupSyncAccount = mGroupMembershipInserter.getColumnIndex(GroupMembership.GROUP_SYNC_ACCOUNT);
-        mIndexGroupMembershipGroupSyncId = mGroupMembershipInserter.getColumnIndex(GroupMembership.GROUP_SYNC_ID);
+        mIndexGroupMembershipPersonId =
+                mGroupMembershipInserter.getColumnIndex(GroupMembership.PERSON_ID);
+        mIndexGroupMembershipGroupSyncAccountName =
+                mGroupMembershipInserter.getColumnIndex(GroupMembership.GROUP_SYNC_ACCOUNT);
+        mIndexGroupMembershipGroupSyncAccountType =
+                mGroupMembershipInserter.getColumnIndex(GroupMembership.GROUP_SYNC_ACCOUNT_TYPE);
+        mIndexGroupMembershipGroupSyncId =
+                mGroupMembershipInserter.getColumnIndex(GroupMembership.GROUP_SYNC_ID);
 
         mCallsInserter = new DatabaseUtils.InsertHelper(db, sCallsTable);
 
@@ -307,23 +302,9 @@
             // use new token format from 73
             db.execSQL("delete from peopleLookup");
             try {
-                // With longForQuery(), _TOKERNIZE() is called just once, toward the first entry
-                // in "people" table. This may be a bug. Instead, we use rawQuery() for now. 
-                // DatabaseUtils.longForQuery(db, query, null);
-
-                // Cursors objects are lazily executed. So we have to call some method which forces
-                // the cursor to run the query.
-                Cursor cursor =
-                    db.rawQuery("SELECT _TOKENIZE('peopleLookup', _id, name, ' ') from people",
-                            null);
-                try {
-                    int rows = cursor.getCount();
-                    Log.i(TAG, "Processed " + rows + " contacts.");
-                } finally {
-                    if (cursor != null) {
-                        cursor.close();
-                    }
-                }
+                DatabaseUtils.longForQuery(db,
+                        "SELECT _TOKENIZE('peopleLookup', _id, name, ' ') from people;",
+                        null);
             } catch (SQLiteDoneException ex) {
                 // it is ok to throw this, 
                 // it just means you don't have data in people table
@@ -385,52 +366,71 @@
             oldVersion = 80;
         }
 
-        // Because of historical reason, version 81 have two types.
-        // 1) One type already has "peopleLookupWithPhoneticName" table but does not have
-        // "peopleLookup" table with token_index.
-        // 2) Another type has "peopleLookup" table with token_index but does not have
-        // "peopleLookupWithPhoneticName" table.
-        // For simplicity, both databases are once dropped here.
-        // This is slow but should be done just once anyway...
-        if (oldVersion == 80 || oldVersion == 81) {
+        if (oldVersion == 80) {
+            db.execSQL("ALTER TABLE people ADD COLUMN _sync_account_type TEXT;");
+            db.execSQL("ALTER TABLE _deleted_people ADD COLUMN _sync_account_type TEXT;");
+            db.execSQL("ALTER TABLE groups ADD COLUMN _sync_account_type TEXT;");
+            db.execSQL("ALTER TABLE _deleted_groups ADD COLUMN _sync_account_type TEXT;");
+            db.execSQL("ALTER TABLE settings ADD COLUMN _sync_account_type TEXT;");
+            db.execSQL("ALTER TABLE photos ADD COLUMN _sync_account_type TEXT;");
+            db.execSQL("ALTER TABLE groupmembership ADD COLUMN _sync_account_type TEXT;");
+
+            db.execSQL("UPDATE people"
+                    + " SET _sync_account_type='com.google.GAIA'"
+                    + " WHERE _sync_account IS NOT NULL");
+            db.execSQL("UPDATE _deleted_people"
+                    + " SET _sync_account_type='com.google.GAIA'"
+                    + " WHERE _sync_account IS NOT NULL");
+            db.execSQL("UPDATE groups"
+                    + " SET _sync_account_type='com.google.GAIA'"
+                    + " WHERE _sync_account IS NOT NULL");
+            db.execSQL("UPDATE _deleted_groups"
+                    + " SET _sync_account_type='com.google.GAIA'"
+                    + " WHERE _sync_account IS NOT NULL");
+            db.execSQL("UPDATE settings"
+                    + " SET _sync_account_type='com.google.GAIA'"
+                    + " WHERE _sync_account IS NOT NULL");
+            db.execSQL("UPDATE photos"
+                    + " SET _sync_account_type='com.google.GAIA'"
+                    + " WHERE _sync_account IS NOT NULL");
+            db.execSQL("UPDATE groupmembership"
+                    + " SET _sync_account_type='com.google.GAIA'"
+                    + " WHERE _sync_account IS NOT NULL");
+
+            db.execSQL("CREATE INDEX groupTempIndex ON groups ("
+                    + Groups.NAME + ","  + Groups.SYSTEM_ID + "," + Groups._SYNC_ACCOUNT + ","
+                    + Groups._SYNC_ACCOUNT_TYPE + ");");
+
+            db.execSQL("DROP INDEX groupmembershipIndex3");
+            db.execSQL("CREATE INDEX groupmembershipIndex3 ON groupmembership "
+                    + "(group_sync_account_type, group_sync_account, group_sync_id);");
+
+            // Trigger to move an account_people row to _deleted_account_people when it is deleted
+            db.execSQL("DROP TRIGGER groups_to_deleted");
+            db.execSQL("CREATE TRIGGER groups_to_deleted DELETE ON groups " +
+                        "WHEN old._sync_id is not null " +
+                        "BEGIN " +
+                            "INSERT INTO _deleted_groups " +
+                                "(_sync_id, _sync_account, _sync_account_type, _sync_version) " +
+                                "VALUES (old._sync_id, old._sync_account, old._sync_account_type," +
+                                "old._sync_version);" +
+                        "END");
+
+            oldVersion++;
+        }
+
+        if (oldVersion == 81) {
             Log.i(TAG, "Upgrading contacts database from version " + oldVersion + " to " +
                     newVersion + ", which will preserve existing data");
-
-            recreatePeopleLookupTable(db);
-            try {
-                String query = "SELECT _TOKENIZE('peopleLookup', _id, name, ' ', 1) FROM people";
-                Cursor cursor = db.rawQuery(query, null);
-                try {
-                    int rows = cursor.getCount();
-                    Log.i(TAG, "Processed " + rows + " contacts.");
-                } finally {
-                    if (cursor != null) {
-                        cursor.close();
-                    }
-                }
-            } catch (SQLiteException e) {
-                Log.e(TAG, e.toString() + ": " + e.getMessage());
-            }
-            
-            recreatePeopleLookupWithPhoneticNameTable(db);
-            try {
-                String query = "SELECT _TOKENIZE('peopleLookupWithPhoneticName', _id, "
-                    + PHONETIC_LOOKUP_SQL_SIMPLE +
-                    ", ' ', 1) FROM people";
-                Cursor cursor = db.rawQuery(query, null);
-                try {
-                    int rows = cursor.getCount();
-                    Log.i(TAG, "Processed " + rows + " contacts.");
-                } finally {
-                    if (cursor != null) {
-                        cursor.close();
-                    }
-                }
-            } catch (SQLiteException e) {
-                Log.e(TAG, e.toString() + ": " + e.getMessage());
-            }
-            
-            oldVersion = 82;
+            // 81 adds the token_index column
+            db.execSQL("DELETE FROM peopleLookup");
+            db.execSQL("ALTER TABLE peopleLookup ADD token_index INTEGER;");
+            String[] tokenize = {"_TOKENIZE('peopleLookup', _id, name, ' ', 1)"};
+            Cursor cursor = db.query("people", tokenize, null, null, null, null, null);
+            int rows = cursor.getCount();
+            cursor.close();
+            Log.i(TAG, "Processed " + rows + " contacts.");
+            oldVersion = 81;
         }
 
         return upgradeWasLossless;
@@ -439,7 +439,6 @@
     protected void dropTables(SQLiteDatabase db) {
         db.execSQL("DROP TABLE IF EXISTS people");
         db.execSQL("DROP TABLE IF EXISTS peopleLookup");
-        db.execSQL("DROP TABLE IF EXISTS peopleLookupWithPhoneticName");
         db.execSQL("DROP TABLE IF EXISTS _deleted_people");
         db.execSQL("DROP TABLE IF EXISTS phones");
         db.execSQL("DROP TABLE IF EXISTS contact_methods");
@@ -454,74 +453,13 @@
         db.execSQL("DROP TABLE IF EXISTS settings");
     }
 
-    private void recreatePeopleLookupTable(SQLiteDatabase db) {
-        db.execSQL("DROP TABLE IF EXISTS peopleLookup");
-        db.execSQL("DROP INDEX IF EXISTS peopleLookupIndex");
-        db.execSQL("DROP TRIGGER IF EXISTS peopleLookup_update"); 
-        db.execSQL("DROP TRIGGER IF EXISTS peopleLookup_insert");
-
-        db.execSQL("CREATE TABLE peopleLookup (" +
-                "token TEXT," +
-                "source INTEGER REFERENCES people(_id)," +
-                "token_index INTEGER" +
-                ");");
-        db.execSQL("CREATE INDEX peopleLookupIndex ON peopleLookup (" +
-                "token," +
-                "source" +
-                ");");
-        
-        // Triggers to keep the peopleLookup table up to date
-        db.execSQL("CREATE TRIGGER peopleLookup_update UPDATE OF name ON people " +
-                    "BEGIN " +
-                        "DELETE FROM peopleLookup WHERE source = new._id;" +
-                        "SELECT _TOKENIZE('peopleLookup', new._id, new.name, ' ', 1);" +
-                    "END");
-        db.execSQL("CREATE TRIGGER peopleLookup_insert AFTER INSERT ON people " +
-                    "BEGIN " +
-                        "SELECT _TOKENIZE('peopleLookup', new._id, new.name, ' ', 1);" +
-                    "END");
-    }
-    
-    private void recreatePeopleLookupWithPhoneticNameTable(SQLiteDatabase db) {
-        db.execSQL("DROP TABLE IF EXISTS peopleLookupWithPhoneticName");
-        db.execSQL("DROP INDEX IF EXISTS peopleLookupwithPhoneticNameIndex");
-        db.execSQL("DROP TRIGGER IF EXISTS peopleLookupWithPhoneticName_update");
-        db.execSQL("DROP TRIGGER IF EXISTS peopleLookupWithPhoneticName_insert");
-
-        db.execSQL("CREATE TABLE peopleLookupWithPhoneticName (" +
-                "token TEXT," +
-                "source INTEGER REFERENCES people(_id)," +
-                "token_index INTEGER" +
-                ");");
-        db.execSQL("CREATE INDEX peopleLookupWithPhoneticNameIndex ON " +
-                "peopleLookupWithPhoneticName (" +
-                "token," +
-                "source" +
-                ");");
-
-        // Triggers to keep the peopleLookupWithPhoneticName table up to date
-        db.execSQL("CREATE TRIGGER peopleLookupWithPhoneticName_update UPDATE OF " +
-                    "name, phonetic_name ON people " +
-                    "BEGIN " +
-                        "DELETE FROM peopleLookupWithPhoneticName WHERE source = new._id;" +
-                        "SELECT _TOKENIZE('peopleLookupWithPhoneticName', new._id, " +
-                        PHONETIC_LOOKUP_SQL_SIMPLE_WITH_NEW +
-                        ", ' ', 1);" +
-                    "END");
-        db.execSQL("CREATE TRIGGER peopleLookupWithPhoneticName_insert AFTER INSERT ON people " +
-                    "BEGIN " +
-                        "SELECT _TOKENIZE('peopleLookupWithPhoneticName', new._id, " +
-                        PHONETIC_LOOKUP_SQL_SIMPLE_WITH_NEW +
-                        ", ' ', 1);" +
-                    "END");
-    }
-    
     @Override
     protected void bootstrapDatabase(SQLiteDatabase db) {
         super.bootstrapDatabase(db);
         db.execSQL("CREATE TABLE people (" +
                     People._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
                     People._SYNC_ACCOUNT + " TEXT," + // From the sync source
+                    People._SYNC_ACCOUNT_TYPE + " TEXT," + // From the sync source
                     People._SYNC_ID + " TEXT," + // From the sync source
                     People._SYNC_TIME + " TEXT," + // From the sync source
                     People._SYNC_VERSION + " TEXT," + // From the sync source
@@ -560,6 +498,7 @@
         db.execSQL("CREATE TABLE groups (" +
                 Groups._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
                 Groups._SYNC_ACCOUNT + " TEXT," + // From the sync source
+                Groups._SYNC_ACCOUNT_TYPE + " TEXT," + // From the sync source
                 Groups._SYNC_ID + " TEXT," + // From the sync source
                 Groups._SYNC_TIME + " TEXT," + // From the sync source
                 Groups._SYNC_VERSION + " TEXT," + // From the sync source
@@ -574,7 +513,8 @@
                 Groups.SHOULD_SYNC + " INTEGER NOT NULL DEFAULT 0," +
                 Groups.SYSTEM_ID + " TEXT," +
                 "UNIQUE(" +
-                Groups.NAME + ","  + Groups.SYSTEM_ID + "," + Groups._SYNC_ACCOUNT + ")" +
+                Groups.NAME + ","  + Groups.SYSTEM_ID + "," + Groups._SYNC_ACCOUNT + "," +
+                Groups._SYNC_ACCOUNT_TYPE + ")" +
                 ");");
 
         db.execSQL("CREATE INDEX groupsSyncDirtyIndex ON groups (" + Groups._SYNC_DIRTY + ");");
@@ -603,6 +543,7 @@
                 + Photos.DATA + " BLOB,"
                 + Photos.SYNC_ERROR + " TEXT,"
                 + Photos._SYNC_ACCOUNT + " TEXT,"
+                + Photos._SYNC_ACCOUNT_TYPE + " TEXT,"
                 + Photos._SYNC_ID + " TEXT,"
                 + Photos._SYNC_TIME + " TEXT,"
                 + Photos._SYNC_VERSION + " TEXT,"
@@ -627,6 +568,7 @@
                     "_sync_id TEXT," +
                     (isTemporary() ? "_sync_local_id INTEGER," : "") + // Used while syncing,
                     "_sync_account TEXT," +
+                    "_sync_account_type TEXT," +
                     "_sync_mark INTEGER)"); // Used to filter out new rows
 
         db.execSQL("CREATE TABLE _deleted_groups (" +
@@ -634,6 +576,7 @@
                     "_sync_id TEXT," +
                     (isTemporary() ? "_sync_local_id INTEGER," : "") + // Used while syncing,
                     "_sync_account TEXT," +
+                    "_sync_account_type TEXT," +
                     "_sync_mark INTEGER)"); // Used to filter out new rows
 
         db.execSQL("CREATE TABLE phones (" +
@@ -680,6 +623,7 @@
         db.execSQL("CREATE TABLE settings (" +
                     "_id INTEGER PRIMARY KEY," +
                     "_sync_account TEXT," +
+                    "_sync_account_type TEXT," +
                     "key STRING NOT NULL," +
                     "value STRING " +
                     ");");
@@ -712,18 +656,18 @@
                 "person INTEGER REFERENCES people(_id)," +
                 "group_id INTEGER REFERENCES groups(_id)," +
                 "group_sync_account STRING," +
+                "group_sync_account_type STRING," +
                 "group_sync_id STRING" +
                 ");");
         db.execSQL("CREATE INDEX groupmembershipIndex1 ON groupmembership (person, group_id);");
         db.execSQL("CREATE INDEX groupmembershipIndex2 ON groupmembership (group_id, person);");
         db.execSQL("CREATE INDEX groupmembershipIndex3 ON groupmembership "
-                + "(group_sync_account, group_sync_id);");
+                + "(group_sync_account, group_sync_account_type, group_sync_id);");
 
         // Trigger to completely remove a contacts data when they're deleted
         db.execSQL("CREATE TRIGGER contact_cleanup DELETE ON people " +
                     "BEGIN " +
                         "DELETE FROM peopleLookup WHERE source = old._id;" +
-                        "DELETE FROM peopleLookupWithPhoneticName WHERE source = old._id;" +
                         "DELETE FROM phones WHERE person = old._id;" +
                         "DELETE FROM contact_methods WHERE person = old._id;" +
                         "DELETE FROM organizations WHERE person = old._id;" +
@@ -743,14 +687,22 @@
                     "WHEN old._sync_id is not null " +
                     "BEGIN " +
                         "INSERT INTO _deleted_groups " +
-                            "(_sync_id, _sync_account, _sync_version) " +
-                            "VALUES (old._sync_id, old._sync_account, " +
+                            "(_sync_id, _sync_account, _sync_account_type, _sync_version) " +
+                            "VALUES (old._sync_id, old._sync_account, old._sync_account_type, " +
                             "old._sync_version);" +
                     "END");
 
-        recreatePeopleLookupTable(db);
-        recreatePeopleLookupWithPhoneticNameTable(db);
-        
+        // Triggers to keep the peopleLookup table up to date
+        db.execSQL("CREATE TRIGGER peopleLookup_update UPDATE OF name ON people " +
+                    "BEGIN " +
+                        "DELETE FROM peopleLookup WHERE source = new._id;" +
+                        "SELECT _TOKENIZE('peopleLookup', new._id, new.name, ' ', 1);" +
+                    "END");
+        db.execSQL("CREATE TRIGGER peopleLookup_insert AFTER INSERT ON people " +
+                    "BEGIN " +
+                        "SELECT _TOKENIZE('peopleLookup', new._id, new.name, ' ', 1);" +
+                    "END");
+
         // Triggers to set the _sync_dirty flag when a phone is changed,
         // inserted or deleted
         db.execSQL("CREATE TRIGGER phones_update UPDATE ON phones " +
@@ -887,10 +839,10 @@
                 + Presence.PERSON_ID + ");");
     }
 
-    private String buildPeopleLookupWhereClauseCommon(String filterParam, String tableName) {
-        StringBuilder filter = new StringBuilder("people._id IN (SELECT source FROM ");
-        filter.append(tableName);
-        filter.append(" WHERE token GLOB ");
+    @SuppressWarnings("deprecation")
+    private String buildPeopleLookupWhereClause(String filterParam) {
+        StringBuilder filter = new StringBuilder(
+                "people._id IN (SELECT source FROM peopleLookup WHERE token 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.
@@ -899,18 +851,7 @@
         filter.append(')');
         return filter.toString();
     }
-    
-    private String buildPeopleLookupWhereClause(String filterParam) {
-        return buildPeopleLookupWhereClauseCommon(filterParam, "peopleLookup");
-    }
 
-    private String buildPeopleLookupWhereClauseForSuggestion(String filterParam) {
-        return buildPeopleLookupWhereClauseCommon(filterParam,
-                usePhoneticNameForPeopleLookup()
-                        ? "peopleLookupWithPhoneticName"
-                        : "peopleLookup");
-    }
-    
     @Override
     public Cursor queryInternal(Uri url, String[] projectionIn,
             String selection, String[] selectionArgs, String sort) {
@@ -1079,7 +1020,7 @@
             }
             case SEARCH_SHORTCUT: {
                 qb.setTables(PEOPLE_PHONES_PHOTOS_ORGANIZATIONS_JOIN);
-                qb.setProjectionMap(getCurrentSearchSuggestionsProjectionMap());
+                qb.setProjectionMap(sSearchSuggestionsProjectionMap);
                 qb.appendWhere(SearchManager.SUGGEST_COLUMN_SHORTCUT_ID + "=");
                 qb.appendWhere(url.getPathSegments().get(1));
                 break;
@@ -1472,7 +1413,8 @@
         return "people._id IN (SELECT person FROM groupmembership JOIN groups " +
                 "ON (group_id=groups._id OR " +
                 "(group_sync_id = groups._sync_id AND " +
-                    "group_sync_account = groups._sync_account)) "+
+                    "group_sync_account = groups._sync_account AND " +
+                    "group_sync_account_type = groups._sync_account_type)) "+
                 "WHERE " + Groups.NAME + "="
                 + DatabaseUtils.sqlEscapeString(groupName) + ")";
     }
@@ -1511,17 +1453,6 @@
         }
     }
 
-    private HashMap<String, String> getCurrentSearchSuggestionsProjectionMap() {
-        String currentLanguage = Locale.getDefault().getLanguage();
-        synchronized (this) {
-            if (!currentLanguage.equals(mSearchSuggestionLanguage)) {
-                mSearchSuggestionLanguage = currentLanguage;
-                updateSuggestColumnTexts();
-            }
-        }
-        return mSearchSuggestionsProjectionMap; 
-    }
-    
     /**
      * Either sets up the query builder so we can run the proper query against the database
      * and returns null, or returns a cursor with the results already in it.
@@ -1532,7 +1463,7 @@
      */
     private Cursor handleSearchSuggestionsQuery(Uri url, SQLiteQueryBuilder qb) {
         qb.setTables(PEOPLE_PHONES_PHOTOS_ORGANIZATIONS_JOIN);
-        qb.setProjectionMap(getCurrentSearchSuggestionsProjectionMap());
+        qb.setProjectionMap(sSearchSuggestionsProjectionMap);
         if (url.getPathSegments().size() > 1) {
             // A search term was entered, use it to filter
 
@@ -1546,7 +1477,7 @@
             // match the query
             final String searchClause = url.getLastPathSegment();
             if (!TextUtils.isDigitsOnly(searchClause)) {
-                qb.appendWhere(buildPeopleLookupWhereClauseForSuggestion(searchClause));
+                qb.appendWhere(buildPeopleLookupWhereClause(searchClause));
             } else {
                 final String[] columnNames = new String[] {
                         "_id",
@@ -1699,18 +1630,19 @@
         return mime;
     }
 
-    private ContentValues queryAndroidStarredGroupId(String account) {
+    private ContentValues queryAndroidStarredGroupId(Account account) {
         String whereString;
         String[] whereArgs;
-        if (!TextUtils.isEmpty(account)) {
-            whereString = "_sync_account=? AND name=?";
-            whereArgs = new String[]{account, Groups.GROUP_ANDROID_STARRED};
+        if (account != null) {
+            whereString = "_sync_account=? AND _sync_account_type=? AND name=?";
+            whereArgs = new String[]{account.mName, account.mType, Groups.GROUP_ANDROID_STARRED};
         } else {
             whereString = "_sync_account is null AND name=?";
             whereArgs = new String[]{Groups.GROUP_ANDROID_STARRED};
         }
         Cursor cursor = getDatabase().query(sGroupsTable,
-                new String[]{Groups._ID, Groups._SYNC_ID, Groups._SYNC_ACCOUNT},
+                new String[]{Groups._ID, Groups._SYNC_ID, Groups._SYNC_ACCOUNT,
+                        Groups._SYNC_ACCOUNT_TYPE},
                 whereString, whereArgs, null, null, null);
         try {
             if (cursor.moveToNext()) {
@@ -1718,6 +1650,7 @@
                 result.put(Groups._ID, cursor.getLong(0));
                 result.put(Groups._SYNC_ID, cursor.getString(1));
                 result.put(Groups._SYNC_ACCOUNT, cursor.getString(2));
+                result.put(Groups._SYNC_ACCOUNT_TYPE, cursor.getString(3));
                 return result;
             }
             return null;
@@ -1783,9 +1716,11 @@
                 if (rowID > 0) {
                     resultUri = ContentUris.withAppendedId(Groups.CONTENT_URI, rowID);
                     if (!isTemporary() && newMap.containsKey(Groups.SHOULD_SYNC)) {
-                        final String account = newMap.getAsString(Groups._SYNC_ACCOUNT);
-                        if (!TextUtils.isEmpty(account)) {
+                        final String accountName = newMap.getAsString(Groups._SYNC_ACCOUNT);
+                        final String accountType = newMap.getAsString(Groups._SYNC_ACCOUNT_TYPE);
+                        if (!TextUtils.isEmpty(accountName) || !TextUtils.isEmpty(accountType)) {
                             final ContentResolver cr = getContext().getContentResolver();
+                            final Account account = new Account(accountName, accountType);
                             onLocalChangesForAccount(cr, account, false);
                         }
                     }
@@ -1804,7 +1739,12 @@
                 if (rowID > 0) {
                     resultUri = ContentUris.withAppendedId(People.CONTENT_URI, rowID);
                     if (!isTemporary()) {
-                        String account = mValues.getAsString(People._SYNC_ACCOUNT);
+                        String accountName = mValues.getAsString(People._SYNC_ACCOUNT);
+                        String accountType = mValues.getAsString(People._SYNC_ACCOUNT_TYPE);
+                        Account account = null;
+                        if (accountName != null || accountType != null) {
+                            account = new Account(accountName, accountType);
+                        }
                         Long starredValue = mValues.getAsLong(People.STARRED);
                         final String syncId = mValues.getAsString(People._SYNC_ID);
                         boolean isStarred = starredValue != null && starredValue != 0;
@@ -1813,7 +1753,8 @@
                         mDb.delete(sPhotosTable, "person=" + rowID, null);
                         mValues.clear();
                         mValues.put(Photos.PERSON_ID, rowID);
-                        mValues.put(Photos._SYNC_ACCOUNT, account);
+                        mValues.put(Photos._SYNC_ACCOUNT, accountName);
+                        mValues.put(Photos._SYNC_ACCOUNT_TYPE, accountType);
                         mValues.put(Photos._SYNC_ID, syncId);
                         mValues.put(Photos._SYNC_DIRTY, 0);
                         mPhotosInserter.insert(mValues);
@@ -1973,19 +1914,26 @@
     }
 
     @Override
-    protected void onAccountsChanged(String[] accountsArray) {
+    protected void onAccountsChanged(Account[] accountsArray) {
         super.onAccountsChanged(accountsArray);
         synchronized (mAccountsLock) {
-            mAccounts = new String[accountsArray.length];
+            mAccounts = new Account[accountsArray.length];
             System.arraycopy(accountsArray, 0, mAccounts, 0, mAccounts.length);
         }
     }
 
     private void ensureSyncAccountIsSet(ContentValues values) {
         synchronized (mAccountsLock) {
-            String account = values.getAsString(SyncConstValue._SYNC_ACCOUNT);
+            final String accountName = values.getAsString(SyncConstValue._SYNC_ACCOUNT);
+            final String accountType = values.getAsString(SyncConstValue._SYNC_ACCOUNT_TYPE);
+            Account account = null;
+            if (!TextUtils.isEmpty(accountName) || !TextUtils.isEmpty(accountType)) {
+                account = new Account(accountName, accountType);
+            }
             if (account == null && mAccounts.length > 0) {
-                values.put(SyncConstValue._SYNC_ACCOUNT, mAccounts[0]);
+                // TODO(fredq) change this to pick the account that is syncable for contacts
+                values.put(SyncConstValue._SYNC_ACCOUNT, mAccounts[0].mName);
+                values.put(SyncConstValue._SYNC_ACCOUNT_TYPE, mAccounts[0].mType);
             }
         }
     }
@@ -2008,21 +1956,28 @@
     }
 
     private Uri insertIntoGroupmembership(ContentValues values) {
-        String groupSyncAccount = values.getAsString(GroupMembership.GROUP_SYNC_ACCOUNT);
+        String groupSyncAccountName = values.getAsString(GroupMembership.GROUP_SYNC_ACCOUNT);
+        String groupSyncAccountType = values.getAsString(GroupMembership.GROUP_SYNC_ACCOUNT_TYPE);
         String groupSyncId = values.getAsString(GroupMembership.GROUP_SYNC_ID);
         final Long personId = values.getAsLong(GroupMembership.PERSON_ID);
         if (!values.containsKey(GroupMembership.GROUP_ID)) {
-            if (TextUtils.isEmpty(groupSyncAccount) || TextUtils.isEmpty(groupSyncId)) {
+            if (TextUtils.isEmpty(groupSyncAccountName) || TextUtils.isEmpty(groupSyncAccountType)
+                    || TextUtils.isEmpty(groupSyncId)) {
                 throw new IllegalArgumentException(
                         "insertIntoGroupmembership: no GROUP_ID wasn't specified and non-empty "
-                        + "GROUP_SYNC_ID and GROUP_SYNC_ACCOUNT fields weren't specifid, "
+                        + "GROUP_SYNC_ID and GROUP_SYNC_ACCOUNT and GROUP_SYNC_ACCOUNT_TYPE fields "
+                        + "weren't specifid, "
                         + values);
             }
             if (0 != DatabaseUtils.longForQuery(getDatabase(), ""
                     + "SELECT COUNT(*) "
                     + "FROM groupmembership "
-                    + "WHERE group_sync_id=? AND person=?",
-                    new String[]{groupSyncId, String.valueOf(personId)})) {
+                    + "WHERE group_sync_id=? "
+                    + "  AND group_sync_account=? "
+                    + "  AND group_sync_account_type=? "
+                    + "  AND person=?",
+                    new String[]{groupSyncId, groupSyncAccountName, groupSyncAccountType,
+                            String.valueOf(personId)})) {
                 final String errorMessage =
                         "insertIntoGroupmembership: a row with this server key already exists, "
                                 + values;
@@ -2031,10 +1986,12 @@
             }
         } else {
             long groupId = values.getAsLong(GroupMembership.GROUP_ID);
-            if (!TextUtils.isEmpty(groupSyncAccount) || !TextUtils.isEmpty(groupSyncId)) {
+            if (!TextUtils.isEmpty(groupSyncAccountName) || !TextUtils.isEmpty(groupSyncAccountType)
+                    || !TextUtils.isEmpty(groupSyncId)) {
                 throw new IllegalArgumentException(
                         "insertIntoGroupmembership: GROUP_ID was specified but "
-                        + "GROUP_SYNC_ID and GROUP_SYNC_ACCOUNT fields were also specifid, "
+                        + "GROUP_SYNC_ID and GROUP_SYNC_ACCOUNT and GROUP_SYNC_ACCOUNT_TYPE fields "
+                        + "were also specifid, "
                         + values);
             }
             if (0 != DatabaseUtils.longForQuery(getDatabase(),
@@ -2064,7 +2021,7 @@
         return ContentUris.withAppendedId(GroupMembership.CONTENT_URI, rowId);
     }
 
-    private void fixupGroupMembershipAfterPeopleUpdate(String account, long personId,
+    private void fixupGroupMembershipAfterPeopleUpdate(Account account, long personId,
             boolean makeStarred) {
         ContentValues starredGroupInfo = queryAndroidStarredGroupId(account);
         if (makeStarred) {
@@ -2073,17 +2030,22 @@
                 mValuesLocal.clear();
                 mValuesLocal.put(Groups.NAME, Groups.GROUP_ANDROID_STARRED);
                 mValuesLocal.put(Groups._SYNC_DIRTY, 1);
-                mValuesLocal.put(Groups._SYNC_ACCOUNT, account);
+                mValuesLocal.put(Groups._SYNC_ACCOUNT, account == null ? null : account.mName);
+                mValuesLocal.put(Groups._SYNC_ACCOUNT_TYPE, account == null ? null : account.mType);
                 long groupId = mGroupsInserter.insert(mValuesLocal);
                 starredGroupInfo = new ContentValues();
                 starredGroupInfo.put(Groups._ID, groupId);
-                starredGroupInfo.put(Groups._SYNC_ACCOUNT, account);
+                starredGroupInfo.put(Groups._SYNC_ACCOUNT,
+                        mValuesLocal.getAsString(Groups._SYNC_ACCOUNT));
+                starredGroupInfo.put(Groups._SYNC_ACCOUNT_TYPE,
+                        mValuesLocal.getAsString(Groups._SYNC_ACCOUNT_TYPE));
                 // don't put the _SYNC_ID in here since we don't know it yet
             }
 
             final Long groupId = starredGroupInfo.getAsLong(Groups._ID);
             final String syncId = starredGroupInfo.getAsString(Groups._SYNC_ID);
-            final String syncAccount = starredGroupInfo.getAsString(Groups._SYNC_ACCOUNT);
+            final String syncAccountName = starredGroupInfo.getAsString(Groups._SYNC_ACCOUNT);
+            final String syncAccountType = starredGroupInfo.getAsString(Groups._SYNC_ACCOUNT_TYPE);
 
             // check that either groupId is set or the syncId/Account is set
             final boolean hasSyncId = !TextUtils.isEmpty(syncId);
@@ -2098,17 +2060,21 @@
             mValuesLocal.put(GroupMembership.PERSON_ID, personId);
             mValuesLocal.put(GroupMembership.GROUP_ID, groupId);
             mValuesLocal.put(GroupMembership.GROUP_SYNC_ID, syncId);
-            mValuesLocal.put(GroupMembership.GROUP_SYNC_ACCOUNT, syncAccount);
+            mValuesLocal.put(GroupMembership.GROUP_SYNC_ACCOUNT, syncAccountName);
+            mValuesLocal.put(GroupMembership.GROUP_SYNC_ACCOUNT_TYPE, syncAccountType);
             mGroupMembershipInserter.insert(mValuesLocal);
         } else {
             if (starredGroupInfo != null) {
                 // delete the groupmembership rows for this person that match the starred group id
-                String syncAccount = starredGroupInfo.getAsString(Groups._SYNC_ACCOUNT);
+                String syncAccountName = starredGroupInfo.getAsString(Groups._SYNC_ACCOUNT);
+                String syncAccountType = starredGroupInfo.getAsString(Groups._SYNC_ACCOUNT_TYPE);
                 String syncId = starredGroupInfo.getAsString(Groups._SYNC_ID);
                 if (!TextUtils.isEmpty(syncId)) {
                     mDb.delete(sGroupmembershipTable,
-                            "person=? AND group_sync_id=? AND group_sync_account=?",
-                            new String[]{String.valueOf(personId), syncId, syncAccount});
+                            "person=? AND group_sync_id=? AND group_sync_account=?"
+                                    + " AND group_sync_account_type=?",
+                            new String[]{String.valueOf(personId), syncId,
+                                    syncAccountName, syncAccountType});
                 } else {
                     mDb.delete(sGroupmembershipTable, "person=? AND group_id=?",
                             new String[]{
@@ -2346,11 +2312,14 @@
         Cursor cursor = db.query(sPeopleTable, null, where, whereArgs, null, null, null);
         try {
             final int idxSyncId = cursor.getColumnIndexOrThrow(People._SYNC_ID);
-            final int idxSyncAccount = cursor.getColumnIndexOrThrow(People._SYNC_ACCOUNT);
+            final int idxSyncAccountName = cursor.getColumnIndexOrThrow(People._SYNC_ACCOUNT);
+            final int idxSyncAccountType = cursor.getColumnIndexOrThrow(People._SYNC_ACCOUNT_TYPE);
             final int idxSyncVersion = cursor.getColumnIndexOrThrow(People._SYNC_VERSION);
             final int dstIdxSyncId = mDeletedPeopleInserter.getColumnIndex(SyncConstValue._SYNC_ID);
-            final int dstIdxSyncAccount =
+            final int dstIdxSyncAccountName =
                     mDeletedPeopleInserter.getColumnIndex(SyncConstValue._SYNC_ACCOUNT);
+            final int dstIdxSyncAccountType =
+                    mDeletedPeopleInserter.getColumnIndex(SyncConstValue._SYNC_ACCOUNT_TYPE);
             final int dstIdxSyncVersion =
                     mDeletedPeopleInserter.getColumnIndex(SyncConstValue._SYNC_VERSION);
             while (cursor.moveToNext()) {
@@ -2359,7 +2328,10 @@
                 // insert into deleted table
                 mDeletedPeopleInserter.prepareForInsert();
                 mDeletedPeopleInserter.bind(dstIdxSyncId, syncId);
-                mDeletedPeopleInserter.bind(dstIdxSyncAccount, cursor.getString(idxSyncAccount));
+                mDeletedPeopleInserter.bind(dstIdxSyncAccountName,
+                        cursor.getString(idxSyncAccountName));
+                mDeletedPeopleInserter.bind(dstIdxSyncAccountType,
+                        cursor.getString(idxSyncAccountType));
                 mDeletedPeopleInserter.bind(dstIdxSyncVersion, cursor.getString(idxSyncVersion));
                 mDeletedPeopleInserter.execute();
             }
@@ -2372,27 +2344,31 @@
     }
 
     private int deleteFromGroups(String where, String[] whereArgs) {
-        HashSet<String> modifiedAccounts = Sets.newHashSet();
+        HashSet<Account> modifiedAccounts = Sets.newHashSet();
         Cursor cursor = getDatabase().query(sGroupsTable, null, where, whereArgs,
                 null, null, null);
         try {
             final int indexName = cursor.getColumnIndexOrThrow(Groups.NAME);
             final int indexSyncAccount = cursor.getColumnIndexOrThrow(Groups._SYNC_ACCOUNT);
+            final int indexSyncAccountType =
+                    cursor.getColumnIndexOrThrow(Groups._SYNC_ACCOUNT_TYPE);
             final int indexSyncId = cursor.getColumnIndexOrThrow(Groups._SYNC_ID);
             final int indexId = cursor.getColumnIndexOrThrow(Groups._ID);
             final int indexShouldSync = cursor.getColumnIndexOrThrow(Groups.SHOULD_SYNC);
             while (cursor.moveToNext()) {
                 String oldName = cursor.getString(indexName);
-                String syncAccount = cursor.getString(indexSyncAccount);
+                String syncAccountName = cursor.getString(indexSyncAccount);
+                String syncAccountType = cursor.getString(indexSyncAccountType);
                 String syncId = cursor.getString(indexSyncId);
                 boolean shouldSync = cursor.getLong(indexShouldSync) != 0;
                 long id = cursor.getLong(indexId);
                 fixupPeopleStarredOnGroupRename(oldName, null, id);
-                if (!TextUtils.isEmpty(syncAccount) && !TextUtils.isEmpty(syncId)) {
-                    fixupPeopleStarredOnGroupRename(oldName, null, syncAccount, syncId);
+                if (!TextUtils.isEmpty(syncAccountName) && !TextUtils.isEmpty(syncId)) {
+                    fixupPeopleStarredOnGroupRename(oldName, null,
+                            new Account(syncAccountName, syncAccountType), syncId);
                 }
-                if (!TextUtils.isEmpty(syncAccount) && shouldSync) {
-                    modifiedAccounts.add(syncAccount);
+                if (!TextUtils.isEmpty(syncAccountName) && shouldSync) {
+                    modifiedAccounts.add(new Account(syncAccountName, syncAccountType));
                 }
             }
         } finally {
@@ -2403,7 +2379,7 @@
         if (numRows > 0) {
             if (!isTemporary()) {
                 final ContentResolver cr = getContext().getContentResolver();
-                for (String account : modifiedAccounts) {
+                for (Account account : modifiedAccounts) {
                     onLocalChangesForAccount(cr, account, true);
                 }
             }
@@ -2418,7 +2394,7 @@
      * @param resolver the content resolver to use
      * @param account the account the changes are tied to
      */
-    protected void onLocalChangesForAccount(final ContentResolver resolver, String account,
+    protected void onLocalChangesForAccount(final ContentResolver resolver, Account account,
             boolean groupsModified) {
         // Do nothing
     }
@@ -2603,7 +2579,9 @@
                         Cursor c = mDb.query(sPeopleTable, null,
                                 where, whereArgs, null, null, null);
                         try {
-                            int indexAccount = c.getColumnIndexOrThrow(People._SYNC_ACCOUNT);
+                            int indexAccountName = c.getColumnIndexOrThrow(People._SYNC_ACCOUNT);
+                            int indexAccountType =
+                                    c.getColumnIndexOrThrow(People._SYNC_ACCOUNT_TYPE);
                             int indexId = c.getColumnIndexOrThrow(People._ID);
                             Long starredValue = values.getAsLong(People.STARRED);
                             Long primaryPhone = values.getAsLong(People.PRIMARY_PHONE_ID);
@@ -2613,7 +2591,13 @@
                             while (c.moveToNext()) {
                                 final long personId = c.getLong(indexId);
                                 if (hasStarred) {
-                                    fixupGroupMembershipAfterPeopleUpdate(c.getString(indexAccount),
+                                    final String accountName = c.getString(indexAccountName);
+                                    final String accountType = c.getString(indexAccountType);
+                                    final Account account =
+                                            (accountName != null || accountType != null)
+                                                    ? new Account(accountName, accountType)
+                                                    : null;
+                                    fixupGroupMembershipAfterPeopleUpdate(account,
                                             personId, starredValue != null && starredValue != 0);
                                 }
 
@@ -2654,18 +2638,21 @@
 
     private int updateSettings(ContentValues values) {
         final SQLiteDatabase db = getDatabase();
-        final String account = values.getAsString(Contacts.Settings._SYNC_ACCOUNT);
+        final String accountName = values.getAsString(Contacts.Settings._SYNC_ACCOUNT);
+        final String accountType = values.getAsString(Contacts.Settings._SYNC_ACCOUNT_TYPE);
         final String key = values.getAsString(Contacts.Settings.KEY);
         if (key == null) {
             throw new IllegalArgumentException("you must specify the key when updating settings");
         }
+        Account account = null;
+        if (accountName != null || accountType != null) {
+            account = new Account(accountName, accountType);
+        }
         if (account == null) {
             db.delete(sSettingsTable, "_sync_account IS NULL AND key=?", new String[]{key});
         } else {
-            if (TextUtils.isEmpty(account)) {
-                throw new IllegalArgumentException("account cannot be the empty string, " + values);
-            }
-            db.delete(sSettingsTable, "_sync_account=? AND key=?", new String[]{account, key});
+            db.delete(sSettingsTable, "_sync_account=? AND _sync_account_type=? AND key=?",
+                    new String[]{account.mName, account.mType, key});
         }
         long rowId = db.insert(sSettingsTable, Contacts.Settings.KEY, values);
         if (rowId < 0) {
@@ -2684,7 +2671,7 @@
             }
         }
 
-        Set<String> modifiedAccounts = Sets.newHashSet();
+        Set<Account> modifiedAccounts = Sets.newHashSet();
         final SQLiteDatabase db = getDatabase();
         if (values.containsKey(Groups.NAME) || values.containsKey(Groups.SHOULD_SYNC)) {
             String newName = values.getAsString(Groups.NAME);
@@ -2692,21 +2679,25 @@
             try {
                 final int indexName = cursor.getColumnIndexOrThrow(Groups.NAME);
                 final int indexSyncAccount = cursor.getColumnIndexOrThrow(Groups._SYNC_ACCOUNT);
+                final int indexSyncAccountType =
+                        cursor.getColumnIndexOrThrow(Groups._SYNC_ACCOUNT_TYPE);
                 final int indexSyncId = cursor.getColumnIndexOrThrow(Groups._SYNC_ID);
                 final int indexId = cursor.getColumnIndexOrThrow(Groups._ID);
                 while (cursor.moveToNext()) {
-                    String syncAccount = cursor.getString(indexSyncAccount);
+                    String accountName = cursor.getString(indexSyncAccount);
+                    String accountType = cursor.getString(indexSyncAccountType);
                     if (values.containsKey(Groups.NAME)) {
                         String oldName = cursor.getString(indexName);
                         String syncId = cursor.getString(indexSyncId);
                         long id = cursor.getLong(indexId);
                         fixupPeopleStarredOnGroupRename(oldName, newName, id);
-                        if (!TextUtils.isEmpty(syncAccount) && !TextUtils.isEmpty(syncId)) {
-                            fixupPeopleStarredOnGroupRename(oldName, newName, syncAccount, syncId);
+                        if (!TextUtils.isEmpty(accountName) && !TextUtils.isEmpty(syncId)) {
+                            fixupPeopleStarredOnGroupRename(oldName, newName,
+                                    new Account(accountName, accountType), syncId);
                         }
                     }
-                    if (!TextUtils.isEmpty(syncAccount) && values.containsKey(Groups.SHOULD_SYNC)) {
-                        modifiedAccounts.add(syncAccount);
+                    if (!TextUtils.isEmpty(accountName) && values.containsKey(Groups.SHOULD_SYNC)) {
+                        modifiedAccounts.add(new Account(accountName, accountType));
                     }
                 }
             } finally {
@@ -2718,7 +2709,7 @@
         if (numRows > 0) {
             if (!isTemporary()) {
                 final ContentResolver cr = getContext().getContentResolver();
-                for (String account : modifiedAccounts) {
+                for (Account account : modifiedAccounts) {
                     onLocalChangesForAccount(cr, account, true);
                 }
             }
@@ -2747,9 +2738,10 @@
     }
 
     void fixupPeopleStarredOnGroupRename(String oldName, String newName,
-            String syncAccount, String syncId) {
-        fixupPeopleStarredOnGroupRename(oldName, newName, "_sync_account=? AND _sync_id=?",
-                new String[]{syncAccount, syncId});
+            Account syncAccount, String syncId) {
+        fixupPeopleStarredOnGroupRename(oldName, newName,
+                "_sync_account=? AND _sync_account_type=? AND _sync_id=?",
+                new String[]{syncAccount.mName, syncAccount.mType, syncId});
     }
 
     void fixupPeopleStarredOnGroupRename(String oldName, String newName, long groupId) {
@@ -3106,14 +3098,24 @@
 
             // Copy the person
             mPeopleInserter.prepareForInsert();
-            DatabaseUtils.cursorStringToInsertHelper(diffsCursor, People._SYNC_ID, mPeopleInserter, mIndexPeopleSyncId);
-            DatabaseUtils.cursorStringToInsertHelper(diffsCursor, People._SYNC_TIME, mPeopleInserter, mIndexPeopleSyncTime);
-            DatabaseUtils.cursorStringToInsertHelper(diffsCursor, People._SYNC_VERSION, mPeopleInserter, mIndexPeopleSyncVersion);
-            DatabaseUtils.cursorStringToInsertHelper(diffsCursor, People._SYNC_DIRTY, mPeopleInserter, mIndexPeopleSyncDirty);
-            DatabaseUtils.cursorStringToInsertHelper(diffsCursor, People._SYNC_ACCOUNT, mPeopleInserter, mIndexPeopleSyncAccount);
-            DatabaseUtils.cursorStringToInsertHelper(diffsCursor, People.NAME, mPeopleInserter, mIndexPeopleName);
-            DatabaseUtils.cursorStringToInsertHelper(diffsCursor, People.PHONETIC_NAME, mPeopleInserter, mIndexPeoplePhoneticName);
-            DatabaseUtils.cursorStringToInsertHelper(diffsCursor, People.NOTES, mPeopleInserter, mIndexPeopleNotes);
+            DatabaseUtils.cursorStringToInsertHelper(diffsCursor,
+                    People._SYNC_ID, mPeopleInserter, mIndexPeopleSyncId);
+            DatabaseUtils.cursorStringToInsertHelper(diffsCursor,
+                    People._SYNC_TIME, mPeopleInserter, mIndexPeopleSyncTime);
+            DatabaseUtils.cursorStringToInsertHelper(diffsCursor,
+                    People._SYNC_VERSION, mPeopleInserter, mIndexPeopleSyncVersion);
+            DatabaseUtils.cursorStringToInsertHelper(diffsCursor,
+                    People._SYNC_DIRTY, mPeopleInserter, mIndexPeopleSyncDirty);
+            DatabaseUtils.cursorStringToInsertHelper(diffsCursor,
+                    People._SYNC_ACCOUNT, mPeopleInserter, mIndexPeopleSyncAccountName);
+            DatabaseUtils.cursorStringToInsertHelper(diffsCursor,
+                    People._SYNC_ACCOUNT_TYPE, mPeopleInserter, mIndexPeopleSyncAccountType);
+            DatabaseUtils.cursorStringToInsertHelper(diffsCursor,
+                    People.NAME, mPeopleInserter, mIndexPeopleName);
+            DatabaseUtils.cursorStringToInsertHelper(diffsCursor,
+                    People.PHONETIC_NAME, mPeopleInserter, mIndexPeoplePhoneticName);
+            DatabaseUtils.cursorStringToInsertHelper(diffsCursor,
+                    People.NOTES, mPeopleInserter, mIndexPeopleNotes);
             long localPersonID = mPeopleInserter.execute();
 
             Cursor c;
@@ -3133,7 +3135,9 @@
                     DatabaseUtils.cursorStringToInsertHelper(c, Photos._SYNC_VERSION,
                             mPhotosInserter, mIndexPhotosSyncVersion);
                     DatabaseUtils.cursorStringToInsertHelper(c, Photos._SYNC_ACCOUNT,
-                            mPhotosInserter, mIndexPhotosSyncAccount);
+                            mPhotosInserter, mIndexPhotosSyncAccountName);
+                    DatabaseUtils.cursorStringToInsertHelper(c, Photos._SYNC_ACCOUNT_TYPE,
+                            mPhotosInserter, mIndexPhotosSyncAccountType);
                     DatabaseUtils.cursorStringToInsertHelper(c, Photos.EXISTS_ON_SERVER,
                             mPhotosInserter, mIndexPhotosExistsOnServer);
                     mPhotosInserter.bind(mIndexPhotosSyncError, (String)null);
@@ -3209,11 +3213,13 @@
                     final int isPrimaryValue = c.getInt(primaryIndex);
                     mContactMethodsInserter.prepareForInsert();
                     mContactMethodsInserter.bind(mIndexContactMethodsPersonId, localPersonID);
-                    mContactMethodsInserter.bind(mIndexContactMethodsLabel, c.getString(labelIndex));
+                    mContactMethodsInserter.bind(mIndexContactMethodsLabel,
+                            c.getString(labelIndex));
                     mContactMethodsInserter.bind(mIndexContactMethodsKind, kind);
                     mContactMethodsInserter.bind(mIndexContactMethodsType, type);
                     mContactMethodsInserter.bind(mIndexContactMethodsData, c.getString(dataIndex));
-                    mContactMethodsInserter.bind(mIndexContactMethodsAuxData, c.getString(auxDataIndex));
+                    mContactMethodsInserter.bind(mIndexContactMethodsAuxData,
+                            c.getString(auxDataIndex));
                     mContactMethodsInserter.bind(mIndexContactMethodsIsPrimary, isPrimaryValue);
                     long rowId = mContactMethodsInserter.execute();
                     if ((kind == Contacts.KIND_EMAIL) && (isPrimaryValue != 0)) {
@@ -3258,7 +3264,8 @@
                     mOrganizationsInserter.bind(mIndexOrganizationsPersonId, localPersonID);
                     mOrganizationsInserter.bind(mIndexOrganizationsLabel, c.getString(labelIndex));
                     mOrganizationsInserter.bind(mIndexOrganizationsType, type);
-                    mOrganizationsInserter.bind(mIndexOrganizationsCompany, c.getString(companyIndex));
+                    mOrganizationsInserter.bind(mIndexOrganizationsCompany,
+                            c.getString(companyIndex));
                     mOrganizationsInserter.bind(mIndexOrganizationsTitle, c.getString(titleIndex));
                     mOrganizationsInserter.bind(mIndexOrganizationsIsPrimary, isPrimaryValue);
                     long rowId = mOrganizationsInserter.execute();
@@ -3291,14 +3298,20 @@
             c = doSubQuery(diffsDb, sGroupmembershipTable, null, diffsPersonID,
                     sGroupmembershipTable + "._id");
             try {
-                final int accountIndex =
+                final int accountNameIndex =
                     c.getColumnIndexOrThrow(GroupMembership.GROUP_SYNC_ACCOUNT);
+                final int accountTypeIndex =
+                    c.getColumnIndexOrThrow(GroupMembership.GROUP_SYNC_ACCOUNT_TYPE);
                 final int idIndex = c.getColumnIndexOrThrow(GroupMembership.GROUP_SYNC_ID);
                 while(c.moveToNext()) {
                     mGroupMembershipInserter.prepareForInsert();
                     mGroupMembershipInserter.bind(mIndexGroupMembershipPersonId, localPersonID);
-                    mGroupMembershipInserter.bind(mIndexGroupMembershipGroupSyncAccount, c.getString(accountIndex));
-                    mGroupMembershipInserter.bind(mIndexGroupMembershipGroupSyncId, c.getString(idIndex));
+                    mGroupMembershipInserter.bind(mIndexGroupMembershipGroupSyncAccountName,
+                            c.getString(accountNameIndex));
+                    mGroupMembershipInserter.bind(mIndexGroupMembershipGroupSyncAccountType,
+                            c.getString(accountTypeIndex));
+                    mGroupMembershipInserter.bind(mIndexGroupMembershipGroupSyncId,
+                            c.getString(idIndex));
                     mGroupMembershipInserter.execute();
                 }
             } finally {
@@ -3306,7 +3319,8 @@
             }
 
             // Copy all extensions rows
-            c = doSubQuery(diffsDb, sExtensionsTable, null, diffsPersonID, sExtensionsTable + "._id");
+            c = doSubQuery(diffsDb, sExtensionsTable, null, diffsPersonID,
+                    sExtensionsTable + "._id");
             try {
                 final int nameIndex = c.getColumnIndexOrThrow(Extensions.NAME);
                 final int valueIndex = c.getColumnIndexOrThrow(Extensions.VALUE);
@@ -3595,6 +3609,8 @@
                             DatabaseUtils.cursorStringToContentValues(cRemote,
                                     GroupMembership.GROUP_SYNC_ACCOUNT, mValues);
                             DatabaseUtils.cursorStringToContentValues(cRemote,
+                                    GroupMembership.GROUP_SYNC_ACCOUNT_TYPE, mValues);
+                            DatabaseUtils.cursorStringToContentValues(cRemote,
                                     GroupMembership.GROUP_SYNC_ID, mValues);
                             if (joinResult == CursorJoiner.Result.RIGHT) {
                                 mValues.put(GroupMembership.PERSON_ID, localPersonID);
@@ -3660,7 +3676,10 @@
                 if(cRemote.moveToNext()) {
                     mValues.clear();
                     DatabaseUtils.cursorStringToContentValues(cRemote, Photos._SYNC_ID, mValues);
-                    DatabaseUtils.cursorStringToContentValues(cRemote, Photos._SYNC_ACCOUNT, mValues);
+                    DatabaseUtils.cursorStringToContentValues(cRemote,
+                            Photos._SYNC_ACCOUNT, mValues);
+                    DatabaseUtils.cursorStringToContentValues(cRemote,
+                            Photos._SYNC_ACCOUNT_TYPE, mValues);
                     db.update(sPhotosTable, mValues, Photos.PERSON_ID + '=' + localPersonID, null);
                 }
             } finally {
@@ -3687,6 +3706,8 @@
             DatabaseUtils.cursorStringToContentValues(diffsCursor, People._SYNC_TIME, mValues);
             DatabaseUtils.cursorStringToContentValues(diffsCursor, People._SYNC_VERSION, mValues);
             DatabaseUtils.cursorStringToContentValues(diffsCursor, People._SYNC_ACCOUNT, mValues);
+            DatabaseUtils.cursorStringToContentValues(diffsCursor,
+                    People._SYNC_ACCOUNT_TYPE, mValues);
             DatabaseUtils.cursorStringToContentValues(diffsCursor, People.NAME, mValues);
             DatabaseUtils.cursorStringToContentValues(diffsCursor, People.PHONETIC_NAME, mValues);
             DatabaseUtils.cursorStringToContentValues(diffsCursor, People.NOTES, mValues);
@@ -3794,6 +3815,7 @@
             DatabaseUtils.cursorStringToContentValues(cursor, Groups._SYNC_TIME, mValues);
             DatabaseUtils.cursorStringToContentValues(cursor, Groups._SYNC_VERSION, mValues);
             DatabaseUtils.cursorStringToContentValues(cursor, Groups._SYNC_ACCOUNT, mValues);
+            DatabaseUtils.cursorStringToContentValues(cursor, Groups._SYNC_ACCOUNT_TYPE, mValues);
             DatabaseUtils.cursorStringToContentValues(cursor, Groups.NAME, mValues);
             DatabaseUtils.cursorStringToContentValues(cursor, Groups.NOTES, mValues);
             DatabaseUtils.cursorStringToContentValues(cursor, Groups.SYSTEM_ID, mValues);
@@ -3816,16 +3838,21 @@
                 // We may have just synced the metadata for a groups we previously marked for
                 // syncing.
                 final ContentResolver cr = getContext().getContentResolver();
-                final String account = mValues.getAsString(Groups._SYNC_ACCOUNT);
-                onLocalChangesForAccount(cr, account, false);
+                final String accountName = mValues.getAsString(Groups._SYNC_ACCOUNT);
+                final String accountType = mValues.getAsString(Groups._SYNC_ACCOUNT_TYPE);
+                onLocalChangesForAccount(cr, new Account(accountName, accountType), false);
             }
 
             String oldName = null;
             String newName = cursor.getString(cursor.getColumnIndexOrThrow(Groups.NAME));
-            String account = cursor.getString(cursor.getColumnIndexOrThrow(Groups._SYNC_ACCOUNT));
+            String accountName = cursor.getString(
+                    cursor.getColumnIndexOrThrow(Groups._SYNC_ACCOUNT));
+            String accountType = cursor.getString(
+                    cursor.getColumnIndexOrThrow(Groups._SYNC_ACCOUNT_TYPE));
             String syncId = cursor.getString(cursor.getColumnIndexOrThrow(Groups._SYNC_ID));
             // this must come after the insert, otherwise the join won't work
-            fixupPeopleStarredOnGroupRename(oldName, newName, account, syncId);
+            fixupPeopleStarredOnGroupRename(oldName, newName, new Account(accountName, accountType),
+                    syncId);
         }
 
         @Override
@@ -3846,16 +3873,21 @@
             String oldName = DatabaseUtils.stringForQuery(db,
                     "select name from groups where _id=" + localRowId, null);
             String newName = cursor.getString(cursor.getColumnIndexOrThrow(Groups.NAME));
-            String account = cursor.getString(cursor.getColumnIndexOrThrow(Groups._SYNC_ACCOUNT));
+            String accountName = cursor.getString(
+                    cursor.getColumnIndexOrThrow(Groups._SYNC_ACCOUNT));
+            String accountType = cursor.getString(
+                    cursor.getColumnIndexOrThrow(Groups._SYNC_ACCOUNT_TYPE));
             String syncId = cursor.getString(cursor.getColumnIndexOrThrow(Groups._SYNC_ID));
             // this can come before or after the delete
-            fixupPeopleStarredOnGroupRename(oldName, newName, account, syncId);
+            fixupPeopleStarredOnGroupRename(oldName, newName,
+                    new Account(accountName, accountType), syncId);
 
             mValues.clear();
             DatabaseUtils.cursorStringToContentValues(cursor, Groups._SYNC_ID, mValues);
             DatabaseUtils.cursorStringToContentValues(cursor, Groups._SYNC_TIME, mValues);
             DatabaseUtils.cursorStringToContentValues(cursor, Groups._SYNC_VERSION, mValues);
             DatabaseUtils.cursorStringToContentValues(cursor, Groups._SYNC_ACCOUNT, mValues);
+            DatabaseUtils.cursorStringToContentValues(cursor, Groups._SYNC_ACCOUNT_TYPE, mValues);
             DatabaseUtils.cursorStringToContentValues(cursor, Groups.NAME, mValues);
             DatabaseUtils.cursorStringToContentValues(cursor, Groups.NOTES, mValues);
             DatabaseUtils.cursorStringToContentValues(cursor, Groups.SYSTEM_ID, mValues);
@@ -3874,7 +3906,9 @@
                 c.moveToNext();
                 String oldName = c.getString(c.getColumnIndexOrThrow(Groups.NAME));
                 String newName = null;
-                String account = c.getString(c.getColumnIndexOrThrow(Groups._SYNC_ACCOUNT));
+                String accountName = c.getString(c.getColumnIndexOrThrow(Groups._SYNC_ACCOUNT));
+                String accountType = c.getString(
+                        c.getColumnIndexOrThrow(Groups._SYNC_ACCOUNT_TYPE));
                 String syncId = c.getString(c.getColumnIndexOrThrow(Groups._SYNC_ID));
                 String systemId = c.getString(c.getColumnIndexOrThrow(Groups.SYSTEM_ID));
                 if (!TextUtils.isEmpty(systemId)) {
@@ -3887,7 +3921,8 @@
                 }
 
                 // this must come before the delete, since the join won't work once this row is gone
-                fixupPeopleStarredOnGroupRename(oldName, newName, account, syncId);
+                fixupPeopleStarredOnGroupRename(oldName, newName,
+                        new Account(accountName, accountType), syncId);
             } finally {
                 c.close();
             }
@@ -4096,6 +4131,7 @@
     private static final HashMap<String, String> sPresenceProjectionMap;
     private static final HashMap<String, String> sEmailSearchProjectionMap;
     private static final HashMap<String, String> sOrganizationsProjectionMap;
+    private static final HashMap<String, String> sSearchSuggestionsProjectionMap;
     private static final HashMap<String, String> sGroupMembershipProjectionMap;
     private static final HashMap<String, String> sPhotosProjectionMap;
     private static final HashMap<String, String> sExtensionsProjectionMap;
@@ -4132,7 +4168,7 @@
             + "CASE WHEN (phonetic_name IS NOT NULL AND phonetic_name != '') "
                 + "THEN phonetic_name "
             + "ELSE "
-                + "(CASE WHEN (name is NOT NULL AND name != '') "
+                + "(CASE WHEN (name is NOT NULL AND name != '')"
                     + "THEN name "
                 + "ELSE "
                     + "(CASE WHEN primary_email IS NOT NULL THEN "
@@ -4149,9 +4185,6 @@
             + "END"
         + ")";
     
-    private static final String NAME_WHEN_SQL
-            = " WHEN name is NOT NULL ANd name != '' THEN name";
-    
     private static final String PRIMARY_ORGANIZATION_WHEN_SQL
             = " WHEN primary_organization is NOT NULL THEN "
             + "(SELECT company FROM organizations WHERE organizations._id = primary_organization)";
@@ -4205,92 +4238,6 @@
             + " THEN " + Presence.getPresenceIconResourceId(status);
     }
 
-
-    // This is similar to DISPLAY_NAME_SQL. Only difference is that this prioritize
-    // phonetic_name.
-    private static final String PHONETIC_LOOKUP_STRING_SQL = 
-        "GET_NORMALIZED_STRING("
-            + "CASE WHEN (phonetic_name IS NOT NULL AND phonetic_name != '') " 
-                + "THEN phonetic_name "
-            + "ELSE "
-                + "(CASE WHEN (name is NOT NULL AND name != '') "
-                    + "THEN name "
-                + "ELSE "
-                    + "(CASE WHEN primary_organization is NOT NULL THEN "
-                        + "(SELECT company FROM organizations WHERE "
-                            + "organizations._id = primary_organization) "
-                    + "ELSE "
-                        + "(CASE WHEN primary_phone IS NOT NULL THEN "
-                            +"(SELECT number FROM phones WHERE phones._id = primary_phone) "
-                        + "ELSE "
-                            + "(CASE WHEN primary_email IS NOT NULL THEN "
-                                + "(SELECT data FROM contact_methods WHERE "
-                                    + "contact_methods._id = primary_email) "
-                            + "ELSE "
-                                + "null "
-                            + "END) "
-                        + "END) "
-                    + "END) "
-                + "END) "
-            + "END)";
-
-    private static final String PHONETIC_SUGGEST_DESCRIPTION_SQL =
-        "(CASE"
-            + " WHEN (phonetic_name IS NOT NULL AND phonetic_name != '') THEN "
-            // PHONETIC_LOOKUP_STRING_SQL returns phonetic_name. try name, org, phone, email
-                + "(CASE"
-                    + NAME_WHEN_SQL
-                    + PRIMARY_ORGANIZATION_WHEN_SQL
-                    + PRIMARY_PHONE_WHEN_SQL
-                    + PRIMARY_EMAIL_WHEN_SQL
-                    + " ELSE null END)"
-            // PHONETIC_LOOKUP_STRING_SQL returns name, try org, phone, email
-            + " WHEN (name IS NOT NULL AND name != '') THEN "
-                + "(CASE"
-                    + PRIMARY_ORGANIZATION_WHEN_SQL
-                    + PRIMARY_PHONE_WHEN_SQL
-                    + PRIMARY_EMAIL_WHEN_SQL
-                    + " ELSE null END)"
-            // PHONETIC_LOOKUP_STRING_SQL returns org, try phone, email
-            + " WHEN primary_organization is NOT NULL THEN "
-                + "(CASE"
-                    + PRIMARY_PHONE_WHEN_SQL
-                    + PRIMARY_EMAIL_WHEN_SQL
-                    + " ELSE null END)"
-            // PHONETIC_LOOKUP_STRING_SQL returns phone, try email
-            + " WHEN primary_phone IS NOT NULL THEN "
-                + "(CASE"
-                    + PRIMARY_EMAIL_WHEN_SQL
-                    + " ELSE null END)"
-            // PHONETIC_LOOKUP_STRING_SQL returns email or NULL, return NULL
-        + " ELSE null END)";
-    
-    // "primary_organization" etc. are not considered here, since peopleLookup does not
-    // consider them either.
-    private static final String PHONETIC_LOOKUP_SQL_SIMPLE =
-        "GET_NORMALIZED_STRING("
-            + "CASE WHEN (phonetic_name IS NOT NULL AND phonetic_name != '') "
-                + "THEN phonetic_name "
-            + "ELSE "
-                + "(CASE WHEN (name is NOT NULL AND name != '') "
-                    + "THEN name "
-                + "ELSE "
-                    + "'' "
-                + "END) "
-            + "END)";
-    
-    private static final String PHONETIC_LOOKUP_SQL_SIMPLE_WITH_NEW =
-        "GET_NORMALIZED_STRING("
-            + "CASE WHEN (new.phonetic_name IS NOT NULL AND new.phonetic_name != '') "
-                + "THEN new.phonetic_name "
-            + "ELSE "
-                + "(CASE WHEN (new.name is NOT NULL AND new.name != '') "
-                    + "THEN new.name "
-                + "ELSE "
-                    + "'' "
-                + "END) "
-            + "END)";
-    
     private static final String[] sPhonesKeyColumns;
     private static final String[] sContactMethodsKeyColumns;
     private static final String[] sOrganizationsKeyColumns;
@@ -4312,28 +4259,6 @@
         return (sb == null) ? "" : sb.toString();
     }
 
-    /**
-     * @return true when phonetic_name should be considered when looking up people's names.
-     */
-    private synchronized boolean usePhoneticNameForPeopleLookup() {
-        return mSearchSuggestionLanguage.equals(Locale.JAPAN.getLanguage());
-    }
-    
-    private void updateSuggestColumnTexts() {
-        if (usePhoneticNameForPeopleLookup()) {
-            mSearchSuggestionsProjectionMap.put(SearchManager.SUGGEST_COLUMN_TEXT_1,
-                    PHONETIC_LOOKUP_STRING_SQL + " AS " + SearchManager.SUGGEST_COLUMN_TEXT_1);
-            mSearchSuggestionsProjectionMap.put(SearchManager.SUGGEST_COLUMN_TEXT_2,
-                    PHONETIC_SUGGEST_DESCRIPTION_SQL + " AS " + 
-                    SearchManager.SUGGEST_COLUMN_TEXT_2);
-        } else {
-            mSearchSuggestionsProjectionMap.put(SearchManager.SUGGEST_COLUMN_TEXT_1,
-                    DISPLAY_NAME_SQL + " AS " + SearchManager.SUGGEST_COLUMN_TEXT_1);
-            mSearchSuggestionsProjectionMap.put(SearchManager.SUGGEST_COLUMN_TEXT_2,
-                    SUGGEST_DESCRIPTION_SQL + " AS " + SearchManager.SUGGEST_COLUMN_TEXT_2);
-        }
-    }
-    
     static {
         // Contacts URI matching table
         UriMatcher matcher = sURIMatcher;
@@ -4463,6 +4388,7 @@
         syncColumns.put(SyncConstValue._SYNC_LOCAL_ID, SyncConstValue._SYNC_LOCAL_ID);
         syncColumns.put(SyncConstValue._SYNC_DIRTY, SyncConstValue._SYNC_DIRTY);
         syncColumns.put(SyncConstValue._SYNC_ACCOUNT, SyncConstValue._SYNC_ACCOUNT);
+        syncColumns.put(SyncConstValue._SYNC_ACCOUNT_TYPE, SyncConstValue._SYNC_ACCOUNT_TYPE);
 
         // Phones columns
         HashMap<String, String> phonesColumns = new HashMap<String, String>();
@@ -4491,8 +4417,10 @@
         // People with E-mail or IM projection map
         map = new HashMap<String, String>();
         map.put(People._ID, "people._id AS " + People._ID);
-        map.put(ContactMethods.DATA, "contact_methods." + ContactMethods.DATA + " AS " + ContactMethods.DATA);
-        map.put(ContactMethods.KIND, "contact_methods." + ContactMethods.KIND + " AS " + ContactMethods.KIND);
+        map.put(ContactMethods.DATA,
+                "contact_methods." + ContactMethods.DATA + " AS " + ContactMethods.DATA);
+        map.put(ContactMethods.KIND,
+                "contact_methods." + ContactMethods.KIND + " AS " + ContactMethods.KIND);
         map.putAll(peopleColumns);
         sPeopleWithEmailOrImProjectionMap = map;
         
@@ -4509,6 +4437,7 @@
         map.put(GroupMembership.PERSON_ID, GroupMembership.PERSON_ID);
         map.put(GroupMembership.GROUP_ID, "groups._id AS " + GroupMembership.GROUP_ID);
         map.put(GroupMembership.GROUP_SYNC_ACCOUNT, GroupMembership.GROUP_SYNC_ACCOUNT);
+        map.put(GroupMembership.GROUP_SYNC_ACCOUNT_TYPE, GroupMembership.GROUP_SYNC_ACCOUNT_TYPE);
         map.put(GroupMembership.GROUP_SYNC_ID, GroupMembership.GROUP_SYNC_ID);
         map.putAll(groupsColumns);
         sGroupMembershipProjectionMap = map;
@@ -4597,6 +4526,27 @@
         map.putAll(peopleColumns);
         sPresenceProjectionMap = map;
 
+        // Search suggestions projection map
+        map = new HashMap<String, String>();
+        map.put(SearchManager.SUGGEST_COLUMN_TEXT_1,
+                DISPLAY_NAME_SQL + " AS " + SearchManager.SUGGEST_COLUMN_TEXT_1);
+        map.put(SearchManager.SUGGEST_COLUMN_TEXT_2,
+                SUGGEST_DESCRIPTION_SQL + " AS " + SearchManager.SUGGEST_COLUMN_TEXT_2);
+        map.put(SearchManager.SUGGEST_COLUMN_ICON_1,
+                "(CASE WHEN " + Photos.DATA + " IS NOT NULL"
+                + " THEN '" + People.CONTENT_URI + "/' || people._id ||"
+                        + " '/" + Photos.CONTENT_DIRECTORY + "/data'"
+                + " ELSE " + com.android.internal.R.drawable.ic_contact_picture
+                + " END) AS " + SearchManager.SUGGEST_COLUMN_ICON_1);
+        map.put(SearchManager.SUGGEST_COLUMN_ICON_2,
+                PRESENCE_ICON_SQL + " AS " + SearchManager.SUGGEST_COLUMN_ICON_2);
+        map.put(SearchManager.SUGGEST_COLUMN_INTENT_DATA_ID,
+                "people._id AS " + SearchManager.SUGGEST_COLUMN_INTENT_DATA_ID);
+        map.put(SearchManager.SUGGEST_COLUMN_SHORTCUT_ID,
+                "people._id AS " + SearchManager.SUGGEST_COLUMN_SHORTCUT_ID);
+        map.put(People._ID, "people._id AS " + People._ID);
+        sSearchSuggestionsProjectionMap = map;
+
         // Photos projection map
         map = new HashMap<String, String>();
         map.put(Photos._ID, Photos._ID);
@@ -4628,18 +4578,22 @@
                 ContactMethods.DATA, ContactMethods.KIND);
         sOrganizationsKeyOrderBy = buildOrderBy(sOrganizationsTable, Organizations.COMPANY);
         sGroupmembershipKeyOrderBy =
-                buildOrderBy(sGroupmembershipTable, GroupMembership.GROUP_SYNC_ACCOUNT);
+                buildOrderBy(sGroupmembershipTable, GroupMembership.GROUP_SYNC_ACCOUNT_TYPE,
+                        GroupMembership.GROUP_SYNC_ACCOUNT);
 
         sPhonesKeyColumns = new String[]{Phones.NUMBER};
         sContactMethodsKeyColumns = new String[]{ContactMethods.DATA, ContactMethods.KIND};
         sOrganizationsKeyColumns = new String[]{Organizations.COMPANY};
-        sGroupmembershipKeyColumns = new String[]{GroupMembership.GROUP_SYNC_ACCOUNT};
+        sGroupmembershipKeyColumns = new String[]{GroupMembership.GROUP_SYNC_ACCOUNT,
+                GroupMembership.GROUP_SYNC_ACCOUNT_TYPE};
         sExtensionsKeyColumns = new String[]{Extensions.NAME};
 
         String groupJoinByLocalId = "groups._id=groupmembership.group_id";
         String groupJoinByServerId = "("
                 + "groups._sync_account=groupmembership.group_sync_account"
                 + " AND "
+                + "groups._sync_account_type=groupmembership.group_sync_account_type"
+                + " AND "
                 + "groups._sync_id=groupmembership.group_sync_id"
                 + ")";
         sGroupsJoinString = "(" + groupJoinByLocalId + " OR " + groupJoinByServerId + ")";
diff --git a/src/com/android/providers/contacts/ContactsProvider2.java b/src/com/android/providers/contacts/ContactsProvider2.java
new file mode 100644
index 0000000..d8af3da
--- /dev/null
+++ b/src/com/android/providers/contacts/ContactsProvider2.java
@@ -0,0 +1,2905 @@
+/*
+ * 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.content.SyncStateContentProviderHelper;
+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.DataColumns;
+import com.android.providers.contacts.OpenHelper.GroupsColumns;
+import com.android.providers.contacts.OpenHelper.MimetypesColumns;
+import com.android.providers.contacts.OpenHelper.PackagesColumns;
+import com.android.providers.contacts.OpenHelper.PhoneColumns;
+import com.android.providers.contacts.OpenHelper.PhoneLookupColumns;
+import com.android.providers.contacts.OpenHelper.RawContactsColumns;
+import com.android.providers.contacts.OpenHelper.Tables;
+import com.google.android.collect.Lists;
+
+import android.accounts.Account;
+import android.app.SearchManager;
+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.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.RawContacts;
+import android.provider.ContactsContract.CommonDataKinds.BaseTypes;
+import android.provider.ContactsContract.CommonDataKinds.Email;
+import android.provider.ContactsContract.CommonDataKinds.GroupMembership;
+import android.provider.ContactsContract.CommonDataKinds.Im;
+import android.provider.ContactsContract.CommonDataKinds.Nickname;
+import android.provider.ContactsContract.CommonDataKinds.Organization;
+import android.provider.ContactsContract.CommonDataKinds.Phone;
+import android.provider.ContactsContract.CommonDataKinds.StructuredName;
+import android.provider.ContactsContract.CommonDataKinds.StructuredPostal;
+import android.provider.ContactsContract.Contacts.AggregationSuggestions;
+import android.telephony.PhoneNumberUtils;
+import android.text.TextUtils;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+
+/**
+ * Contacts content provider. The contract between this provider and applications
+ * is defined in {@link ContactsContract}.
+ */
+public class ContactsProvider2 extends ContentProvider {
+    // TODO: clean up debug tag and rename this class
+    private static final String TAG = "ContactsProvider ~~~~";
+
+    // TODO: carefully prevent all incoming nested queries; they can be gaping security holes
+    // TODO: check for restricted flag during insert(), update(), and delete() calls
+
+    /** Default for the maximum number of returned aggregation suggestions. */
+    private static final int DEFAULT_MAX_SUGGESTIONS = 5;
+
+    private static final UriMatcher sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
+
+    private static final String STREQUENT_ORDER_BY = Contacts.STARRED + " DESC, "
+            + Contacts.TIMES_CONTACTED + " DESC, "
+            + Contacts.DISPLAY_NAME + " ASC";
+    private static final String STREQUENT_LIMIT =
+            "(SELECT COUNT(1) FROM " + Tables.CONTACTS + " WHERE "
+            + Contacts.STARRED + "=1) + 25";
+
+    private static final int CONTACTS = 1000;
+    private static final int CONTACTS_ID = 1001;
+    private static final int CONTACTS_DATA = 1002;
+    private static final int CONTACTS_SUMMARY = 1003;
+    private static final int CONTACTS_RAW_CONTACTS = 1004;
+    private static final int CONTACTS_SUMMARY_ID = 1005;
+    private static final int CONTACTS_SUMMARY_FILTER = 1006;
+    private static final int CONTACTS_SUMMARY_STREQUENT = 1007;
+    private static final int CONTACTS_SUMMARY_STREQUENT_FILTER = 1008;
+    private static final int CONTACTS_SUMMARY_GROUP = 1009;
+
+    private static final int RAW_CONTACTS = 2002;
+    private static final int RAW_CONTACTS_ID = 2003;
+    private static final int RAW_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 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 GROUPS = 10000;
+    private static final int GROUPS_ID = 10001;
+    private static final int GROUPS_SUMMARY = 10003;
+
+    private static final int SYNCSTATE = 11000;
+
+    private static final int SEARCH_SUGGESTIONS = 12001;
+    private static final int SEARCH_SHORTCUT = 12002;
+
+    private interface ContactsQuery {
+        public static final String TABLE = Tables.RAW_CONTACTS;
+
+        public static final String[] PROJECTION = new String[] {
+            RawContactsColumns.CONCRETE_ID,
+            RawContacts.ACCOUNT_NAME,
+            RawContacts.ACCOUNT_TYPE,
+        };
+
+        public static final int RAW_CONTACT_ID = 0;
+        public static final int ACCOUNT_NAME = 1;
+        public static final int ACCOUNT_TYPE = 2;
+    }
+
+    private interface DataRawContactsQuery {
+        public static final String TABLE = Tables.DATA_JOIN_MIMETYPE_RAW_CONTACTS;
+
+        public static final String[] PROJECTION = new String[] {
+            RawContactsColumns.CONCRETE_ID,
+            DataColumns.CONCRETE_ID,
+            RawContacts.CONTACT_ID,
+            RawContacts.IS_RESTRICTED,
+            Data.MIMETYPE,
+        };
+
+        public static final int RAW_CONTACT_ID = 0;
+        public static final int DATA_ID = 1;
+        public static final int CONTACT_ID = 2;
+        public static final int IS_RESTRICTED = 3;
+        public static final int MIMETYPE = 4;
+    }
+
+    private interface DataContactsQuery {
+        public static final String TABLE = Tables.DATA_JOIN_MIMETYPES_RAW_CONTACTS_CONTACTS;
+
+        public static final String[] PROJECTION = new String[] {
+            RawContactsColumns.CONCRETE_ID,
+            DataColumns.CONCRETE_ID,
+            ContactsColumns.CONCRETE_ID,
+            MimetypesColumns.CONCRETE_ID,
+            Phone.NUMBER,
+            Email.DATA,
+            ContactsColumns.OPTIMAL_PRIMARY_PHONE_ID,
+            ContactsColumns.FALLBACK_PRIMARY_PHONE_ID,
+            ContactsColumns.OPTIMAL_PRIMARY_EMAIL_ID,
+            ContactsColumns.FALLBACK_PRIMARY_EMAIL_ID,
+        };
+
+        public static final int RAW_CONTACT_ID = 0;
+        public static final int DATA_ID = 1;
+        public static final int CONTACT_ID = 2;
+        public static final int MIMETYPE_ID = 3;
+        public static final int PHONE_NUMBER = 4;
+        public static final int EMAIL_DATA = 5;
+        public static final int OPTIMAL_PHONE_ID = 6;
+        public static final int FALLBACK_PHONE_ID = 7;
+        public static final int OPTIMAL_EMAIL_ID = 8;
+        public static final int FALLBACK_EMAIL_ID = 9;
+
+    }
+
+    private interface DisplayNameQuery {
+        public static final String TABLE = Tables.DATA_JOIN_MIMETYPES;
+
+        public static final String[] COLUMNS = new String[] {
+            MimetypesColumns.MIMETYPE,
+            Data.IS_PRIMARY,
+            Data.DATA2,
+            StructuredName.DISPLAY_NAME,
+        };
+
+        public static final int MIMETYPE = 0;
+        public static final int IS_PRIMARY = 1;
+        public static final int DATA2 = 2;
+        public static final int DISPLAY_NAME = 3;
+    }
+
+    private interface DataQuery {
+        public static final String TABLE = Tables.DATA_JOIN_MIMETYPES;
+
+        public static final String[] COLUMNS = new String[] {
+            DataColumns.CONCRETE_ID,
+            MimetypesColumns.MIMETYPE,
+            Data.RAW_CONTACT_ID,
+            Data.IS_PRIMARY,
+            Data.DATA1,
+            Data.DATA2,
+            Data.DATA3,
+            Data.DATA4,
+            Data.DATA5,
+            Data.DATA6,
+            Data.DATA7,
+            Data.DATA8,
+            Data.DATA9,
+            Data.DATA10,
+            Data.DATA11,
+            Data.DATA12,
+            Data.DATA13,
+            Data.DATA14,
+            Data.DATA15,
+        };
+
+        public static final int ID = 0;
+        public static final int MIMETYPE = 1;
+        public static final int RAW_CONTACT_ID = 2;
+        public static final int IS_PRIMARY = 3;
+        public static final int DATA1 = 4;
+        public static final int DATA2 = 5;
+        public static final int DATA3 = 6;
+        public static final int DATA4 = 7;
+        public static final int DATA5 = 8;
+        public static final int DATA6 = 9;
+        public static final int DATA7 = 10;
+        public static final int DATA8 = 11;
+        public static final int DATA9 = 12;
+        public static final int DATA10 = 13;
+        public static final int DATA11 = 14;
+        public static final int DATA12 = 15;
+        public static final int DATA13 = 16;
+        public static final int DATA14 = 17;
+        public static final int DATA15 = 18;
+    }
+
+    private interface DataIdQuery {
+        String[] COLUMNS = { Data._ID };
+
+        int _ID = 0;
+    }
+
+    // Higher number represents higher priority in choosing what data to use for the display name
+    private static final int DISPLAY_NAME_PRIORITY_EMAIL = 1;
+    private static final int DISPLAY_NAME_PRIORITY_PHONE = 2;
+    private static final int DISPLAY_NAME_PRIORITY_ORGANIZATION = 3;
+    private static final int DISPLAY_NAME_PRIORITY_STRUCTURED_NAME = 4;
+
+    private static final HashMap<String, Integer> sDisplayNamePriorities;
+    static {
+        sDisplayNamePriorities = new HashMap<String, Integer>();
+        sDisplayNamePriorities.put(StructuredName.CONTENT_ITEM_TYPE,
+                DISPLAY_NAME_PRIORITY_STRUCTURED_NAME);
+        sDisplayNamePriorities.put(Organization.CONTENT_ITEM_TYPE,
+                DISPLAY_NAME_PRIORITY_ORGANIZATION);
+        sDisplayNamePriorities.put(Phone.CONTENT_ITEM_TYPE,
+                DISPLAY_NAME_PRIORITY_PHONE);
+        sDisplayNamePriorities.put(Email.CONTENT_ITEM_TYPE,
+                DISPLAY_NAME_PRIORITY_EMAIL);
+    }
+
+    /** Contains just the contacts columns */
+    private static final HashMap<String, String> sContactsProjectionMap;
+    /** Contains the contact columns along with primary phone */
+    private static final HashMap<String, String> sContactsSummaryProjectionMap;
+    /** Contains the data, contacts, and contact columns, for joined tables. */
+    private static final HashMap<String, String> sDataRawContactsContactProjectionMap;
+    /** Contains the data, contacts, group sourceid and contact columns, for joined tables. */
+    private static final HashMap<String, String> sDataRawContactsGroupsContactProjectionMap;
+    /** Contains the contacts, and raw contact columns, for joined tables. */
+    private static final HashMap<String, String> sRawContactsContactsProjectionMap;
+    /** Contains just the contacts columns */
+    private static final HashMap<String, String> sRawContactsProjectionMap;
+    /** Contains just the data columns */
+    private static final HashMap<String, String> sDataGroupsProjectionMap;
+    /** Contains the data and contacts columns, for joined tables */
+    private static final HashMap<String, String> sDataRawContactsGroupsProjectionMap;
+    /** Contains the data and contacts columns, for joined tables */
+    private static final HashMap<String, String> sDataRawContactsProjectionMap;
+    /** 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 agg_exceptions columns */
+    private static final HashMap<String, String> sAggregationExceptionsProjectionMap;
+    /** Contains Presence columns */
+    private static final HashMap<String, String> sPresenceProjectionMap;
+
+    /** Sql select statement that returns the contact id associated with a data record. */
+    private static final String sNestedRawContactIdSelect;
+    /** Sql select statement that returns the mimetype id associated with a data record. */
+    private static final String sNestedMimetypeSelect;
+    /** Sql select statement that returns the contact id associated with a contact record. */
+    private static final String sNestedContactIdSelect;
+    /** Sql select statement that returns a list of contact ids associated with an contact 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;
+    /** Sql where statement for filtering on groups. */
+    private static final String sContactsInGroupSelect;
+    /** Precompiled sql statement for setting a data record to the primary. */
+    private SQLiteStatement mSetPrimaryStatement;
+    /** Precompiled sql statement for setting a data record to the super primary. */
+    private SQLiteStatement mSetSuperPrimaryStatement;
+    /** Precompiled sql statement for incrementing times contacted for an contact */
+    private SQLiteStatement mLastTimeContactedUpdate;
+    /** Precompiled sql statement for updating a contact display name */
+    private SQLiteStatement mContactDisplayNameUpdate;
+
+    static {
+        // Contacts URI matching table
+        final UriMatcher matcher = sUriMatcher;
+        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/#/raw_contacts", CONTACTS_RAW_CONTACTS);
+        matcher.addURI(ContactsContract.AUTHORITY, "contacts_summary", CONTACTS_SUMMARY);
+        matcher.addURI(ContactsContract.AUTHORITY, "contacts_summary/#", CONTACTS_SUMMARY_ID);
+        matcher.addURI(ContactsContract.AUTHORITY, "contacts_summary/filter/*",
+                CONTACTS_SUMMARY_FILTER);
+        matcher.addURI(ContactsContract.AUTHORITY, "contacts_summary/strequent/",
+                CONTACTS_SUMMARY_STREQUENT);
+        matcher.addURI(ContactsContract.AUTHORITY, "contacts_summary/strequent/filter/*",
+                CONTACTS_SUMMARY_STREQUENT_FILTER);
+        matcher.addURI(ContactsContract.AUTHORITY, "contacts_summary/group/*",
+                CONTACTS_SUMMARY_GROUP);
+        matcher.addURI(ContactsContract.AUTHORITY, "contacts/#/suggestions",
+                AGGREGATION_SUGGESTIONS);
+        matcher.addURI(ContactsContract.AUTHORITY, "raw_contacts", RAW_CONTACTS);
+        matcher.addURI(ContactsContract.AUTHORITY, "raw_contacts/#", RAW_CONTACTS_ID);
+        matcher.addURI(ContactsContract.AUTHORITY, "raw_contacts/#/data", RAW_CONTACTS_DATA);
+        matcher.addURI(ContactsContract.AUTHORITY, "raw_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, SyncStateContentProviderHelper.PATH, SYNCSTATE);
+
+        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, SearchManager.SUGGEST_URI_PATH_QUERY,
+                SEARCH_SUGGESTIONS);
+        matcher.addURI(ContactsContract.AUTHORITY, SearchManager.SUGGEST_URI_PATH_QUERY + "/*",
+                SEARCH_SUGGESTIONS);
+        matcher.addURI(ContactsContract.AUTHORITY, SearchManager.SUGGEST_URI_PATH_SHORTCUT + "/#",
+                SEARCH_SHORTCUT);
+
+        HashMap<String, String> columns;
+
+        // Contacts projection map
+        columns = new HashMap<String, String>();
+        columns.put(Contacts._ID, "contacts._id AS _id");
+        columns.put(Contacts.DISPLAY_NAME, ContactsColumns.CONCRETE_DISPLAY_NAME + " AS "
+                + Contacts.DISPLAY_NAME);
+        columns.put(Contacts.LAST_TIME_CONTACTED, ContactsColumns.CONCRETE_LAST_TIME_CONTACTED
+                + " AS " + Contacts.LAST_TIME_CONTACTED);
+        columns.put(Contacts.TIMES_CONTACTED, ContactsColumns.CONCRETE_TIMES_CONTACTED + " AS "
+                + Contacts.TIMES_CONTACTED);
+        columns.put(Contacts.STARRED, ContactsColumns.CONCRETE_STARRED + " AS "
+                + Contacts.STARRED);
+        columns.put(Contacts.IN_VISIBLE_GROUP, Contacts.IN_VISIBLE_GROUP);
+        columns.put(Contacts.PHOTO_ID, Contacts.PHOTO_ID);
+        columns.put(Contacts.PRIMARY_PHONE_ID, Contacts.PRIMARY_PHONE_ID);
+        columns.put(Contacts.PRIMARY_EMAIL_ID, Contacts.PRIMARY_EMAIL_ID);
+        columns.put(Contacts.CUSTOM_RINGTONE, ContactsColumns.CONCRETE_CUSTOM_RINGTONE + " AS "
+                + Contacts.CUSTOM_RINGTONE);
+        columns.put(Contacts.SEND_TO_VOICEMAIL, ContactsColumns.CONCRETE_SEND_TO_VOICEMAIL
+                + " AS " + Contacts.SEND_TO_VOICEMAIL);
+        columns.put(ContactsColumns.FALLBACK_PRIMARY_PHONE_ID,
+                ContactsColumns.FALLBACK_PRIMARY_PHONE_ID);
+        columns.put(ContactsColumns.FALLBACK_PRIMARY_EMAIL_ID,
+                ContactsColumns.FALLBACK_PRIMARY_EMAIL_ID);
+        sContactsProjectionMap = columns;
+
+        columns = new HashMap<String, String>();
+        columns.putAll(sContactsProjectionMap);
+
+        // Contacts primaries projection map. The overall presence status is
+        // the most-present value, as indicated by the largest value.
+        columns.put(Contacts.PRESENCE_STATUS, "MAX(" + Presence.PRESENCE_STATUS + ")");
+        columns.put(Contacts.PRIMARY_PHONE_TYPE, CommonDataKinds.Phone.TYPE);
+        columns.put(Contacts.PRIMARY_PHONE_LABEL, CommonDataKinds.Phone.LABEL);
+        columns.put(Contacts.PRIMARY_PHONE_NUMBER, CommonDataKinds.Phone.NUMBER);
+        sContactsSummaryProjectionMap = columns;
+
+        // RawContacts projection map
+        columns = new HashMap<String, String>();
+        columns.put(RawContacts._ID, Tables.RAW_CONTACTS + "." + RawContacts._ID + " AS _id");
+        columns.put(RawContacts.CONTACT_ID, RawContacts.CONTACT_ID);
+        columns.put(RawContacts.ACCOUNT_NAME,
+                OpenHelper.RawContactsColumns.CONCRETE_ACCOUNT_NAME
+                        + " AS " + RawContacts.ACCOUNT_NAME);
+        columns.put(RawContacts.ACCOUNT_TYPE,
+                OpenHelper.RawContactsColumns.CONCRETE_ACCOUNT_TYPE
+                        + " AS " + RawContacts.ACCOUNT_TYPE);
+        columns.put(RawContacts.SOURCE_ID,
+                OpenHelper.RawContactsColumns.CONCRETE_SOURCE_ID
+                        + " AS " + RawContacts.SOURCE_ID);
+        columns.put(RawContacts.VERSION,
+                OpenHelper.RawContactsColumns.CONCRETE_VERSION
+                        + " AS " + RawContacts.VERSION);
+        columns.put(RawContacts.DIRTY,
+                OpenHelper.RawContactsColumns.CONCRETE_DIRTY
+                        + " AS " + RawContacts.DIRTY);
+        columns.put(RawContacts.DELETED,
+                OpenHelper.RawContactsColumns.CONCRETE_DELETED
+                        + " AS " + RawContacts.DELETED);
+        sRawContactsProjectionMap = columns;
+
+        columns = new HashMap<String, String>();
+        columns.putAll(sContactsProjectionMap);
+        columns.putAll(sRawContactsProjectionMap);
+        sRawContactsContactsProjectionMap = columns;
+
+        // Data projection map
+        columns = new HashMap<String, String>();
+        columns.put(Data._ID, Tables.DATA + "." + Data._ID + " AS _id");
+        columns.put(Data.RAW_CONTACT_ID, Data.RAW_CONTACT_ID);
+        columns.put(Data.RES_PACKAGE, PackagesColumns.PACKAGE + " AS " + Data.RES_PACKAGE);
+        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");
+        columns.put(Data.DATA11, "data.data11 as data11");
+        columns.put(Data.DATA12, "data.data12 as data12");
+        columns.put(Data.DATA13, "data.data13 as data13");
+        columns.put(Data.DATA14, "data.data14 as data14");
+        columns.put(Data.DATA15, "data.data15 as data15");
+        columns.put(GroupMembership.GROUP_SOURCE_ID, GroupsColumns.CONCRETE_SOURCE_ID + " AS "
+                + GroupMembership.GROUP_SOURCE_ID);
+
+        // TODO: remove this projection
+        // Mappings used for backwards compatibility.
+        columns.put("number", Phone.NUMBER);
+        sDataGroupsProjectionMap = columns;
+
+        // Data, groups and contacts projection map for joins. _id comes from the data table
+        columns = new HashMap<String, String>();
+        columns.putAll(sRawContactsProjectionMap);
+        columns.putAll(sDataGroupsProjectionMap); // _id will be replaced with the one from data
+        columns.put(Data.RAW_CONTACT_ID, DataColumns.CONCRETE_RAW_CONTACT_ID);
+        sDataRawContactsGroupsProjectionMap = columns;
+
+        // Data and contacts projection map for joins. _id comes from the data table
+        columns = new HashMap<String, String>();
+        columns.putAll(sDataRawContactsGroupsProjectionMap);
+        columns.remove(GroupMembership.GROUP_SOURCE_ID);
+        sDataRawContactsProjectionMap = columns;
+
+        // Data and contacts projection map for joins. _id comes from the data table
+        columns = new HashMap<String, String>();
+        columns.putAll(sContactsProjectionMap);
+        columns.putAll(sRawContactsProjectionMap); //
+        columns.putAll(sDataGroupsProjectionMap); // _id will be replaced with the one from data
+        columns.put(Data.RAW_CONTACT_ID, DataColumns.CONCRETE_RAW_CONTACT_ID);
+        sDataRawContactsGroupsContactProjectionMap = columns;
+
+        // Data and contacts projection map for joins. _id comes from the data table
+        columns = new HashMap<String, String>();
+        columns.putAll(sDataRawContactsGroupsContactProjectionMap);
+        columns.remove(GroupMembership.GROUP_SOURCE_ID);
+        sDataRawContactsContactProjectionMap = columns;
+
+        // Groups projection map
+        columns = new HashMap<String, String>();
+        columns.put(Groups._ID, "groups._id AS _id");
+        columns.put(Groups.ACCOUNT_NAME, Groups.ACCOUNT_NAME);
+        columns.put(Groups.ACCOUNT_TYPE, Groups.ACCOUNT_TYPE);
+        columns.put(Groups.SOURCE_ID, Groups.SOURCE_ID);
+        columns.put(Groups.DIRTY, Groups.DIRTY);
+        columns.put(Groups.VERSION, Groups.VERSION);
+        columns.put(Groups.RES_PACKAGE, PackagesColumns.PACKAGE + " AS " + Groups.RES_PACKAGE);
+        columns.put(Groups.TITLE, Groups.TITLE);
+        columns.put(Groups.TITLE_RES, Groups.TITLE_RES);
+        columns.put(Groups.GROUP_VISIBLE, Groups.GROUP_VISIBLE);
+        sGroupsProjectionMap = columns;
+
+        // RawContacts and groups projection map
+        columns = new HashMap<String, String>();
+        columns.putAll(sGroupsProjectionMap);
+
+        columns.put(Groups.SUMMARY_COUNT, "(SELECT COUNT(DISTINCT " + ContactsColumns.CONCRETE_ID
+                + ") FROM " + Tables.DATA_JOIN_MIMETYPES_RAW_CONTACTS_CONTACTS + " WHERE "
+                + Clauses.MIMETYPE_IS_GROUP_MEMBERSHIP + " AND " + Clauses.BELONGS_TO_GROUP
+                + ") AS " + Groups.SUMMARY_COUNT);
+
+        columns.put(Groups.SUMMARY_WITH_PHONES, "(SELECT COUNT(DISTINCT "
+                + ContactsColumns.CONCRETE_ID + ") FROM "
+                + Tables.DATA_JOIN_MIMETYPES_RAW_CONTACTS_CONTACTS + " 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.CONTACT_ID,
+                "raw_contacts1." + RawContacts.CONTACT_ID
+                + " AS " + AggregationExceptions.CONTACT_ID);
+        columns.put(AggregationExceptions.RAW_CONTACT_ID, AggregationExceptionColumns.RAW_CONTACT_ID2);
+        sAggregationExceptionsProjectionMap = columns;
+
+
+        columns = new HashMap<String, String>();
+        columns.put(Presence._ID, Presence._ID);
+        columns.put(Presence.RAW_CONTACT_ID, Presence.RAW_CONTACT_ID);
+        columns.put(Presence.DATA_ID, Presence.DATA_ID);
+        columns.put(Presence.IM_ACCOUNT, Presence.IM_ACCOUNT);
+        columns.put(Presence.IM_HANDLE, Presence.IM_HANDLE);
+        columns.put(Presence.IM_PROTOCOL, Presence.IM_PROTOCOL);
+        columns.put(Presence.PRESENCE_STATUS, Presence.PRESENCE_STATUS);
+        columns.put(Presence.PRESENCE_CUSTOM_STATUS, Presence.PRESENCE_CUSTOM_STATUS);
+        sPresenceProjectionMap = columns;
+
+        sNestedRawContactIdSelect = "SELECT " + Data.RAW_CONTACT_ID + " FROM " + Tables.DATA + " WHERE "
+                + Data._ID + "=?";
+        sNestedMimetypeSelect = "SELECT " + DataColumns.MIMETYPE_ID + " FROM " + Tables.DATA
+                + " WHERE " + Data._ID + "=?";
+        sNestedContactIdSelect = "SELECT " + RawContacts.CONTACT_ID + " FROM " + Tables.RAW_CONTACTS
+                + " WHERE " + RawContacts._ID + "=(" + sNestedRawContactIdSelect + ")";
+        sNestedContactIdListSelect = "SELECT " + RawContacts._ID + " FROM " + Tables.RAW_CONTACTS
+                + " WHERE " + RawContacts.CONTACT_ID + "=(" + sNestedContactIdSelect + ")";
+        sSetPrimaryWhere = Data.RAW_CONTACT_ID + "=(" + sNestedRawContactIdSelect + ") AND "
+                + DataColumns.MIMETYPE_ID + "=(" + sNestedMimetypeSelect + ")";
+        sSetSuperPrimaryWhere = Data.RAW_CONTACT_ID + " IN (" + sNestedContactIdListSelect + ") AND "
+                + DataColumns.MIMETYPE_ID + "=(" + sNestedMimetypeSelect + ")";
+        sContactsInGroupSelect = ContactsColumns.CONCRETE_ID + " IN (SELECT "
+                + RawContacts.CONTACT_ID + " FROM " + Tables.RAW_CONTACTS + " WHERE ("
+                + RawContactsColumns.CONCRETE_ID + " IN (SELECT " + Tables.DATA + "."
+                + Data.RAW_CONTACT_ID + " FROM " + Tables.DATA_JOIN_MIMETYPES + " WHERE ("
+                + Data.MIMETYPE + "='" + GroupMembership.CONTENT_ITEM_TYPE + "' AND "
+                + GroupMembership.GROUP_ROW_ID + "=(SELECT " + Tables.GROUPS + "."
+                + Groups._ID + " FROM " + Tables.GROUPS + " WHERE " + Groups.TITLE + "=?)))))";
+    }
+
+    /**
+     * Handles inserts and update for a specific Data type.
+     */
+    private abstract class DataRowHandler {
+
+        protected final String mMimetype;
+
+        public DataRowHandler(String mimetype) {
+            mMimetype = mimetype;
+        }
+
+        /**
+         * Inserts a row into the {@link Data} table.
+         */
+        public long insert(SQLiteDatabase db, long rawContactId, ContentValues values) {
+            final long dataId = db.insert(Tables.DATA, null, values);
+
+            Integer primary = values.getAsInteger(Data.IS_PRIMARY);
+            if (primary != null && primary != 0) {
+                setIsPrimary(dataId);
+            }
+
+            fixContactDisplayName(db, rawContactId);
+            return dataId;
+        }
+
+        /**
+         * Validates data and updates a {@link Data} row using the cursor, which contains
+         * the current data.
+         */
+        public void update(SQLiteDatabase db, ContentValues values, Cursor cursor) {
+            throw new UnsupportedOperationException();
+        }
+
+        public int delete(SQLiteDatabase db, Cursor c) {
+            long dataId = c.getLong(DataQuery.ID);
+            long rawContactId = c.getLong(DataQuery.RAW_CONTACT_ID);
+            boolean primary = c.getInt(DataQuery.IS_PRIMARY) != 0;
+            int count = db.delete(Tables.DATA, Data._ID + "=" + dataId, null);
+            if (count != 0 && primary) {
+                fixPrimary(db, rawContactId);
+                fixContactDisplayName(db, rawContactId);
+            }
+            return count;
+        }
+
+        private void fixPrimary(SQLiteDatabase db, long rawContactId) {
+            long newPrimaryId = findNewPrimaryDataId(db, rawContactId);
+            if (newPrimaryId != -1) {
+                ContactsProvider2.this.setIsPrimary(newPrimaryId);
+            }
+        }
+
+        protected long findNewPrimaryDataId(SQLiteDatabase db, long rawContactId) {
+            long primaryId = -1;
+            int primaryType = -1;
+            Cursor c = queryData(db, rawContactId);
+            try {
+                while (c.moveToNext()) {
+                    long dataId = c.getLong(DataQuery.ID);
+                    int type = c.getInt(DataQuery.DATA2);
+                    if (primaryType == -1 || getTypeRank(type) < getTypeRank(primaryType)) {
+                        primaryId = dataId;
+                        primaryType = type;
+                    }
+                }
+            } finally {
+                c.close();
+            }
+            return primaryId;
+        }
+
+        /**
+         * Returns the rank of a specific record type to be used in determining the primary
+         * row. Lower number represents higher priority.
+         */
+        protected int getTypeRank(int type) {
+            return 0;
+        }
+
+        protected Cursor queryData(SQLiteDatabase db, long rawContactId) {
+            // TODO Lookup integer mimetype IDs' instead of joining for speed
+            return db.query(DataQuery.TABLE, DataQuery.COLUMNS, Data.RAW_CONTACT_ID + "="
+                    + rawContactId + " AND " + MimetypesColumns.MIMETYPE + "='" + mMimetype + "'",
+                    null, null, null, null);
+        }
+
+        protected void fixContactDisplayName(SQLiteDatabase db, long rawContactId) {
+            if (!sDisplayNamePriorities.containsKey(mMimetype)) {
+                return;
+            }
+
+            String bestDisplayName = null;
+            Cursor c = db.query(DisplayNameQuery.TABLE, DisplayNameQuery.COLUMNS,
+                    Data.RAW_CONTACT_ID + "=" + rawContactId, null, null, null, null);
+            try {
+                int maxPriority = -1;
+                while (c.moveToNext()) {
+                    String mimeType = c.getString(DisplayNameQuery.MIMETYPE);
+                    boolean primary;
+                    String name;
+
+                    if (StructuredName.CONTENT_ITEM_TYPE.equals(mimeType)) {
+                        name = c.getString(DisplayNameQuery.DISPLAY_NAME);
+                        primary = true;
+                    } else {
+                        name = c.getString(DisplayNameQuery.DATA2);
+                        primary = (c.getInt(DisplayNameQuery.IS_PRIMARY) != 0);
+                    }
+
+                    if (primary && name != null) {
+                        Integer priority = sDisplayNamePriorities.get(mimeType);
+                        if (priority != null && priority > maxPriority) {
+                            maxPriority = priority;
+                            bestDisplayName = name;
+                        }
+                    }
+                }
+
+            } finally {
+                c.close();
+            }
+
+            ContactsProvider2.this.setDisplayName(rawContactId, bestDisplayName);
+        }
+    }
+
+    public class CustomDataRowHandler extends DataRowHandler {
+
+        public CustomDataRowHandler(String mimetype) {
+            super(mimetype);
+        }
+    }
+
+    public class StructuredNameRowHandler extends DataRowHandler {
+
+        private final NameSplitter mNameSplitter;
+
+        public StructuredNameRowHandler(NameSplitter nameSplitter) {
+            super(StructuredName.CONTENT_ITEM_TYPE);
+            mNameSplitter = nameSplitter;
+        }
+
+        @Override
+        public long insert(SQLiteDatabase db, long rawContactId, ContentValues values) {
+            fixStructuredNameComponents(values);
+            return super.insert(db, rawContactId, values);
+        }
+
+        @Override
+        public void update(SQLiteDatabase db, ContentValues values, Cursor cursor) {
+            // TODO Parse the full name if it has changed and replace pre-existing piece parts.
+        }
+
+        /**
+         * Parses the supplied display name, but only if the incoming values do not already contain
+         * structured name parts.  Also, if the display name is not provided, generate one by
+         * concatenating first name and last name
+         *
+         * TODO see if the order of first and last names needs to be conditionally reversed for
+         * some locales, e.g. China.
+         */
+        private void fixStructuredNameComponents(ContentValues values) {
+            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))) {
+                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());
+            }
+
+            if (TextUtils.isEmpty(fullName)) {
+                String givenName = values.getAsString(StructuredName.GIVEN_NAME);
+                String familyName = values.getAsString(StructuredName.FAMILY_NAME);
+                if (TextUtils.isEmpty(givenName)) {
+                    fullName = familyName;
+                } else if (TextUtils.isEmpty(familyName)) {
+                    fullName = givenName;
+                } else {
+                    fullName = givenName + " " + familyName;
+                }
+
+                if (!TextUtils.isEmpty(fullName)) {
+                    values.put(StructuredName.DISPLAY_NAME, fullName);
+                }
+            }
+        }
+    }
+
+    public class CommonDataRowHandler extends DataRowHandler {
+
+        private final String mTypeColumn;
+        private final String mLabelColumn;
+
+        public CommonDataRowHandler(String mimetype, String typeColumn, String labelColumn) {
+            super(mimetype);
+            mTypeColumn = typeColumn;
+            mLabelColumn = labelColumn;
+        }
+
+        @Override
+        public long insert(SQLiteDatabase db, long rawContactId, ContentValues values) {
+            int type;
+            String label;
+            if (values.containsKey(mTypeColumn)) {
+                type = values.getAsInteger(mTypeColumn);
+            } else {
+                type = BaseTypes.TYPE_CUSTOM;
+            }
+            if (values.containsKey(mLabelColumn)) {
+                label = values.getAsString(mLabelColumn);
+            } else {
+                label = null;
+            }
+
+            if (type != BaseTypes.TYPE_CUSTOM && label != null) {
+                throw new RuntimeException(mLabelColumn + " value can only be specified with "
+                        + mTypeColumn + "=" + BaseTypes.TYPE_CUSTOM + "(custom)");
+            }
+
+            if (type == BaseTypes.TYPE_CUSTOM && label == null) {
+                throw new RuntimeException(mLabelColumn + " value must be specified when "
+                        + mTypeColumn + "=" + BaseTypes.TYPE_CUSTOM + "(custom)");
+            }
+
+            return super.insert(db, rawContactId, values);
+        }
+
+        @Override
+        public void update(SQLiteDatabase db, ContentValues values, Cursor cursor) {
+            // TODO read the data and check the constraint
+        }
+    }
+
+    public class OrganizationDataRowHandler extends CommonDataRowHandler {
+
+        public OrganizationDataRowHandler() {
+            super(Organization.CONTENT_ITEM_TYPE, Organization.TYPE, Organization.LABEL);
+        }
+
+        @Override
+        public long insert(SQLiteDatabase db, long rawContactId, ContentValues values) {
+            long id = super.insert(db, rawContactId, values);
+            fixContactDisplayName(db, rawContactId);
+            return id;
+        }
+
+        @Override
+        protected int getTypeRank(int type) {
+            switch (type) {
+                case Organization.TYPE_WORK: return 0;
+                case Organization.TYPE_CUSTOM: return 1;
+                case Organization.TYPE_OTHER: return 2;
+                default: return 1000;
+            }
+        }
+    }
+
+    public class EmailDataRowHandler extends CommonDataRowHandler {
+
+        public EmailDataRowHandler() {
+            super(Email.CONTENT_ITEM_TYPE, Email.TYPE, Email.LABEL);
+        }
+
+        @Override
+        public long insert(SQLiteDatabase db, long rawContactId, ContentValues values) {
+            long id = super.insert(db, rawContactId, values);
+            fixContactDisplayName(db, rawContactId);
+            return id;
+        }
+
+        @Override
+        protected int getTypeRank(int type) {
+            switch (type) {
+                case Email.TYPE_HOME: return 0;
+                case Email.TYPE_WORK: return 1;
+                case Email.TYPE_CUSTOM: return 2;
+                case Email.TYPE_OTHER: return 3;
+                default: return 1000;
+            }
+        }
+    }
+
+    public class PhoneDataRowHandler extends CommonDataRowHandler {
+
+        public PhoneDataRowHandler() {
+            super(Phone.CONTENT_ITEM_TYPE, Phone.TYPE, Phone.LABEL);
+        }
+
+        @Override
+        public long insert(SQLiteDatabase db, long rawContactId, ContentValues values) {
+            ContentValues phoneValues = new ContentValues();
+            String number = values.getAsString(Phone.NUMBER);
+            String normalizedNumber = null;
+            if (number != null) {
+                normalizedNumber = PhoneNumberUtils.getStrippedReversed(number);
+                values.put(PhoneColumns.NORMALIZED_NUMBER, normalizedNumber);
+            }
+
+            long id = super.insert(db, rawContactId, values);
+
+            if (number != null) {
+                phoneValues.put(PhoneLookupColumns.RAW_CONTACT_ID, rawContactId);
+                phoneValues.put(PhoneLookupColumns.DATA_ID, id);
+                phoneValues.put(PhoneLookupColumns.NORMALIZED_NUMBER, normalizedNumber);
+                db.insert(Tables.PHONE_LOOKUP, null, phoneValues);
+            }
+
+            return id;
+        }
+
+        @Override
+        protected int getTypeRank(int type) {
+            switch (type) {
+                case Phone.TYPE_MOBILE: return 0;
+                case Phone.TYPE_WORK: return 1;
+                case Phone.TYPE_HOME: return 2;
+                case Phone.TYPE_PAGER: return 3;
+                case Phone.TYPE_CUSTOM: return 4;
+                case Phone.TYPE_OTHER: return 5;
+                case Phone.TYPE_FAX_WORK: return 6;
+                case Phone.TYPE_FAX_HOME: return 7;
+                default: return 1000;
+            }
+        }
+    }
+
+    private HashMap<String, DataRowHandler> mDataRowHandlers;
+    private final ContactAggregationScheduler mAggregationScheduler;
+    private OpenHelper mOpenHelper;
+
+    private ContactAggregator mContactAggregator;
+    private NameSplitter mNameSplitter;
+    private LegacyApiSupport mLegacyApiSupport;
+    private GlobalSearchSupport mGlobalSearchSupport;
+
+    private ContentValues mValues = new ContentValues();
+
+    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);
+        mGlobalSearchSupport = new GlobalSearchSupport(this);
+        mLegacyApiSupport = new LegacyApiSupport(context, mOpenHelper, this, mGlobalSearchSupport);
+        mContactAggregator = new ContactAggregator(context, mOpenHelper, mAggregationScheduler);
+
+        final SQLiteDatabase db = mOpenHelper.getReadableDatabase();
+        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);
+        mLastTimeContactedUpdate = db.compileStatement("UPDATE " + Tables.RAW_CONTACTS + " SET "
+                + RawContacts.TIMES_CONTACTED + "=" + RawContacts.TIMES_CONTACTED + "+1,"
+                + RawContacts.LAST_TIME_CONTACTED + "=? WHERE " + RawContacts.CONTACT_ID + "=?");
+
+        mContactDisplayNameUpdate = db.compileStatement("UPDATE " + Tables.RAW_CONTACTS + " SET "
+                + RawContactsColumns.DISPLAY_NAME + "=? WHERE " + RawContacts._ID + "=?");
+
+        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));
+
+        mDataRowHandlers = new HashMap<String, DataRowHandler>();
+
+        mDataRowHandlers.put(Email.CONTENT_ITEM_TYPE, new EmailDataRowHandler());
+        mDataRowHandlers.put(Im.CONTENT_ITEM_TYPE,
+                new CommonDataRowHandler(Im.CONTENT_ITEM_TYPE, Im.TYPE, Im.LABEL));
+        mDataRowHandlers.put(Nickname.CONTENT_ITEM_TYPE, new CommonDataRowHandler(
+                StructuredPostal.CONTENT_ITEM_TYPE, StructuredPostal.TYPE, StructuredPostal.LABEL));
+        mDataRowHandlers.put(Organization.CONTENT_ITEM_TYPE, new OrganizationDataRowHandler());
+        mDataRowHandlers.put(Phone.CONTENT_ITEM_TYPE, new PhoneDataRowHandler());
+        mDataRowHandlers.put(Nickname.CONTENT_ITEM_TYPE, new CommonDataRowHandler(
+                Nickname.CONTENT_ITEM_TYPE, Nickname.TYPE, Nickname.LABEL));
+        mDataRowHandlers.put(StructuredName.CONTENT_ITEM_TYPE,
+                new StructuredNameRowHandler(mNameSplitter));
+
+        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();
+    }
+
+    /**
+     * 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;
+    }
+
+    private DataRowHandler getDataRowHandler(final String mimeType) {
+        DataRowHandler handler = mDataRowHandlers.get(mimeType);
+        if (handler == null) {
+            handler = new CustomDataRowHandler(mimeType);
+            mDataRowHandlers.put(mimeType, handler);
+        }
+        return handler;
+    }
+
+    @Override
+    public Uri insert(Uri uri, ContentValues values) {
+        final int match = sUriMatcher.match(uri);
+        long id = 0;
+
+        switch (match) {
+            case SYNCSTATE:
+                id = mOpenHelper.getSyncState().insert(mOpenHelper.getWritableDatabase(), values);
+                break;
+
+            case CONTACTS: {
+                insertContact(values);
+                break;
+            }
+
+            case RAW_CONTACTS: {
+                final Account account = readAccountFromQueryParams(uri);
+                id = insertRawContact(values, account);
+                break;
+            }
+
+            case RAW_CONTACTS_DATA: {
+                values.put(Data.RAW_CONTACT_ID, uri.getPathSegments().get(1));
+                id = insertData(values);
+                break;
+            }
+
+            case DATA: {
+                id = insertData(values);
+                break;
+            }
+
+            case GROUPS: {
+                final Account account = readAccountFromQueryParams(uri);
+                id = insertGroup(values, account);
+                break;
+            }
+
+            case PRESENCE: {
+                id = insertPresence(values);
+                break;
+            }
+
+            default:
+                return mLegacyApiSupport.insert(uri, values);
+        }
+
+        if (id < 0) {
+            return null;
+        }
+
+        final Uri result = ContentUris.withAppendedId(uri, id);
+        onChange(result);
+        return result;
+    }
+
+    /**
+     * If account is non-null then store it in the values. If the account is already
+     * specified in the values then it must be consistent with the account, if it is non-null.
+     * @param values the ContentValues to read from and update
+     * @param account the explicitly provided Account
+     * @return false if the accounts are inconsistent
+     */
+    private boolean resolveAccount(ContentValues values, Account account) {
+        // If either is specified then both must be specified.
+        final String accountName = values.getAsString(RawContacts.ACCOUNT_NAME);
+        final String accountType = values.getAsString(RawContacts.ACCOUNT_TYPE);
+        if (!TextUtils.isEmpty(accountName) || !TextUtils.isEmpty(accountType)) {
+            final Account valuesAccount = new Account(accountName, accountType);
+            if (account != null && !valuesAccount.equals(account)) {
+                return false;
+            }
+            account = valuesAccount;
+        }
+        if (account != null) {
+            values.put(RawContacts.ACCOUNT_NAME, account.mName);
+            values.put(RawContacts.ACCOUNT_TYPE, account.mType);
+        }
+        return true;
+    }
+
+    /**
+     * Inserts an item in the contacts table
+     *
+     * @param values the values for the new row
+     * @return the row ID of the newly created row
+     */
+    private long insertContact(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 insertRawContact(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(RawContacts.CONTACT_ID);
+        if (!resolveAccount(overriddenValues, account)) {
+            return -1;
+        }
+
+        return db.insert(Tables.RAW_CONTACTS, RawContacts.CONTACT_ID, overriddenValues);
+    }
+
+    /**
+     * Inserts an item in the data table
+     *
+     * @param values the values for the new row
+     * @return the row ID of the newly created row
+     */
+    private long insertData(ContentValues values) {
+        int aggregationMode = RawContacts.AGGREGATION_MODE_DISABLED;
+
+        final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+        long id = 0;
+        db.beginTransaction();
+        try {
+            mValues.clear();
+            mValues.putAll(values);
+
+            long rawContactId = mValues.getAsLong(Data.RAW_CONTACT_ID);
+
+            // Replace package with internal mapping
+            final String packageName = mValues.getAsString(Data.RES_PACKAGE);
+            if (packageName != null) {
+                mValues.put(DataColumns.PACKAGE_ID, mOpenHelper.getPackageId(packageName));
+            }
+            mValues.remove(Data.RES_PACKAGE);
+
+            // Replace mimetype with internal mapping
+            final String mimeType = mValues.getAsString(Data.MIMETYPE);
+            if (TextUtils.isEmpty(mimeType)) {
+                throw new RuntimeException(Data.MIMETYPE + " is required");
+            }
+
+            mValues.put(DataColumns.MIMETYPE_ID, mOpenHelper.getMimeTypeId(mimeType));
+            mValues.remove(Data.MIMETYPE);
+
+            if (GroupMembership.CONTENT_ITEM_TYPE.equals(mimeType)) {
+                boolean containsGroupSourceId = mValues.containsKey(GroupMembership.GROUP_SOURCE_ID);
+                boolean containsGroupId = mValues.containsKey(GroupMembership.GROUP_ROW_ID);
+                if (containsGroupSourceId && containsGroupId) {
+                    throw new IllegalArgumentException(
+                            "you are not allowed to set both the GroupMembership.GROUP_SOURCE_ID "
+                                    + "and GroupMembership.GROUP_ROW_ID");
+                }
+
+                if (!containsGroupSourceId && !containsGroupId) {
+                    throw new IllegalArgumentException(
+                            "you must set exactly one of GroupMembership.GROUP_SOURCE_ID "
+                                    + "and GroupMembership.GROUP_ROW_ID");
+                }
+
+                if (containsGroupSourceId) {
+                    final String sourceId = mValues.getAsString(GroupMembership.GROUP_SOURCE_ID);
+                    final long groupId = getOrMakeGroup(db, rawContactId, sourceId);
+                    mValues.remove(GroupMembership.GROUP_SOURCE_ID);
+                    mValues.put(GroupMembership.GROUP_ROW_ID, groupId);
+                }
+            }
+
+            id = getDataRowHandler(mimeType).insert(db, rawContactId, mValues);
+
+            aggregationMode = mContactAggregator.markContactForAggregation(rawContactId);
+
+            db.setTransactionSuccessful();
+        } finally {
+            db.endTransaction();
+        }
+
+        triggerAggregation(id, aggregationMode);
+        return id;
+    }
+
+    private void triggerAggregation(long rawContactId, int aggregationMode) {
+        switch (aggregationMode) {
+            case RawContacts.AGGREGATION_MODE_DEFAULT:
+                mContactAggregator.schedule();
+                break;
+
+            case RawContacts.AGGREGATION_MODE_IMMEDITATE:
+                mContactAggregator.aggregateContact(rawContactId);
+                break;
+
+            case RawContacts.AGGREGATION_MODE_DISABLED:
+                // Do nothing
+                break;
+        }
+    }
+
+    /**
+     * Returns the group id of the group with sourceId and the same account as rawContactId.
+     * If the group doesn't already exist then it is first created,
+     * @param db SQLiteDatabase to use for this operation
+     * @param rawContactId the contact this group is associated with
+     * @param sourceId the sourceIf of the group to query or create
+     * @return the group id of the existing or created group
+     * @throws IllegalArgumentException if the contact is not associated with an account
+     * @throws IllegalStateException if a group needs to be created but the creation failed
+     */
+    private long getOrMakeGroup(SQLiteDatabase db, long rawContactId, String sourceId) {
+        Account account = null;
+        Cursor c = db.query(ContactsQuery.TABLE, ContactsQuery.PROJECTION, RawContacts._ID + "="
+                + rawContactId, null, null, null, null);
+        try {
+            if (c.moveToNext()) {
+                final String accountName = c.getString(ContactsQuery.ACCOUNT_NAME);
+                final String accountType = c.getString(ContactsQuery.ACCOUNT_TYPE);
+                if (!TextUtils.isEmpty(accountName) && !TextUtils.isEmpty(accountType)) {
+                    account = new Account(accountName, accountType);
+                }
+            }
+        } finally {
+            c.close();
+        }
+        if (account == null) {
+            throw new IllegalArgumentException("if the groupmembership only "
+                    + "has a sourceid the the contact must be associate with "
+                    + "an account");
+        }
+
+        // look up the group that contains this sourceId and has the same account name and type
+        // as the contact refered to by rawContactId
+        c = db.query(Tables.GROUPS, new String[]{RawContacts._ID},
+                Clauses.GROUP_HAS_ACCOUNT_AND_SOURCE_ID,
+                new String[]{sourceId, account.mName, account.mType}, null, null, null);
+        try {
+            if (c.moveToNext()) {
+                return c.getLong(0);
+            } else {
+                ContentValues groupValues = new ContentValues();
+                groupValues.put(Groups.ACCOUNT_NAME, account.mName);
+                groupValues.put(Groups.ACCOUNT_TYPE, account.mType);
+                groupValues.put(Groups.SOURCE_ID, sourceId);
+                long groupId = db.insert(Tables.GROUPS, Groups.ACCOUNT_NAME, groupValues);
+                if (groupId < 0) {
+                    throw new IllegalStateException("unable to create a new group with "
+                            + "this sourceid: " + groupValues);
+                }
+                return groupId;
+            }
+        } finally {
+            c.close();
+        }
+    }
+
+    /**
+     * Delete data row by row so that fixing of primaries etc work correctly.
+     */
+    private int deleteData(String selection, String[] selectionArgs) {
+        SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+        int count = 0;
+        db.beginTransaction();
+        try {
+
+            // Note that the query will return data according to the access restrictions,
+            // so we don't need to worry about deleting data we don't have permission to read.
+            Cursor c = query(Data.CONTENT_URI, DataIdQuery.COLUMNS, selection, selectionArgs, null);
+            try {
+                while(c.moveToNext()) {
+                    long dataId = c.getLong(DataIdQuery._ID);
+                    count += deleteData(dataId);
+                }
+            } finally {
+                c.close();
+            }
+            db.setTransactionSuccessful();
+        } finally {
+            db.endTransaction();
+        }
+
+        return count;
+    }
+
+    public int deleteData(long dataId, String[] allowedMimeTypes) {
+        SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+        Cursor c = db.query(DataQuery.TABLE, DataQuery.COLUMNS,
+                DataColumns.CONCRETE_ID + "=" + dataId, null, null, null, null);
+        // TODO apply restrictions
+        try {
+            if (!c.moveToFirst()) {
+                return 0;
+            }
+
+            String mimeType = c.getString(DataQuery.MIMETYPE);
+            boolean valid = false;
+            for (int i = 0; i < allowedMimeTypes.length; i++) {
+                if (TextUtils.equals(mimeType, allowedMimeTypes[i])) {
+                    valid = true;
+                    break;
+                }
+            }
+
+            if (!valid) {
+                throw new RuntimeException("Data type mismatch: expected "
+                        + Lists.newArrayList(allowedMimeTypes));
+            }
+
+            return getDataRowHandler(mimeType).delete(db, c);
+        } finally {
+            c.close();
+        }
+    }
+
+    /**
+     * Delete the given {@link Data} row, fixing up any {@link Contacts}
+     * 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(DataContactsQuery.TABLE, DataContactsQuery.PROJECTION,
+                    DataColumns.CONCRETE_ID + "=" + dataId, null, null, null, null);
+            if (cursor.moveToFirst()) {
+                aggId = cursor.getLong(DataContactsQuery.CONTACT_ID);
+                mimeId = cursor.getLong(DataContactsQuery.MIMETYPE_ID);
+                if (mimeId == mimePhone) {
+                    dataRaw = cursor.getString(DataContactsQuery.PHONE_NUMBER);
+                    fixOptimal = (cursor.getLong(DataContactsQuery.OPTIMAL_PHONE_ID) == dataId);
+                    fixFallback = (cursor.getLong(DataContactsQuery.FALLBACK_PHONE_ID) == dataId);
+                } else if (mimeId == mimeEmail) {
+                    dataRaw = cursor.getString(DataContactsQuery.EMAIL_DATA);
+                    fixOptimal = (cursor.getLong(DataContactsQuery.OPTIMAL_EMAIL_ID) == dataId);
+                    fixFallback = (cursor.getLong(DataContactsQuery.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,
+                    RawContacts.IS_RESTRICTED,
+                    scoreClause.toString(),
+            };
+
+            final int COL_DATA_ID = 0;
+            final int COL_IS_RESTRICTED = 1;
+            final int COL_SCORE = 2;
+
+            cursor = db.query(Tables.DATA_JOIN_MIMETYPES_RAW_CONTACTS_CONTACTS, PROJ_PRIMARY,
+                    ContactsColumns.CONCRETE_ID + "=" + aggId + " AND " + DataColumns.MIMETYPE_ID
+                            + "=" + mimeId, null, null, null, SCORE);
+
+            if (fixOptimal) {
+                String colId = null;
+                String colIsRestricted = null;
+                if (mimeId == mimePhone) {
+                    colId = ContactsColumns.OPTIMAL_PRIMARY_PHONE_ID;
+                    colIsRestricted = ContactsColumns.OPTIMAL_PRIMARY_PHONE_IS_RESTRICTED;
+                } else if (mimeId == mimeEmail) {
+                    colId = ContactsColumns.OPTIMAL_PRIMARY_EMAIL_ID;
+                    colIsRestricted = ContactsColumns.OPTIMAL_PRIMARY_EMAIL_IS_RESTRICTED;
+                }
+
+                // Start by replacing with null, since fixOptimal told us that
+                // the previous aggregate values are bad.
+                values.putNull(colId);
+                values.putNull(colIsRestricted);
+
+                // 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 newIsRestricted = cursor.getLong(COL_IS_RESTRICTED);
+
+                    if (newOptimal != 0) {
+                        values.put(colId, newOptimal);
+                    }
+                    if (newIsRestricted != 0) {
+                        values.put(colIsRestricted, newIsRestricted);
+                    }
+                }
+            }
+
+            if (fixFallback) {
+                String colId = null;
+                if (mimeId == mimePhone) {
+                    colId = ContactsColumns.FALLBACK_PRIMARY_PHONE_ID;
+                } else if (mimeId == mimeEmail) {
+                    colId = ContactsColumns.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 contact updates we have
+            if (values.size() > 0) {
+                db.update(Tables.CONTACTS, values, ContactsColumns.CONCRETE_ID + "=" + aggId,
+                        null);
+            }
+        }
+
+        return dataDeleted;
+    }
+
+    /**
+     * 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.RES_PACKAGE);
+        if (packageName != null) {
+            overriddenValues.put(GroupsColumns.PACKAGE_ID, mOpenHelper.getPackageId(packageName));
+        }
+        overriddenValues.remove(Groups.RES_PACKAGE);
+
+        return db.insert(Tables.GROUPS, Groups.TITLE, overriddenValues);
+    }
+
+    /**
+     * Inserts a presence update.
+     */
+    public 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 = Im.PROTOCOL_GOOGLE_TALK == Integer.parseInt(protocol);
+
+        StringBuilder selection = new StringBuilder();
+        String[] selectionArgs;
+        if (matchEmail) {
+            selection.append("(" + Clauses.WHERE_IM_MATCHES + ") OR ("
+                    + Clauses.WHERE_EMAIL_MATCHES + ")");
+            selectionArgs = new String[] { protocol, handle, handle };
+        } else {
+            selection.append(Clauses.WHERE_IM_MATCHES);
+            selectionArgs = new String[] { protocol, handle };
+        }
+
+        if (values.containsKey(Presence.DATA_ID)) {
+            selection.append(" AND " + DataColumns.CONCRETE_ID + "=")
+                    .append(values.getAsLong(Presence.DATA_ID));
+        }
+
+        if (values.containsKey(Presence.RAW_CONTACT_ID)) {
+            selection.append(" AND " + DataColumns.CONCRETE_RAW_CONTACT_ID + "=")
+                    .append(values.getAsLong(Presence.RAW_CONTACT_ID));
+        }
+
+        selection.append(" AND ").append(getContactsRestrictionExceptions());
+
+        long dataId = -1;
+        long rawContactId = -1;
+
+        Cursor cursor = null;
+        try {
+            cursor = db.query(DataContactsQuery.TABLE, DataContactsQuery.PROJECTION,
+                    selection.toString(), selectionArgs, null, null, null);
+            if (cursor.moveToFirst()) {
+                dataId = cursor.getLong(DataContactsQuery.DATA_ID);
+                rawContactId = cursor.getLong(DataContactsQuery.RAW_CONTACT_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.RAW_CONTACT_ID, rawContactId);
+
+        // 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 SYNCSTATE:
+                return mOpenHelper.getSyncState().delete(db, selection, selectionArgs);
+
+            case CONTACTS_ID: {
+                long contactId = ContentUris.parseId(uri);
+
+                // Remove references to the contact first
+                ContentValues values = new ContentValues();
+                values.putNull(RawContacts.CONTACT_ID);
+                db.update(Tables.RAW_CONTACTS, values,
+                        RawContacts.CONTACT_ID + "=" + contactId, null);
+
+                return db.delete(Tables.CONTACTS, BaseColumns._ID + "=" + contactId, null);
+            }
+
+            case RAW_CONTACTS_ID: {
+                return deleteRawContact(uri);
+            }
+
+            case DATA: {
+                return deleteData(selection, selectionArgs);
+            }
+
+            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:
+                return mLegacyApiSupport.delete(uri, selection, selectionArgs);
+        }
+    }
+
+    private int deleteRawContact(Uri uri) {
+        boolean permanentDeletion = false;
+        String permanent = uri.getQueryParameter(RawContacts.DELETE_PERMANENTLY);
+        if (permanent != null && !"false".equals(permanent.toLowerCase())) {
+            permanentDeletion = true;
+        }
+
+        long rawContactId = ContentUris.parseId(uri);
+        return deleteRawContact(rawContactId, permanentDeletion);
+    }
+
+    public int deleteRawContact(long rawContactId, boolean permanently) {
+        final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+
+        // TODO delete aggregation exceptions
+        mOpenHelper.removeContactIfSingleton(rawContactId);
+        if (permanently) {
+            db.delete(Tables.PRESENCE, Presence.RAW_CONTACT_ID + "=" + rawContactId, null);
+            return db.delete(Tables.RAW_CONTACTS, RawContacts._ID + "=" + rawContactId, null);
+        } else {
+            mValues.clear();
+            mValues.put(RawContacts.DELETED, true);
+            mValues.put(RawContacts.AGGREGATION_MODE, RawContacts.AGGREGATION_MODE_DISABLED);
+            mValues.putNull(RawContacts.CONTACT_ID);
+            return updateRawContact(rawContactId, mValues, null, null);
+        }
+    }
+
+    private static Account readAccountFromQueryParams(Uri uri) {
+        final String name = uri.getQueryParameter(RawContacts.ACCOUNT_NAME);
+        final String type = uri.getQueryParameter(RawContacts.ACCOUNT_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) {
+        final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+        int count = 0;
+
+        final int match = sUriMatcher.match(uri);
+        switch(match) {
+            case SYNCSTATE:
+                return mOpenHelper.getSyncState().update(db, values, selection, selectionArgs);
+
+            // TODO(emillar): We will want to disallow editing the contacts table at some point.
+            case CONTACTS: {
+                count = db.update(Tables.CONTACTS, values, selection, selectionArgs);
+                break;
+            }
+
+            case CONTACTS_ID: {
+                count = updateContactData(db, ContentUris.parseId(uri), values);
+                break;
+            }
+
+            case DATA: {
+                count = updateData(values, selection, selectionArgs);
+                break;
+            }
+
+            case DATA_ID: {
+                count = updateData(ContentUris.parseId(uri), values);
+                break;
+            }
+
+            case RAW_CONTACTS: {
+                count = db.update(Tables.RAW_CONTACTS, values, selection, selectionArgs);
+                break;
+            }
+
+            case RAW_CONTACTS_ID: {
+                long rawContactId = ContentUris.parseId(uri);
+                count = updateRawContact(rawContactId, 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 contacts
+                if (values.containsKey(Groups.GROUP_VISIBLE)) {
+                    mOpenHelper.updateAllVisible();
+                }
+
+                break;
+            }
+
+            case AGGREGATION_EXCEPTIONS: {
+                count = updateAggregationException(db, values);
+                break;
+            }
+
+            default:
+                return mLegacyApiSupport.update(uri, values, selection, selectionArgs);
+        }
+
+        if (count > 0) {
+            getContext().getContentResolver().notifyChange(uri, null);
+        }
+        return count;
+    }
+
+    private int updateRawContact(long rawContactId, ContentValues values, String selection,
+            String[] selectionArgs) {
+        final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+        String selectionWithId = (RawContacts._ID + " = " + rawContactId + " ")
+                + (selection == null ? "" : " AND " + selection);
+        return db.update(Tables.RAW_CONTACTS, values, selectionWithId, selectionArgs);
+    }
+
+    private int updateData(ContentValues values, String selection,
+            String[] selectionArgs) {
+        SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+        int count = 0;
+        db.beginTransaction();
+        try {
+
+            // Note that the query will return data according to the access restrictions,
+            // so we don't need to worry about deleting data we don't have permission to read.
+            Cursor c = query(Data.CONTENT_URI, DataIdQuery.COLUMNS, selection, selectionArgs, null);
+            try {
+                while(c.moveToNext()) {
+                    long dataId = c.getLong(DataIdQuery._ID);
+                    count += updateData(dataId, values);
+                }
+            } finally {
+                c.close();
+            }
+            db.setTransactionSuccessful();
+        } finally {
+            db.endTransaction();
+        }
+
+        return count;
+    }
+
+    private int updateData(long dataId, ContentValues values) {
+        SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+
+        mValues.clear();
+        mValues.putAll(values);
+        mValues.remove(Data._ID);
+        mValues.remove(Data.RAW_CONTACT_ID);
+        mValues.remove(Data.MIMETYPE);
+
+        String packageName = values.getAsString(Data.RES_PACKAGE);
+        if (packageName != null) {
+            mValues.remove(Data.RES_PACKAGE);
+            mValues.put(DataColumns.PACKAGE_ID, mOpenHelper.getPackageId(packageName));
+        }
+
+        boolean containsIsSuperPrimary = mValues.containsKey(Data.IS_SUPER_PRIMARY);
+        boolean containsIsPrimary = mValues.containsKey(Data.IS_PRIMARY);
+
+        // Remove primary or super primary values being set to 0. This is disallowed by the
+        // content provider.
+        if (containsIsSuperPrimary && mValues.getAsInteger(Data.IS_SUPER_PRIMARY) == 0) {
+            containsIsSuperPrimary = false;
+            mValues.remove(Data.IS_SUPER_PRIMARY);
+        }
+        if (containsIsPrimary && mValues.getAsInteger(Data.IS_PRIMARY) == 0) {
+            containsIsPrimary = false;
+            mValues.remove(Data.IS_PRIMARY);
+        }
+
+        if (containsIsSuperPrimary) {
+            setIsSuperPrimary(dataId);
+            setIsPrimary(dataId);
+
+            // Now that we've taken care of setting these, remove them from "values".
+            mValues.remove(Data.IS_SUPER_PRIMARY);
+            if (containsIsPrimary) {
+                mValues.remove(Data.IS_PRIMARY);
+            }
+        } else if (containsIsPrimary) {
+            setIsPrimary(dataId);
+
+            // Now that we've taken care of setting this, remove it from "values".
+            mValues.remove(Data.IS_PRIMARY);
+        }
+
+        if (mValues.size() > 0) {
+            return db.update(Tables.DATA, mValues, Data._ID + " = " + dataId, null);
+        }
+        return 0;
+    }
+
+    private int updateContactData(SQLiteDatabase db, long contactId, ContentValues values) {
+
+        // First update all constituent contacts
+        ContentValues optionValues = new ContentValues(5);
+        OpenHelper.copyStringValue(optionValues, RawContacts.CUSTOM_RINGTONE,
+                values, Contacts.CUSTOM_RINGTONE);
+        OpenHelper.copyLongValue(optionValues, RawContacts.SEND_TO_VOICEMAIL,
+                values, Contacts.SEND_TO_VOICEMAIL);
+        OpenHelper.copyLongValue(optionValues, RawContacts.LAST_TIME_CONTACTED,
+                values, Contacts.LAST_TIME_CONTACTED);
+        OpenHelper.copyLongValue(optionValues, RawContacts.TIMES_CONTACTED,
+                values, Contacts.TIMES_CONTACTED);
+        OpenHelper.copyLongValue(optionValues, RawContacts.STARRED,
+                values, Contacts.STARRED);
+
+        // Nothing to update - just return
+        if (optionValues.size() == 0) {
+            return 0;
+        }
+
+        db.update(Tables.RAW_CONTACTS, optionValues,
+                RawContacts.CONTACT_ID + "=" + contactId, null);
+        return db.update(Tables.CONTACTS, values, Contacts._ID + "=" + contactId, null);
+    }
+
+    public void updateContactTime(long contactId, long lastTimeContacted) {
+        mLastTimeContactedUpdate.bindLong(1, lastTimeContacted);
+        mLastTimeContactedUpdate.bindLong(2, contactId);
+        mLastTimeContactedUpdate.execute();
+    }
+
+    private static class RawContactPair {
+        final long rawContactId1;
+        final long rawContactId2;
+
+        /**
+         * Constructor that ensures that this.rawContactId1 &lt; this.rawContactId2
+         */
+        public RawContactPair(long rawContactId1, long rawContactId2) {
+            if (rawContactId1 < rawContactId2) {
+                this.rawContactId1 = rawContactId1;
+                this.rawContactId2 = rawContactId2;
+            } else {
+                this.rawContactId2 = rawContactId1;
+                this.rawContactId1 = rawContactId2;
+            }
+        }
+    }
+
+    private int updateAggregationException(SQLiteDatabase db, ContentValues values) {
+        int exceptionType = values.getAsInteger(AggregationExceptions.TYPE);
+        long contactId = values.getAsInteger(AggregationExceptions.CONTACT_ID);
+        long rawContactId = values.getAsInteger(AggregationExceptions.RAW_CONTACT_ID);
+
+        // First, we build a list of contactID-contactID pairs for the given contact and contact.
+        ArrayList<RawContactPair> pairs = new ArrayList<RawContactPair>();
+        Cursor c = db.query(ContactsQuery.TABLE, ContactsQuery.PROJECTION, RawContacts.CONTACT_ID
+                + "=" + contactId, null, null, null, null);
+        try {
+            while (c.moveToNext()) {
+                long aggregatedContactId = c.getLong(ContactsQuery.RAW_CONTACT_ID);
+                if (aggregatedContactId != rawContactId) {
+                    pairs.add(new RawContactPair(aggregatedContactId, rawContactId));
+                }
+            }
+        } 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 (RawContactPair pair : pairs) {
+            final String whereClause =
+                    AggregationExceptionColumns.RAW_CONTACT_ID1 + "=" + pair.rawContactId1 + " AND "
+                    + AggregationExceptionColumns.RAW_CONTACT_ID2 + "=" + pair.rawContactId2;
+            if (exceptionType == AggregationExceptions.TYPE_AUTOMATIC) {
+                db.delete(Tables.AGGREGATION_EXCEPTIONS, whereClause, null);
+            } else {
+                exceptionValues.put(AggregationExceptionColumns.RAW_CONTACT_ID1, pair.rawContactId1);
+                exceptionValues.put(AggregationExceptionColumns.RAW_CONTACT_ID2, pair.rawContactId2);
+                db.replace(Tables.AGGREGATION_EXCEPTIONS, AggregationExceptions._ID,
+                        exceptionValues);
+            }
+        }
+
+        int aggregationMode = mContactAggregator.markContactForAggregation(rawContactId);
+        if (aggregationMode != RawContacts.AGGREGATION_MODE_DISABLED) {
+            mContactAggregator.aggregateContact(db, rawContactId);
+            if (exceptionType == AggregationExceptions.TYPE_AUTOMATIC
+                    || exceptionType == AggregationExceptions.TYPE_KEEP_OUT) {
+                mContactAggregator.updateAggregateData(contactId);
+            }
+        }
+
+        // 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 = getLimit(uri);
+
+        String contactIdColName = Tables.CONTACTS + "." + Contacts._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 SYNCSTATE:
+                return mOpenHelper.getSyncState().query(db, projection, selection,  selectionArgs,
+                        sortOrder);
+
+            case CONTACTS: {
+                qb.setTables(Tables.CONTACTS);
+                applyAggregateRestrictionExceptions(qb);
+                applyAggregatePrimaryRestrictionExceptions(sContactsProjectionMap);
+                qb.setProjectionMap(sContactsProjectionMap);
+                break;
+            }
+
+            case CONTACTS_ID: {
+                long aggId = ContentUris.parseId(uri);
+                qb.setTables(Tables.CONTACTS);
+                qb.appendWhere(ContactsColumns.CONCRETE_ID + "=" + aggId + " AND ");
+                applyAggregateRestrictionExceptions(qb);
+                applyAggregatePrimaryRestrictionExceptions(sContactsProjectionMap);
+                qb.setProjectionMap(sContactsProjectionMap);
+                break;
+            }
+
+            case CONTACTS_SUMMARY: {
+                // TODO: join into social status tables
+                qb.setTables(Tables.CONTACTS_JOIN_PRESENCE_PRIMARY_PHONE);
+                applyAggregateRestrictionExceptions(qb);
+                applyAggregatePrimaryRestrictionExceptions(sContactsSummaryProjectionMap);
+                projection = assertContained(projection, Contacts.PRIMARY_PHONE_ID);
+                qb.setProjectionMap(sContactsSummaryProjectionMap);
+                groupBy = contactIdColName;
+                break;
+            }
+
+            case CONTACTS_SUMMARY_ID: {
+                // TODO: join into social status tables
+                long aggId = ContentUris.parseId(uri);
+                qb.setTables(Tables.CONTACTS_JOIN_PRESENCE_PRIMARY_PHONE);
+                qb.appendWhere(ContactsColumns.CONCRETE_ID + "=" + aggId + " AND ");
+                applyAggregateRestrictionExceptions(qb);
+                applyAggregatePrimaryRestrictionExceptions(sContactsSummaryProjectionMap);
+                projection = assertContained(projection, Contacts.PRIMARY_PHONE_ID);
+                qb.setProjectionMap(sContactsSummaryProjectionMap);
+                groupBy = contactIdColName;
+                break;
+            }
+
+            case CONTACTS_SUMMARY_FILTER: {
+                // TODO: filter query based on callingUid
+                qb.setTables(Tables.CONTACTS_JOIN_PRESENCE_PRIMARY_PHONE);
+                qb.setProjectionMap(sContactsSummaryProjectionMap);
+                if (uri.getPathSegments().size() > 2) {
+                    qb.appendWhere(buildContactLookupWhereClause(uri.getLastPathSegment()));
+                }
+                groupBy = contactIdColName;
+                break;
+            }
+
+            case CONTACTS_SUMMARY_STREQUENT_FILTER:
+            case CONTACTS_SUMMARY_STREQUENT: {
+                // Build the first query for starred
+                qb.setTables(Tables.CONTACTS_JOIN_PRESENCE_PRIMARY_PHONE);
+                qb.setProjectionMap(sContactsSummaryProjectionMap);
+                if (match == CONTACTS_SUMMARY_STREQUENT_FILTER
+                        && uri.getPathSegments().size() > 3) {
+                    qb.appendWhere(buildContactLookupWhereClause(uri.getLastPathSegment()));
+                }
+                final String starredQuery = qb.buildQuery(projection, Contacts.STARRED + "=1",
+                        null, contactIdColName, null, null,
+                        null /* limit */);
+
+                // Build the second query for frequent
+                qb = new SQLiteQueryBuilder();
+                qb.setTables(Tables.CONTACTS_JOIN_PRESENCE_PRIMARY_PHONE);
+                qb.setProjectionMap(sContactsSummaryProjectionMap);
+                if (match == CONTACTS_SUMMARY_STREQUENT_FILTER
+                        && uri.getPathSegments().size() > 3) {
+                    qb.appendWhere(buildContactLookupWhereClause(uri.getLastPathSegment()));
+                }
+                final String frequentQuery = qb.buildQuery(projection,
+                        Contacts.TIMES_CONTACTED + " > 0 AND (" + Contacts.STARRED
+                        + " = 0 OR " + Contacts.STARRED + " IS NULL)",
+                        null, contactIdColName, 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.CONTACTS_JOIN_PRESENCE_PRIMARY_PHONE);
+
+                if ((c != null) && !isTemporary()) {
+                    c.setNotificationUri(getContext().getContentResolver(),
+                            ContactsContract.AUTHORITY_URI);
+                }
+                return c;
+            }
+
+            case CONTACTS_SUMMARY_GROUP: {
+                qb.setTables(Tables.CONTACTS_JOIN_PRESENCE_PRIMARY_PHONE);
+                applyAggregateRestrictionExceptions(qb);
+                applyAggregatePrimaryRestrictionExceptions(sContactsSummaryProjectionMap);
+                projection = assertContained(projection, Contacts.PRIMARY_PHONE_ID);
+                qb.setProjectionMap(sContactsSummaryProjectionMap);
+                if (uri.getPathSegments().size() > 2) {
+                    qb.appendWhere(" AND " + sContactsInGroupSelect);
+                    selectionArgs = appendGroupArg(selectionArgs, uri.getLastPathSegment());
+                }
+                groupBy = contactIdColName;
+                break;
+            }
+
+            case CONTACTS_DATA: {
+                long aggId = Long.parseLong(uri.getPathSegments().get(1));
+                qb.setTables(Tables.DATA_JOIN_PACKAGES_MIMETYPES_RAW_CONTACTS_CONTACTS_GROUPS);
+                qb.setProjectionMap(sDataRawContactsGroupsContactProjectionMap);
+                qb.appendWhere(RawContacts.CONTACT_ID + "=" + aggId + " AND ");
+                applyDataRestrictionExceptions(qb);
+                break;
+            }
+
+            case CONTACTS_RAW_CONTACTS: {
+                long contactId = Long.parseLong(uri.getPathSegments().get(1));
+                qb.setTables(Tables.RAW_CONTACTS_JOIN_CONTACTS);
+                qb.setProjectionMap(sRawContactsContactsProjectionMap);
+                qb.appendWhere(RawContacts.CONTACT_ID + "=" + contactId + " AND ");
+                applyDataRestrictionExceptions(qb);
+                break;
+            }
+
+            case PHONES_FILTER: {
+                qb.setTables(Tables.DATA_JOIN_PACKAGES_MIMETYPES_RAW_CONTACTS_CONTACTS);
+                qb.setProjectionMap(sDataRawContactsContactProjectionMap);
+                qb.appendWhere(Data.MIMETYPE + " = '" + Phone.CONTENT_ITEM_TYPE + "'");
+                if (uri.getPathSegments().size() > 2) {
+                    qb.appendWhere(" AND " + buildContactLookupWhereClause(
+                            uri.getLastPathSegment()));
+                }
+                break;
+            }
+
+            case PHONES: {
+                qb.setTables(Tables.DATA_JOIN_PACKAGES_MIMETYPES_RAW_CONTACTS_CONTACTS);
+                qb.setProjectionMap(sDataRawContactsContactProjectionMap);
+                qb.appendWhere(Data.MIMETYPE + " = \"" + Phone.CONTENT_ITEM_TYPE + "\"");
+                break;
+            }
+
+            case POSTALS: {
+                qb.setTables(Tables.DATA_JOIN_PACKAGES_MIMETYPES_RAW_CONTACTS_CONTACTS);
+                qb.setProjectionMap(sDataRawContactsContactProjectionMap);
+                qb.appendWhere(Data.MIMETYPE + " = \"" + StructuredPostal.CONTENT_ITEM_TYPE + "\"");
+                break;
+            }
+
+            case RAW_CONTACTS: {
+                qb.setTables(Tables.RAW_CONTACTS);
+                qb.setProjectionMap(sRawContactsProjectionMap);
+                applyContactsRestrictionExceptions(qb);
+                break;
+            }
+
+            case RAW_CONTACTS_ID: {
+                long rawContactId = ContentUris.parseId(uri);
+                qb.setTables(Tables.RAW_CONTACTS);
+                qb.setProjectionMap(sRawContactsProjectionMap);
+                qb.appendWhere(RawContactsColumns.CONCRETE_ID + "=" + rawContactId + " AND ");
+                applyContactsRestrictionExceptions(qb);
+                break;
+            }
+
+            case RAW_CONTACTS_DATA: {
+                long rawContactId = Long.parseLong(uri.getPathSegments().get(1));
+                qb.setTables(Tables.DATA_JOIN_PACKAGES_MIMETYPES_RAW_CONTACTS_GROUPS);
+                qb.setProjectionMap(sDataRawContactsGroupsProjectionMap);
+                qb.appendWhere(Data.RAW_CONTACT_ID + "=" + rawContactId + " AND ");
+                applyDataRestrictionExceptions(qb);
+                break;
+            }
+
+            case CONTACTS_FILTER_EMAIL: {
+                // TODO: filter query based on callingUid
+                qb.setTables(Tables.DATA_JOIN_PACKAGES_MIMETYPES_RAW_CONTACTS_CONTACTS);
+                qb.setProjectionMap(sDataRawContactsProjectionMap);
+                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(RawContacts.ACCOUNT_NAME);
+                final String accountType = uri.getQueryParameter(RawContacts.ACCOUNT_TYPE);
+                if (!TextUtils.isEmpty(accountName)) {
+                    qb.appendWhere(RawContactsColumns.CONCRETE_ACCOUNT_NAME + "="
+                            + DatabaseUtils.sqlEscapeString(accountName) + " AND "
+                            + RawContactsColumns.CONCRETE_ACCOUNT_TYPE + "="
+                            + DatabaseUtils.sqlEscapeString(accountType) + " AND ");
+                }
+                qb.setTables(Tables.DATA_JOIN_PACKAGES_MIMETYPES_RAW_CONTACTS_GROUPS);
+                qb.setProjectionMap(sDataGroupsProjectionMap);
+                applyDataRestrictionExceptions(qb);
+                break;
+            }
+
+            case DATA_ID: {
+                qb.setTables(Tables.DATA_JOIN_PACKAGES_MIMETYPES_RAW_CONTACTS_GROUPS);
+                qb.setProjectionMap(sDataGroupsProjectionMap);
+                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.RAW_CONTACT_ID;
+                }
+
+                final String number = uri.getLastPathSegment();
+                OpenHelper.buildPhoneLookupQuery(qb, number);
+                qb.setProjectionMap(sDataRawContactsProjectionMap);
+                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_RAW_CONTACTS_CONTACTS);
+                qb.setProjectionMap(sGroupsSummaryProjectionMap);
+                groupBy = GroupsColumns.CONCRETE_ID;
+                break;
+            }
+
+            case AGGREGATION_EXCEPTIONS: {
+                qb.setTables(Tables.AGGREGATION_EXCEPTIONS_JOIN_RAW_CONTACTS);
+                qb.setProjectionMap(sAggregationExceptionsProjectionMap);
+                break;
+            }
+
+            case AGGREGATION_SUGGESTIONS: {
+                long contactId = Long.parseLong(uri.getPathSegments().get(1));
+
+                // TODO drop MAX_SUGGESTIONS in favor of LIMIT
+                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(contactId, projection,
+                        sContactsProjectionMap, maxSuggestions);
+            }
+
+            case PRESENCE: {
+                qb.setTables(Tables.PRESENCE);
+                qb.setProjectionMap(sPresenceProjectionMap);
+                break;
+            }
+
+            case PRESENCE_ID: {
+                qb.setTables(Tables.PRESENCE);
+                qb.setProjectionMap(sPresenceProjectionMap);
+                qb.appendWhere(Presence._ID + "=" + ContentUris.parseId(uri));
+                break;
+            }
+
+            case SEARCH_SUGGESTIONS: {
+                return mGlobalSearchSupport.handleSearchSuggestionsQuery(db, uri, limit);
+            }
+
+            case SEARCH_SHORTCUT: {
+                // TODO
+                break;
+            }
+
+            default:
+                return mLegacyApiSupport.query(uri, projection, selection, selectionArgs,
+                        sortOrder, limit);
+        }
+
+        // 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;
+    }
+
+    /**
+     * Gets the value of the "limit" URI query parameter.
+     *
+     * @return A string containing a non-negative integer, or <code>null</code> if
+     *         the parameter is not set, or is set to an invalid value.
+     */
+    private String getLimit(Uri url) {
+        String limitParam = url.getQueryParameter("limit");
+        if (limitParam == null) {
+            return null;
+        }
+        // make sure that the limit is a non-negative integer
+        try {
+            int l = Integer.parseInt(limitParam);
+            if (l < 0) {
+                Log.w(TAG, "Invalid limit parameter: " + limitParam);
+                return null;
+            }
+            return String.valueOf(l);
+        } catch (NumberFormatException ex) {
+            Log.w(TAG, "Invalid limit parameter: " + limitParam);
+            return null;
+        }
+    }
+
+    /**
+     * List of package names with access to {@link RawContacts#IS_RESTRICTED} data.
+     */
+    private static final String[] sAllowedPackages = new String[] {
+        "com.android.contacts",
+        "com.facebook",
+    };
+
+    /**
+     * Check if {@link Binder#getCallingUid()} should be allowed access to
+     * {@link RawContacts#IS_RESTRICTED} data.
+     */
+    private boolean hasRestrictedAccess() {
+        final PackageManager pm = getContext().getPackageManager();
+        final String[] callerPackages = pm.getPackagesForUid(Binder.getCallingUid());
+
+        // Has restricted access if caller matches any packages
+        for (String callerPackage : callerPackages) {
+            for (String allowedPackage : sAllowedPackages) {
+                if (allowedPackage.equals(callerPackage)) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Restrict selection of {@link Contacts} to only public ones, or those
+     * the caller has been granted an exception to.
+     */
+    private void applyAggregateRestrictionExceptions(SQLiteQueryBuilder qb) {
+        if (hasRestrictedAccess()) {
+            qb.appendWhere("1");
+        } else {
+            qb.appendWhere(ContactsColumns.SINGLE_IS_RESTRICTED + "=0");
+        }
+    }
+
+    /**
+     * Find any exceptions that have been granted to the calling process, and
+     * add projections to correctly select {@link Contacts#PRIMARY_PHONE_ID}
+     * and {@link Contacts#PRIMARY_EMAIL_ID}.
+     */
+    private void applyAggregatePrimaryRestrictionExceptions(HashMap<String, String> projection) {
+        String projectionPhone;
+        String projectionEmail;
+
+        if (hasRestrictedAccess()) {
+            // With restricted access, always give optimal values
+            projectionPhone = ContactsColumns.OPTIMAL_PRIMARY_PHONE_ID + " AS "
+                    + Contacts.PRIMARY_PHONE_ID;
+            projectionEmail = ContactsColumns.OPTIMAL_PRIMARY_EMAIL_ID + " AS "
+                    + Contacts.PRIMARY_EMAIL_ID;
+        } else {
+            // With general access, always give fallback values
+            projectionPhone = ContactsColumns.FALLBACK_PRIMARY_PHONE_ID + " AS "
+                    + Contacts.PRIMARY_PHONE_ID;
+            projectionEmail = ContactsColumns.FALLBACK_PRIMARY_EMAIL_ID + " AS "
+                    + Contacts.PRIMARY_EMAIL_ID;
+        }
+
+        projection.remove(Contacts.PRIMARY_PHONE_ID);
+        projection.put(Contacts.PRIMARY_PHONE_ID, projectionPhone);
+
+        projection.remove(Contacts.PRIMARY_EMAIL_ID);
+        projection.put(Contacts.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) {
+        qb.appendWhere(getContactsRestrictionExceptions());
+    }
+
+    String getContactsRestrictionExceptions() {
+        if (hasRestrictedAccess()) {
+            return "1";
+        } else {
+            return RawContacts.IS_RESTRICTED + "=0";
+        }
+    }
+
+    public String getContactsRestrictionExceptionAsNestedQuery(String contactIdColumn) {
+        if (hasRestrictedAccess()) {
+            return "1";
+        } else {
+            return "(SELECT " + RawContacts.IS_RESTRICTED + " FROM " + Tables.RAW_CONTACTS
+                    + " WHERE " + RawContactsColumns.CONCRETE_ID + "=" + contactIdColumn + ")=0";
+        }
+    }
+
+    /**
+     * 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.
+     */
+    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 static final String[] DATA_KEYS = new String[]{
+                "data1",
+                "data2",
+                "data3",
+                "data4",
+                "data5",
+                "data6",
+                "data7",
+                "data8",
+                "data9",
+                "data10",
+                "data11",
+                "data12",
+                "data13",
+                "data14",
+                "data15"};
+
+        private static final String[] PROJECTION = new String[]{
+                RawContacts.ACCOUNT_NAME,
+                RawContacts.ACCOUNT_TYPE,
+                RawContacts.SOURCE_ID,
+                RawContacts.VERSION,
+                RawContacts.DIRTY,
+                RawContacts.Data._ID,
+                RawContacts.Data.RES_PACKAGE,
+                RawContacts.Data.MIMETYPE,
+                RawContacts.Data.DATA1,
+                RawContacts.Data.DATA2,
+                RawContacts.Data.DATA3,
+                RawContacts.Data.DATA4,
+                RawContacts.Data.DATA5,
+                RawContacts.Data.DATA6,
+                RawContacts.Data.DATA7,
+                RawContacts.Data.DATA8,
+                RawContacts.Data.DATA9,
+                RawContacts.Data.DATA10,
+                RawContacts.Data.DATA11,
+                RawContacts.Data.DATA12,
+                RawContacts.Data.DATA13,
+                RawContacts.Data.DATA14,
+                RawContacts.Data.DATA15,
+                RawContacts.Data.RAW_CONTACT_ID,
+                RawContacts.Data.IS_PRIMARY,
+                RawContacts.Data.DATA_VERSION,
+                GroupMembership.GROUP_SOURCE_ID};
+
+        private static final int COLUMN_ACCOUNT_NAME = 0;
+        private static final int COLUMN_ACCOUNT_TYPE = 1;
+        private static final int COLUMN_SOURCE_ID = 2;
+        private static final int COLUMN_VERSION = 3;
+        private static final int COLUMN_DIRTY = 4;
+        private static final int COLUMN_DATA_ID = 5;
+        private static final int COLUMN_RES_PACKAGE = 6;
+        private static final int COLUMN_MIMETYPE = 7;
+        private static final int COLUMN_DATA1 = 8;
+        private static final int COLUMN_CONTACT_ID = 23;
+        private static final int COLUMN_IS_PRIMARY = 24;
+        private static final int COLUMN_DATA_VERSION = 25;
+        private static final int COLUMN_GROUP_SOURCE_ID = 26;
+
+        public ContactsEntityIterator(ContactsProvider2 provider, String contactsIdString, Uri uri,
+                String selection, String[] selectionArgs, String sortOrder) {
+            mIsClosed = false;
+
+            final String updatedSortOrder = (sortOrder == null)
+                    ? RawContacts.Data.RAW_CONTACT_ID
+                    : (RawContacts.Data.RAW_CONTACT_ID + "," + sortOrder);
+
+            final SQLiteDatabase db = provider.mOpenHelper.getReadableDatabase();
+            final SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
+            qb.setTables(Tables.CONTACT_ENTITIES);
+            if (contactsIdString != null) {
+                qb.appendWhere(Data.RAW_CONTACT_ID + "=" + contactsIdString);
+            }
+            final String accountName = uri.getQueryParameter(RawContacts.ACCOUNT_NAME);
+            final String accountType = uri.getQueryParameter(RawContacts.ACCOUNT_TYPE);
+            if (!TextUtils.isEmpty(accountName)) {
+                qb.appendWhere(RawContacts.ACCOUNT_NAME + "="
+                        + DatabaseUtils.sqlEscapeString(accountName) + " AND "
+                        + RawContacts.ACCOUNT_TYPE + "="
+                        + DatabaseUtils.sqlEscapeString(accountType));
+            }
+            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 rawContactId = 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(RawContacts.ACCOUNT_NAME, c.getString(COLUMN_ACCOUNT_NAME));
+            contactValues.put(RawContacts.ACCOUNT_TYPE, c.getString(COLUMN_ACCOUNT_TYPE));
+            contactValues.put(RawContacts._ID, rawContactId);
+            contactValues.put(RawContacts.DIRTY, c.getLong(COLUMN_DIRTY));
+            contactValues.put(RawContacts.VERSION, c.getLong(COLUMN_VERSION));
+            contactValues.put(RawContacts.SOURCE_ID, c.getString(COLUMN_SOURCE_ID));
+            Entity contact = new Entity(contactValues);
+
+            // read data rows until the contact id changes
+            do {
+                if (rawContactId != c.getLong(COLUMN_CONTACT_ID)) {
+                    break;
+                }
+                // add the data to to the contact
+                ContentValues dataValues = new ContentValues();
+                dataValues.put(RawContacts.Data._ID, c.getString(COLUMN_DATA_ID));
+                dataValues.put(RawContacts.Data.RES_PACKAGE, c.getString(COLUMN_RES_PACKAGE));
+                dataValues.put(RawContacts.Data.MIMETYPE, c.getString(COLUMN_MIMETYPE));
+                dataValues.put(RawContacts.Data.IS_PRIMARY, c.getString(COLUMN_IS_PRIMARY));
+                dataValues.put(RawContacts.Data.DATA_VERSION, c.getLong(COLUMN_DATA_VERSION));
+                if (!c.isNull(COLUMN_GROUP_SOURCE_ID)) {
+                    dataValues.put(GroupMembership.GROUP_SOURCE_ID,
+                            c.getString(COLUMN_GROUP_SOURCE_ID));
+                }
+                dataValues.put(RawContacts.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;
+        }
+    }
+
+    /**
+     * 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 GroupsEntityIterator implements EntityIterator {
+        private final Cursor mEntityCursor;
+        private volatile boolean mIsClosed;
+
+        private static final String[] PROJECTION = new String[]{
+                Groups._ID,
+                Groups.ACCOUNT_NAME,
+                Groups.ACCOUNT_TYPE,
+                Groups.SOURCE_ID,
+                Groups.DIRTY,
+                Groups.VERSION,
+                Groups.RES_PACKAGE,
+                Groups.TITLE,
+                Groups.TITLE_RES,
+                Groups.GROUP_VISIBLE};
+
+        private static final int COLUMN_ID = 0;
+        private static final int COLUMN_ACCOUNT_NAME = 1;
+        private static final int COLUMN_ACCOUNT_TYPE = 2;
+        private static final int COLUMN_SOURCE_ID = 3;
+        private static final int COLUMN_DIRTY = 4;
+        private static final int COLUMN_VERSION = 5;
+        private static final int COLUMN_RES_PACKAGE = 6;
+        private static final int COLUMN_TITLE = 7;
+        private static final int COLUMN_TITLE_RES = 8;
+        private static final int COLUMN_GROUP_VISIBLE = 9;
+
+        public GroupsEntityIterator(ContactsProvider2 provider, String groupIdString, Uri uri,
+                String selection, String[] selectionArgs, String sortOrder) {
+            mIsClosed = false;
+
+            final String updatedSortOrder = (sortOrder == null)
+                    ? Groups._ID
+                    : (Groups._ID + "," + sortOrder);
+
+            final SQLiteDatabase db = provider.mOpenHelper.getReadableDatabase();
+            final SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
+            qb.setTables(Tables.GROUPS_JOIN_PACKAGES);
+            qb.setProjectionMap(sGroupsProjectionMap);
+            if (groupIdString != null) {
+                qb.appendWhere(Groups._ID + "=" + groupIdString);
+            }
+            final String accountName = uri.getQueryParameter(Groups.ACCOUNT_NAME);
+            final String accountType = uri.getQueryParameter(Groups.ACCOUNT_TYPE);
+            if (!TextUtils.isEmpty(accountName)) {
+                qb.appendWhere(Groups.ACCOUNT_NAME + "="
+                        + DatabaseUtils.sqlEscapeString(accountName) + " AND "
+                        + Groups.ACCOUNT_TYPE + "="
+                        + DatabaseUtils.sqlEscapeString(accountType));
+            }
+            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 groupId = c.getLong(COLUMN_ID);
+
+            // we expect the cursor is already at the row we need to read from
+            ContentValues groupValues = new ContentValues();
+            groupValues.put(Groups.ACCOUNT_NAME, c.getString(COLUMN_ACCOUNT_NAME));
+            groupValues.put(Groups.ACCOUNT_TYPE, c.getString(COLUMN_ACCOUNT_TYPE));
+            groupValues.put(Groups._ID, groupId);
+            groupValues.put(Groups.DIRTY, c.getLong(COLUMN_DIRTY));
+            groupValues.put(Groups.VERSION, c.getLong(COLUMN_VERSION));
+            groupValues.put(Groups.SOURCE_ID, c.getString(COLUMN_SOURCE_ID));
+            groupValues.put(Groups.RES_PACKAGE, c.getString(COLUMN_RES_PACKAGE));
+            groupValues.put(Groups.TITLE, c.getString(COLUMN_TITLE));
+            groupValues.put(Groups.TITLE_RES, c.getString(COLUMN_TITLE_RES));
+            groupValues.put(Groups.GROUP_VISIBLE, c.getLong(COLUMN_GROUP_VISIBLE));
+            Entity group = new Entity(groupValues);
+
+            mEntityCursor.moveToNext();
+
+            return group;
+        }
+    }
+
+    @Override
+    public EntityIterator queryEntities(Uri uri, String selection, String[] selectionArgs,
+            String sortOrder) {
+        final int match = sUriMatcher.match(uri);
+        switch (match) {
+            case RAW_CONTACTS:
+            case RAW_CONTACTS_ID:
+                String contactsIdString = null;
+                if (match == RAW_CONTACTS_ID) {
+                    contactsIdString = uri.getPathSegments().get(1);
+                }
+
+                return new ContactsEntityIterator(this, contactsIdString,
+                        uri, selection, selectionArgs, sortOrder);
+            case GROUPS:
+            case GROUPS_ID:
+                String idString = null;
+                if (match == GROUPS_ID) {
+                    idString = uri.getPathSegments().get(1);
+                }
+
+                return new GroupsEntityIterator(this, idString,
+                        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 CONTACTS: return Contacts.CONTENT_TYPE;
+            case CONTACTS_ID: return Contacts.CONTENT_ITEM_TYPE;
+            case RAW_CONTACTS: return RawContacts.CONTENT_TYPE;
+            case RAW_CONTACTS_ID: return RawContacts.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 Contacts.CONTENT_TYPE;
+            case SEARCH_SUGGESTIONS:
+                return SearchManager.SUGGEST_MIME_TYPE;
+            case SEARCH_SHORTCUT:
+                return SearchManager.SHORTCUT_MIME_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();
+        }
+    }
+
+    private void setDisplayName(long rawContactId, String displayName) {
+        if (displayName != null) {
+            mContactDisplayNameUpdate.bindString(1, displayName);
+        } else {
+            mContactDisplayNameUpdate.bindNull(1);
+        }
+        mContactDisplayNameUpdate.bindLong(2, rawContactId);
+        mContactDisplayNameUpdate.execute();
+    }
+
+    /*
+     * 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;
+        boolean isRestricted = false;
+        String mimeType = null;
+
+        Cursor cursor = null;
+        try {
+            cursor = db.query(DataRawContactsQuery.TABLE, DataRawContactsQuery.PROJECTION,
+                    DataColumns.CONCRETE_ID + "=" + dataId, null, null, null, null);
+            if (cursor.moveToFirst()) {
+                aggId = cursor.getLong(DataRawContactsQuery.CONTACT_ID);
+                isRestricted = (cursor.getInt(DataRawContactsQuery.IS_RESTRICTED) == 1);
+                mimeType = cursor.getString(DataRawContactsQuery.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(ContactsColumns.OPTIMAL_PRIMARY_PHONE_ID, dataId);
+            values.put(ContactsColumns.OPTIMAL_PRIMARY_PHONE_IS_RESTRICTED, isRestricted);
+        } else if (isEmail) {
+            values.put(ContactsColumns.OPTIMAL_PRIMARY_EMAIL_ID, dataId);
+            values.put(ContactsColumns.OPTIMAL_PRIMARY_EMAIL_IS_RESTRICTED, isRestricted);
+        }
+
+        // If this data is unrestricted, then also set as fallback
+        if (!isRestricted && isPhone) {
+            values.put(ContactsColumns.FALLBACK_PRIMARY_PHONE_ID, dataId);
+        } else if (!isRestricted && isEmail) {
+            values.put(ContactsColumns.FALLBACK_PRIMARY_EMAIL_ID, dataId);
+        }
+
+        // Push update into contacts table, if needed
+        if (values.size() > 0) {
+            db.update(Tables.CONTACTS, values, Contacts._ID + "=" + aggId, null);
+        }
+    }
+
+    private String buildContactLookupWhereClause(String filterParam) {
+        StringBuilder filter = new StringBuilder();
+        filter.append(Tables.CONTACTS);
+        filter.append(".");
+        filter.append(Contacts._ID);
+        filter.append(" IN (SELECT ");
+        filter.append(RawContacts.CONTACT_ID);
+        filter.append(" FROM ");
+        filter.append(Tables.RAW_CONTACTS);
+        filter.append(" WHERE ");
+        filter.append(RawContacts._ID);
+        filter.append(" IN ");
+        appendRawContactsByFilterAsNestedQuery(filter, filterParam, null);
+        filter.append(")");
+        return filter.toString();
+    }
+
+    public String getRawContactsByFilterAsNestedQuery(String filterParam) {
+        StringBuilder sb = new StringBuilder();
+        appendRawContactsByFilterAsNestedQuery(sb, filterParam, null);
+        return sb.toString();
+    }
+
+    public void appendRawContactsByFilterAsNestedQuery(StringBuilder sb, String filterParam,
+            String limit) {
+        sb.append("(SELECT DISTINCT raw_contact_id FROM name_lookup WHERE normalized_name GLOB '");
+        sb.append(NameNormalizer.normalize(filterParam));
+        sb.append("*'");
+        if (limit != null) {
+            sb.append(" LIMIT ").append(limit);
+        }
+        sb.append(")");
+    }
+
+    private String[] appendGroupArg(String[] selectionArgs, String arg) {
+        if (selectionArgs == null) {
+            return new String[] {arg};
+        } else {
+            int newLength = selectionArgs.length + 1;
+            String[] newSelectionArgs = new String[newLength];
+            System.arraycopy(selectionArgs, 0, newSelectionArgs, 0, selectionArgs.length);
+            newSelectionArgs[newLength - 1] = arg;
+            return newSelectionArgs;
+        }
+    }
+}
diff --git a/src/com/android/providers/contacts/GlobalSearchSupport.java b/src/com/android/providers/contacts/GlobalSearchSupport.java
new file mode 100644
index 0000000..40e1089
--- /dev/null
+++ b/src/com/android/providers/contacts/GlobalSearchSupport.java
@@ -0,0 +1,327 @@
+/*
+ * 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.database.ArrayListCursor;
+import com.android.providers.contacts.OpenHelper.ContactsColumns;
+import com.android.providers.contacts.OpenHelper.DataColumns;
+import com.android.providers.contacts.OpenHelper.MimetypesColumns;
+import com.android.providers.contacts.OpenHelper.RawContactsColumns;
+import com.android.providers.contacts.OpenHelper.Tables;
+
+import android.app.SearchManager;
+import android.content.ContentUris;
+import android.content.res.Resources;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.net.Uri;
+import android.provider.Contacts.Intents;
+import android.provider.ContactsContract.Contacts;
+import android.provider.ContactsContract.Data;
+import android.provider.ContactsContract.Presence;
+import android.provider.ContactsContract.CommonDataKinds.Email;
+import android.provider.ContactsContract.CommonDataKinds.GroupMembership;
+import android.provider.ContactsContract.CommonDataKinds.Organization;
+import android.provider.ContactsContract.CommonDataKinds.Phone;
+import android.provider.ContactsContract.CommonDataKinds.Photo;
+import android.provider.ContactsContract.CommonDataKinds.StructuredName;
+import android.text.TextUtils;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+
+/**
+ * Support for global search integration for Contacts.
+ */
+public class GlobalSearchSupport {
+
+    private static final String[] SEARCH_SUGGESTIONS_BASED_ON_PHONE_NUMBER_COLUMNS = {
+            "_id",
+            SearchManager.SUGGEST_COLUMN_TEXT_1,
+            SearchManager.SUGGEST_COLUMN_TEXT_2,
+            SearchManager.SUGGEST_COLUMN_ICON_1,
+            SearchManager.SUGGEST_COLUMN_INTENT_DATA,
+            SearchManager.SUGGEST_COLUMN_INTENT_ACTION,
+            SearchManager.SUGGEST_COLUMN_SHORTCUT_ID,
+    };
+
+    private static final String[] SEARCH_SUGGESTIONS_BASED_ON_NAME_COLUMNS = {
+            "_id",
+            SearchManager.SUGGEST_COLUMN_TEXT_1,
+            SearchManager.SUGGEST_COLUMN_TEXT_2,
+            SearchManager.SUGGEST_COLUMN_ICON_1,
+            SearchManager.SUGGEST_COLUMN_ICON_2,
+            SearchManager.SUGGEST_COLUMN_INTENT_DATA_ID,
+            SearchManager.SUGGEST_COLUMN_SHORTCUT_ID,
+    };
+
+    private interface SearchSuggestionQuery {
+        public static final String JOIN_RAW_CONTACTS =
+                " JOIN raw_contacts ON (data.raw_contact_id = raw_contacts._id) ";
+
+        public static final String JOIN_CONTACTS =
+                " JOIN contacts ON (raw_contacts.contact_id = contacts._id)";
+
+        public static final String JOIN_MIMETYPES =
+                " JOIN mimetypes ON (data.mimetype_id = mimetypes._id AND mimetypes.mimetype IN ('"
+                + StructuredName.CONTENT_ITEM_TYPE + "','" + Email.CONTENT_ITEM_TYPE + "','"
+                + Phone.CONTENT_ITEM_TYPE + "','" + Organization.CONTENT_ITEM_TYPE + "','"
+                + Photo.CONTENT_ITEM_TYPE + "','" + GroupMembership.CONTENT_ITEM_TYPE + "')) ";
+
+        public static final String TABLE = "data " + JOIN_RAW_CONTACTS + JOIN_MIMETYPES
+                + JOIN_CONTACTS;
+
+        public static final String PRESENCE_SQL = "(SELECT MAX(" + Presence.PRESENCE_STATUS
+                + ") FROM " + Tables.PRESENCE + " WHERE " + Tables.PRESENCE + "."
+                + Presence.RAW_CONTACT_ID + "=" + RawContactsColumns.CONCRETE_ID + ")";
+
+        public static final String[] COLUMNS = {
+            ContactsColumns.CONCRETE_ID + " AS " + Contacts._ID,
+            ContactsColumns.CONCRETE_DISPLAY_NAME + " AS " + Contacts.DISPLAY_NAME,
+            PRESENCE_SQL + " AS " + Contacts.PRESENCE_STATUS,
+            DataColumns.CONCRETE_ID + " AS data_id",
+            MimetypesColumns.MIMETYPE,
+            Data.IS_SUPER_PRIMARY,
+            Data.DATA2,
+        };
+
+        public static final int CONTACT_ID = 0;
+        public static final int DISPLAY_NAME = 1;
+        public static final int PRESENCE_STATUS = 2;
+        public static final int DATA_ID = 3;
+        public static final int MIMETYPE = 4;
+        public static final int IS_SUPER_PRIMARY = 5;
+        public static final int DATA2 = 6;
+    }
+
+    private static class SearchSuggestion {
+        String contactId;
+        boolean titleIsName;
+        String organization;
+        String email;
+        String phoneNumber;
+        String photoUri;
+        String normalizedName;
+        int presence = -1;
+        boolean processed;
+        String text1;
+        String text2;
+        String icon1;
+        String icon2;
+
+        public SearchSuggestion(long contactId) {
+            this.contactId = String.valueOf(contactId);
+        }
+
+        private void process() {
+            if (processed) {
+                return;
+            }
+
+            boolean hasOrganization = !TextUtils.isEmpty(organization);
+            boolean hasEmail = !TextUtils.isEmpty(email);
+            boolean hasPhone = !TextUtils.isEmpty(phoneNumber);
+
+            boolean titleIsOrganization = !titleIsName && hasOrganization;
+            boolean titleIsEmail = !titleIsName && !titleIsOrganization && hasEmail;
+            boolean titleIsPhone = !titleIsName && !titleIsOrganization && !titleIsEmail
+                    && hasPhone;
+
+            if (!titleIsOrganization && hasOrganization) {
+                text2 = organization;
+            } else if (!titleIsEmail && hasEmail) {
+                text2 = email;
+            } else if (!titleIsPhone && hasPhone) {
+                text2 = phoneNumber;
+            }
+
+            if (photoUri != null) {
+                icon1 = photoUri;
+            } else {
+                icon1 = String.valueOf(com.android.internal.R.drawable.ic_contact_picture);
+            }
+
+            if (presence != -1) {
+                icon2 = String.valueOf(Presence.getPresenceIconResourceId(presence));
+            }
+
+            processed = true;
+        }
+
+        public String getSortKey() {
+            if (normalizedName == null) {
+                process();
+                normalizedName = text1 == null ? "" : NameNormalizer.normalize(text1);
+            }
+            return normalizedName;
+        }
+
+        @SuppressWarnings({"unchecked"})
+        public ArrayList asList() {
+            process();
+
+            ArrayList<Object> list = new ArrayList<Object>();
+            list.add(contactId);
+            list.add(text1);
+            list.add(text2);
+            list.add(icon1);
+            list.add(icon2);
+            list.add(contactId);
+            list.add(contactId);
+            return list;
+        }
+    }
+
+    private final ContactsProvider2 mContactsProvider;
+
+    public GlobalSearchSupport(ContactsProvider2 contactsProvider) {
+        mContactsProvider = contactsProvider;
+    }
+
+    public Cursor handleSearchSuggestionsQuery(SQLiteDatabase db, Uri url, String limit) {
+        if (url.getPathSegments().size() <= 1) {
+            return null;
+        }
+
+        final String searchClause = url.getLastPathSegment();
+        if (TextUtils.isDigitsOnly(searchClause)) {
+            return buildCursorForSearchSuggestionsBasedOnPhoneNumber(searchClause);
+        } else {
+            return buildCursorForSearchSuggestionsBasedOnName(db, searchClause, limit);
+        }
+    }
+
+    private Cursor buildCursorForSearchSuggestionsBasedOnPhoneNumber(String searchClause) {
+        Resources r = mContactsProvider.getContext().getResources();
+        String s;
+        int i;
+
+        ArrayList<Object> dialNumber = new ArrayList<Object>();
+        dialNumber.add(0);  // _id
+        s = r.getString(com.android.internal.R.string.dial_number_using, searchClause);
+        i = s.indexOf('\n');
+        if (i < 0) {
+            dialNumber.add(s);
+            dialNumber.add("");
+        } else {
+            dialNumber.add(s.substring(0, i));
+            dialNumber.add(s.substring(i + 1));
+        }
+        dialNumber.add(String.valueOf(com.android.internal.R.drawable.call_contact));
+        dialNumber.add("tel:" + searchClause);
+        dialNumber.add(Intents.SEARCH_SUGGESTION_DIAL_NUMBER_CLICKED);
+        dialNumber.add(null);
+
+        ArrayList<Object> createContact = new ArrayList<Object>();
+        createContact.add(1);  // _id
+        s = r.getString(com.android.internal.R.string.create_contact_using, searchClause);
+        i = s.indexOf('\n');
+        if (i < 0) {
+            createContact.add(s);
+            createContact.add("");
+        } else {
+            createContact.add(s.substring(0, i));
+            createContact.add(s.substring(i + 1));
+        }
+        createContact.add(String.valueOf(com.android.internal.R.drawable.create_contact));
+        createContact.add("tel:" + searchClause);
+        createContact.add(Intents.SEARCH_SUGGESTION_CREATE_CONTACT_CLICKED);
+        createContact.add(SearchManager.SUGGEST_NEVER_MAKE_SHORTCUT);
+
+        @SuppressWarnings({"unchecked"}) ArrayList<ArrayList> rows = new ArrayList<ArrayList>();
+        rows.add(dialNumber);
+        rows.add(createContact);
+
+        return new ArrayListCursor(SEARCH_SUGGESTIONS_BASED_ON_PHONE_NUMBER_COLUMNS, rows);
+    }
+
+    private Cursor buildCursorForSearchSuggestionsBasedOnName(SQLiteDatabase db,
+            String searchClause, String limit) {
+        ArrayList<SearchSuggestion> suggestionList = new ArrayList<SearchSuggestion>();
+        HashMap<Long, SearchSuggestion> suggestionMap = new HashMap<Long, SearchSuggestion>();
+
+        StringBuilder selection = new StringBuilder();
+        selection.append(mContactsProvider.getContactsRestrictionExceptions());
+        selection.append(" AND " + DataColumns.CONCRETE_RAW_CONTACT_ID + " IN ");
+        mContactsProvider.appendRawContactsByFilterAsNestedQuery(selection, searchClause, limit);
+        selection.append(" AND " + Contacts.IN_VISIBLE_GROUP + "=1");
+
+        Cursor c = db.query(true, SearchSuggestionQuery.TABLE,
+                SearchSuggestionQuery.COLUMNS, selection.toString(), null, null, null, null, null);
+        try {
+            while (c.moveToNext()) {
+
+                long contactId = c.getLong(SearchSuggestionQuery.CONTACT_ID);
+                SearchSuggestion suggestion = suggestionMap.get(contactId);
+                if (suggestion == null) {
+                    suggestion = new SearchSuggestion(contactId);
+                    suggestionList.add(suggestion);
+                    suggestionMap.put(contactId, suggestion);
+                }
+
+                boolean isSuperPrimary = c.getInt(SearchSuggestionQuery.IS_SUPER_PRIMARY) != 0;
+                suggestion.text1 = c.getString(SearchSuggestionQuery.DISPLAY_NAME);
+
+                if (!c.isNull(SearchSuggestionQuery.PRESENCE_STATUS)) {
+                    suggestion.presence = c.getInt(SearchSuggestionQuery.PRESENCE_STATUS);
+                }
+
+                String mimetype = c.getString(SearchSuggestionQuery.MIMETYPE);
+                if (StructuredName.CONTENT_ITEM_TYPE.equals(mimetype)) {
+                    suggestion.titleIsName = true;
+                } else if (Photo.CONTENT_ITEM_TYPE.equals(mimetype)) {
+                    if (isSuperPrimary || suggestion.photoUri == null) {
+
+                        // TODO introduce a dedicated URI for contact photo: /contact/#/photo
+                        long dataId = c.getLong(SearchSuggestionQuery.DATA_ID);
+                        suggestion.photoUri =
+                                ContentUris.withAppendedId(Data.CONTENT_URI, dataId).toString();
+                    }
+                } else if (Organization.CONTENT_ITEM_TYPE.equals(mimetype)) {
+                    if (isSuperPrimary || suggestion.organization == null) {
+                        suggestion.organization = c.getString(SearchSuggestionQuery.DATA2);
+                    }
+                } else if (Email.CONTENT_ITEM_TYPE.equals(mimetype)) {
+                    if (isSuperPrimary || suggestion.email == null) {
+                        suggestion.email = c.getString(SearchSuggestionQuery.DATA2);
+                    }
+                } else if (Phone.CONTENT_ITEM_TYPE.equals(mimetype)) {
+                    if (isSuperPrimary || suggestion.phoneNumber == null) {
+                        suggestion.phoneNumber = c.getString(SearchSuggestionQuery.DATA2);
+                    }
+                }
+            }
+        } finally {
+            c.close();
+        }
+
+        Collections.sort(suggestionList, new Comparator<SearchSuggestion>() {
+            public int compare(SearchSuggestion row1, SearchSuggestion row2) {
+                return row1.getSortKey().compareTo(row2.getSortKey());
+            }
+        });
+
+        @SuppressWarnings({"unchecked"}) ArrayList<ArrayList> rows = new ArrayList<ArrayList>();
+        for (int i = 0; i < suggestionList.size(); i++) {
+            rows.add(suggestionList.get(i).asList());
+        }
+
+        return new ArrayListCursor(SEARCH_SUGGESTIONS_BASED_ON_NAME_COLUMNS, rows);
+    }
+}
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/LegacyApiSupport.java b/src/com/android/providers/contacts/LegacyApiSupport.java
new file mode 100644
index 0000000..af4a74e
--- /dev/null
+++ b/src/com/android/providers/contacts/LegacyApiSupport.java
@@ -0,0 +1,1336 @@
+/*
+ * 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.DataColumns;
+import com.android.providers.contacts.OpenHelper.ExtensionsColumns;
+import com.android.providers.contacts.OpenHelper.GroupsColumns;
+import com.android.providers.contacts.OpenHelper.MimetypesColumns;
+import com.android.providers.contacts.OpenHelper.PhoneColumns;
+import com.android.providers.contacts.OpenHelper.RawContactsColumns;
+import com.android.providers.contacts.OpenHelper.Tables;
+
+import android.app.SearchManager;
+import android.content.ContentUris;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.UriMatcher;
+import android.database.Cursor;
+import android.database.DatabaseUtils;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteQueryBuilder;
+import android.database.sqlite.SQLiteStatement;
+import android.net.Uri;
+import android.provider.ContactsContract;
+import android.provider.Contacts.ContactMethods;
+import android.provider.Contacts.People;
+import android.provider.ContactsContract.Data;
+import android.provider.ContactsContract.Groups;
+import android.provider.ContactsContract.Presence;
+import android.provider.ContactsContract.RawContacts;
+import android.provider.ContactsContract.CommonDataKinds.Email;
+import android.provider.ContactsContract.CommonDataKinds.GroupMembership;
+import android.provider.ContactsContract.CommonDataKinds.Im;
+import android.provider.ContactsContract.CommonDataKinds.Note;
+import android.provider.ContactsContract.CommonDataKinds.Organization;
+import android.provider.ContactsContract.CommonDataKinds.Phone;
+import android.provider.ContactsContract.CommonDataKinds.Photo;
+import android.provider.ContactsContract.CommonDataKinds.StructuredName;
+import android.provider.ContactsContract.CommonDataKinds.StructuredPostal;
+import android.util.Log;
+
+import java.util.HashMap;
+
+public class LegacyApiSupport implements OpenHelper.Delegate {
+
+    private static final UriMatcher sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
+
+    private static final int PEOPLE = 1;
+    private static final int PEOPLE_ID = 2;
+    private static final int PEOPLE_UPDATE_CONTACT_TIME = 3;
+    private static final int ORGANIZATIONS = 4;
+    private static final int ORGANIZATIONS_ID = 5;
+    private static final int PEOPLE_CONTACTMETHODS = 6;
+    private static final int PEOPLE_CONTACTMETHODS_ID = 7;
+    private static final int CONTACTMETHODS = 8;
+    private static final int CONTACTMETHODS_ID = 9;
+    private static final int PEOPLE_PHONES = 10;
+    private static final int PEOPLE_PHONES_ID = 11;
+    private static final int PHONES = 12;
+    private static final int PHONES_ID = 13;
+    private static final int EXTENSIONS = 14;
+    private static final int EXTENSIONS_ID = 15;
+    private static final int PEOPLE_EXTENSIONS = 16;
+    private static final int PEOPLE_EXTENSIONS_ID = 17;
+    private static final int GROUPS = 18;
+    private static final int GROUPS_ID = 19;
+    private static final int GROUPMEMBERSHIP = 20;
+    private static final int GROUPMEMBERSHIP_ID = 21;
+    private static final int PEOPLE_GROUPMEMBERSHIP = 22;
+    private static final int PEOPLE_GROUPMEMBERSHIP_ID = 23;
+    private static final int PEOPLE_PHOTO = 24;
+    private static final int PHOTOS = 25;
+    private static final int PHOTOS_ID = 26;
+    private static final int PRESENCE = 27;
+    private static final int PRESENCE_ID = 28;
+    private static final int PEOPLE_FILTER = 29;
+    private static final int DELETED_PEOPLE = 30;
+    private static final int DELETED_GROUPS = 31;
+    private static final int SEARCH_SUGGESTIONS = 32;
+
+
+
+    private static final String PEOPLE_JOINS =
+            " LEFT OUTER JOIN data name ON (raw_contacts._id = name.raw_contact_id"
+            + " AND (SELECT mimetype FROM mimetypes WHERE mimetypes._id = name.mimetype_id)"
+                    + "='" + StructuredName.CONTENT_ITEM_TYPE + "')"
+            + " LEFT OUTER JOIN data organization ON (raw_contacts._id = organization.raw_contact_id"
+            + " AND (SELECT mimetype FROM mimetypes WHERE mimetypes._id = organization.mimetype_id)"
+                    + "='" + Organization.CONTENT_ITEM_TYPE + "' AND organization.is_primary)"
+            + " LEFT OUTER JOIN data email ON (raw_contacts._id = email.raw_contact_id"
+            + " AND (SELECT mimetype FROM mimetypes WHERE mimetypes._id = email.mimetype_id)"
+                    + "='" + Email.CONTENT_ITEM_TYPE + "' AND email.is_primary)"
+            + " LEFT OUTER JOIN data note ON (raw_contacts._id = note.raw_contact_id"
+            + " AND (SELECT mimetype FROM mimetypes WHERE mimetypes._id = note.mimetype_id)"
+                    + "='" + Note.CONTENT_ITEM_TYPE + "')"
+            + " LEFT OUTER JOIN data phone ON (raw_contacts._id = phone.raw_contact_id"
+            + " AND (SELECT mimetype FROM mimetypes WHERE mimetypes._id = phone.mimetype_id)"
+                    + "='" + Phone.CONTENT_ITEM_TYPE + "' AND phone.is_primary)";
+
+    public static final String DATA_JOINS =
+            " JOIN mimetypes ON (mimetypes._id = data.mimetype_id)"
+            + " JOIN raw_contacts ON (raw_contacts._id = data.raw_contact_id)"
+            + PEOPLE_JOINS;
+
+    public static final String PRESENCE_JOINS =
+            " LEFT OUTER JOIN presence ON ("
+            + " presence.presence_id = (SELECT max(presence_id) FROM presence"
+            + " WHERE view_v1_people._id = presence.raw_contact_id))";
+
+    private static final String PHONETIC_NAME_SQL = "trim(trim("
+            + "ifnull(name." + StructuredName.PHONETIC_GIVEN_NAME + ",' ')||' '||"
+            + "ifnull(name." + StructuredName.PHONETIC_MIDDLE_NAME + ",' '))||' '||"
+            + "ifnull(name." + StructuredName.PHONETIC_FAMILY_NAME + ",' ')) ";
+
+    private static final String CONTACT_METHOD_KIND_SQL =
+            "CAST ((CASE WHEN mimetype='" + Email.CONTENT_ITEM_TYPE + "'"
+                + " THEN " + android.provider.Contacts.KIND_EMAIL
+                + " ELSE"
+                    + " (CASE WHEN mimetype='" + Im.CONTENT_ITEM_TYPE +"'"
+                        + " THEN " + android.provider.Contacts.KIND_IM
+                        + " ELSE"
+                        + " (CASE WHEN mimetype='" + StructuredPostal.CONTENT_ITEM_TYPE + "'"
+                            + " THEN "  + android.provider.Contacts.KIND_POSTAL
+                            + " ELSE"
+                                + " NULL"
+                            + " END)"
+                        + " END)"
+                + " END) AS INTEGER)";
+
+    public interface LegacyTables {
+        public static final String PEOPLE = "view_v1_people";
+        public static final String PEOPLE_JOIN_PRESENCE = "view_v1_people" + PRESENCE_JOINS;
+        public static final String GROUPS = "view_v1_groups";
+        public static final String ORGANIZATIONS = "view_v1_organizations";
+        public static final String CONTACT_METHODS = "view_v1_contact_methods";
+        public static final String PHONES = "view_v1_phones";
+        public static final String EXTENSIONS = "view_v1_extensions";
+        public static final String GROUP_MEMBERSHIP = "view_v1_group_membership";
+        public static final String PHOTOS = "view_v1_photos";
+        public static final String PRESENCE_JOIN_CONTACTS = Tables.PRESENCE +
+                " LEFT OUTER JOIN " + Tables.RAW_CONTACTS
+                + " ON (" + Tables.PRESENCE + "." + Presence.RAW_CONTACT_ID + "="
+                + RawContactsColumns.CONCRETE_ID + ")";
+    }
+
+    private static final String[] ORGANIZATION_MIME_TYPES = new String[] {
+        Organization.CONTENT_ITEM_TYPE
+    };
+
+    private static final String[] CONTACT_METHOD_MIME_TYPES = new String[] {
+        Email.CONTENT_ITEM_TYPE,
+        Im.CONTENT_ITEM_TYPE,
+        StructuredPostal.CONTENT_ITEM_TYPE,
+    };
+
+    private static final String[] PHONE_MIME_TYPES = new String[] {
+        Phone.CONTENT_ITEM_TYPE
+    };
+
+    private interface PhotoQuery {
+        String[] COLUMNS = { Data._ID };
+
+        int _ID = 0;
+    }
+
+    /**
+     * A custom data row that is used to store legacy photo data fields no
+     * longer directly supported by the API.
+     */
+    private interface LegacyPhotoData {
+        public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/photo_v1_extras";
+
+        public static final String PHOTO_DATA_ID = Data.DATA1;
+        public static final String LOCAL_VERSION = Data.DATA2;
+        public static final String DOWNLOAD_REQUIRED = Data.DATA3;
+        public static final String EXISTS_ON_SERVER = Data.DATA4;
+        public static final String SYNC_ERROR = Data.DATA5;
+    }
+
+    public static final String LEGACY_PHOTO_JOIN =
+            " LEFT OUTER JOIN data legacy_photo ON (raw_contacts._id = legacy_photo.raw_contact_id"
+            + " AND (SELECT mimetype FROM mimetypes WHERE mimetypes._id = legacy_photo.mimetype_id)"
+                + "='" + LegacyPhotoData.CONTENT_ITEM_TYPE + "'"
+            + " AND " + DataColumns.CONCRETE_ID + " = legacy_photo." + LegacyPhotoData.PHOTO_DATA_ID
+            + ")";
+
+    private static final HashMap<String, String> sPeopleProjectionMap;
+    private static final HashMap<String, String> sOrganizationProjectionMap;
+    private static final HashMap<String, String> sContactMethodProjectionMap;
+    private static final HashMap<String, String> sPhoneProjectionMap;
+    private static final HashMap<String, String> sExtensionProjectionMap;
+    private static final HashMap<String, String> sGroupProjectionMap;
+    private static final HashMap<String, String> sGroupMembershipProjectionMap;
+    private static final HashMap<String, String> sPhotoProjectionMap;
+    private static final HashMap<String, String> sPresenceProjectionMap;
+
+    static {
+
+        // Contacts URI matching table
+        UriMatcher matcher = sUriMatcher;
+
+        String authority = android.provider.Contacts.AUTHORITY;
+        matcher.addURI(authority, "extensions", EXTENSIONS);
+        matcher.addURI(authority, "extensions/#", EXTENSIONS_ID);
+        matcher.addURI(authority, "groups", GROUPS);
+        matcher.addURI(authority, "groups/#", GROUPS_ID);
+//        matcher.addURI(authority, "groups/name/*/members", GROUP_NAME_MEMBERS);
+//        matcher.addURI(authority, "groups/name/*/members/filter/*",
+//                GROUP_NAME_MEMBERS_FILTER);
+//        matcher.addURI(authority, "groups/system_id/*/members", GROUP_SYSTEM_ID_MEMBERS);
+//        matcher.addURI(authority, "groups/system_id/*/members/filter/*",
+//                GROUP_SYSTEM_ID_MEMBERS_FILTER);
+        matcher.addURI(authority, "groupmembership", GROUPMEMBERSHIP);
+        matcher.addURI(authority, "groupmembership/#", GROUPMEMBERSHIP_ID);
+//        matcher.addURI(authority, "groupmembershipraw", GROUPMEMBERSHIP_RAW);
+        matcher.addURI(authority, "people", PEOPLE);
+//        matcher.addURI(authority, "people/strequent", PEOPLE_STREQUENT);
+//        matcher.addURI(authority, "people/strequent/filter/*", PEOPLE_STREQUENT_FILTER);
+        matcher.addURI(authority, "people/filter/*", PEOPLE_FILTER);
+//        matcher.addURI(authority, "people/with_phones_filter/*",
+//                PEOPLE_WITH_PHONES_FILTER);
+//        matcher.addURI(authority, "people/with_email_or_im_filter/*",
+//                PEOPLE_WITH_EMAIL_OR_IM_FILTER);
+        matcher.addURI(authority, "people/#", PEOPLE_ID);
+        matcher.addURI(authority, "people/#/extensions", PEOPLE_EXTENSIONS);
+        matcher.addURI(authority, "people/#/extensions/#", PEOPLE_EXTENSIONS_ID);
+        matcher.addURI(authority, "people/#/phones", PEOPLE_PHONES);
+        matcher.addURI(authority, "people/#/phones/#", PEOPLE_PHONES_ID);
+//        matcher.addURI(authority, "people/#/phones_with_presence",
+//                PEOPLE_PHONES_WITH_PRESENCE);
+        matcher.addURI(authority, "people/#/photo", PEOPLE_PHOTO);
+//        matcher.addURI(authority, "people/#/photo/data", PEOPLE_PHOTO_DATA);
+        matcher.addURI(authority, "people/#/contact_methods", PEOPLE_CONTACTMETHODS);
+//        matcher.addURI(authority, "people/#/contact_methods_with_presence",
+//                PEOPLE_CONTACTMETHODS_WITH_PRESENCE);
+        matcher.addURI(authority, "people/#/contact_methods/#", PEOPLE_CONTACTMETHODS_ID);
+//        matcher.addURI(authority, "people/#/organizations", PEOPLE_ORGANIZATIONS);
+//        matcher.addURI(authority, "people/#/organizations/#", PEOPLE_ORGANIZATIONS_ID);
+        matcher.addURI(authority, "people/#/groupmembership", PEOPLE_GROUPMEMBERSHIP);
+        matcher.addURI(authority, "people/#/groupmembership/#", PEOPLE_GROUPMEMBERSHIP_ID);
+//        matcher.addURI(authority, "people/raw", PEOPLE_RAW);
+//        matcher.addURI(authority, "people/owner", PEOPLE_OWNER);
+        matcher.addURI(authority, "people/#/update_contact_time",
+                PEOPLE_UPDATE_CONTACT_TIME);
+        matcher.addURI(authority, "deleted_people", DELETED_PEOPLE);
+        matcher.addURI(authority, "deleted_groups", DELETED_GROUPS);
+        matcher.addURI(authority, "phones", PHONES);
+//        matcher.addURI(authority, "phones_with_presence", PHONES_WITH_PRESENCE);
+//        matcher.addURI(authority, "phones/filter/*", PHONES_FILTER);
+//        matcher.addURI(authority, "phones/filter_name/*", PHONES_FILTER_NAME);
+//        matcher.addURI(authority, "phones/mobile_filter_name/*",
+//                PHONES_MOBILE_FILTER_NAME);
+        matcher.addURI(authority, "phones/#", PHONES_ID);
+        matcher.addURI(authority, "photos", PHOTOS);
+        matcher.addURI(authority, "photos/#", PHOTOS_ID);
+        matcher.addURI(authority, "contact_methods", CONTACTMETHODS);
+//        matcher.addURI(authority, "contact_methods/email", CONTACTMETHODS_EMAIL);
+//        matcher.addURI(authority, "contact_methods/email/*", CONTACTMETHODS_EMAIL_FILTER);
+        matcher.addURI(authority, "contact_methods/#", CONTACTMETHODS_ID);
+//        matcher.addURI(authority, "contact_methods/with_presence",
+//                CONTACTMETHODS_WITH_PRESENCE);
+        matcher.addURI(authority, "presence", PRESENCE);
+        matcher.addURI(authority, "presence/#", PRESENCE_ID);
+        matcher.addURI(authority, "organizations", ORGANIZATIONS);
+        matcher.addURI(authority, "organizations/#", ORGANIZATIONS_ID);
+//        matcher.addURI(authority, "voice_dialer_timestamp", VOICE_DIALER_TIMESTAMP);
+        matcher.addURI(authority, SearchManager.SUGGEST_URI_PATH_QUERY,
+                SEARCH_SUGGESTIONS);
+        matcher.addURI(authority, SearchManager.SUGGEST_URI_PATH_QUERY + "/*",
+                SEARCH_SUGGESTIONS);
+//        matcher.addURI(authority, SearchManager.SUGGEST_URI_PATH_SHORTCUT + "/#",
+//                SEARCH_SHORTCUT);
+//        matcher.addURI(authority, "settings", SETTINGS);
+//
+//        matcher.addURI(authority, "live_folders/people", LIVE_FOLDERS_PEOPLE);
+//        matcher.addURI(authority, "live_folders/people/*",
+//                LIVE_FOLDERS_PEOPLE_GROUP_NAME);
+//        matcher.addURI(authority, "live_folders/people_with_phones",
+//                LIVE_FOLDERS_PEOPLE_WITH_PHONES);
+//        matcher.addURI(authority, "live_folders/favorites",
+//                LIVE_FOLDERS_PEOPLE_FAVORITES);
+
+
+        HashMap<String, String> peopleProjectionMap = new HashMap<String, String>();
+        peopleProjectionMap.put(People.NAME, People.NAME);
+        peopleProjectionMap.put(People.DISPLAY_NAME, People.DISPLAY_NAME);
+        peopleProjectionMap.put(People.PHONETIC_NAME, People.PHONETIC_NAME);
+        peopleProjectionMap.put(People.NOTES, People.NOTES);
+        peopleProjectionMap.put(People.TIMES_CONTACTED, People.TIMES_CONTACTED);
+        peopleProjectionMap.put(People.LAST_TIME_CONTACTED, People.LAST_TIME_CONTACTED);
+        peopleProjectionMap.put(People.CUSTOM_RINGTONE, People.CUSTOM_RINGTONE);
+        peopleProjectionMap.put(People.SEND_TO_VOICEMAIL, People.SEND_TO_VOICEMAIL);
+        peopleProjectionMap.put(People.STARRED, People.STARRED);
+
+        sPeopleProjectionMap = new HashMap<String, String>(peopleProjectionMap);
+        sPeopleProjectionMap.put(People.PRIMARY_ORGANIZATION_ID, People.PRIMARY_ORGANIZATION_ID);
+        sPeopleProjectionMap.put(People.PRIMARY_EMAIL_ID, People.PRIMARY_EMAIL_ID);
+        sPeopleProjectionMap.put(People.PRIMARY_PHONE_ID, People.PRIMARY_PHONE_ID);
+        sPeopleProjectionMap.put(People.NUMBER, People.NUMBER);
+        sPeopleProjectionMap.put(People.TYPE, People.TYPE);
+        sPeopleProjectionMap.put(People.LABEL, People.LABEL);
+        sPeopleProjectionMap.put(People.NUMBER_KEY, People.NUMBER_KEY);
+        sPeopleProjectionMap.put(People.IM_PROTOCOL, People.IM_PROTOCOL);
+        sPeopleProjectionMap.put(People.IM_HANDLE, People.IM_HANDLE);
+        sPeopleProjectionMap.put(People.IM_ACCOUNT, People.IM_ACCOUNT);
+        sPeopleProjectionMap.put(People.PRESENCE_STATUS, People.PRESENCE_STATUS);
+        sPeopleProjectionMap.put(People.PRESENCE_CUSTOM_STATUS, People.PRESENCE_CUSTOM_STATUS);
+
+        sOrganizationProjectionMap = new HashMap<String, String>();
+        sOrganizationProjectionMap.put(android.provider.Contacts.Organizations.PERSON_ID,
+                android.provider.Contacts.Organizations.PERSON_ID);
+        sOrganizationProjectionMap.put(android.provider.Contacts.Organizations.ISPRIMARY,
+                android.provider.Contacts.Organizations.ISPRIMARY);
+        sOrganizationProjectionMap.put(android.provider.Contacts.Organizations.COMPANY,
+                android.provider.Contacts.Organizations.COMPANY);
+        sOrganizationProjectionMap.put(android.provider.Contacts.Organizations.TYPE,
+                android.provider.Contacts.Organizations.TYPE);
+        sOrganizationProjectionMap.put(android.provider.Contacts.Organizations.LABEL,
+                android.provider.Contacts.Organizations.LABEL);
+        sOrganizationProjectionMap.put(android.provider.Contacts.Organizations.TITLE,
+                android.provider.Contacts.Organizations.TITLE);
+
+        sContactMethodProjectionMap = new HashMap<String, String>(peopleProjectionMap);
+        sContactMethodProjectionMap.put(ContactMethods.PERSON_ID, ContactMethods.PERSON_ID);
+        sContactMethodProjectionMap.put(ContactMethods.KIND, ContactMethods.KIND);
+        sContactMethodProjectionMap.put(ContactMethods.ISPRIMARY, ContactMethods.ISPRIMARY);
+        sContactMethodProjectionMap.put(ContactMethods.TYPE, ContactMethods.TYPE);
+        sContactMethodProjectionMap.put(ContactMethods.DATA, ContactMethods.DATA);
+        sContactMethodProjectionMap.put(ContactMethods.LABEL, ContactMethods.LABEL);
+        sContactMethodProjectionMap.put(ContactMethods.AUX_DATA, ContactMethods.AUX_DATA);
+
+        sPhoneProjectionMap = new HashMap<String, String>(peopleProjectionMap);
+        sPhoneProjectionMap.put(android.provider.Contacts.Phones.PERSON_ID,
+                android.provider.Contacts.Phones.PERSON_ID);
+        sPhoneProjectionMap.put(android.provider.Contacts.Phones.ISPRIMARY,
+                android.provider.Contacts.Phones.ISPRIMARY);
+        sPhoneProjectionMap.put(android.provider.Contacts.Phones.NUMBER,
+                android.provider.Contacts.Phones.NUMBER);
+        sPhoneProjectionMap.put(android.provider.Contacts.Phones.TYPE,
+                android.provider.Contacts.Phones.TYPE);
+        sPhoneProjectionMap.put(android.provider.Contacts.Phones.LABEL,
+                android.provider.Contacts.Phones.LABEL);
+        sPhoneProjectionMap.put(android.provider.Contacts.Phones.NUMBER_KEY,
+                android.provider.Contacts.Phones.NUMBER_KEY);
+
+        sExtensionProjectionMap = new HashMap<String, String>();
+        sExtensionProjectionMap.put(android.provider.Contacts.Extensions.PERSON_ID,
+                android.provider.Contacts.Extensions.PERSON_ID);
+        sExtensionProjectionMap.put(android.provider.Contacts.Extensions.NAME,
+                android.provider.Contacts.Extensions.NAME);
+        sExtensionProjectionMap.put(android.provider.Contacts.Extensions.VALUE,
+                android.provider.Contacts.Extensions.VALUE);
+
+        sGroupProjectionMap = new HashMap<String, String>();
+        sGroupProjectionMap.put(android.provider.Contacts.Groups._ID,
+                android.provider.Contacts.Groups._ID);
+        sGroupProjectionMap.put(android.provider.Contacts.Groups.NAME,
+                android.provider.Contacts.Groups.NAME);
+        sGroupProjectionMap.put(android.provider.Contacts.Groups.NOTES,
+                android.provider.Contacts.Groups.NOTES);
+        sGroupProjectionMap.put(android.provider.Contacts.Groups.SYSTEM_ID,
+                android.provider.Contacts.Groups.SYSTEM_ID);
+
+        sGroupMembershipProjectionMap = new HashMap<String, String>();
+        sGroupMembershipProjectionMap.put(android.provider.Contacts.GroupMembership.PERSON_ID,
+                android.provider.Contacts.GroupMembership.PERSON_ID);
+        sGroupMembershipProjectionMap.put(android.provider.Contacts.GroupMembership.GROUP_ID,
+                android.provider.Contacts.GroupMembership.GROUP_ID);
+
+        sPhotoProjectionMap = new HashMap<String, String>();
+        sPhotoProjectionMap.put(android.provider.Contacts.Photos.PERSON_ID,
+                android.provider.Contacts.Photos.PERSON_ID);
+        sPhotoProjectionMap.put(android.provider.Contacts.Photos.DATA,
+                android.provider.Contacts.Photos.DATA);
+        sPhotoProjectionMap.put(android.provider.Contacts.Photos.LOCAL_VERSION,
+                android.provider.Contacts.Photos.LOCAL_VERSION);
+        sPhotoProjectionMap.put(android.provider.Contacts.Photos.DOWNLOAD_REQUIRED,
+                android.provider.Contacts.Photos.DOWNLOAD_REQUIRED);
+        sPhotoProjectionMap.put(android.provider.Contacts.Photos.EXISTS_ON_SERVER,
+                android.provider.Contacts.Photos.EXISTS_ON_SERVER);
+        sPhotoProjectionMap.put(android.provider.Contacts.Photos.SYNC_ERROR,
+                android.provider.Contacts.Photos.SYNC_ERROR);
+
+        sPresenceProjectionMap = new HashMap<String, String>();
+        sPresenceProjectionMap.put(android.provider.Contacts.Presence._ID,
+                Tables.PRESENCE + "." + Presence._ID
+                        + " AS " + android.provider.Contacts.Presence._ID);
+        sPresenceProjectionMap.put(android.provider.Contacts.Presence.PERSON_ID,
+                Tables.PRESENCE + "." + Presence.RAW_CONTACT_ID
+                        + " AS " + android.provider.Contacts.Presence.PERSON_ID);
+        sPresenceProjectionMap.put(android.provider.Contacts.Presence.IM_PROTOCOL,
+                Presence.IM_PROTOCOL
+                    + " AS " + android.provider.Contacts.Presence.IM_PROTOCOL);
+        sPresenceProjectionMap.put(android.provider.Contacts.Presence.IM_HANDLE,
+                Presence.IM_HANDLE
+                    + " AS " + android.provider.Contacts.Presence.IM_HANDLE);
+        sPresenceProjectionMap.put(android.provider.Contacts.Presence.IM_ACCOUNT,
+                Presence.IM_ACCOUNT
+                    + " AS " + android.provider.Contacts.Presence.IM_ACCOUNT);
+        sPresenceProjectionMap.put(android.provider.Contacts.Presence.PRESENCE_STATUS,
+                Presence.PRESENCE_STATUS
+                    + " AS " + android.provider.Contacts.Presence.PRESENCE_STATUS);
+        sPresenceProjectionMap.put(android.provider.Contacts.Presence.PRESENCE_CUSTOM_STATUS,
+                Presence.PRESENCE_CUSTOM_STATUS
+                    + " AS " + android.provider.Contacts.Presence.PRESENCE_CUSTOM_STATUS);
+    }
+
+    private final Context mContext;
+    private final OpenHelper mOpenHelper;
+    private final ContactsProvider2 mContactsProvider;
+    private final NameSplitter mPhoneticNameSplitter;
+    private final GlobalSearchSupport mGlobalSearchSupport;
+
+    /** Precompiled sql statement for incrementing times contacted for a contact */
+    private final SQLiteStatement mLastTimeContactedUpdate;
+
+    private final ContentValues mValues = new ContentValues();
+
+
+    public LegacyApiSupport(Context context, OpenHelper openHelper,
+            ContactsProvider2 contactsProvider, GlobalSearchSupport globalSearchSupport) {
+        mContext = context;
+        mContactsProvider = contactsProvider;
+        mOpenHelper = openHelper;
+        mGlobalSearchSupport = globalSearchSupport;
+        mOpenHelper.setDelegate(this);
+
+        mPhoneticNameSplitter = new NameSplitter("", "", "",
+                context.getString(com.android.internal.R.string.common_name_conjunctions));
+
+        SQLiteDatabase db = mOpenHelper.getReadableDatabase();
+        mLastTimeContactedUpdate = db.compileStatement("UPDATE " + Tables.RAW_CONTACTS + " SET "
+                + RawContacts.TIMES_CONTACTED + "="
+                + RawContacts.TIMES_CONTACTED + "+1,"
+                + RawContacts.LAST_TIME_CONTACTED + "=? WHERE "
+                + RawContacts._ID + "=?");
+    }
+
+
+    public void createDatabase(SQLiteDatabase db) {
+
+        db.execSQL("DROP VIEW IF EXISTS " + LegacyTables.PEOPLE + ";");
+        db.execSQL("CREATE VIEW " + LegacyTables.PEOPLE + " AS SELECT " +
+                RawContactsColumns.CONCRETE_ID
+                        + " AS " + android.provider.Contacts.People._ID + ", " +
+                "name." + StructuredName.DISPLAY_NAME
+                        + " AS " + People.NAME + ", " +
+                Tables.RAW_CONTACTS + "." + RawContactsColumns.DISPLAY_NAME
+                        + " AS " + People.DISPLAY_NAME + ", " +
+                PHONETIC_NAME_SQL
+                        + " AS " + People.PHONETIC_NAME + " , " +
+                "note." + Note.NOTE
+                        + " AS " + People.NOTES + ", " +
+                Tables.RAW_CONTACTS + "." + RawContacts.TIMES_CONTACTED
+                        + " AS " + People.TIMES_CONTACTED + ", " +
+                Tables.RAW_CONTACTS + "." + RawContacts.LAST_TIME_CONTACTED
+                        + " AS " + People.LAST_TIME_CONTACTED + ", " +
+                Tables.RAW_CONTACTS + "." + RawContacts.CUSTOM_RINGTONE
+                        + " AS " + People.CUSTOM_RINGTONE + ", " +
+                Tables.RAW_CONTACTS + "." + RawContacts.SEND_TO_VOICEMAIL
+                        + " AS " + People.SEND_TO_VOICEMAIL + ", " +
+                Tables.RAW_CONTACTS + "." + RawContacts.STARRED
+                        + " AS " + People.STARRED + ", " +
+                "organization." + Data._ID
+                        + " AS " + People.PRIMARY_ORGANIZATION_ID + ", " +
+                "email." + Data._ID
+                        + " AS " + People.PRIMARY_EMAIL_ID + ", " +
+                "phone." + Data._ID
+                        + " AS " + People.PRIMARY_PHONE_ID + ", " +
+                "phone." + Phone.NUMBER
+                        + " AS " + People.NUMBER + ", " +
+                "phone." + Phone.TYPE
+                        + " AS " + People.TYPE + ", " +
+                "phone." + Phone.LABEL
+                        + " AS " + People.LABEL + ", " +
+                "phone." + PhoneColumns.NORMALIZED_NUMBER
+                        + " AS " + People.NUMBER_KEY + ", " +
+                RawContacts.IS_RESTRICTED +
+                " FROM " + Tables.RAW_CONTACTS + PEOPLE_JOINS +
+                " WHERE " + Tables.RAW_CONTACTS + "." + RawContacts.DELETED + "=0" +
+        ";");
+
+        db.execSQL("DROP VIEW IF EXISTS " + LegacyTables.ORGANIZATIONS + ";");
+        db.execSQL("CREATE VIEW " + LegacyTables.ORGANIZATIONS + " AS SELECT " +
+                DataColumns.CONCRETE_ID
+                        + " AS " + android.provider.Contacts.Organizations._ID + ", " +
+                Data.RAW_CONTACT_ID
+                        + " AS " + android.provider.Contacts.Organizations.PERSON_ID + ", " +
+                Data.IS_PRIMARY
+                        + " AS " + android.provider.Contacts.Organizations.ISPRIMARY + ", " +
+                Organization.COMPANY
+                        + " AS " + android.provider.Contacts.Organizations.COMPANY + ", " +
+                Organization.TYPE
+                        + " AS " + android.provider.Contacts.Organizations.TYPE + ", " +
+                Organization.LABEL
+                        + " AS " + android.provider.Contacts.Organizations.LABEL + ", " +
+                Organization.TITLE
+                        + " AS " + android.provider.Contacts.Organizations.TITLE + ", " +
+                RawContacts.IS_RESTRICTED +
+                " FROM " + Tables.DATA_JOIN_MIMETYPE_RAW_CONTACTS +
+                " WHERE " + MimetypesColumns.CONCRETE_MIMETYPE + "='"
+                        + Organization.CONTENT_ITEM_TYPE + "'"
+                        + " AND " + Tables.RAW_CONTACTS + "." + RawContacts.DELETED + "=0" +
+        ";");
+
+        db.execSQL("DROP VIEW IF EXISTS " + LegacyTables.CONTACT_METHODS + ";");
+        db.execSQL("CREATE VIEW " + LegacyTables.CONTACT_METHODS + " AS SELECT " +
+                DataColumns.CONCRETE_ID
+                        + " AS " + ContactMethods._ID + ", " +
+                DataColumns.CONCRETE_RAW_CONTACT_ID
+                        + " AS " + ContactMethods.PERSON_ID + ", " +
+                CONTACT_METHOD_KIND_SQL
+                        + " AS " + ContactMethods.KIND + ", " +
+                DataColumns.CONCRETE_IS_PRIMARY
+                        + " AS " + ContactMethods.ISPRIMARY + ", " +
+                DataColumns.CONCRETE_DATA1
+                        + " AS " + ContactMethods.TYPE + ", " +
+                DataColumns.CONCRETE_DATA2
+                        + " AS " + ContactMethods.DATA + ", " +
+                DataColumns.CONCRETE_DATA3
+                        + " AS " + ContactMethods.LABEL + ", " +
+                DataColumns.CONCRETE_DATA14
+                        + " AS " + ContactMethods.AUX_DATA + ", " +
+                "name." + StructuredName.DISPLAY_NAME
+                        + " AS " + ContactMethods.NAME + ", " +
+                Tables.RAW_CONTACTS + "." + RawContactsColumns.DISPLAY_NAME
+                        + " AS " + ContactMethods.DISPLAY_NAME + ", " +
+                PHONETIC_NAME_SQL
+                        + " AS " + ContactMethods.PHONETIC_NAME + " , " +
+                "note." + Note.NOTE
+                        + " AS " + ContactMethods.NOTES + ", " +
+                Tables.RAW_CONTACTS + "." + RawContacts.TIMES_CONTACTED
+                        + " AS " + ContactMethods.TIMES_CONTACTED + ", " +
+                Tables.RAW_CONTACTS + "." + RawContacts.LAST_TIME_CONTACTED
+                        + " AS " + ContactMethods.LAST_TIME_CONTACTED + ", " +
+                Tables.RAW_CONTACTS + "." + RawContacts.CUSTOM_RINGTONE
+                        + " AS " + ContactMethods.CUSTOM_RINGTONE + ", " +
+                Tables.RAW_CONTACTS + "." + RawContacts.SEND_TO_VOICEMAIL
+                        + " AS " + ContactMethods.SEND_TO_VOICEMAIL + ", " +
+                Tables.RAW_CONTACTS + "." + RawContacts.STARRED
+                        + " AS " + ContactMethods.STARRED + ", " +
+                RawContacts.IS_RESTRICTED +
+                " FROM " + Tables.DATA + DATA_JOINS +
+                " WHERE " + ContactMethods.KIND + " IS NOT NULL"
+                    + " AND " + Tables.RAW_CONTACTS + "." + RawContacts.DELETED + "=0" +
+        ";");
+
+
+        db.execSQL("DROP VIEW IF EXISTS " + LegacyTables.PHONES + ";");
+        db.execSQL("CREATE VIEW " + LegacyTables.PHONES + " AS SELECT " +
+                DataColumns.CONCRETE_ID
+                        + " AS " + android.provider.Contacts.Phones._ID + ", " +
+                DataColumns.CONCRETE_RAW_CONTACT_ID
+                        + " AS " + android.provider.Contacts.Phones.PERSON_ID + ", " +
+                DataColumns.CONCRETE_IS_PRIMARY
+                        + " AS " + android.provider.Contacts.Phones.ISPRIMARY + ", " +
+                Tables.DATA + "." + Phone.NUMBER
+                        + " AS " + android.provider.Contacts.Phones.NUMBER + ", " +
+                Tables.DATA + "." + Phone.TYPE
+                        + " AS " + android.provider.Contacts.Phones.TYPE + ", " +
+                Tables.DATA + "." + Phone.LABEL
+                        + " AS " + android.provider.Contacts.Phones.LABEL + ", " +
+                PhoneColumns.CONCRETE_NORMALIZED_NUMBER
+                        + " AS " + android.provider.Contacts.Phones.NUMBER_KEY + ", " +
+                "name." + StructuredName.DISPLAY_NAME
+                        + " AS " + android.provider.Contacts.Phones.NAME + ", " +
+                Tables.RAW_CONTACTS + "." + RawContactsColumns.DISPLAY_NAME
+                        + " AS " + android.provider.Contacts.Phones.DISPLAY_NAME + ", " +
+                PHONETIC_NAME_SQL
+                        + " AS " + android.provider.Contacts.Phones.PHONETIC_NAME + " , " +
+                "note." + Note.NOTE
+                        + " AS " + android.provider.Contacts.Phones.NOTES + ", " +
+                Tables.RAW_CONTACTS + "." + RawContacts.TIMES_CONTACTED
+                        + " AS " + android.provider.Contacts.Phones.TIMES_CONTACTED + ", " +
+                Tables.RAW_CONTACTS + "." + RawContacts.LAST_TIME_CONTACTED
+                        + " AS " + android.provider.Contacts.Phones.LAST_TIME_CONTACTED + ", " +
+                Tables.RAW_CONTACTS + "." + RawContacts.CUSTOM_RINGTONE
+                        + " AS " + android.provider.Contacts.Phones.CUSTOM_RINGTONE + ", " +
+                Tables.RAW_CONTACTS + "." + RawContacts.SEND_TO_VOICEMAIL
+                        + " AS " + android.provider.Contacts.Phones.SEND_TO_VOICEMAIL + ", " +
+                Tables.RAW_CONTACTS + "." + RawContacts.STARRED
+                        + " AS " + android.provider.Contacts.Phones.STARRED + ", " +
+                RawContacts.IS_RESTRICTED +
+                " FROM " + Tables.DATA + DATA_JOINS +
+                " WHERE " + MimetypesColumns.CONCRETE_MIMETYPE + "='"
+                        + Phone.CONTENT_ITEM_TYPE + "'"
+                        + " AND " + Tables.RAW_CONTACTS + "." + RawContacts.DELETED + "=0" +
+        ";");
+
+        db.execSQL("DROP VIEW IF EXISTS " + LegacyTables.EXTENSIONS + ";");
+        db.execSQL("CREATE VIEW " + LegacyTables.EXTENSIONS + " AS SELECT " +
+                DataColumns.CONCRETE_ID
+                        + " AS " + android.provider.Contacts.Extensions._ID + ", " +
+                DataColumns.CONCRETE_RAW_CONTACT_ID
+                        + " AS " + android.provider.Contacts.Extensions.PERSON_ID + ", " +
+                ExtensionsColumns.NAME
+                        + " AS " + android.provider.Contacts.Extensions.NAME + ", " +
+                ExtensionsColumns.VALUE
+                        + " AS " + android.provider.Contacts.Extensions.VALUE + ", " +
+                RawContacts.IS_RESTRICTED +
+                " FROM " + Tables.DATA_JOIN_MIMETYPE_RAW_CONTACTS +
+                " WHERE " + MimetypesColumns.CONCRETE_MIMETYPE + "='"
+                        + android.provider.Contacts.Extensions.CONTENT_ITEM_TYPE + "'"
+                        + " AND " + Tables.RAW_CONTACTS + "." + RawContacts.DELETED + "=0" +
+        ";");
+
+        db.execSQL("DROP VIEW IF EXISTS " + LegacyTables.GROUPS + ";");
+        db.execSQL("CREATE VIEW " + LegacyTables.GROUPS + " AS SELECT " +
+                GroupsColumns.CONCRETE_ID + " AS " + android.provider.Contacts.Groups._ID + ", " +
+                Groups.TITLE + " AS " + android.provider.Contacts.Groups.NAME + ", " +
+                Groups.NOTES + " AS " + android.provider.Contacts.Groups.NOTES + " , " +
+                Groups.SYSTEM_ID + " AS " + android.provider.Contacts.Groups.SYSTEM_ID +
+                " FROM " + Tables.GROUPS +
+        ";");
+
+        db.execSQL("DROP VIEW IF EXISTS " + LegacyTables.GROUP_MEMBERSHIP + ";");
+        db.execSQL("CREATE VIEW " + LegacyTables.GROUP_MEMBERSHIP + " AS SELECT " +
+                DataColumns.CONCRETE_ID
+                        + " AS " + android.provider.Contacts.GroupMembership._ID + ", " +
+                DataColumns.CONCRETE_RAW_CONTACT_ID
+                        + " AS " + android.provider.Contacts.GroupMembership.PERSON_ID + ", " +
+                GroupMembership.GROUP_ROW_ID
+                        + " AS " + android.provider.Contacts.GroupMembership.GROUP_ID + ", " +
+                Groups.TITLE
+                        + " AS " + android.provider.Contacts.GroupMembership.NAME + ", " +
+                Groups.NOTES
+                        + " AS " + android.provider.Contacts.GroupMembership.NOTES + " , " +
+                Groups.SYSTEM_ID
+                        + " AS " + android.provider.Contacts.GroupMembership.SYSTEM_ID + ", " +
+                RawContacts.IS_RESTRICTED +
+                " FROM " + Tables.DATA_JOIN_PACKAGES_MIMETYPES_RAW_CONTACTS_GROUPS +
+                " WHERE " + MimetypesColumns.CONCRETE_MIMETYPE + "='"
+                        + GroupMembership.CONTENT_ITEM_TYPE + "'"
+                        + " AND " + Tables.RAW_CONTACTS + "." + RawContacts.DELETED + "=0" +
+        ";");
+
+        db.execSQL("DROP VIEW IF EXISTS " + LegacyTables.PHOTOS + ";");
+        db.execSQL("CREATE VIEW " + LegacyTables.PHOTOS + " AS SELECT " +
+                DataColumns.CONCRETE_ID
+                        + " AS " + android.provider.Contacts.Photos._ID + ", " +
+                DataColumns.CONCRETE_RAW_CONTACT_ID
+                        + " AS " + android.provider.Contacts.Photos.PERSON_ID + ", " +
+                Tables.DATA + "." + Photo.PHOTO
+                        + " AS " + android.provider.Contacts.Photos.DATA + ", " +
+                "legacy_photo." + LegacyPhotoData.EXISTS_ON_SERVER
+                        + " AS " + android.provider.Contacts.Photos.EXISTS_ON_SERVER + ", " +
+                "legacy_photo." + LegacyPhotoData.DOWNLOAD_REQUIRED
+                        + " AS " + android.provider.Contacts.Photos.DOWNLOAD_REQUIRED + ", " +
+                "legacy_photo." + LegacyPhotoData.LOCAL_VERSION
+                        + " AS " + android.provider.Contacts.Photos.LOCAL_VERSION + ", " +
+                "legacy_photo." + LegacyPhotoData.SYNC_ERROR
+                        + " AS " + android.provider.Contacts.Photos.SYNC_ERROR + ", " +
+                RawContacts.IS_RESTRICTED +
+                " FROM " + Tables.DATA + DATA_JOINS + LEGACY_PHOTO_JOIN +
+                " WHERE " + MimetypesColumns.CONCRETE_MIMETYPE + "='"
+                        + Photo.CONTENT_ITEM_TYPE + "'"
+                        + " AND " + Tables.RAW_CONTACTS + "." + RawContacts.DELETED + "=0" +
+        ";");
+    }
+
+    public Uri insert(Uri uri, ContentValues values) {
+        final int match = sUriMatcher.match(uri);
+        long id = 0;
+        switch (match) {
+            case PEOPLE:
+                id = insertPeople(values);
+                break;
+
+            case ORGANIZATIONS:
+                id = insertOrganization(values);
+                break;
+
+            case PEOPLE_CONTACTMETHODS: {
+                long rawContactId = Long.parseLong(uri.getPathSegments().get(1));
+                id = insertContactMethod(rawContactId, values);
+                break;
+            }
+
+            case CONTACTMETHODS: {
+                long rawContactId = getRequiredValue(values, ContactMethods.PERSON_ID);
+                id = insertContactMethod(rawContactId, values);
+                break;
+            }
+
+            case PHONES: {
+                long rawContactId = getRequiredValue(values,
+                        android.provider.Contacts.Phones.PERSON_ID);
+                id = insertPhone(rawContactId, values);
+                break;
+            }
+
+            case EXTENSIONS: {
+                long rawContactId = getRequiredValue(values,
+                        android.provider.Contacts.Extensions.PERSON_ID);
+                id = insertExtension(rawContactId, values);
+                break;
+            }
+
+            case GROUPS:
+                id = insertGroup(values);
+                break;
+
+            case GROUPMEMBERSHIP: {
+                long rawContactId = getRequiredValue(values,
+                        android.provider.Contacts.GroupMembership.PERSON_ID);
+                long groupId = getRequiredValue(values,
+                        android.provider.Contacts.GroupMembership.GROUP_ID);
+                id = insertGroupMembership(rawContactId, groupId);
+                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;
+    }
+
+    private long getRequiredValue(ContentValues values, String column) {
+        if (!values.containsKey(column)) {
+            throw new RuntimeException("Required value: " + column);
+        }
+
+        return values.getAsLong(column);
+    }
+
+    private long insertPeople(ContentValues values) {
+        mValues.clear();
+
+        OpenHelper.copyStringValue(mValues, RawContacts.CUSTOM_RINGTONE,
+                values, People.CUSTOM_RINGTONE);
+        OpenHelper.copyLongValue(mValues, RawContacts.SEND_TO_VOICEMAIL,
+                values, People.SEND_TO_VOICEMAIL);
+        OpenHelper.copyLongValue(mValues, RawContacts.LAST_TIME_CONTACTED,
+                values, People.LAST_TIME_CONTACTED);
+        OpenHelper.copyLongValue(mValues, RawContacts.TIMES_CONTACTED,
+                values, People.TIMES_CONTACTED);
+        OpenHelper.copyLongValue(mValues, RawContacts.STARRED,
+                values, People.STARRED);
+        Uri contactUri = mContactsProvider.insert(RawContacts.CONTENT_URI, mValues);
+        long rawContactId = ContentUris.parseId(contactUri);
+
+        if (values.containsKey(People.NAME) || values.containsKey(People.PHONETIC_NAME)) {
+            mValues.clear();
+            mValues.put(ContactsContract.Data.RAW_CONTACT_ID, rawContactId);
+            mValues.put(ContactsContract.Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE);
+            OpenHelper.copyStringValue(mValues, StructuredName.DISPLAY_NAME,
+                    values, People.NAME);
+            if (values.containsKey(People.PHONETIC_NAME)) {
+                String phoneticName = values.getAsString(People.PHONETIC_NAME);
+                NameSplitter.Name parsedName = new NameSplitter.Name();
+                mPhoneticNameSplitter.split(parsedName, phoneticName);
+                mValues.put(StructuredName.PHONETIC_GIVEN_NAME, parsedName.getGivenNames());
+                mValues.put(StructuredName.PHONETIC_MIDDLE_NAME, parsedName.getMiddleName());
+                mValues.put(StructuredName.PHONETIC_FAMILY_NAME, parsedName.getFamilyName());
+            }
+
+            mContactsProvider.insert(ContactsContract.Data.CONTENT_URI, mValues);
+        }
+
+        if (values.containsKey(People.NOTES)) {
+            mValues.clear();
+            mValues.put(Data.RAW_CONTACT_ID, rawContactId);
+            mValues.put(Data.MIMETYPE, Note.CONTENT_ITEM_TYPE);
+            OpenHelper.copyStringValue(mValues, Note.NOTE, values, People.NOTES);
+            mContactsProvider.insert(Data.CONTENT_URI, mValues);
+        }
+
+        // TODO instant aggregation
+        return rawContactId;
+    }
+
+    private long insertOrganization(ContentValues values) {
+        mValues.clear();
+
+        OpenHelper.copyLongValue(mValues, Data.RAW_CONTACT_ID,
+                values, android.provider.Contacts.Organizations.PERSON_ID);
+        mValues.put(Data.MIMETYPE, Organization.CONTENT_ITEM_TYPE);
+
+        OpenHelper.copyLongValue(mValues, Data.IS_PRIMARY,
+                values, android.provider.Contacts.Organizations.ISPRIMARY);
+
+        OpenHelper.copyStringValue(mValues, Organization.COMPANY,
+                values, android.provider.Contacts.Organizations.COMPANY);
+
+        // TYPE values happen to remain the same between V1 and V2 - can just copy the value
+        OpenHelper.copyLongValue(mValues, Organization.TYPE,
+                values, android.provider.Contacts.Organizations.TYPE);
+
+        OpenHelper.copyStringValue(mValues, Organization.LABEL,
+                values, android.provider.Contacts.Organizations.LABEL);
+        OpenHelper.copyStringValue(mValues, Organization.TITLE,
+                values, android.provider.Contacts.Organizations.TITLE);
+
+        Uri uri = mContactsProvider.insert(Data.CONTENT_URI, mValues);
+
+        return ContentUris.parseId(uri);
+    }
+
+    private long insertPhone(long rawContactId, ContentValues values) {
+        mValues.clear();
+
+        mValues.put(Data.RAW_CONTACT_ID, rawContactId);
+        mValues.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
+
+        OpenHelper.copyLongValue(mValues, Data.IS_PRIMARY,
+                values, android.provider.Contacts.Phones.ISPRIMARY);
+
+        OpenHelper.copyStringValue(mValues, Phone.NUMBER,
+                values, android.provider.Contacts.Phones.NUMBER);
+
+        // TYPE values happen to remain the same between V1 and V2 - can just copy the value
+        OpenHelper.copyLongValue(mValues, Phone.TYPE,
+                values, android.provider.Contacts.Phones.TYPE);
+
+        OpenHelper.copyStringValue(mValues, Phone.LABEL,
+                values, android.provider.Contacts.Phones.LABEL);
+
+        Uri uri = mContactsProvider.insert(Data.CONTENT_URI, mValues);
+
+        return ContentUris.parseId(uri);
+    }
+
+    private long insertContactMethod(long rawContactId, ContentValues values) {
+        Integer kind = values.getAsInteger(ContactMethods.KIND);
+        if (kind == null) {
+            throw new RuntimeException("Required value: " + ContactMethods.KIND);
+        }
+
+        mValues.clear();
+        mValues.put(Data.RAW_CONTACT_ID, rawContactId);
+
+        OpenHelper.copyLongValue(mValues, Data.IS_PRIMARY, values, ContactMethods.ISPRIMARY);
+
+        switch (kind) {
+            case android.provider.Contacts.KIND_EMAIL:
+                copyCommonFields(values, Email.CONTENT_ITEM_TYPE, Email.TYPE, Email.LABEL,
+                        Email.DATA, Data.DATA14);
+                break;
+
+            case android.provider.Contacts.KIND_IM:
+                copyCommonFields(values, Im.CONTENT_ITEM_TYPE, Im.TYPE, Im.LABEL,
+                        Email.DATA, Data.DATA14);
+                break;
+
+            case android.provider.Contacts.KIND_POSTAL:
+                copyCommonFields(values, StructuredPostal.CONTENT_ITEM_TYPE, StructuredPostal.TYPE,
+                        StructuredPostal.LABEL, StructuredPostal.FORMATTED_ADDRESS, Data.DATA14);
+                break;
+        }
+
+        Uri uri = mContactsProvider.insert(Data.CONTENT_URI, mValues);
+        return ContentUris.parseId(uri);
+    }
+
+    private void copyCommonFields(ContentValues values, String mimeType, String typeColumn,
+            String labelColumn, String dataColumn, String auxDataColumn) {
+        mValues.put(Data.MIMETYPE, mimeType);
+        OpenHelper.copyLongValue(mValues, typeColumn, values, ContactMethods.TYPE);
+        OpenHelper.copyStringValue(mValues, labelColumn, values, ContactMethods.LABEL);
+        OpenHelper.copyStringValue(mValues, dataColumn, values, ContactMethods.DATA);
+        OpenHelper.copyStringValue(mValues, auxDataColumn, values, ContactMethods.AUX_DATA);
+    }
+
+    private long insertExtension(long rawContactId, ContentValues values) {
+        mValues.clear();
+
+        mValues.put(Data.RAW_CONTACT_ID, rawContactId);
+        mValues.put(Data.MIMETYPE, android.provider.Contacts.Extensions.CONTENT_ITEM_TYPE);
+
+        OpenHelper.copyStringValue(mValues, ExtensionsColumns.NAME,
+                values, android.provider.Contacts.People.Extensions.NAME);
+        OpenHelper.copyStringValue(mValues, ExtensionsColumns.VALUE,
+                values, android.provider.Contacts.People.Extensions.VALUE);
+
+        Uri uri = mContactsProvider.insert(Data.CONTENT_URI, mValues);
+        return ContentUris.parseId(uri);
+    }
+
+    private long insertGroup(ContentValues values) {
+        mValues.clear();
+
+        OpenHelper.copyStringValue(mValues, Groups.TITLE,
+                values, android.provider.Contacts.Groups.NAME);
+        OpenHelper.copyStringValue(mValues, Groups.NOTES,
+                values, android.provider.Contacts.Groups.NOTES);
+        OpenHelper.copyStringValue(mValues, Groups.SYSTEM_ID,
+                values, android.provider.Contacts.Groups.SYSTEM_ID);
+
+        Uri uri = mContactsProvider.insert(Groups.CONTENT_URI, mValues);
+        return ContentUris.parseId(uri);
+    }
+
+    private long insertGroupMembership(long rawContactId, long groupId) {
+        mValues.clear();
+
+        mValues.put(Data.MIMETYPE, GroupMembership.CONTENT_ITEM_TYPE);
+        mValues.put(GroupMembership.RAW_CONTACT_ID, rawContactId);
+        mValues.put(GroupMembership.GROUP_ROW_ID, groupId);
+
+        Uri uri = mContactsProvider.insert(Data.CONTENT_URI, mValues);
+        return ContentUris.parseId(uri);
+    }
+
+    private long insertPresence(ContentValues values) {
+        mValues.clear();
+
+        OpenHelper.copyLongValue(mValues, Presence._ID,
+                values, android.provider.Contacts.Presence._ID);
+        OpenHelper.copyLongValue(mValues, Presence.RAW_CONTACT_ID,
+                values, android.provider.Contacts.Presence.PERSON_ID);
+        OpenHelper.copyStringValue(mValues, Presence.IM_PROTOCOL,
+                values, android.provider.Contacts.Presence.IM_PROTOCOL);
+        OpenHelper.copyStringValue(mValues, Presence.IM_HANDLE,
+                values, android.provider.Contacts.Presence.IM_HANDLE);
+        OpenHelper.copyStringValue(mValues, Presence.IM_ACCOUNT,
+                values, android.provider.Contacts.Presence.IM_ACCOUNT);
+        OpenHelper.copyLongValue(mValues, Presence.PRESENCE_STATUS,
+                values, android.provider.Contacts.Presence.PRESENCE_STATUS);
+        OpenHelper.copyStringValue(mValues, Presence.PRESENCE_CUSTOM_STATUS,
+                values, android.provider.Contacts.Presence.PRESENCE_CUSTOM_STATUS);
+
+        return mContactsProvider.insertPresence(mValues);
+    }
+
+    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
+        final int match = sUriMatcher.match(uri);
+        int count = 0;
+        switch(match) {
+            case PEOPLE_UPDATE_CONTACT_TIME:
+                count = updateContactTime(uri, values);
+                break;
+
+            case PEOPLE_PHOTO: {
+                long rawContactId = Long.parseLong(uri.getPathSegments().get(1));
+                return updatePhoto(rawContactId, values);
+            }
+
+            case PHOTOS:
+                // TODO
+                break;
+
+            case PHOTOS_ID:
+                // TODO
+                break;
+
+
+            default:
+                throw new UnsupportedOperationException("Unknown uri: " + uri);
+        }
+
+        if (count > 0) {
+            mContext.getContentResolver().notifyChange(uri, null);
+        }
+        return count;
+    }
+
+
+    private int updateContactTime(Uri uri, ContentValues values) {
+
+        // TODO check sanctions
+
+        long lastTimeContacted;
+        if (values.containsKey(People.LAST_TIME_CONTACTED)) {
+            lastTimeContacted = values.getAsLong(People.LAST_TIME_CONTACTED);
+        } else {
+            lastTimeContacted = System.currentTimeMillis();
+        }
+
+        long rawContactId = Long.parseLong(uri.getPathSegments().get(1));
+        long contactId = mOpenHelper.getContactId(rawContactId);
+        if (contactId != 0) {
+            mContactsProvider.updateContactTime(contactId, lastTimeContacted);
+        } else {
+            mLastTimeContactedUpdate.bindLong(1, lastTimeContacted);
+            mLastTimeContactedUpdate.bindLong(2, rawContactId);
+            mLastTimeContactedUpdate.execute();
+        }
+        return 1;
+    }
+
+    private int updatePhoto(long rawContactId, ContentValues values) {
+
+        // TODO check sanctions
+
+        int count;
+
+        long dataId = -1;
+        Cursor c = mContactsProvider.query(Data.CONTENT_URI, PhotoQuery.COLUMNS,
+                Data.RAW_CONTACT_ID + "=" + rawContactId + " AND "
+                        + Data.MIMETYPE + "=" + mOpenHelper.getMimeTypeId(Photo.CONTENT_ITEM_TYPE),
+                null, null);
+        try {
+            if (c.moveToFirst()) {
+                dataId = c.getLong(PhotoQuery._ID);
+            }
+        } finally {
+            c.close();
+        }
+
+        mValues.clear();
+        byte[] bytes = values.getAsByteArray(android.provider.Contacts.Photos.DATA);
+        mValues.put(Photo.PHOTO, bytes);
+
+        if (dataId == -1) {
+            mValues.put(Data.MIMETYPE, Photo.CONTENT_ITEM_TYPE);
+            mValues.put(Data.RAW_CONTACT_ID, rawContactId);
+            Uri dataUri = mContactsProvider.insert(Data.CONTENT_URI, mValues);
+            dataId = ContentUris.parseId(dataUri);
+            count = 1;
+        } else {
+            Uri dataUri = ContentUris.withAppendedId(Data.CONTENT_URI, dataId);
+            count = mContactsProvider.update(dataUri, mValues, null, null);
+        }
+
+        mValues.clear();
+        OpenHelper.copyStringValue(mValues, LegacyPhotoData.LOCAL_VERSION,
+                values, android.provider.Contacts.Photos.LOCAL_VERSION);
+        OpenHelper.copyStringValue(mValues, LegacyPhotoData.DOWNLOAD_REQUIRED,
+                values, android.provider.Contacts.Photos.DOWNLOAD_REQUIRED);
+        OpenHelper.copyStringValue(mValues, LegacyPhotoData.EXISTS_ON_SERVER,
+                values, android.provider.Contacts.Photos.EXISTS_ON_SERVER);
+        OpenHelper.copyStringValue(mValues, LegacyPhotoData.SYNC_ERROR,
+                values, android.provider.Contacts.Photos.SYNC_ERROR);
+
+        int updated = mContactsProvider.update(Data.CONTENT_URI, mValues,
+                Data.MIMETYPE + "='" + LegacyPhotoData.CONTENT_ITEM_TYPE + "'"
+                        + " AND " + Data.RAW_CONTACT_ID + "=" + rawContactId
+                        + " AND " + LegacyPhotoData.PHOTO_DATA_ID + "=" + dataId, null);
+        if (updated == 0) {
+            mValues.put(Data.RAW_CONTACT_ID, rawContactId);
+            mValues.put(Data.MIMETYPE, LegacyPhotoData.CONTENT_ITEM_TYPE);
+            mValues.put(LegacyPhotoData.PHOTO_DATA_ID, dataId);
+            mContactsProvider.insert(Data.CONTENT_URI, mValues);
+        }
+
+        return count;
+    }
+
+    public int delete(Uri uri, String selection, String[] selectionArgs) {
+        final int match = sUriMatcher.match(uri);
+        int count = 0;
+        switch (match) {
+            case PEOPLE_ID:
+                count = mContactsProvider.deleteRawContact(ContentUris.parseId(uri), false);
+                break;
+
+            case ORGANIZATIONS_ID:
+                count = mContactsProvider.deleteData(ContentUris.parseId(uri),
+                        ORGANIZATION_MIME_TYPES);
+                break;
+
+            case CONTACTMETHODS_ID:
+                count = mContactsProvider.deleteData(ContentUris.parseId(uri),
+                        CONTACT_METHOD_MIME_TYPES);
+                break;
+
+            case PHONES_ID:
+                count = mContactsProvider.deleteData(ContentUris.parseId(uri),
+                        PHONE_MIME_TYPES);
+                break;
+
+            default:
+                throw new UnsupportedOperationException("Unknown uri: " + uri);
+        }
+
+        return count;
+    }
+
+    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
+            String sortOrder, String limit) {
+        final SQLiteDatabase db = mOpenHelper.getReadableDatabase();
+        SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
+        String groupBy = null;
+
+        final int match = sUriMatcher.match(uri);
+        switch (match) {
+            case PEOPLE: {
+                qb.setTables(LegacyTables.PEOPLE_JOIN_PRESENCE);
+                qb.setProjectionMap(sPeopleProjectionMap);
+                break;
+            }
+
+            case PEOPLE_ID:
+                qb.setTables(LegacyTables.PEOPLE_JOIN_PRESENCE);
+                qb.setProjectionMap(sPeopleProjectionMap);
+                qb.appendWhere(People._ID + "=");
+                qb.appendWhere(uri.getPathSegments().get(1));
+                break;
+
+            case PEOPLE_FILTER: {
+                qb.setTables(LegacyTables.PEOPLE_JOIN_PRESENCE);
+                qb.setProjectionMap(sPeopleProjectionMap);
+                String filterParam = uri.getPathSegments().get(2);
+                qb.appendWhere(People._ID + " IN "
+                        + mContactsProvider.getRawContactsByFilterAsNestedQuery(filterParam));
+                break;
+            }
+
+            case ORGANIZATIONS:
+                qb.setTables(LegacyTables.ORGANIZATIONS);
+                qb.setProjectionMap(sOrganizationProjectionMap);
+                mContactsProvider.applyDataRestrictionExceptions(qb);
+                break;
+
+            case ORGANIZATIONS_ID:
+                qb.setTables(LegacyTables.ORGANIZATIONS);
+                qb.setProjectionMap(sOrganizationProjectionMap);
+                mContactsProvider.applyDataRestrictionExceptions(qb);
+                qb.appendWhere(" AND " + android.provider.Contacts.Organizations._ID + "=");
+                qb.appendWhere(uri.getPathSegments().get(1));
+                break;
+
+            case CONTACTMETHODS:
+                qb.setTables(LegacyTables.CONTACT_METHODS);
+                qb.setProjectionMap(sContactMethodProjectionMap);
+                mContactsProvider.applyDataRestrictionExceptions(qb);
+                break;
+
+            case CONTACTMETHODS_ID:
+                qb.setTables(LegacyTables.CONTACT_METHODS);
+                qb.setProjectionMap(sContactMethodProjectionMap);
+                mContactsProvider.applyDataRestrictionExceptions(qb);
+                qb.appendWhere(" AND " + ContactMethods._ID + "=");
+                qb.appendWhere(uri.getPathSegments().get(1));
+                break;
+
+            case PEOPLE_CONTACTMETHODS:
+                qb.setTables(LegacyTables.CONTACT_METHODS);
+                qb.setProjectionMap(sContactMethodProjectionMap);
+                mContactsProvider.applyDataRestrictionExceptions(qb);
+                qb.appendWhere(" AND " + ContactMethods.PERSON_ID + "=");
+                qb.appendWhere(uri.getPathSegments().get(1));
+                qb.appendWhere(" AND " + ContactMethods.KIND + " IS NOT NULL");
+                break;
+
+            case PEOPLE_CONTACTMETHODS_ID:
+                qb.setTables(LegacyTables.CONTACT_METHODS);
+                qb.setProjectionMap(sContactMethodProjectionMap);
+                mContactsProvider.applyDataRestrictionExceptions(qb);
+                qb.appendWhere(" AND " + ContactMethods.PERSON_ID + "=");
+                qb.appendWhere(uri.getPathSegments().get(1));
+                qb.appendWhere(" AND " + ContactMethods._ID + "=");
+                qb.appendWhere(uri.getPathSegments().get(3));
+                qb.appendWhere(" AND " + ContactMethods.KIND + " IS NOT NULL");
+                break;
+
+            case PHONES:
+                qb.setTables(LegacyTables.PHONES);
+                qb.setProjectionMap(sPhoneProjectionMap);
+                mContactsProvider.applyDataRestrictionExceptions(qb);
+                break;
+
+            case PHONES_ID:
+                qb.setTables(LegacyTables.PHONES);
+                qb.setProjectionMap(sPhoneProjectionMap);
+                mContactsProvider.applyDataRestrictionExceptions(qb);
+                qb.appendWhere(" AND " + android.provider.Contacts.Phones._ID + "=");
+                qb.appendWhere(uri.getPathSegments().get(1));
+                break;
+
+            case PEOPLE_PHONES:
+                qb.setTables(LegacyTables.PHONES);
+                qb.setProjectionMap(sPhoneProjectionMap);
+                mContactsProvider.applyDataRestrictionExceptions(qb);
+                qb.appendWhere(" AND " + android.provider.Contacts.Phones.PERSON_ID + "=");
+                qb.appendWhere(uri.getPathSegments().get(1));
+                break;
+
+            case PEOPLE_PHONES_ID:
+                qb.setTables(LegacyTables.PHONES);
+                qb.setProjectionMap(sPhoneProjectionMap);
+                mContactsProvider.applyDataRestrictionExceptions(qb);
+                qb.appendWhere(" AND " + android.provider.Contacts.Phones.PERSON_ID + "=");
+                qb.appendWhere(uri.getPathSegments().get(1));
+                qb.appendWhere(" AND " + android.provider.Contacts.Phones._ID + "=");
+                qb.appendWhere(uri.getPathSegments().get(3));
+                break;
+
+            case EXTENSIONS:
+                qb.setTables(LegacyTables.EXTENSIONS);
+                qb.setProjectionMap(sExtensionProjectionMap);
+                mContactsProvider.applyDataRestrictionExceptions(qb);
+                break;
+
+            case EXTENSIONS_ID:
+                qb.setTables(LegacyTables.EXTENSIONS);
+                qb.setProjectionMap(sExtensionProjectionMap);
+                mContactsProvider.applyDataRestrictionExceptions(qb);
+                qb.appendWhere(" AND " + android.provider.Contacts.Extensions._ID + "=");
+                qb.appendWhere(uri.getPathSegments().get(1));
+                break;
+
+            case PEOPLE_EXTENSIONS:
+                qb.setTables(LegacyTables.EXTENSIONS);
+                qb.setProjectionMap(sExtensionProjectionMap);
+                mContactsProvider.applyDataRestrictionExceptions(qb);
+                qb.appendWhere(" AND " + android.provider.Contacts.Extensions.PERSON_ID + "=");
+                qb.appendWhere(uri.getPathSegments().get(1));
+                break;
+
+            case PEOPLE_EXTENSIONS_ID:
+                qb.setTables(LegacyTables.EXTENSIONS);
+                qb.setProjectionMap(sExtensionProjectionMap);
+                mContactsProvider.applyDataRestrictionExceptions(qb);
+                qb.appendWhere(" AND " + android.provider.Contacts.Extensions.PERSON_ID + "=");
+                qb.appendWhere(uri.getPathSegments().get(1));
+                qb.appendWhere(" AND " + android.provider.Contacts.Extensions._ID + "=");
+                qb.appendWhere(uri.getPathSegments().get(3));
+                break;
+
+            case GROUPS:
+                qb.setTables(LegacyTables.GROUPS);
+                qb.setProjectionMap(sGroupProjectionMap);
+                break;
+
+            case GROUPS_ID:
+                qb.setTables(LegacyTables.GROUPS);
+                qb.setProjectionMap(sGroupProjectionMap);
+                qb.appendWhere(android.provider.Contacts.Groups._ID + "=");
+                qb.appendWhere(uri.getPathSegments().get(1));
+                break;
+
+            case GROUPMEMBERSHIP:
+                qb.setTables(LegacyTables.GROUP_MEMBERSHIP);
+                qb.setProjectionMap(sGroupMembershipProjectionMap);
+                mContactsProvider.applyDataRestrictionExceptions(qb);
+                break;
+
+            case GROUPMEMBERSHIP_ID:
+                qb.setTables(LegacyTables.GROUP_MEMBERSHIP);
+                qb.setProjectionMap(sGroupMembershipProjectionMap);
+                mContactsProvider.applyDataRestrictionExceptions(qb);
+                qb.appendWhere(" AND " + android.provider.Contacts.GroupMembership._ID + "=");
+                qb.appendWhere(uri.getPathSegments().get(1));
+                break;
+
+            case PEOPLE_GROUPMEMBERSHIP:
+                qb.setTables(LegacyTables.GROUP_MEMBERSHIP);
+                qb.setProjectionMap(sGroupMembershipProjectionMap);
+                mContactsProvider.applyDataRestrictionExceptions(qb);
+                qb.appendWhere(" AND " + android.provider.Contacts.GroupMembership.PERSON_ID + "=");
+                qb.appendWhere(uri.getPathSegments().get(1));
+                break;
+
+            case PEOPLE_GROUPMEMBERSHIP_ID:
+                qb.setTables(LegacyTables.GROUP_MEMBERSHIP);
+                qb.setProjectionMap(sGroupMembershipProjectionMap);
+                mContactsProvider.applyDataRestrictionExceptions(qb);
+                qb.appendWhere(" AND " + android.provider.Contacts.GroupMembership.PERSON_ID + "=");
+                qb.appendWhere(uri.getPathSegments().get(1));
+                qb.appendWhere(" AND " + android.provider.Contacts.GroupMembership._ID + "=");
+                qb.appendWhere(uri.getPathSegments().get(3));
+                break;
+
+            case PEOPLE_PHOTO:
+                qb.setTables(LegacyTables.PHOTOS);
+                qb.setProjectionMap(sPhotoProjectionMap);
+                mContactsProvider.applyDataRestrictionExceptions(qb);
+                qb.appendWhere(" AND " + android.provider.Contacts.Photos.PERSON_ID + "=");
+                qb.appendWhere(uri.getPathSegments().get(1));
+                limit = "1";
+                break;
+
+            case PRESENCE:
+                qb.setTables(Tables.PRESENCE);
+                qb.setProjectionMap(sPresenceProjectionMap);
+                qb.appendWhere(mContactsProvider.getContactsRestrictionExceptionAsNestedQuery(
+                        android.provider.Contacts.Presence.PERSON_ID));
+                break;
+
+            case PRESENCE_ID:
+                qb.setTables(Tables.PRESENCE);
+                qb.setProjectionMap(sPresenceProjectionMap);
+                qb.appendWhere(mContactsProvider.getContactsRestrictionExceptionAsNestedQuery(
+                        android.provider.Contacts.Presence.PERSON_ID));
+                qb.appendWhere(" AND " + android.provider.Contacts.Presence._ID + "=");
+                qb.appendWhere(uri.getPathSegments().get(1));
+                break;
+
+            case SEARCH_SUGGESTIONS:
+
+                // No legacy compatibility for search suggestions
+                return mGlobalSearchSupport.handleSearchSuggestionsQuery(db, uri, limit);
+
+            case DELETED_PEOPLE:
+            case DELETED_GROUPS:
+                throw new UnsupportedOperationException();
+
+            default:
+                throw new IllegalArgumentException("Unknown URL " + 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(mContext.getContentResolver(), RawContacts.CONTENT_URI);
+        }
+        DatabaseUtils.dumpCursor(c);
+        return c;
+    }
+
+    /**
+     * Called when a change has been made.
+     *
+     * @param uri the uri that the change was made to
+     */
+    private void onChange(Uri uri) {
+        mContext.getContentResolver().notifyChange(android.provider.Contacts.CONTENT_URI, null);
+    }
+}
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..01c41d4
--- /dev/null
+++ b/src/com/android/providers/contacts/OpenHelper.java
@@ -0,0 +1,1178 @@
+/*
+ * 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.content.SyncStateContentProviderHelper;
+
+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.provider.BaseColumns;
+import android.provider.CallLog.Calls;
+import android.provider.ContactsContract.AggregationExceptions;
+import android.provider.ContactsContract.Contacts;
+import android.provider.ContactsContract.Data;
+import android.provider.ContactsContract.Groups;
+import android.provider.ContactsContract.Presence;
+import android.provider.ContactsContract.RawContacts;
+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.provider.SocialContract.Activities;
+import android.telephony.PhoneNumberUtils;
+import android.util.Log;
+
+import java.util.HashMap;
+
+/**
+ * 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 = 58;
+    private static final String DATABASE_NAME = "contacts2.db";
+    private static final String DATABASE_PRESENCE = "presence_db";
+
+    public interface Delegate {
+        void createDatabase(SQLiteDatabase db);
+    }
+
+    public interface Tables {
+        public static final String ACCOUNTS = "accounts";
+        public static final String CONTACTS = "contacts";
+        public static final String RAW_CONTACTS = "raw_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 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 CALLS = "calls";
+        public static final String CONTACT_ENTITIES = "contact_entities_view";
+
+        public static final String CONTACTS_JOIN_PRESENCE_PRIMARY_PHONE = "contacts "
+                + "LEFT OUTER JOIN raw_contacts ON (contacts._id = raw_contacts.contact_id) "
+                + "LEFT OUTER JOIN presence ON (raw_contacts._id = presence.raw_contact_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_RAW_CONTACTS = "data "
+                + "JOIN mimetypes ON (data.mimetype_id = mimetypes._id) "
+                + "JOIN raw_contacts ON (data.raw_contact_id = raw_contacts._id)";
+
+        public static final String DATA_JOIN_RAW_CONTACTS_GROUPS = "data "
+                + "LEFT OUTER JOIN raw_contacts ON (data.raw_contact_id = raw_contacts._id)"
+                + "LEFT OUTER JOIN groups ON (groups._id = data." + GroupMembership.GROUP_ROW_ID
+                + ")";
+
+        public static final String DATA_JOIN_PACKAGES_MIMETYPES_RAW_CONTACTS = "data "
+                + "LEFT OUTER JOIN packages ON (data.package_id = packages._id) "
+                + "LEFT OUTER JOIN mimetypes ON (data.mimetype_id = mimetypes._id) "
+                + "LEFT OUTER JOIN raw_contacts ON (data.raw_contact_id = raw_contacts._id)";
+
+        public static final String DATA_JOIN_PACKAGES_MIMETYPES_RAW_CONTACTS_CONTACTS = "data "
+                + "LEFT OUTER JOIN packages ON (data.package_id = packages._id) "
+                + "LEFT OUTER JOIN mimetypes ON (data.mimetype_id = mimetypes._id) "
+                + "LEFT OUTER JOIN raw_contacts ON (data.raw_contact_id = raw_contacts._id) "
+                + "LEFT OUTER JOIN contacts ON (raw_contacts.contact_id = contacts._id)";
+
+        public static final String RAW_CONTACTS_JOIN_CONTACTS = "raw_contacts "
+                + "LEFT OUTER JOIN contacts ON (raw_contacts.contact_id = contacts._id)";
+
+        public static final String DATA_JOIN_MIMETYPES_RAW_CONTACTS_CONTACTS = "data "
+                + "LEFT OUTER JOIN mimetypes ON (data.mimetype_id = mimetypes._id) "
+                + "LEFT OUTER JOIN raw_contacts ON (data.raw_contact_id = raw_contacts._id) "
+                + "LEFT OUTER JOIN contacts ON (raw_contacts.contact_id = contacts._id)";
+
+        public static final String DATA_INNER_JOIN_MIMETYPES_RAW_CONTACTS_CONTACTS = "data "
+                + "JOIN mimetypes ON (data.mimetype_id = mimetypes._id) "
+                + "JOIN raw_contacts ON (data.raw_contact_id = raw_contacts._id) "
+                + "JOIN contacts ON (raw_contacts.contact_id = contacts._id)";
+
+        public static final String DATA_JOIN_PACKAGES_MIMETYPES_RAW_CONTACTS_CONTACTS_GROUPS =
+                "data "
+                + "LEFT OUTER JOIN packages ON (data.package_id = packages._id) "
+                + "LEFT OUTER JOIN mimetypes ON (data.mimetype_id = mimetypes._id) "
+                + "LEFT OUTER JOIN groups "
+                + "  ON (mimetypes.mimetype='" + GroupMembership.CONTENT_ITEM_TYPE + "' "
+                + "      AND groups._id = data." + GroupMembership.GROUP_ROW_ID + ") "
+                + "LEFT OUTER JOIN raw_contacts ON (data.raw_contact_id = raw_contacts._id) "
+                + "LEFT OUTER JOIN contacts ON (raw_contacts.contact_id = contacts._id)";
+
+        public static final String DATA_JOIN_PACKAGES_MIMETYPES_RAW_CONTACTS_GROUPS = "data "
+                + "LEFT OUTER JOIN packages ON (data.package_id = packages._id) "
+                + "LEFT OUTER JOIN mimetypes ON (data.mimetype_id = mimetypes._id) "
+                + "LEFT OUTER JOIN raw_contacts ON (data.raw_contact_id = raw_contacts._id) "
+                + "LEFT OUTER JOIN groups "
+                + "  ON (mimetypes.mimetype='" + GroupMembership.CONTENT_ITEM_TYPE + "' "
+                + "      AND 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 GROUPS_JOIN_PACKAGES_DATA_RAW_CONTACTS_CONTACTS = "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 raw_contacts ON (data.raw_contact_id = raw_contacts._id) "
+                + "LEFT OUTER JOIN contacts ON (raw_contacts.contact_id = contacts._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_PACKAGES_MIMETYPES_RAW_CONTACTS_CONTACTS =
+                "activities "
+                + "LEFT OUTER JOIN packages ON (activities.package_id = packages._id) "
+                + "LEFT OUTER JOIN mimetypes ON (activities.mimetype_id = mimetypes._id) "
+                + "LEFT OUTER JOIN raw_contacts ON (activities.author_contact_id = " +
+                		"raw_contacts._id) "
+                + "LEFT OUTER JOIN contacts ON (raw_contacts.contact_id = contacts._id)";
+
+        public static final String NAME_LOOKUP_JOIN_RAW_CONTACTS = "name_lookup "
+                + "INNER JOIN raw_contacts ON (name_lookup.raw_contact_id = raw_contacts._id)";
+
+        public static final String AGGREGATION_EXCEPTIONS_JOIN_RAW_CONTACTS = "agg_exceptions "
+                + "INNER JOIN raw_contacts raw_contacts1 "
+                + "ON (agg_exceptions.raw_contact_id1 = raw_contacts1._id) ";
+
+        public static final String AGGREGATION_EXCEPTIONS_JOIN_RAW_CONTACTS_TWICE =
+                "agg_exceptions "
+                + "INNER JOIN raw_contacts raw_contacts1 "
+                + "ON (agg_exceptions.raw_contact_id1 = raw_contacts1._id) "
+                + "INNER JOIN raw_contacts raw_contacts2 "
+                + "ON (agg_exceptions.raw_contact_id2 = raw_contacts2._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 = "("
+                + ContactsColumns.OPTIMAL_PRIMARY_PHONE_ID + " IS NOT NULL OR "
+                + ContactsColumns.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_RAW_CONTACTS_GROUPS + " WHERE "
+                + DataColumns.MIMETYPE_ID + "=? AND " + RawContacts.CONTACT_ID + "="
+                + ContactsColumns.CONCRETE_ID + " AND " + Groups.GROUP_VISIBLE + "=1";
+
+        public static final String GROUP_HAS_ACCOUNT_AND_SOURCE_ID =
+                Groups.SOURCE_ID + "=? AND "
+                        + Groups.ACCOUNT_NAME + "=? AND "
+                        + Groups.ACCOUNT_TYPE + "=?";
+    }
+
+    public interface ContactsColumns {
+        public static final String OPTIMAL_PRIMARY_PHONE_ID = "optimal_phone_id";
+        public static final String OPTIMAL_PRIMARY_PHONE_IS_RESTRICTED =
+                "optimal_phone_is_restricted";
+        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_IS_RESTRICTED =
+                "optimal_email_is_restricted";
+        public static final String FALLBACK_PRIMARY_EMAIL_ID = "fallback_email_id";
+
+        public static final String SINGLE_IS_RESTRICTED = "single_is_restricted";
+
+        public static final String CONCRETE_ID = Tables.CONTACTS + "." + BaseColumns._ID;
+        public static final String CONCRETE_DISPLAY_NAME = Tables.CONTACTS + "."
+                + Contacts.DISPLAY_NAME;
+
+        public static final String CONCRETE_TIMES_CONTACTED = Tables.CONTACTS + "."
+                + Contacts.TIMES_CONTACTED;
+        public static final String CONCRETE_LAST_TIME_CONTACTED = Tables.CONTACTS + "."
+                + Contacts.LAST_TIME_CONTACTED;
+        public static final String CONCRETE_STARRED = Tables.CONTACTS + "." + Contacts.STARRED;
+        public static final String CONCRETE_CUSTOM_RINGTONE = Tables.CONTACTS + "."
+                + Contacts.CUSTOM_RINGTONE;
+        public static final String CONCRETE_SEND_TO_VOICEMAIL = Tables.CONTACTS + "."
+                + Contacts.SEND_TO_VOICEMAIL;
+    }
+
+    public interface RawContactsColumns {
+        public static final String CONCRETE_ID =
+                Tables.RAW_CONTACTS + "." + BaseColumns._ID;
+        public static final String CONCRETE_ACCOUNT_NAME =
+                Tables.RAW_CONTACTS + "." + RawContacts.ACCOUNT_NAME;
+        public static final String CONCRETE_ACCOUNT_TYPE =
+                Tables.RAW_CONTACTS + "." + RawContacts.ACCOUNT_TYPE;
+        public static final String CONCRETE_SOURCE_ID =
+                Tables.RAW_CONTACTS + "." + RawContacts.SOURCE_ID;
+        public static final String CONCRETE_VERSION =
+                Tables.RAW_CONTACTS + "." + RawContacts.VERSION;
+        public static final String CONCRETE_DIRTY =
+                Tables.RAW_CONTACTS + "." + RawContacts.DIRTY;
+        public static final String CONCRETE_DELETED =
+                Tables.RAW_CONTACTS + "." + RawContacts.DELETED;
+        public static final String DISPLAY_NAME = "display_name";
+    }
+
+    public interface DataColumns {
+        public static final String PACKAGE_ID = "package_id";
+        public static final String MIMETYPE_ID = "mimetype_id";
+
+        public static final String CONCRETE_ID = Tables.DATA + "." + BaseColumns._ID;
+        public static final String CONCRETE_MIMETYPE_ID = Tables.DATA + "." + MIMETYPE_ID;
+        public static final String CONCRETE_RAW_CONTACT_ID = Tables.DATA + "."
+                + Data.RAW_CONTACT_ID;
+        public static final String CONCRETE_GROUP_ID = Tables.DATA + "."
+                + GroupMembership.GROUP_ROW_ID;
+
+        public static final String CONCRETE_DATA1 = Tables.DATA + "." + Data.DATA1;
+        public static final String CONCRETE_DATA2 = Tables.DATA + "." + Data.DATA2;
+        public static final String CONCRETE_DATA3 = Tables.DATA + "." + Data.DATA3;
+        public static final String CONCRETE_DATA4 = Tables.DATA + "." + Data.DATA4;
+        public static final String CONCRETE_DATA5 = Tables.DATA + "." + Data.DATA5;
+        public static final String CONCRETE_DATA6 = Tables.DATA + "." + Data.DATA6;
+        public static final String CONCRETE_DATA7 = Tables.DATA + "." + Data.DATA7;
+        public static final String CONCRETE_DATA8 = Tables.DATA + "." + Data.DATA8;
+        public static final String CONCRETE_DATA9 = Tables.DATA + "." + Data.DATA9;
+        public static final String CONCRETE_DATA10 = Tables.DATA + "." + Data.DATA10;
+        public static final String CONCRETE_DATA11 = Tables.DATA + "." + Data.DATA11;
+        public static final String CONCRETE_DATA12 = Tables.DATA + "." + Data.DATA12;
+        public static final String CONCRETE_DATA13 = Tables.DATA + "." + Data.DATA13;
+        public static final String CONCRETE_DATA14 = Tables.DATA + "." + Data.DATA14;
+        public static final String CONCRETE_DATA15 = Tables.DATA + "." + Data.DATA15;
+        public static final String CONCRETE_IS_PRIMARY = Tables.DATA + "." + Data.IS_PRIMARY;
+        public static final String CONCRETE_PACKAGE_ID = Tables.DATA + "." + PACKAGE_ID;
+    }
+
+    // Used only for legacy API support
+    public interface ExtensionsColumns {
+        public static final String NAME = Data.DATA1;
+        public static final String VALUE = Data.DATA2;
+    }
+
+    public interface GroupMembershipColumns {
+        public static final String RAW_CONTACT_ID = Data.RAW_CONTACT_ID;
+        public static final String GROUP_ROW_ID = GroupMembership.GROUP_ROW_ID;
+    }
+
+    public interface PhoneColumns {
+        public static final String NORMALIZED_NUMBER = Data.DATA4;
+        public static final String CONCRETE_NORMALIZED_NUMBER = DataColumns.CONCRETE_DATA4;
+    }
+
+    public interface GroupsColumns {
+        public static final String PACKAGE_ID = "package_id";
+
+        public static final String CONCRETE_ID = Tables.GROUPS + "." + BaseColumns._ID;
+        public static final String CONCRETE_SOURCE_ID = Tables.GROUPS + "." + Groups.SOURCE_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 RAW_CONTACT_ID = "raw_contact_id";
+        public static final String NORMALIZED_NUMBER = "normalized_number";
+    }
+
+    public interface NameLookupColumns {
+        public static final String _ID = BaseColumns._ID;
+        public static final String RAW_CONTACT_ID = "raw_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 static final String CONCRETE_ID = Tables.PACKAGES + "." + _ID;
+    }
+
+    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 RAW_CONTACT_ID1 = "raw_contact_id1";
+        public static final String RAW_CONTACT_ID2 = "raw_contact_id2";
+    }
+
+    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 mContactIdQuery;
+    private SQLiteStatement mAggregationModeQuery;
+    private SQLiteStatement mContactIdUpdate;
+    private SQLiteStatement mMimetypeInsert;
+    private SQLiteStatement mPackageInsert;
+    private SQLiteStatement mNameLookupInsert;
+
+    private SQLiteStatement mDataMimetypeQuery;
+    private SQLiteStatement mActivitiesMimetypeQuery;
+
+    private final Context mContext;
+    private final SyncStateContentProviderHelper mSyncState;
+    private HashMap<String, String[]> mNicknameClusterCache;
+
+    /** Compiled statements for updating {@link Contacts#IN_VISIBLE_GROUP}. */
+    private SQLiteStatement mVisibleAllUpdate;
+    private SQLiteStatement mVisibleSpecificUpdate;
+
+    private Delegate mDelegate;
+
+    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(android.content.Context)} instead.
+     */
+    /* package */ OpenHelper(Context context) {
+        super(context, DATABASE_NAME, null, DATABASE_VERSION);
+        Log.i(TAG, "Creating OpenHelper");
+
+        mContext = context;
+        mSyncState = new SyncStateContentProviderHelper();
+    }
+
+    public Delegate getDelegate() {
+        return mDelegate;
+    }
+
+    public void setDelegate(Delegate delegate) {
+        mDelegate = delegate;
+    }
+
+    @Override
+    public void onOpen(SQLiteDatabase db) {
+        mSyncState.onDatabaseOpened(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 + "=?");
+        mContactIdQuery = db.compileStatement("SELECT " + RawContacts.CONTACT_ID + " FROM "
+                + Tables.RAW_CONTACTS + " WHERE " + RawContacts._ID + "=?");
+        mContactIdUpdate = db.compileStatement("UPDATE " + Tables.RAW_CONTACTS + " SET "
+                + RawContacts.CONTACT_ID + "=?" + " WHERE " + RawContacts._ID + "=?");
+        mAggregationModeQuery = db.compileStatement("SELECT " + RawContacts.AGGREGATION_MODE
+                + " FROM " + Tables.RAW_CONTACTS + " WHERE " + RawContacts._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.RAW_CONTACT_ID + "," + NameLookupColumns.NAME_TYPE + ","
+                + NameLookupColumns.NORMALIZED_NAME + ") VALUES (?,?,?)");
+
+        final String visibleUpdate = "UPDATE " + Tables.CONTACTS + " SET "
+                + Contacts.IN_VISIBLE_GROUP + "= (" + Clauses.IN_VISIBLE_GROUP + ")";
+
+        mVisibleAllUpdate = db.compileStatement(visibleUpdate);
+        mVisibleSpecificUpdate = db.compileStatement(visibleUpdate + " WHERE "
+                + ContactsColumns.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 + " ("+
+                Presence._ID + " INTEGER PRIMARY KEY," +
+                Presence.RAW_CONTACT_ID + " INTEGER REFERENCES raw_contacts(_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.RAW_CONTACT_ID + ");");
+    }
+
+    @Override
+    public void onCreate(SQLiteDatabase db) {
+        Log.i(TAG, "Bootstrapping database");
+
+        mSyncState.createDatabase(db);
+
+        // One row per group of contacts corresponding to the same person
+        db.execSQL("CREATE TABLE " + Tables.CONTACTS + " (" +
+                BaseColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
+                Contacts.DISPLAY_NAME + " TEXT," +
+                Contacts.PHOTO_ID + " INTEGER REFERENCES data(_id)," +
+                Contacts.CUSTOM_RINGTONE + " TEXT," +
+                Contacts.SEND_TO_VOICEMAIL + " INTEGER NOT NULL DEFAULT 0," +
+                Contacts.TIMES_CONTACTED + " INTEGER NOT NULL DEFAULT 0," +
+                Contacts.LAST_TIME_CONTACTED + " INTEGER," +
+                Contacts.STARRED + " INTEGER NOT NULL DEFAULT 0," +
+                Contacts.IN_VISIBLE_GROUP + " INTEGER NOT NULL DEFAULT 1," +
+                ContactsColumns.OPTIMAL_PRIMARY_PHONE_ID + " INTEGER REFERENCES data(_id)," +
+                ContactsColumns.OPTIMAL_PRIMARY_PHONE_IS_RESTRICTED + " INTEGER DEFAULT 0," +
+                ContactsColumns.FALLBACK_PRIMARY_PHONE_ID + " INTEGER REFERENCES data(_id)," +
+                ContactsColumns.OPTIMAL_PRIMARY_EMAIL_ID + " INTEGER REFERENCES data(_id)," +
+                ContactsColumns.OPTIMAL_PRIMARY_EMAIL_IS_RESTRICTED + " INTEGER DEFAULT 0," +
+                ContactsColumns.FALLBACK_PRIMARY_EMAIL_ID + " INTEGER REFERENCES data(_id)," +
+                ContactsColumns.SINGLE_IS_RESTRICTED + " INTEGER REFERENCES package(_id)" +
+        ");");
+
+        // Contacts table
+        db.execSQL("CREATE TABLE " + Tables.RAW_CONTACTS + " (" +
+                RawContacts._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
+                RawContacts.IS_RESTRICTED + " INTEGER DEFAULT 0," +
+                RawContacts.ACCOUNT_NAME + " STRING DEFAULT NULL, " +
+                RawContacts.ACCOUNT_TYPE + " STRING DEFAULT NULL, " +
+                RawContacts.SOURCE_ID + " TEXT," +
+                RawContacts.VERSION + " INTEGER NOT NULL DEFAULT 1," +
+                RawContacts.DIRTY + " INTEGER NOT NULL DEFAULT 1," +
+                RawContacts.DELETED + " INTEGER NOT NULL DEFAULT 0," +
+                RawContacts.CONTACT_ID + " INTEGER," +
+                RawContacts.AGGREGATION_MODE + " INTEGER NOT NULL DEFAULT " +
+                        RawContacts.AGGREGATION_MODE_DEFAULT + "," +
+                RawContacts.CUSTOM_RINGTONE + " TEXT," +
+                RawContacts.SEND_TO_VOICEMAIL + " INTEGER NOT NULL DEFAULT 0," +
+                RawContacts.TIMES_CONTACTED + " INTEGER NOT NULL DEFAULT 0," +
+                RawContacts.LAST_TIME_CONTACTED + " INTEGER," +
+                RawContacts.STARRED + " INTEGER NOT NULL DEFAULT 0," +
+                RawContactsColumns.DISPLAY_NAME + " TEXT" +
+        ");");
+
+        // 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.PACKAGE_ID + " INTEGER REFERENCES package(_id)," +
+                DataColumns.MIMETYPE_ID + " INTEGER REFERENCES mimetype(_id) NOT NULL," +
+                Data.RAW_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," +
+                Data.DATA11 + " TEXT," +
+                Data.DATA12 + " TEXT," +
+                Data.DATA13 + " TEXT," +
+                Data.DATA14 + " TEXT," +
+                Data.DATA15 + " TEXT" +
+        ");");
+
+        /**
+         * Automatically delete Data rows when a raw contact is deleted.
+         */
+        db.execSQL("CREATE TRIGGER " + Tables.RAW_CONTACTS + "_deleted "
+                + "   BEFORE DELETE ON " + Tables.RAW_CONTACTS
+                + " BEGIN "
+                + "   DELETE FROM " + Tables.DATA
+                + "     WHERE " + Data.RAW_CONTACT_ID + "=OLD." + RawContacts._ID + ";"
+                + "   DELETE FROM " + Tables.PHONE_LOOKUP
+                + "     WHERE " + PhoneLookupColumns.RAW_CONTACT_ID + "=OLD." + RawContacts._ID + ";"
+                + " END");
+
+        /**
+         * Triggers that set {@link RawContacts#DIRTY} and update {@link RawContacts#VERSION}
+         * when the contact is marked for deletion or any time a data row is inserted, updated
+         * or deleted.
+         */
+        db.execSQL("CREATE TRIGGER " + Tables.RAW_CONTACTS + "_marked_deleted "
+                + "   BEFORE UPDATE ON " + Tables.RAW_CONTACTS
+                + " BEGIN "
+                + "   UPDATE " + Tables.RAW_CONTACTS
+                + "     SET "
+                +         RawContacts.VERSION + "=OLD." + RawContacts.VERSION + "+1, "
+                +         RawContacts.DIRTY + "=1"
+                + "     WHERE " + RawContacts._ID + "=OLD." + RawContacts._ID
+                + "       AND NEW." + RawContacts.DELETED + "!= OLD." + RawContacts.DELETED + ";"
+                + " 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.RAW_CONTACTS
+                + "     SET " + RawContacts.DIRTY + "=1, "
+                + "         " +	RawContacts.VERSION + "=" + RawContacts.VERSION + "+1 "
+                + "     WHERE " + RawContacts._ID + "=OLD." + Data.RAW_CONTACT_ID + ";"
+                + " END");
+
+        db.execSQL("CREATE TRIGGER " + Tables.DATA + "_inserted BEFORE INSERT ON " + Tables.DATA
+                + " BEGIN "
+                + "   UPDATE " + Tables.RAW_CONTACTS
+                + "     SET " + RawContacts.DIRTY + "=1, "
+                + "         " + RawContacts.VERSION + "=" + RawContacts.VERSION + "+1 "
+                + "     WHERE " + RawContacts._ID + "=NEW." + Data.RAW_CONTACT_ID + ";"
+                + " END");
+
+        db.execSQL("CREATE TRIGGER " + Tables.DATA + "_deleted BEFORE DELETE ON " + Tables.DATA
+                + " BEGIN "
+                + "   UPDATE " + Tables.RAW_CONTACTS
+                + "     SET " + RawContacts.DIRTY + "=1,"
+                + "         " + RawContacts.VERSION + "=" + RawContacts.VERSION + "+1 "
+                + "     WHERE " + RawContacts._ID + "=OLD." + Data.RAW_CONTACT_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.RAW_CONTACT_ID
+                        + " INTEGER REFERENCES raw_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.RAW_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.RAW_CONTACT_ID
+                        + " INTEGER REFERENCES raw_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.RAW_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," +
+                GroupsColumns.PACKAGE_ID + " INTEGER REFERENCES package(_id)," +
+                Groups.ACCOUNT_NAME + " STRING DEFAULT NULL, " +
+                Groups.ACCOUNT_TYPE + " STRING DEFAULT NULL, " +
+                Groups.SOURCE_ID + " TEXT," +
+                Groups.VERSION + " INTEGER NOT NULL DEFAULT 1," +
+                Groups.DIRTY + " INTEGER NOT NULL DEFAULT 1," +
+                Groups.TITLE + " TEXT," +
+                Groups.TITLE_RES + " INTEGER," +
+                Groups.NOTES + " TEXT," +
+                Groups.SYSTEM_ID + " TEXT," +
+                Groups.GROUP_VISIBLE + " INTEGER" +
+        ");");
+
+        db.execSQL("CREATE TRIGGER " + Tables.GROUPS + "_updated1 "
+                + "   BEFORE UPDATE ON " + Tables.GROUPS
+                + " BEGIN "
+                + "   UPDATE " + Tables.GROUPS
+                + "     SET "
+                +         Groups.VERSION + "=OLD." + Groups.VERSION + "+1, "
+                +         Groups.DIRTY + "=1"
+                + "     WHERE " + Groups._ID + "=OLD." + Groups._ID + ";"
+                + " END");
+
+        db.execSQL("CREATE TABLE IF NOT EXISTS " + Tables.AGGREGATION_EXCEPTIONS + " (" +
+                AggregationExceptionColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
+                AggregationExceptions.TYPE + " INTEGER NOT NULL, " +
+                AggregationExceptionColumns.RAW_CONTACT_ID1
+                        + " INTEGER REFERENCES raw_contacts(_id), " +
+                AggregationExceptionColumns.RAW_CONTACT_ID2
+                        + " INTEGER REFERENCES raw_contacts(_id)" +
+        ");");
+
+        db.execSQL("CREATE UNIQUE INDEX IF NOT EXISTS aggregation_exception_index1 ON " +
+                Tables.AGGREGATION_EXCEPTIONS + " (" +
+                AggregationExceptionColumns.RAW_CONTACT_ID1 + ", " +
+                AggregationExceptionColumns.RAW_CONTACT_ID2 +
+        ");");
+
+        db.execSQL("CREATE UNIQUE INDEX IF NOT EXISTS aggregation_exception_index2 ON " +
+                Tables.AGGREGATION_EXCEPTIONS + " (" +
+                AggregationExceptionColumns.RAW_CONTACT_ID2 + ", " +
+                AggregationExceptionColumns.RAW_CONTACT_ID1 +
+        ");");
+
+        // The table for recent calls is here so we can do table joins
+        // on people, phones, and calls all in one place.
+        db.execSQL("CREATE TABLE " + Tables.CALLS + " (" +
+                Calls._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
+                Calls.NUMBER + " TEXT," +
+                Calls.DATE + " INTEGER," +
+                Calls.DURATION + " INTEGER," +
+                Calls.TYPE + " INTEGER," +
+                Calls.NEW + " INTEGER," +
+                Calls.CACHED_NAME + " TEXT," +
+                Calls.CACHED_NUMBER_TYPE + " INTEGER," +
+                Calls.CACHED_NUMBER_LABEL + " TEXT" +
+        ");");
+
+        // Activities table
+        db.execSQL("CREATE TABLE " + Tables.ACTIVITIES + " (" +
+                Activities._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
+                ActivitiesColumns.PACKAGE_ID + " INTEGER REFERENCES package(_id)," +
+                ActivitiesColumns.MIMETYPE_ID + " INTEGER REFERENCES mimetype(_id) NOT NULL," +
+                Activities.RAW_ID + " TEXT," +
+                Activities.IN_REPLY_TO + " TEXT," +
+                Activities.AUTHOR_CONTACT_ID +  " INTEGER REFERENCES raw_contacts(_id)," +
+                Activities.TARGET_CONTACT_ID + " INTEGER REFERENCES raw_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" +
+        ");");
+
+        db.execSQL("CREATE VIEW " + Tables.CONTACT_ENTITIES + " AS SELECT "
+                + RawContactsColumns.CONCRETE_ACCOUNT_NAME + " AS " + RawContacts.ACCOUNT_NAME + ","
+                + RawContactsColumns.CONCRETE_ACCOUNT_TYPE + " AS " + RawContacts.ACCOUNT_TYPE + ","
+                + RawContactsColumns.CONCRETE_SOURCE_ID + " AS " + RawContacts.SOURCE_ID + ","
+                + RawContactsColumns.CONCRETE_VERSION + " AS " + RawContacts.VERSION + ","
+                + RawContactsColumns.CONCRETE_DIRTY + " AS " + RawContacts.DIRTY + ","
+                + PackagesColumns.PACKAGE + " AS " + Data.RES_PACKAGE + ","
+                + RawContacts.CONTACT_ID + ", "
+                + Data.MIMETYPE + ", "
+                + Data.DATA1 + ", "
+                + Data.DATA2 + ", "
+                + Data.DATA3 + ", "
+                + Data.DATA4 + ", "
+                + Data.DATA5 + ", "
+                + Data.DATA6 + ", "
+                + Data.DATA7 + ", "
+                + Data.DATA8 + ", "
+                + Data.DATA9 + ", "
+                + Data.DATA10 + ", "
+                + Data.DATA11 + ", "
+                + Data.DATA12 + ", "
+                + Data.DATA13 + ", "
+                + Data.DATA14 + ", "
+                + Data.DATA15 + ", "
+                + Data.RAW_CONTACT_ID + ", "
+                + Data.IS_PRIMARY + ", "
+                + Data.DATA_VERSION + ", "
+                + DataColumns.CONCRETE_ID + " AS " + RawContacts._ID + ","
+                + Tables.GROUPS + "." + Groups.SOURCE_ID + " AS " + GroupMembership.GROUP_SOURCE_ID
+                + " FROM " + Tables.DATA
+                + " LEFT OUTER JOIN " + Tables.PACKAGES + " ON ("
+                +   DataColumns.CONCRETE_PACKAGE_ID + "=" + PackagesColumns.CONCRETE_ID + ")"
+                + " LEFT OUTER JOIN " + Tables.MIMETYPES + " ON ("
+                +   DataColumns.CONCRETE_MIMETYPE_ID + "=" + MimetypesColumns.CONCRETE_ID + ")"
+                + " LEFT OUTER JOIN " + Tables.RAW_CONTACTS + " ON ("
+                +   DataColumns.CONCRETE_RAW_CONTACT_ID + "=" + RawContactsColumns.CONCRETE_ID + ")"
+                + " LEFT OUTER JOIN " + Tables.GROUPS + " ON ("
+                +   MimetypesColumns.CONCRETE_MIMETYPE + "='" + GroupMembership.CONTENT_ITEM_TYPE
+                +   "' AND " + GroupsColumns.CONCRETE_ID + "=" + DataColumns.CONCRETE_DATA1 + ")");
+
+        loadNicknameLookupTable(db);
+        if (mDelegate != null) {
+            mDelegate.createDatabase(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.CONTACTS + ";");
+        db.execSQL("DROP TABLE IF EXISTS " + Tables.RAW_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.ACTIVITIES + ";");
+        db.execSQL("DROP TABLE IF EXISTS " + Tables.CALLS);
+
+        db.execSQL("DROP VIEW IF EXISTS " + Tables.CONTACT_ENTITIES + ";");
+
+        // 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 + ";");
+
+        onCreate(db);
+
+        // TODO: eventually when this supports upgrades we should do something like the following:
+//        if (!upgradeDatabase(db, oldVersion, newVersion)) {
+//            mSyncState.discardSyncData(db, null /* all accounts */);
+//            ContentResolver.requestSync(null /* all accounts */,
+//                    mContentUri.getAuthority(), new Bundle());
+//        }
+    }
+
+    /**
+     * Wipes all data except mime type and package lookup tables.
+     */
+    public void wipeData() {
+        SQLiteDatabase db = getWritableDatabase();
+        db.execSQL("DELETE FROM " + Tables.CONTACTS + ";");
+        db.execSQL("DELETE FROM " + Tables.RAW_CONTACTS + ";");
+        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.ACTIVITIES + ";");
+        db.execSQL("DELETE FROM " + Tables.CALLS);
+
+        // 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 Contacts#IN_VISIBLE_GROUP} for all contacts.
+     */
+    public void updateAllVisible() {
+        final long groupMembershipMimetypeId = getMimeTypeId(GroupMembership.CONTENT_ITEM_TYPE);
+        mVisibleAllUpdate.bindLong(1, groupMembershipMimetypeId);
+        mVisibleAllUpdate.execute();
+    }
+
+    /**
+     * Update {@link Contacts#IN_VISIBLE_GROUP} for a specific contact.
+     */
+    public void updateContactVisible(long aggId) {
+        final long groupMembershipMimetypeId = getMimeTypeId(GroupMembership.CONTENT_ITEM_TYPE);
+        mVisibleSpecificUpdate.bindLong(1, groupMembershipMimetypeId);
+        mVisibleSpecificUpdate.bindLong(2, aggId);
+        mVisibleSpecificUpdate.execute();
+    }
+
+    /**
+     * Updates the contact ID for the specified contact.
+     */
+    public void setContactId(long rawContactId, long contactId) {
+        getWritableDatabase();
+        DatabaseUtils.bindObjectToProgram(mContactIdUpdate, 1, contactId);
+        DatabaseUtils.bindObjectToProgram(mContactIdUpdate, 2, rawContactId);
+        mContactIdUpdate.execute();
+    }
+
+    /**
+     * Returns contact ID for the given contact or zero if it is NULL.
+     */
+    public long getContactId(long rawContactId) {
+        getReadableDatabase();
+        try {
+            DatabaseUtils.bindObjectToProgram(mContactIdQuery, 1, rawContactId);
+            return mContactIdQuery.simpleQueryForLong();
+        } catch (SQLiteDoneException e) {
+            // No valid mapping found, so return -1
+            return 0;
+        }
+    }
+
+    public int getAggregationMode(long rawContactId) {
+        getReadableDatabase();
+        try {
+            DatabaseUtils.bindObjectToProgram(mAggregationModeQuery, 1, rawContactId);
+            return (int)mAggregationModeQuery.simpleQueryForLong();
+        } catch (SQLiteDoneException e) {
+            // No valid row found, so return "disabled"
+            return RawContacts.AGGREGATION_MODE_DISABLED;
+        }
+    }
+
+    /**
+     * Inserts a record in the {@link Tables#NAME_LOOKUP} table.
+     */
+    public void insertNameLookup(long rawContactId, int lookupType, String name) {
+        getWritableDatabase();
+        DatabaseUtils.bindObjectToProgram(mNameLookupInsert, 1, rawContactId);
+        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(Tables.RAW_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.raw_contact_id=raw_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;
+    }
+
+    public static void copyStringValue(ContentValues toValues, String toKey,
+            ContentValues fromValues, String fromKey) {
+        if (fromValues.containsKey(fromKey)) {
+            toValues.put(toKey, fromValues.getAsString(fromKey));
+        }
+    }
+
+    public static void copyLongValue(ContentValues toValues, String toKey,
+            ContentValues fromValues, String fromKey) {
+        if (fromValues.containsKey(fromKey)) {
+            long longValue;
+            Object value = fromValues.get(fromKey);
+            if (value instanceof Boolean) {
+                if ((Boolean)value) {
+                    longValue = 1;
+                } else {
+                    longValue = 0;
+                }
+            } else {
+                longValue = ((Number) value).longValue();
+            }
+            toValues.put(toKey, longValue);
+        }
+    }
+
+    public SyncStateContentProviderHelper getSyncState() {
+        return mSyncState;
+    }
+
+    /**
+     * Delete the aggregate contact if it has no constituent raw contacts other
+     * than the supplied one.
+     */
+    public void removeContactIfSingleton(long rawContactId) {
+        SQLiteDatabase db = getWritableDatabase();
+
+        // Obtain contact ID from the supplied raw contact ID
+        String contactIdFromRawContactId = "(SELECT " + RawContacts.CONTACT_ID + " FROM "
+                + Tables.RAW_CONTACTS + " WHERE " + RawContacts._ID + "=" + rawContactId + ")";
+
+        // Find other raw contacts in the same aggregate contact
+        String otherRawContacts = "(SELECT contacts1." + RawContacts._ID + " FROM "
+                + Tables.RAW_CONTACTS + " contacts1 JOIN " + Tables.RAW_CONTACTS + " contacts2 ON ("
+                + "contacts1." + RawContacts.CONTACT_ID + "=contacts2." + RawContacts.CONTACT_ID
+                + ") WHERE contacts1." + RawContacts._ID + "!=" + rawContactId + ""
+                + " AND contacts2." + RawContacts._ID + "=" + rawContactId + ")";
+
+        db.execSQL("DELETE FROM " + Tables.CONTACTS
+                + " WHERE " + Contacts._ID + "=" + contactIdFromRawContactId
+                + " AND NOT EXISTS " + otherRawContacts + ";");
+    }
+}
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..a5ea0c9
--- /dev/null
+++ b/src/com/android/providers/contacts/SocialProvider.java
@@ -0,0 +1,404 @@
+/*
+ * 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.PackagesColumns;
+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.Contacts;
+import android.provider.ContactsContract.RawContacts;
+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 CONTACT_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> sContactsProjectionMap;
+    /** Contains just the contacts columns */
+    private static final HashMap<String, String> sRawContactsProjectionMap;
+    /** Contains just the activities columns */
+    private static final HashMap<String, String> sActivitiesProjectionMap;
+
+    /** Contains the activities, raw contacts, and contacts columns, for joined tables */
+    private static final HashMap<String, String> sActivitiesContactsProjectionMap;
+
+    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, "contact_status/#", CONTACT_STATUS_ID);
+
+        HashMap<String, String> columns;
+
+        // Contacts projection map
+        columns = new HashMap<String, String>();
+        columns.put(Contacts.DISPLAY_NAME, Contacts.DISPLAY_NAME);
+        sContactsProjectionMap = columns;
+
+        // Contacts projection map
+        columns = new HashMap<String, String>();
+        columns.put(RawContacts._ID, Tables.RAW_CONTACTS + "." + RawContacts._ID + " AS _id");
+        columns.put(RawContacts.CONTACT_ID, RawContacts.CONTACT_ID);
+        sRawContactsProjectionMap = columns;
+
+        // Activities projection map
+        columns = new HashMap<String, String>();
+        columns.put(Activities._ID, "activities._id AS _id");
+        columns.put(Activities.RES_PACKAGE, PackagesColumns.PACKAGE + " AS "
+                + Activities.RES_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, raw contacts, and contacts projection map for joins
+        columns = new HashMap<String, String>();
+        columns.putAll(sContactsProjectionMap);
+        columns.putAll(sRawContactsProjectionMap);
+        columns.putAll(sActivitiesProjectionMap); // Final _id will be from Activities
+        sActivitiesContactsProjectionMap = 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.RES_PACKAGE);
+            if (packageName != null) {
+                values.put(ActivitiesColumns.PACKAGE_ID, mOpenHelper.getPackageId(packageName));
+            }
+            values.remove(Activities.RES_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_PACKAGES_MIMETYPES_RAW_CONTACTS_CONTACTS);
+                qb.setProjectionMap(sActivitiesContactsProjectionMap);
+                break;
+            }
+
+            case ACTIVITIES_ID: {
+                // TODO: enforce that caller has read access to this data
+                long activityId = ContentUris.parseId(uri);
+                qb.setTables(Tables.ACTIVITIES_JOIN_PACKAGES_MIMETYPES_RAW_CONTACTS_CONTACTS);
+                qb.setProjectionMap(sActivitiesContactsProjectionMap);
+                qb.appendWhere(Activities._ID + "=" + activityId);
+                break;
+            }
+
+            case ACTIVITIES_AUTHORED_BY: {
+                long contactId = ContentUris.parseId(uri);
+                qb.setTables(Tables.ACTIVITIES_JOIN_PACKAGES_MIMETYPES_RAW_CONTACTS_CONTACTS);
+                qb.setProjectionMap(sActivitiesContactsProjectionMap);
+                qb.appendWhere(Activities.AUTHOR_CONTACT_ID + "=" + contactId);
+                break;
+            }
+
+            case CONTACT_STATUS_ID: {
+                long aggId = ContentUris.parseId(uri);
+                qb.setTables(Tables.ACTIVITIES_JOIN_PACKAGES_MIMETYPES_RAW_CONTACTS_CONTACTS);
+                qb.setProjectionMap(sActivitiesContactsProjectionMap);
+
+                // Latest status of a contact 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.RAW_CONTACTS + " WHERE " + RawContacts.CONTACT_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 CONTACT_STATUS_ID:
+                return Contacts.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..ec48f5a
--- /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 := ContactsProviderTests
+
+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..5063a7d
--- /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="Contacts 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..cc27428
--- /dev/null
+++ b/tests/src/com/android/providers/contacts/BaseContactsProvider2Test.java
@@ -0,0 +1,600 @@
+/*
+ * 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.accounts.Account;
+import android.content.ContentProvider;
+import android.content.ContentUris;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.Entity;
+import android.content.res.Resources;
+import android.database.Cursor;
+import android.net.Uri;
+import android.provider.ContactsContract;
+import android.provider.ContactsContract.AggregationExceptions;
+import android.provider.ContactsContract.Contacts;
+import android.provider.ContactsContract.Data;
+import android.provider.ContactsContract.Groups;
+import android.provider.ContactsContract.Presence;
+import android.provider.ContactsContract.RawContacts;
+import android.provider.ContactsContract.CommonDataKinds.Email;
+import android.provider.ContactsContract.CommonDataKinds.GroupMembership;
+import android.provider.ContactsContract.CommonDataKinds.Im;
+import android.provider.ContactsContract.CommonDataKinds.Nickname;
+import android.provider.ContactsContract.CommonDataKinds.Phone;
+import android.provider.ContactsContract.CommonDataKinds.Photo;
+import android.provider.ContactsContract.CommonDataKinds.StructuredName;
+import android.test.AndroidTestCase;
+import android.test.mock.MockContentResolver;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * A common superclass for {@link ContactsProvider2}-related tests.
+ */
+@LargeTest
+public abstract class BaseContactsProvider2Test extends AndroidTestCase {
+
+    protected static final String PACKAGE = "ContactsProvider2Test";
+
+    protected ContactsActor mActor;
+    protected MockContentResolver mResolver;
+    protected Account mAccount = new Account("account1", "account type1");
+
+    protected final static Long NO_LONG = new Long(0);
+    protected final static String NO_STRING = new String("");
+    protected final static Account NO_ACCOUNT = new Account("a", "b");
+
+    protected Class<? extends ContentProvider> getProviderClass() {
+        return SynchronousContactsProvider2.class;
+    }
+
+    protected String getAuthority() {
+        return ContactsContract.AUTHORITY;
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        mActor = new ContactsActor(getContext(), PACKAGE_GREY, getProviderClass(), getAuthority());
+        mResolver = mActor.resolver;
+        if (mActor.provider instanceof SynchronousContactsProvider2) {
+            ((SynchronousContactsProvider2) mActor.provider)
+                    .getOpenHelper(mActor.context).wipeData();
+        }
+    }
+
+    public Context getMockContext() {
+        return mActor.context;
+    }
+
+    public void addAuthority(String authority) {
+        mActor.addAuthority(authority);
+    }
+
+    public ContentProvider addProvider(Class<? extends ContentProvider> providerClass,
+            String authority) throws Exception {
+        return mActor.addProvider(providerClass, authority);
+    }
+
+    protected Uri maybeAddAccountQueryParameters(Uri uri, Account account) {
+        if (account == null) {
+            return uri;
+        }
+        return uri.buildUpon()
+                .appendQueryParameter(RawContacts.ACCOUNT_NAME, account.mName)
+                .appendQueryParameter(RawContacts.ACCOUNT_TYPE, account.mType)
+                .build();
+    }
+
+    protected long createRawContact() {
+        return createRawContact(null);
+    }
+
+    protected long createRawContactWithName() {
+        long rawContactId = createRawContact(null);
+        insertStructuredName(rawContactId, "John", "Doe");
+        return rawContactId;
+    }
+
+    protected long createRawContact(Account account, String... extras) {
+        ContentValues values = new ContentValues();
+        for (int i = 0; i < extras.length; ) {
+            values.put(extras[i], extras[i + 1]);
+            i += 2;
+        }
+        final Uri uri = maybeAddAccountQueryParameters(RawContacts.CONTENT_URI, account);
+        Uri contactUri = mResolver.insert(uri, values);
+        return ContentUris.parseId(contactUri);
+    }
+
+    protected long createGroup(Account account, String sourceId, String title) {
+        ContentValues values = new ContentValues();
+        values.put(Groups.SOURCE_ID, sourceId);
+        values.put(Groups.TITLE, title);
+        values.put(Groups.GROUP_VISIBLE, 1);
+        final Uri uri = maybeAddAccountQueryParameters(Groups.CONTENT_URI, account);
+        return ContentUris.parseId(mResolver.insert(uri, values));
+    }
+
+    protected Uri insertStructuredName(long rawContactId, 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(rawContactId, values);
+    }
+
+    protected Uri insertStructuredName(long rawContactId, ContentValues values) {
+        values.put(Data.RAW_CONTACT_ID, rawContactId);
+        values.put(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE);
+        Uri resultUri = mResolver.insert(Data.CONTENT_URI, values);
+        return resultUri;
+    }
+
+    protected Uri insertPhoneNumber(long rawContactId, String phoneNumber) {
+        ContentValues values = new ContentValues();
+        values.put(Data.RAW_CONTACT_ID, rawContactId);
+        values.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
+        values.put(Phone.NUMBER, phoneNumber);
+        values.put(Phone.TYPE, Phone.TYPE_HOME);
+
+        Uri resultUri = mResolver.insert(Data.CONTENT_URI, values);
+        return resultUri;
+    }
+
+    protected Uri insertEmail(long rawContactId, String email) {
+        ContentValues values = new ContentValues();
+        values.put(Data.RAW_CONTACT_ID, rawContactId);
+        values.put(Data.MIMETYPE, Email.CONTENT_ITEM_TYPE);
+        values.put(Email.DATA, email);
+        values.put(Email.TYPE, Email.TYPE_HOME);
+
+        Uri resultUri = mResolver.insert(Data.CONTENT_URI, values);
+        return resultUri;
+    }
+
+    protected Uri insertNickname(long rawContactId, String nickname) {
+        ContentValues values = new ContentValues();
+        values.put(Data.RAW_CONTACT_ID, rawContactId);
+        values.put(Data.MIMETYPE, Nickname.CONTENT_ITEM_TYPE);
+        values.put(Nickname.NAME, nickname);
+        values.put(Nickname.TYPE, Nickname.TYPE_OTHER_NAME);
+
+        Uri resultUri = mResolver.insert(Data.CONTENT_URI, values);
+        return resultUri;
+    }
+
+    protected Uri insertPhoto(long rawContactId) {
+        ContentValues values = new ContentValues();
+        values.put(Data.RAW_CONTACT_ID, rawContactId);
+        values.put(Data.MIMETYPE, Photo.CONTENT_ITEM_TYPE);
+
+        Uri resultUri = mResolver.insert(Data.CONTENT_URI, values);
+        return resultUri;
+    }
+
+    protected Uri insertGroupMembership(long rawContactId, String sourceId) {
+        ContentValues values = new ContentValues();
+        values.put(Data.RAW_CONTACT_ID, rawContactId);
+        values.put(Data.MIMETYPE, GroupMembership.CONTENT_ITEM_TYPE);
+        values.put(GroupMembership.GROUP_SOURCE_ID, sourceId);
+        return mResolver.insert(Data.CONTENT_URI, values);
+    }
+
+    protected Uri insertGroupMembership(long rawContactId, Long groupId) {
+        ContentValues values = new ContentValues();
+        values.put(Data.RAW_CONTACT_ID, rawContactId);
+        values.put(Data.MIMETYPE, GroupMembership.CONTENT_ITEM_TYPE);
+        values.put(GroupMembership.GROUP_ROW_ID, groupId);
+        return mResolver.insert(Data.CONTENT_URI, values);
+    }
+
+    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 rawContactId, int protocol, String handle) {
+        ContentValues values = new ContentValues();
+        values.put(Data.RAW_CONTACT_ID, rawContactId);
+        values.put(Data.MIMETYPE, Im.CONTENT_ITEM_TYPE);
+        values.put(Im.PROTOCOL, protocol);
+        values.put(Im.DATA, handle);
+        values.put(Im.TYPE, Im.TYPE_HOME);
+
+        Uri resultUri = mResolver.insert(Data.CONTENT_URI, values);
+        return resultUri;
+    }
+
+    protected void setContactAccountName(long rawContactId, String accountName) {
+        ContentValues values = new ContentValues();
+        values.put(RawContacts.ACCOUNT_NAME, accountName);
+
+        mResolver.update(ContentUris.withAppendedId(
+                RawContacts.CONTENT_URI, rawContactId), values, null, null);
+    }
+
+    protected void setAggregationException(int type, long contactId, long rawContactId) {
+        ContentValues values = new ContentValues();
+        values.put(AggregationExceptions.CONTACT_ID, contactId);
+        values.put(AggregationExceptions.RAW_CONTACT_ID, rawContactId);
+        values.put(AggregationExceptions.TYPE, type);
+        mResolver.update(AggregationExceptions.CONTENT_URI, values, null, null);
+    }
+
+    protected Cursor queryRawContact(long rawContactId) {
+        return mResolver.query(ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId), null,
+                null, null, null);
+    }
+
+    protected Cursor queryContact(long contactId) {
+        return mResolver.query(ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
+                null, null, null, null);
+    }
+
+    protected Cursor queryContactSummary(long contactId, String[] projection) {
+        return mResolver.query(ContentUris.withAppendedId(Contacts.CONTENT_SUMMARY_URI,
+                contactId), projection, null, null, null);
+    }
+
+    protected Cursor queryContactSummary() {
+        return mResolver.query(Contacts.CONTENT_SUMMARY_URI, null, null, null, null);
+    }
+
+    protected long queryContactId(long rawContactId) {
+        Cursor c = queryRawContact(rawContactId);
+        assertTrue(c.moveToFirst());
+        long contactId = c.getLong(c.getColumnIndex(RawContacts.CONTACT_ID));
+        c.close();
+        return contactId;
+    }
+
+    protected long queryPhotoId(long contactId) {
+        Cursor c = queryContact(contactId);
+        assertTrue(c.moveToFirst());
+        long photoId = c.getInt(c.getColumnIndex(Contacts.PHOTO_ID));
+        c.close();
+        return photoId;
+    }
+
+    protected String queryDisplayName(long contactId) {
+        Cursor c = queryContact(contactId);
+        assertTrue(c.moveToFirst());
+        String displayName = c.getString(c.getColumnIndex(Contacts.DISPLAY_NAME));
+        c.close();
+        return displayName;
+    }
+
+    protected void assertAggregated(long rawContactId1, long rawContactId2) {
+        long contactId1 = queryContactId(rawContactId1);
+        long contactId2 = queryContactId(rawContactId2);
+        assertTrue(contactId1 == contactId2);
+    }
+
+    protected void assertAggregated(long rawContactId1, long rawContactId2,
+            String expectedDisplayName) {
+        long contactId1 = queryContactId(rawContactId1);
+        long contactId2 = queryContactId(rawContactId2);
+        assertTrue(contactId1 == contactId2);
+
+        String displayName = queryDisplayName(contactId1);
+        assertEquals(expectedDisplayName, displayName);
+    }
+
+    protected void assertNotAggregated(long rawContactId1, long rawContactId2) {
+        long contactId1 = queryContactId(rawContactId1);
+        long contactId2 = queryContactId(rawContactId2);
+        assertTrue(contactId1 != contactId2);
+    }
+
+    protected void assertStructuredName(long rawContactId, String prefix, String givenName,
+            String middleName, String familyName, String suffix) {
+        Uri uri =
+                Uri.withAppendedPath(ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
+                RawContacts.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();
+    }
+
+    protected long assertSingleGroup(Long rowId, Account account, String sourceId, String title) {
+        Cursor c = mResolver.query(Groups.CONTENT_URI, null, null, null, null);
+        try {
+            assertTrue(c.moveToNext());
+            long actualRowId = assertGroup(c, rowId, account, sourceId, title);
+            assertFalse(c.moveToNext());
+            return actualRowId;
+        } finally {
+            c.close();
+        }
+    }
+
+    protected long assertSingleGroupMembership(Long rowId, Long rawContactId, Long groupRowId,
+            String sourceId) {
+        Cursor c = mResolver.query(ContactsContract.Data.CONTENT_URI, null, null, null, null);
+        try {
+            assertTrue(c.moveToNext());
+            long actualRowId = assertGroupMembership(c, rowId, rawContactId, groupRowId, sourceId);
+            assertFalse(c.moveToNext());
+            return actualRowId;
+        } finally {
+            c.close();
+        }
+    }
+
+    protected long assertGroupMembership(Cursor c, Long rowId, Long rawContactId, Long groupRowId,
+            String sourceId) {
+        assertNullOrEquals(c, rowId, Data._ID);
+        assertNullOrEquals(c, rawContactId, GroupMembership.RAW_CONTACT_ID);
+        assertNullOrEquals(c, groupRowId, GroupMembership.GROUP_ROW_ID);
+        assertNullOrEquals(c, sourceId, GroupMembership.GROUP_SOURCE_ID);
+        return c.getLong(c.getColumnIndexOrThrow("_id"));
+    }
+
+    protected long assertGroup(Cursor c, Long rowId, Account account, String sourceId, String title) {
+        assertNullOrEquals(c, rowId, Groups._ID);
+        assertNullOrEquals(c, account);
+        assertNullOrEquals(c, sourceId, Groups.SOURCE_ID);
+        assertNullOrEquals(c, title, Groups.TITLE);
+        return c.getLong(c.getColumnIndexOrThrow("_id"));
+    }
+
+    private void assertNullOrEquals(Cursor c, Account account) {
+        if (account == NO_ACCOUNT) {
+            return;
+        }
+        if (account == null) {
+            assertTrue(c.isNull(c.getColumnIndexOrThrow(Groups.ACCOUNT_NAME)));
+            assertTrue(c.isNull(c.getColumnIndexOrThrow(Groups.ACCOUNT_TYPE)));
+        } else {
+            assertEquals(account.mName, c.getString(c.getColumnIndexOrThrow(Groups.ACCOUNT_NAME)));
+            assertEquals(account.mType, c.getString(c.getColumnIndexOrThrow(Groups.ACCOUNT_TYPE)));
+        }
+    }
+
+    private void assertNullOrEquals(Cursor c, Long value, String columnName) {
+        if (value != NO_LONG) {
+            if (value == null) assertTrue(c.isNull(c.getColumnIndexOrThrow(columnName)));
+            else assertEquals((long) value, c.getLong(c.getColumnIndexOrThrow(columnName)));
+        }
+    }
+
+    private void assertNullOrEquals(Cursor c, String value, String columnName) {
+        if (value != NO_STRING) {
+            if (value == null) assertTrue(c.isNull(c.getColumnIndexOrThrow(columnName)));
+            else assertEquals(value, c.getString(c.getColumnIndexOrThrow(columnName)));
+        }
+    }
+
+    protected void assertDataRow(ContentValues actual, String expectedMimetype,
+            Object... expectedArguments) {
+        assertEquals(actual.toString(), expectedMimetype, actual.getAsString(Data.MIMETYPE));
+        for (int i = 0; i < expectedArguments.length; i += 2) {
+            String columnName = (String) expectedArguments[i];
+            Object expectedValue = expectedArguments[i + 1];
+            if (expectedValue instanceof Uri) {
+                expectedValue = ContentUris.parseId((Uri) expectedValue);
+            }
+            if (expectedValue == null) {
+                assertNull(actual.toString(), actual.get(columnName));
+            }
+            if (expectedValue instanceof Long) {
+                assertEquals("mismatch at " + columnName + " from " + actual.toString(),
+                        expectedValue, actual.getAsLong(columnName));
+            } else if (expectedValue instanceof Integer) {
+                assertEquals("mismatch at " + columnName + " from " + actual.toString(),
+                        expectedValue, actual.getAsInteger(columnName));
+            } else if (expectedValue instanceof String) {
+                assertEquals("mismatch at " + columnName + " from " + actual.toString(),
+                        expectedValue, actual.getAsString(columnName));
+            } else {
+                assertEquals("mismatch at " + columnName + " from " + actual.toString(),
+                        expectedValue, actual.get(columnName));
+            }
+        }
+    }
+
+    protected static class IdComparator implements Comparator<ContentValues> {
+        public int compare(ContentValues o1, ContentValues o2) {
+            long id1 = o1.getAsLong(ContactsContract.Data._ID);
+            long id2 = o2.getAsLong(ContactsContract.Data._ID);
+            if (id1 == id2) return 0;
+            return (id1 < id2) ? -1 : 1;
+        }
+    }
+
+    protected ContentValues[] asSortedContentValuesArray(
+            ArrayList<Entity.NamedContentValues> subValues) {
+        ContentValues[] result = new ContentValues[subValues.size()];
+        int i = 0;
+        for (Entity.NamedContentValues subValue : subValues) {
+            result[i] = subValue.values;
+            i++;
+        }
+        Arrays.sort(result, new IdComparator());
+        return result;
+    }
+
+    protected void assertDirty(Uri uri, boolean state) {
+        Cursor c = mResolver.query(uri, new String[]{"dirty"}, null, null, null);
+        assertTrue(c.moveToNext());
+        assertEquals(state, c.getLong(0) != 0);
+        assertFalse(c.moveToNext());
+    }
+
+    protected long getVersion(Uri uri) {
+        Cursor c = mResolver.query(uri, new String[]{"version"}, null, null, null);
+        assertTrue(c.moveToNext());
+        long version = c.getLong(0);
+        assertFalse(c.moveToNext());
+        return version;
+    }
+
+    protected void clearDirty(Uri uri) {
+        ContentValues values = new ContentValues();
+        values.put("dirty", 0);
+        mResolver.update(uri, values, null, null);
+    }
+
+    protected void assertStoredValues(Uri rowUri, String column, String expectedValue) {
+        String value = getStoredValue(rowUri, column);
+        assertEquals("Column value " + column, expectedValue, value);
+    }
+
+    protected String getStoredValue(Uri rowUri, String column) {
+        String value;
+        Cursor c = mResolver.query(rowUri, new String[] { column }, null, null, null);
+        try {
+            c.moveToFirst();
+            value = c.getString(c.getColumnIndex(column));
+        } finally {
+            c.close();
+        }
+        return value;
+    }
+
+    protected void assertStoredValues(Uri rowUri, ContentValues expectedValues) {
+        Cursor c = mResolver.query(rowUri, null, null, null, null);
+        try {
+            assertEquals("Record count", 1, c.getCount());
+            c.moveToFirst();
+            assertCursorValues(c, expectedValues);
+        } finally {
+            c.close();
+        }
+    }
+
+    /**
+     * Constructs a selection (where clause) out of all supplied values, uses it
+     * to query the provider and verifies that a single row is returned and it
+     * has the same values as requested.
+     */
+    protected void assertSelection(Uri uri, ContentValues values, String idColumn, long id) {
+        StringBuilder sb = new StringBuilder();
+        ArrayList<String> selectionArgs = new ArrayList<String>(values.size());
+        if (idColumn != null) {
+            sb.append(idColumn).append("=").append(id);
+        }
+        Set<Map.Entry<String, Object>> entries = values.valueSet();
+        for (Map.Entry<String, Object> entry : entries) {
+            String column = entry.getKey();
+            Object value = entry.getValue();
+            if (sb.length() != 0) {
+                sb.append(" AND ");
+            }
+            sb.append(column);
+            if (value == null) {
+                sb.append(" IS NULL");
+            } else {
+                sb.append("=?");
+                selectionArgs.add(String.valueOf(value));
+            }
+        }
+
+        Cursor c = mResolver.query(uri, null, sb.toString(), selectionArgs.toArray(new String[0]),
+                null);
+        try {
+            assertEquals("Record count", 1, c.getCount());
+            c.moveToFirst();
+            assertCursorValues(c, values);
+        } finally {
+            c.close();
+        }
+    }
+
+    protected void assertCursorValues(Cursor cursor, ContentValues expectedValues) {
+        Set<Map.Entry<String, Object>> entries = expectedValues.valueSet();
+        for (Map.Entry<String, Object> entry : entries) {
+            String column = entry.getKey();
+            int index = cursor.getColumnIndex(column);
+            assertTrue("No such column: " + column, index != -1);
+            Object expectedValue = expectedValues.get(column);
+            String value;
+            if (expectedValue instanceof byte[]) {
+                expectedValue = Hex.encodeHex((byte[])expectedValue, false);
+                value = Hex.encodeHex(cursor.getBlob(index), false);
+            } else {
+                expectedValue = expectedValues.getAsString(column);
+                value = cursor.getString(index);
+            }
+            assertEquals("Column value " + column, expectedValue, value);
+        }
+    }
+
+    protected int getCount(Uri uri, String selection, String[] selectionArgs) {
+        Cursor c = mResolver.query(uri, null, selection, selectionArgs, null);
+        try {
+            return c.getCount();
+        } finally {
+            c.close();
+        }
+    }
+
+    protected byte[] loadTestPhoto() throws IOException {
+        final Resources resources = getContext().getResources();
+        InputStream is =
+                resources.openRawResource(com.android.internal.R.drawable.ic_contact_picture);
+        ByteArrayOutputStream os = new ByteArrayOutputStream();
+        byte[] buffer = new byte[1000];
+        int count;
+        while((count = is.read(buffer)) != -1) {
+            os.write(buffer, 0, count);
+        }
+        return os.toByteArray();
+    }
+}
diff --git a/tests/src/com/android/providers/contacts/CallLogProviderTest.java b/tests/src/com/android/providers/contacts/CallLogProviderTest.java
new file mode 100644
index 0000000..75ebda9
--- /dev/null
+++ b/tests/src/com/android/providers/contacts/CallLogProviderTest.java
@@ -0,0 +1,168 @@
+/*
+ * 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.telephony.CallerInfo;
+import com.android.internal.telephony.Connection;
+
+import android.content.ContentProvider;
+import android.content.ContentUris;
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.Cursor;
+import android.net.Uri;
+import android.provider.CallLog;
+import android.provider.ContactsContract;
+import android.provider.CallLog.Calls;
+import android.provider.Contacts.ContactMethods;
+import android.test.suitebuilder.annotation.LargeTest;
+
+/**
+ * Unit tests for {@link CallLogProvider}.
+ *
+ * Run the test like this:
+ * <code>
+ * adb shell am instrument -w \
+ *         com.android.providers.contacts.tests/android.test.InstrumentationTestRunner
+ * </code>
+ */
+@LargeTest
+public class CallLogProviderTest extends BaseContactsProvider2Test {
+
+    private static final boolean USE_LEGACY_PROVIDER = false;
+
+    @Override
+    protected Class<? extends ContentProvider> getProviderClass() {
+       return USE_LEGACY_PROVIDER ? ContactsProvider.class : ContactsProvider2.class;
+    }
+
+    @Override
+    protected String getAuthority() {
+        return ContactsContract.AUTHORITY;
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        if (USE_LEGACY_PROVIDER) {
+            addAuthority(CallLog.AUTHORITY);
+        } else {
+            addProvider(TestCallLogProvider.class, CallLog.AUTHORITY);
+        }
+    }
+
+    public void testInsert() {
+        ContentValues values = new ContentValues();
+        putCallValues(values);
+        Uri uri = mResolver.insert(Calls.CONTENT_URI, values);
+        assertStoredValues(uri, values);
+        assertSelection(uri, values, Calls._ID, ContentUris.parseId(uri));
+    }
+
+    public void testUpdate() {
+        ContentValues values = new ContentValues();
+        putCallValues(values);
+        Uri uri = mResolver.insert(Calls.CONTENT_URI, values);
+
+        values.clear();
+        values.put(Calls.TYPE, Calls.OUTGOING_TYPE);
+        values.put(Calls.NUMBER, "1-800-263-7643");
+        values.put(Calls.DATE, 2000);
+        values.put(Calls.DURATION, 40);
+        values.put(Calls.CACHED_NAME, "1-800-GOOG-411");
+        values.put(Calls.CACHED_NUMBER_TYPE, ContactMethods.TYPE_CUSTOM);
+        values.put(Calls.CACHED_NUMBER_LABEL, "Directory");
+
+        int count = mResolver.update(uri, values, null, null);
+        assertEquals(1, count);
+        assertStoredValues(uri, values);
+    }
+
+    public void testDelete() {
+        ContentValues values = new ContentValues();
+        putCallValues(values);
+        Uri uri = mResolver.insert(Calls.CONTENT_URI, values);
+        try {
+            mResolver.delete(uri, null, null);
+            fail();
+        } catch (UnsupportedOperationException ex) {
+            // Expected
+        }
+
+        int count = mResolver.delete(Calls.CONTENT_URI, Calls._ID + "="
+                + ContentUris.parseId(uri), null);
+        assertEquals(1, count);
+        assertEquals(0, getCount(uri, null, null));
+    }
+
+    public void testCallLogFilter() {
+        ContentValues values = new ContentValues();
+        putCallValues(values);
+        mResolver.insert(Calls.CONTENT_URI, values);
+
+        Uri filterUri = Uri.withAppendedPath(Calls.CONTENT_FILTER_URI, "1-800-4664-411");
+        Cursor c = mResolver.query(filterUri, null, null, null, null);
+        assertEquals(1, c.getCount());
+        c.moveToFirst();
+        assertCursorValues(c, values);
+        c.close();
+
+        filterUri = Uri.withAppendedPath(Calls.CONTENT_FILTER_URI, "1-888-4664-411");
+        c = mResolver.query(filterUri, null, null, null, null);
+        assertEquals(0, c.getCount());
+        c.close();
+    }
+
+    public void testAddCall() {
+        CallerInfo ci = new CallerInfo();
+        ci.name = "1-800-GOOG-411";
+        ci.numberType = ContactMethods.TYPE_CUSTOM;
+        ci.numberLabel = "Directory";
+        Uri uri = Calls.addCall(ci, getMockContext(), "1-800-263-7643",
+                Connection.PRESENTATION_ALLOWED, Calls.OUTGOING_TYPE, 2000, 40);
+
+        ContentValues values = new ContentValues();
+        values.put(Calls.TYPE, Calls.OUTGOING_TYPE);
+        values.put(Calls.NUMBER, "1-800-263-7643");
+        values.put(Calls.DATE, 2000);
+        values.put(Calls.DURATION, 40);
+        values.put(Calls.CACHED_NAME, "1-800-GOOG-411");
+        values.put(Calls.CACHED_NUMBER_TYPE, ContactMethods.TYPE_CUSTOM);
+        values.put(Calls.CACHED_NUMBER_LABEL, "Directory");
+        assertStoredValues(uri, values);
+    }
+
+    private void putCallValues(ContentValues values) {
+        values.put(Calls.TYPE, Calls.INCOMING_TYPE);
+        values.put(Calls.NUMBER, "1-800-4664-411");
+        values.put(Calls.DATE, 1000);
+        values.put(Calls.DURATION, 30);
+        values.put(Calls.NEW, 1);
+    }
+
+    public static class TestCallLogProvider extends CallLogProvider {
+        private static OpenHelper mOpenHelper;
+
+        @Override
+        protected OpenHelper getOpenHelper(final Context context) {
+            if (mOpenHelper == null) {
+                mOpenHelper = new OpenHelper(context);
+            }
+            return mOpenHelper;
+        }
+    }
+}
+
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..06dc197
--- /dev/null
+++ b/tests/src/com/android/providers/contacts/ContactAggregatorTest.java
@@ -0,0 +1,563 @@
+/*
+ * 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.Contacts;
+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.CONTACT_ID,
+            AggregationExceptions.RAW_CONTACT_ID
+    };
+
+    public void testCrudAggregationExceptions() throws Exception {
+        long rawContactId1 = createRawContact();
+        long contactId = queryContactId(rawContactId1);
+        long rawContactId2 = createRawContact();
+
+        setAggregationException(AggregationExceptions.TYPE_KEEP_IN, contactId, rawContactId2);
+
+        // Refetch the row we have just inserted
+        Cursor c = mResolver.query(AggregationExceptions.CONTENT_URI,
+                AGGREGATION_EXCEPTION_PROJECTION, AggregationExceptions.CONTACT_ID + "="
+                        + contactId, null, null);
+
+        assertTrue(c.moveToFirst());
+        assertEquals(AggregationExceptions.TYPE_KEEP_IN, c.getInt(0));
+        assertEquals(contactId, c.getLong(1));
+        assertEquals(rawContactId2, c.getLong(2));
+        assertFalse(c.moveToNext());
+        c.close();
+
+        // Change from TYPE_KEEP_IN to TYPE_KEEP_OUT
+        setAggregationException(AggregationExceptions.TYPE_KEEP_OUT, contactId, rawContactId2);
+
+        c = mResolver.query(AggregationExceptions.CONTENT_URI,
+                AGGREGATION_EXCEPTION_PROJECTION, AggregationExceptions.CONTACT_ID + "="
+                        + contactId, null, null);
+
+        assertTrue(c.moveToFirst());
+        assertEquals(AggregationExceptions.TYPE_KEEP_OUT, c.getInt(0));
+        assertEquals(contactId, c.getLong(1));
+        assertEquals(rawContactId2, c.getLong(2));
+        assertFalse(c.moveToNext());
+        c.close();
+
+        // Delete the rule
+        setAggregationException(AggregationExceptions.TYPE_AUTOMATIC, contactId, rawContactId2);
+
+        // Verify that the row is gone
+        c = mResolver.query(AggregationExceptions.CONTENT_URI,
+                AGGREGATION_EXCEPTION_PROJECTION, AggregationExceptions.CONTACT_ID + "="
+                        + contactId, null, null);
+        assertFalse(c.moveToFirst());
+        c.close();
+    }
+
+    public void testAggregationCreatesNewAggregate() {
+        long rawContactId = createRawContact();
+
+        Uri resultUri = insertStructuredName(rawContactId, "Johna", "Smitha");
+
+        // Parse the URI and confirm that it contains an ID
+        assertTrue(ContentUris.parseId(resultUri) != 0);
+
+        long contactId = queryContactId(rawContactId);
+        assertTrue(contactId != 0);
+
+        String displayName = queryDisplayName(contactId);
+        assertEquals("Johna Smitha", displayName);
+    }
+
+    public void testAggregationOfExactFullNameMatch() {
+        long rawContactId1 = createRawContact();
+        insertStructuredName(rawContactId1, "Johnb", "Smithb");
+
+        long rawContactId2 = createRawContact();
+        insertStructuredName(rawContactId2, "Johnb", "Smithb");
+
+        assertAggregated(rawContactId1, rawContactId2, "Johnb Smithb");
+    }
+
+    public void testAggregationOfCaseInsensitiveFullNameMatch() {
+        long rawContactId1 = createRawContact();
+        insertStructuredName(rawContactId1, "Johnc", "Smithc");
+
+        long rawContactId2 = createRawContact();
+        insertStructuredName(rawContactId2, "Johnc", "smithc");
+
+        assertAggregated(rawContactId1, rawContactId2, "Johnc Smithc");
+    }
+
+    public void testAggregationOfLastNameMatch() {
+        long rawContactId1 = createRawContact();
+        insertStructuredName(rawContactId1, null, "Johnd");
+
+        long rawContactId2 = createRawContact();
+        insertStructuredName(rawContactId2, null, "johnd");
+
+        assertAggregated(rawContactId1, rawContactId2, "Johnd");
+    }
+
+    public void testNonAggregationOfFirstNameMatch() {
+        long rawContactId1 = createRawContact();
+        insertStructuredName(rawContactId1, "Johne", "Smithe");
+
+        long rawContactId2 = createRawContact();
+        insertStructuredName(rawContactId2, "Johne", null);
+
+        assertNotAggregated(rawContactId1, rawContactId2);
+    }
+
+    // TODO: should this be allowed to match?
+    public void testNonAggregationOfLastNameMatch() {
+        long rawContactId1 = createRawContact();
+        insertStructuredName(rawContactId1, "Johnf", "Smithf");
+
+        long rawContactId2 = createRawContact();
+        insertStructuredName(rawContactId2, null, "Smithf");
+
+        assertNotAggregated(rawContactId1, rawContactId2);
+    }
+
+    public void testAggregationOfConcatenatedFullNameMatch() {
+        long rawContactId1 = createRawContact();
+        insertStructuredName(rawContactId1, "Johng", "Smithg");
+
+        long rawContactId2 = createRawContact();
+        insertStructuredName(rawContactId2, "johngsmithg", null);
+
+        assertAggregated(rawContactId1, rawContactId2, "Johng Smithg");
+    }
+
+    public void testAggregationOfNormalizedFullNameMatch() {
+        long rawContactId1 = createRawContact();
+        insertStructuredName(rawContactId1, "H\u00e9l\u00e8ne", "Bj\u00f8rn");
+
+        long rawContactId2 = createRawContact();
+        insertStructuredName(rawContactId2, "helene bjorn", null);
+
+        assertAggregated(rawContactId1, rawContactId2, "H\u00e9l\u00e8ne Bj\u00f8rn");
+    }
+
+    public void testAggregationBasedOnPhoneNumberNoNameData() {
+        long rawContactId1 = createRawContact();
+        insertPhoneNumber(rawContactId1, "(888)555-1231");
+
+        long rawContactId2 = createRawContact();
+        insertPhoneNumber(rawContactId2, "1(888)555-1231");
+
+        assertAggregated(rawContactId1, rawContactId2);
+    }
+
+    public void testAggregationBasedOnPhoneNumberWhenTargetAggregateHasNoName() {
+        long rawContactId1 = createRawContact();
+        insertPhoneNumber(rawContactId1, "(888)555-1232");
+
+        long rawContactId2 = createRawContact();
+        insertStructuredName(rawContactId2, "Johnl", "Smithl");
+        insertPhoneNumber(rawContactId2, "1(888)555-1232");
+
+        assertAggregated(rawContactId1, rawContactId2);
+    }
+
+    public void testAggregationBasedOnPhoneNumberWhenNewContactHasNoName() {
+        long rawContactId1 = createRawContact();
+        insertStructuredName(rawContactId1, "Johnm", "Smithm");
+        insertPhoneNumber(rawContactId1, "(888)555-1233");
+
+        long rawContactId2 = createRawContact();
+        insertPhoneNumber(rawContactId2, "1(888)555-1233");
+
+        assertAggregated(rawContactId1, rawContactId2);
+    }
+
+    public void testAggregationBasedOnPhoneNumberWithSimilarNames() {
+        long rawContactId1 = createRawContact();
+        insertStructuredName(rawContactId1, "Ogre", "Hunter");
+        insertPhoneNumber(rawContactId1, "(888)555-1234");
+
+        long rawContactId2 = createRawContact();
+        insertStructuredName(rawContactId2, "Opra", "Humper");
+        insertPhoneNumber(rawContactId2, "1(888)555-1234");
+
+        assertAggregated(rawContactId1, rawContactId2);
+    }
+
+    public void testAggregationBasedOnPhoneNumberWithDifferentNames() {
+        long rawContactId1 = createRawContact();
+        insertStructuredName(rawContactId1, "Baby", "Bear");
+        insertPhoneNumber(rawContactId1, "(888)555-1235");
+
+        long rawContactId2 = createRawContact();
+        insertStructuredName(rawContactId2, "Blind", "Mouse");
+        insertPhoneNumber(rawContactId2, "1(888)555-1235");
+
+        assertNotAggregated(rawContactId1, rawContactId2);
+    }
+
+    public void testAggregationBasedOnEmailNoNameData() {
+        long rawContactId1 = createRawContact();
+        insertEmail(rawContactId1, "lightning@android.com");
+
+        long rawContactId2 = createRawContact();
+        insertEmail(rawContactId2, "lightning@android.com");
+
+        assertAggregated(rawContactId1, rawContactId2);
+    }
+
+    public void testAggregationBasedOnEmailWhenTargetAggregateHasNoName() {
+        long rawContactId1 = createRawContact();
+        insertEmail(rawContactId1, "mcqueen@android.com");
+
+        long rawContactId2 = createRawContact();
+        insertStructuredName(rawContactId2, "Lightning", "McQueen");
+        insertEmail(rawContactId2, "mcqueen@android.com");
+
+        assertAggregated(rawContactId1, rawContactId2);
+    }
+
+    public void testAggregationBasedOnEmailWhenNewContactHasNoName() {
+        long rawContactId1 = createRawContact();
+        insertStructuredName(rawContactId1, "Doc", "Hudson");
+        insertEmail(rawContactId1, "doc@android.com");
+
+        long rawContactId2 = createRawContact();
+        insertEmail(rawContactId2, "doc@android.com");
+
+        assertAggregated(rawContactId1, rawContactId2);
+    }
+
+    public void testAggregationBasedOnEmailWithSimilarNames() {
+        long rawContactId1 = createRawContact();
+        insertStructuredName(rawContactId1, "Sally", "Carrera");
+        insertEmail(rawContactId1, "sally@android.com");
+
+        long rawContactId2 = createRawContact();
+        insertStructuredName(rawContactId2, "Sallie", "Carerra");
+        insertEmail(rawContactId2, "sally@android.com");
+
+        assertAggregated(rawContactId1, rawContactId2);
+    }
+
+    public void testAggregationBasedOnEmailWithDifferentNames() {
+        long rawContactId1 = createRawContact();
+        insertStructuredName(rawContactId1, "Chick", "Hicks");
+        insertEmail(rawContactId1, "hicky@android.com");
+
+        long rawContactId2 = createRawContact();
+        insertStructuredName(rawContactId2, "Luigi", "Guido");
+        insertEmail(rawContactId2, "hicky@android.com");
+
+        assertNotAggregated(rawContactId1, rawContactId2);
+    }
+
+    public void testAggregationByCommonNicknameWithLastName() {
+        long rawContactId1 = createRawContact();
+        insertStructuredName(rawContactId1, "Bill", "Gore");
+
+        long rawContactId2 = createRawContact();
+        insertStructuredName(rawContactId2, "William", "Gore");
+
+        assertAggregated(rawContactId1, rawContactId2, "William Gore");
+    }
+
+    public void testAggregationByCommonNicknameOnly() {
+        long rawContactId1 = createRawContact();
+        insertStructuredName(rawContactId1, "Lawrence", null);
+
+        long rawContactId2 = createRawContact();
+        insertStructuredName(rawContactId2, "Larry", null);
+
+        assertAggregated(rawContactId1, rawContactId2, "Lawrence");
+    }
+
+    public void testAggregationByNicknameNoStructuredName() {
+        long rawContactId1 = createRawContact();
+        insertNickname(rawContactId1, "Frozone");
+
+        long rawContactId2 = createRawContact();
+        insertNickname(rawContactId2, "Frozone");
+
+        assertAggregated(rawContactId1, rawContactId2);
+    }
+
+    public void testAggregationByNicknameWithSimilarNames() {
+        long rawContactId1 = createRawContact();
+        insertStructuredName(rawContactId1, "Buddy", "Pine");
+        insertNickname(rawContactId1, "Syndrome");
+
+        long rawContactId2 = createRawContact();
+        insertStructuredName(rawContactId2, "Body", "Pane");
+        insertNickname(rawContactId2, "Syndrome");
+
+        assertAggregated(rawContactId1, rawContactId2);
+    }
+
+    public void testAggregationByNicknameWithDifferentNames() {
+        long rawContactId1 = createRawContact();
+        insertStructuredName(rawContactId1, "Helen", "Parr");
+        insertNickname(rawContactId1, "Elastigirl");
+
+        long rawContactId2 = createRawContact();
+        insertStructuredName(rawContactId2, "Shawn", "Johnson");
+        insertNickname(rawContactId2, "Elastigirl");
+
+        assertNotAggregated(rawContactId1, rawContactId2);
+    }
+
+    public void testAggregationExceptionKeepIn() {
+        long rawContactId1 = createRawContact();
+        insertStructuredName(rawContactId1, "Johnk", "Smithk");
+
+        long rawContactId2 = createRawContact();
+        insertStructuredName(rawContactId2, "Johnkx", "Smithkx");
+
+        long contactId1 = queryContactId(rawContactId1);
+        long contactId2 = queryContactId(rawContactId2);
+
+        setAggregationException(AggregationExceptions.TYPE_KEEP_IN,
+                queryContactId(rawContactId1), rawContactId2);
+
+        assertAggregated(rawContactId1, rawContactId2, "Johnkx Smithkx");
+
+        // Assert that the empty aggregate got removed
+        long newContactId1 = queryContactId(rawContactId1);
+        if (contactId1 != newContactId1) {
+            Cursor cursor = queryContact(contactId1);
+            assertFalse(cursor.moveToFirst());
+            cursor.close();
+        } else {
+            Cursor cursor = queryContact(contactId2);
+            assertFalse(cursor.moveToFirst());
+            cursor.close();
+        }
+    }
+
+    public void testAggregationExceptionKeepOut() {
+        long rawContactId1 = createRawContact();
+        insertStructuredName(rawContactId1, "Johnh", "Smithh");
+
+        long rawContactId2 = createRawContact();
+        insertStructuredName(rawContactId2, "Johnh", "Smithh");
+
+        setAggregationException(AggregationExceptions.TYPE_KEEP_OUT,
+                queryContactId(rawContactId1), rawContactId2);
+
+        assertNotAggregated(rawContactId1, rawContactId2);
+    }
+
+    public void testAggregationExceptionKeepOutCheckUpdatesDisplayName() {
+        long rawContactId1 = createRawContact();
+        insertStructuredName(rawContactId1, "Johni", "Smithi");
+
+        long rawContactId2 = createRawContact();
+        insertStructuredName(rawContactId2, "Johnj", "Smithj");
+
+        setAggregationException(AggregationExceptions.TYPE_KEEP_IN,
+                queryContactId(rawContactId1), rawContactId2);
+
+        assertAggregated(rawContactId1, rawContactId2, "Johnj Smithj");
+
+        setAggregationException(AggregationExceptions.TYPE_KEEP_OUT,
+                queryContactId(rawContactId1), rawContactId2);
+
+        assertNotAggregated(rawContactId1, rawContactId2);
+
+        String displayName1 = queryDisplayName(queryContactId(rawContactId1));
+        assertEquals("Johni Smithi", displayName1);
+
+        String displayName2 = queryDisplayName(queryContactId(rawContactId2));
+        assertEquals("Johnj Smithj", displayName2);
+    }
+
+    public void testAggregationSuggestionsBasedOnName() {
+        long rawContactId1 = createRawContact();
+        insertStructuredName(rawContactId1, "Duane", null);
+
+        // Exact name match
+        long rawContactId2 = createRawContact();
+        insertStructuredName(rawContactId2, "Duane", null);
+        setAggregationException(AggregationExceptions.TYPE_KEEP_OUT,
+                queryContactId(rawContactId1), rawContactId2);
+
+        // Edit distance == 0.84
+        long rawContactId3 = createRawContact();
+        insertStructuredName(rawContactId3, "Dwayne", null);
+
+        // Edit distance == 0.6
+        long rawContactId4 = createRawContact();
+        insertStructuredName(rawContactId4, "Donny", null);
+
+        long contactId1 = queryContactId(rawContactId1);
+        long contactId2 = queryContactId(rawContactId2);
+        long contactId3 = queryContactId(rawContactId3);
+
+        assertSuggestions(contactId1, contactId2, contactId3);
+    }
+
+    public void testAggregationSuggestionsBasedOnPhoneNumber() {
+
+        // Create two contacts that would not be aggregated because of name mismatch
+        long rawContactId1 = createRawContact();
+        insertStructuredName(rawContactId1, "Lord", "Farquaad");
+        insertPhoneNumber(rawContactId1, "(888)555-1236");
+
+        long rawContactId2 = createRawContact();
+        insertStructuredName(rawContactId2, "Talking", "Donkey");
+        insertPhoneNumber(rawContactId2, "1(888)555-1236");
+
+        long contactId1 = queryContactId(rawContactId1);
+        long contactId2 = queryContactId(rawContactId2);
+        assertTrue(contactId1 != contactId2);
+
+        assertSuggestions(contactId1, contactId2);
+    }
+
+    public void testAggregationSuggestionsBasedOnEmailAddress() {
+
+        // Create two contacts that would not be aggregated because of name mismatch
+        long rawContactId1 = createRawContact();
+        insertStructuredName(rawContactId1, "Carl", "Fredricksen");
+        insertEmail(rawContactId1, "up@android.com");
+
+        long rawContactId2 = createRawContact();
+        insertStructuredName(rawContactId2, "Charles", "Muntz");
+        insertEmail(rawContactId2, "up@android.com");
+
+        long contactId1 = queryContactId(rawContactId1);
+        long contactId2 = queryContactId(rawContactId2);
+        assertTrue(contactId1 != contactId2);
+
+        assertSuggestions(contactId1, contactId2);
+    }
+
+    public void testAggregationSuggestionsBasedOnEmailAddressApproximateMatch() {
+
+        // Create two contacts that would not be aggregated because of name mismatch
+        long rawContactId1 = createRawContact();
+        insertStructuredName(rawContactId1, "Bob", null);
+        insertEmail(rawContactId1, "incredible2004@android.com");
+
+        long rawContactId2 = createRawContact();
+        insertStructuredName(rawContactId2, "Lucius", "Best");
+        insertEmail(rawContactId2, "incrediball@androidd.com");
+
+        long contactId1 = queryContactId(rawContactId1);
+        long contactId2 = queryContactId(rawContactId2);
+        assertTrue(contactId1 != contactId2);
+
+        assertSuggestions(contactId1, contactId2);
+    }
+
+    public void testAggregationSuggestionsBasedOnNickname() {
+        long rawContactId1 = createRawContact();
+        insertStructuredName(rawContactId1, "Peter", "Parker");
+        insertNickname(rawContactId1, "Spider-Man");
+
+        long rawContactId2 = createRawContact();
+        insertStructuredName(rawContactId2, "Manny", "Spider");
+
+        long contactId1 = queryContactId(rawContactId1);
+        setAggregationException(AggregationExceptions.TYPE_KEEP_OUT, contactId1, rawContactId2);
+
+        long contactId2 = queryContactId(rawContactId2);
+        assertSuggestions(contactId1, contactId2);
+    }
+
+    public void testAggregationSuggestionsBasedOnNicknameMatchingName() {
+        long rawContactId1 = createRawContact();
+        insertStructuredName(rawContactId1, "Clark", "Kent");
+        insertNickname(rawContactId1, "Superman");
+
+        long rawContactId2 = createRawContact();
+        insertStructuredName(rawContactId2, "Roy", "Williams");
+        insertNickname(rawContactId2, "superman");
+
+        long contactId1 = queryContactId(rawContactId1);
+        setAggregationException(AggregationExceptions.TYPE_KEEP_OUT, contactId1, rawContactId2);
+
+        long contactId2 = queryContactId(rawContactId2);
+        assertSuggestions(contactId1, contactId2);
+    }
+
+    public void testAggregationSuggestionsBasedOnCommonNickname() {
+        long rawContactId1 = createRawContact();
+        insertStructuredName(rawContactId1, "Dick", "Cherry");
+
+        long rawContactId2 = createRawContact();
+        insertStructuredName(rawContactId2, "Richard", "Cherry");
+
+        long contactId1 = queryContactId(rawContactId1);
+        setAggregationException(AggregationExceptions.TYPE_KEEP_OUT, contactId1, rawContactId2);
+
+        long contactId2 = queryContactId(rawContactId2);
+        assertSuggestions(contactId1, contactId2);
+    }
+
+    public void testChoosePhoto() {
+        long rawContactId1 = createRawContact();
+        setContactAccountName(rawContactId1, "donut");
+        long donutId = ContentUris.parseId(insertPhoto(rawContactId1));
+        long contactId = queryContactId(rawContactId1);
+
+        long rawContactId2 = createRawContact();
+        setAggregationException(AggregationExceptions.TYPE_KEEP_IN, contactId, rawContactId2);
+        setContactAccountName(rawContactId2, "cupcake");
+        long cupcakeId = ContentUris.parseId(insertPhoto(rawContactId2));
+
+        long rawContactId3 = createRawContact();
+        setAggregationException(AggregationExceptions.TYPE_KEEP_IN, contactId, rawContactId3);
+        setContactAccountName(rawContactId3, "flan");
+        long flanId = ContentUris.parseId(insertPhoto(rawContactId3));
+
+        assertEquals(cupcakeId, queryPhotoId(queryContactId(rawContactId2)));
+    }
+
+    private void assertSuggestions(long contactId, long... suggestions) {
+        final Uri aggregateUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
+        Uri uri = Uri.withAppendedPath(aggregateUri,
+                Contacts.AggregationSuggestions.CONTENT_DIRECTORY);
+        final Cursor cursor = mResolver.query(uri, new String[] { Contacts._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..eed7b43
--- /dev/null
+++ b/tests/src/com/android/providers/contacts/ContactsActor.java
@@ -0,0 +1,313 @@
+/*
+ * 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.ContentProvider;
+import android.content.ContentResolver;
+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.CommonDataKinds;
+import android.provider.ContactsContract.Contacts;
+import android.provider.ContactsContract.Data;
+import android.provider.ContactsContract.RawContacts;
+import android.test.IsolatedContext;
+import android.test.RenamingDelegatingContext;
+import android.test.mock.MockContentResolver;
+import android.test.mock.MockContext;
+import android.test.mock.MockPackageManager;
+
+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 ContentProvider provider;
+
+    private IsolatedContext mProviderContext;
+
+    /**
+     * 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,
+            Class<? extends ContentProvider> providerClass, String authority) throws Exception {
+        resolver = new MockContentResolver();
+        context = new RestrictionMockContext(overallContext, packageName, resolver);
+        this.packageName = packageName;
+
+        RenamingDelegatingContext targetContextWrapper = new RenamingDelegatingContext(context,
+                overallContext, FILENAME_PREFIX);
+        mProviderContext = new IsolatedContext(resolver, targetContextWrapper);
+        provider = addProvider(providerClass, authority);
+    }
+
+    public void addAuthority(String authority) {
+        resolver.addProvider(authority, provider);
+    }
+
+    public ContentProvider addProvider(Class<? extends ContentProvider> providerClass,
+            String authority) throws Exception {
+        ContentProvider provider = providerClass.newInstance();
+        provider.attachInfo(mProviderContext, null);
+        resolver.addProvider(authority, provider);
+        return 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;
+        private final ContentResolver mResolver;
+
+        /**
+         * Create a {@link Context} under the given package name.
+         */
+        public RestrictionMockContext(Context overallContext, String reportedPackageName,
+                ContentResolver resolver) {
+            mOverallContext = overallContext;
+            mReportedPackageName = reportedPackageName;
+            mResolver = resolver;
+            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();
+        }
+
+        @Override
+        public ContentResolver getContentResolver() {
+            return mResolver;
+        }
+    }
+
+    /**
+     * 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();
+        if (isRestricted) {
+            values.put(RawContacts.IS_RESTRICTED, 1);
+        }
+
+        Uri contactUri = resolver.insert(RawContacts.CONTENT_URI, values);
+        return ContentUris.parseId(contactUri);
+    }
+
+    public long createName(long contactId, String name) {
+        final ContentValues values = new ContentValues();
+        values.put(Data.RAW_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(RawContacts.CONTENT_URI,
+                contactId), RawContacts.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.RAW_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.TYPE,
+                ContactsContract.CommonDataKinds.Phone.TYPE_HOME);
+        values.put(ContactsContract.CommonDataKinds.Phone.NUMBER, phoneNumber);
+        Uri insertUri = Uri.withAppendedPath(ContentUris.withAppendedId(RawContacts.CONTENT_URI,
+                contactId), RawContacts.Data.CONTENT_DIRECTORY);
+        Uri dataUri = resolver.insert(insertUri, values);
+        return ContentUris.parseId(dataUri);
+    }
+
+    public void updateException(String packageProvider, String packageClient, boolean allowAccess) {
+        throw new UnsupportedOperationException("RestrictionExceptions are hard-coded");
+    }
+
+    public long getContactForRawContact(long rawContactId) {
+        Uri contactUri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId);
+        final Cursor cursor = resolver.query(contactUri, Projections.PROJ_RAW_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_ID);
+        cursor.close();
+        return aggId;
+    }
+
+    public int getDataCountForContact(long contactId) {
+        Uri contactUri = Uri.withAppendedPath(ContentUris.withAppendedId(Contacts.CONTENT_URI,
+                contactId), Contacts.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 contactId) {
+        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
+        final Cursor cursor = resolver.query(contactUri, Projections.PROJ_CONTACTS, null,
+                null, null);
+        long primaryPhoneId = -1;
+        if (cursor.moveToFirst()) {
+            primaryPhoneId = cursor.getLong(Projections.COL_CONTACTS_PRIMARY_PHONE_ID);
+        }
+        cursor.close();
+        return primaryPhoneId;
+    }
+
+    public long createGroup(String groupName) {
+        final ContentValues values = new ContentValues();
+        values.put(ContactsContract.Groups.RES_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 rawContactId, long groupId) {
+        final ContentValues values = new ContentValues();
+        values.put(Data.RAW_CONTACT_ID, rawContactId);
+        values.put(Data.MIMETYPE, CommonDataKinds.GroupMembership.CONTENT_ITEM_TYPE);
+        values.put(CommonDataKinds.GroupMembership.GROUP_ROW_ID, groupId);
+        Uri insertUri = Uri.withAppendedPath(ContentUris.withAppendedId(RawContacts.CONTENT_URI,
+                rawContactId), RawContacts.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_RAW_CONTACTS = new String[] {
+                RawContacts.CONTACT_ID
+        };
+
+        static final int COL_CONTACTS_ID = 0;
+
+        static final String[] PROJ_CONTACTS = new String[] {
+                Contacts.PRIMARY_PHONE_ID
+        };
+
+        static final int COL_CONTACTS_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..f6d5bd7
--- /dev/null
+++ b/tests/src/com/android/providers/contacts/ContactsProvider2Test.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.internal.util.ArrayUtils;
+
+import android.content.ContentUris;
+import android.content.ContentValues;
+import android.content.Entity;
+import android.content.EntityIterator;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.RemoteException;
+import android.provider.ContactsContract;
+import android.provider.ContactsContract.AggregationExceptions;
+import android.provider.ContactsContract.Contacts;
+import android.provider.ContactsContract.Data;
+import android.provider.ContactsContract.Presence;
+import android.provider.ContactsContract.RawContacts;
+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.provider.ContactsContract.CommonDataKinds.StructuredName;
+import android.test.suitebuilder.annotation.LargeTest;
+
+/**
+ * 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 rawContactId = createRawContact();
+        ContentValues values = new ContentValues();
+        values.put(StructuredName.DISPLAY_NAME, "Mr.John Kevin von Smith, Jr.");
+        insertStructuredName(rawContactId, values);
+
+        assertStructuredName(rawContactId, "Mr", "John", "Kevin", "von Smith", "Jr");
+    }
+
+    public void testDisplayNameParsingWhenPartsSpecified() {
+        long rawContactId = createRawContact();
+        ContentValues values = new ContentValues();
+        values.put(StructuredName.DISPLAY_NAME, "Mr.John Kevin von Smith, Jr.");
+        values.put(StructuredName.FAMILY_NAME, "Johnson");
+        insertStructuredName(rawContactId, values);
+
+        assertStructuredName(rawContactId, null, null, null, "Johnson", null);
+    }
+
+    public void testSendToVoicemailDefault() {
+        long rawContactId = createRawContactWithName();
+        long contactId = queryContactId(rawContactId);
+
+        Cursor c = queryContact(contactId);
+        assertTrue(c.moveToNext());
+        int sendToVoicemail = c.getInt(c.getColumnIndex(Contacts.SEND_TO_VOICEMAIL));
+        assertEquals(0, sendToVoicemail);
+        c.close();
+    }
+
+    public void testSetSendToVoicemailAndRingtone() {
+        long rawContactId = createRawContactWithName();
+        long contactId = queryContactId(rawContactId);
+
+        updateSendToVoicemailAndRingtone(contactId, true, "foo");
+        assertSendToVoicemailAndRingtone(contactId, true, "foo");
+    }
+
+    public void testSendToVoicemailAndRingtoneAfterAggregation() {
+        long rawContactId1 = createRawContactWithName();
+        long contactId1 = queryContactId(rawContactId1);
+        updateSendToVoicemailAndRingtone(contactId1, true, "foo");
+
+        long rawContactId2 = createRawContactWithName();
+        long contactId2 = queryContactId(rawContactId2);
+        updateSendToVoicemailAndRingtone(contactId2, true, "bar");
+
+        // Aggregate them
+        setAggregationException(AggregationExceptions.TYPE_KEEP_IN, contactId1, rawContactId2);
+
+        // Both contacts had "send to VM", the contact now has the same value
+        assertSendToVoicemailAndRingtone(contactId1, true, "foo,bar"); // Either foo or bar
+    }
+
+    public void testDoNotSendToVoicemailAfterAggregation() {
+        long rawContactId1 = createRawContactWithName();
+        long contactId1 = queryContactId(rawContactId1);
+        updateSendToVoicemailAndRingtone(contactId1, true, null);
+
+        long rawContactId2 = createRawContactWithName();
+        long contactId2 = queryContactId(rawContactId2);
+        updateSendToVoicemailAndRingtone(contactId2, false, null);
+
+        // Aggregate them
+        setAggregationException(AggregationExceptions.TYPE_KEEP_IN, contactId1, rawContactId2);
+
+        // Since one of the contacts had "don't send to VM" that setting wins for the aggregate
+        assertSendToVoicemailAndRingtone(contactId1, false, null);
+    }
+
+    public void testSetSendToVoicemailAndRingtonePreservedAfterJoinAndSplit() {
+        long rawContactId1 = createRawContactWithName();
+        long contactId1 = queryContactId(rawContactId1);
+        updateSendToVoicemailAndRingtone(contactId1, true, "foo");
+
+        long rawContactId2 = createRawContactWithName();
+        long contactId2 = queryContactId(rawContactId2);
+        updateSendToVoicemailAndRingtone(contactId2, false, "bar");
+
+        // Aggregate them
+        setAggregationException(AggregationExceptions.TYPE_KEEP_IN, contactId1, rawContactId2);
+
+        // Split them
+        setAggregationException(AggregationExceptions.TYPE_KEEP_OUT, contactId1, rawContactId2);
+
+        assertSendToVoicemailAndRingtone(contactId1, true, "foo");
+        assertSendToVoicemailAndRingtone(queryContactId(rawContactId2), false, "bar");
+    }
+
+    public void testSinglePresenceRowPerContact() {
+        int protocol1 = Im.PROTOCOL_GOOGLE_TALK;
+        String handle1 = "test@gmail.com";
+
+        long rawContactId1 = createRawContact();
+        insertImHandle(rawContactId1, protocol1, handle1);
+
+        insertPresence(protocol1, handle1, Presence.AVAILABLE);
+        insertPresence(protocol1, handle1, Presence.AWAY);
+        insertPresence(protocol1, handle1, Presence.INVISIBLE);
+
+        Cursor c = queryContactSummary(queryContactId(rawContactId1),
+                new String[] {Presence.PRESENCE_STATUS});
+        assertEquals(c.getCount(), 1);
+
+        c.moveToFirst();
+        assertEquals(c.getInt(0), Presence.AVAILABLE);
+
+    }
+
+    private void updateSendToVoicemailAndRingtone(long contactId, boolean sendToVoicemail,
+            String ringtone) {
+        ContentValues values = new ContentValues();
+        values.put(Contacts.SEND_TO_VOICEMAIL, sendToVoicemail);
+        if (ringtone != null) {
+            values.put(Contacts.CUSTOM_RINGTONE, ringtone);
+        }
+
+        final Uri uri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
+        int count = mResolver.update(uri, values, null, null);
+        assertEquals(1, count);
+    }
+
+    private void assertSendToVoicemailAndRingtone(long contactId, boolean expectedSendToVoicemail,
+            String expectedRingtone) {
+        Cursor c = queryContact(contactId);
+        assertTrue(c.moveToNext());
+        int sendToVoicemail = c.getInt(c.getColumnIndex(Contacts.SEND_TO_VOICEMAIL));
+        assertEquals(expectedSendToVoicemail ? 1 : 0, sendToVoicemail);
+        String ringtone = c.getString(c.getColumnIndex(Contacts.CUSTOM_RINGTONE));
+        if (expectedRingtone == null) {
+            assertNull(ringtone);
+        } else {
+            assertTrue(ArrayUtils.contains(expectedRingtone.split(","), ringtone));
+        }
+        c.close();
+    }
+
+    public void testGroupCreationAfterMembershipInsert() {
+        long rawContactId1 = createRawContact(mAccount);
+        Uri groupMembershipUri = insertGroupMembership(rawContactId1, "gsid1");
+
+        long groupId = assertSingleGroup(NO_LONG, mAccount, "gsid1", null);
+        assertSingleGroupMembership(ContentUris.parseId(groupMembershipUri),
+                rawContactId1, groupId, "gsid1");
+    }
+
+    public void testGroupReuseAfterMembershipInsert() {
+        long rawContactId1 = createRawContact(mAccount);
+        long groupId1 = createGroup(mAccount, "gsid1", "title1");
+        Uri groupMembershipUri = insertGroupMembership(rawContactId1, "gsid1");
+
+        assertSingleGroup(groupId1, mAccount, "gsid1", "title1");
+        assertSingleGroupMembership(ContentUris.parseId(groupMembershipUri),
+                rawContactId1, groupId1, "gsid1");
+    }
+
+    public void testGroupInsertFailureOnGroupIdConflict() {
+        long rawContactId1 = createRawContact(mAccount);
+        long groupId1 = createGroup(mAccount, "gsid1", "title1");
+
+        ContentValues values = new ContentValues();
+        values.put(GroupMembership.RAW_CONTACT_ID, rawContactId1);
+        values.put(GroupMembership.MIMETYPE, GroupMembership.CONTENT_ITEM_TYPE);
+        values.put(GroupMembership.GROUP_SOURCE_ID, "gsid1");
+        values.put(GroupMembership.GROUP_ROW_ID, groupId1);
+        try {
+            mResolver.insert(Data.CONTENT_URI, values);
+            fail("the insert was expected to fail, but it succeeded");
+        } catch (IllegalArgumentException e) {
+            // this was expected
+        }
+    }
+
+    public void testContentEntityIterator() throws RemoteException {
+        // create multiple contacts and check that the selected ones are returned
+        long id;
+
+        long groupId1 = createGroup(mAccount, "gsid1", "title1");
+        long groupId2 = createGroup(mAccount, "gsid2", "title2");
+
+        long c0 = id = createRawContact(mAccount, RawContacts.SOURCE_ID, "c0");
+        Uri id_0_0 = insertGroupMembership(id, "gsid1");
+        Uri id_0_1 = insertEmail(id, "c0@email.com");
+        Uri id_0_2 = insertPhoneNumber(id, "5551212c0");
+
+        long c1 = id = createRawContact(mAccount, RawContacts.SOURCE_ID, "c1");
+        Uri id_1_0 = insertGroupMembership(id, "gsid1");
+        Uri id_1_1 = insertGroupMembership(id, "gsid2");
+        Uri id_1_2 = insertEmail(id, "c1@email.com");
+        Uri id_1_3 = insertPhoneNumber(id, "5551212c1");
+
+        long c2 = id = createRawContact(mAccount, RawContacts.SOURCE_ID, "c2");
+        Uri id_2_0 = insertGroupMembership(id, "gsid1");
+        Uri id_2_1 = insertEmail(id, "c2@email.com");
+        Uri id_2_2 = insertPhoneNumber(id, "5551212c2");
+
+        long c3 = id = createRawContact(mAccount);
+        Uri id_3_0 = insertGroupMembership(id, groupId2);
+        Uri id_3_1 = insertEmail(id, "c3@email.com");
+        Uri id_3_2 = insertPhoneNumber(id, "5551212c3");
+
+        EntityIterator iterator = mResolver.queryEntities(
+                maybeAddAccountQueryParameters(RawContacts.CONTENT_URI, mAccount),
+                RawContacts.SOURCE_ID + " in ('c1', 'c2', 'c3')", null, null);
+        Entity entity;
+        ContentValues[] subValues;
+        entity = iterator.next();
+        assertEquals(c1, (long) entity.getEntityValues().getAsLong(RawContacts._ID));
+        subValues = asSortedContentValuesArray(entity.getSubValues());
+        assertEquals(4, subValues.length);
+        assertDataRow(subValues[0], GroupMembership.CONTENT_ITEM_TYPE,
+                Data._ID, id_1_0,
+                GroupMembership.GROUP_ROW_ID, groupId1,
+                GroupMembership.GROUP_SOURCE_ID, "gsid1");
+        assertDataRow(subValues[1], GroupMembership.CONTENT_ITEM_TYPE,
+                Data._ID, id_1_1,
+                GroupMembership.GROUP_ROW_ID, groupId2,
+                GroupMembership.GROUP_SOURCE_ID, "gsid2");
+        assertDataRow(subValues[2], Email.CONTENT_ITEM_TYPE,
+                Data._ID, id_1_2,
+                Email.DATA, "c1@email.com");
+        assertDataRow(subValues[3], Phone.CONTENT_ITEM_TYPE,
+                Data._ID, id_1_3,
+                Email.DATA, "5551212c1");
+
+        entity = iterator.next();
+        assertEquals(c2, (long) entity.getEntityValues().getAsLong(RawContacts._ID));
+        subValues = asSortedContentValuesArray(entity.getSubValues());
+        assertEquals(3, subValues.length);
+        assertDataRow(subValues[0], GroupMembership.CONTENT_ITEM_TYPE,
+                Data._ID, id_2_0,
+                GroupMembership.GROUP_ROW_ID, groupId1,
+                GroupMembership.GROUP_SOURCE_ID, "gsid1");
+        assertDataRow(subValues[1], Email.CONTENT_ITEM_TYPE,
+                Data._ID, id_2_1,
+                Email.DATA, "c2@email.com");
+        assertDataRow(subValues[2], Phone.CONTENT_ITEM_TYPE,
+                Data._ID, id_2_2,
+                Email.DATA, "5551212c2");
+
+        entity = iterator.next();
+        assertEquals(c3, (long) entity.getEntityValues().getAsLong(RawContacts._ID));
+        subValues = asSortedContentValuesArray(entity.getSubValues());
+        assertEquals(3, subValues.length);
+        assertDataRow(subValues[0], GroupMembership.CONTENT_ITEM_TYPE,
+                Data._ID, id_3_0,
+                GroupMembership.GROUP_ROW_ID, groupId2,
+                GroupMembership.GROUP_SOURCE_ID, "gsid2");
+        assertDataRow(subValues[1], Email.CONTENT_ITEM_TYPE,
+                Data._ID, id_3_1,
+                Email.DATA, "c3@email.com");
+        assertDataRow(subValues[2], Phone.CONTENT_ITEM_TYPE,
+                Data._ID, id_3_2,
+                Email.DATA, "5551212c3");
+
+        assertFalse(iterator.hasNext());
+    }
+
+    public void testDataCreateUpdateDeleteByMimeType() throws Exception {
+        long rawContactId = createRawContact();
+
+        ContentValues values = new ContentValues();
+        values.put(Data.RAW_CONTACT_ID, rawContactId);
+        values.put(Data.MIMETYPE, "testmimetype");
+        values.put(Data.RES_PACKAGE, "oldpackage");
+        values.put(Data.IS_PRIMARY, 1);
+        values.put(Data.IS_SUPER_PRIMARY, 1);
+        values.put(Data.DATA1, "old1");
+        values.put(Data.DATA2, "old2");
+        values.put(Data.DATA3, "old3");
+        values.put(Data.DATA4, "old4");
+        values.put(Data.DATA5, "old5");
+        values.put(Data.DATA6, "old6");
+        values.put(Data.DATA7, "old7");
+        values.put(Data.DATA8, "old8");
+        values.put(Data.DATA9, "old9");
+        values.put(Data.DATA10, "old10");
+        values.put(Data.DATA11, "old11");
+        values.put(Data.DATA12, "old12");
+        values.put(Data.DATA13, "old13");
+        values.put(Data.DATA14, "old14");
+        values.put(Data.DATA15, "old15");
+        Uri uri = mResolver.insert(Data.CONTENT_URI, values);
+        assertStoredValues(uri, values);
+
+        values.clear();
+        values.put(Data.RES_PACKAGE, "newpackage");
+        values.put(Data.IS_PRIMARY, 0);
+        values.put(Data.IS_SUPER_PRIMARY, 0);
+        values.put(Data.DATA1, "new1");
+        values.put(Data.DATA2, "new2");
+        values.put(Data.DATA3, "new3");
+        values.put(Data.DATA4, "new4");
+        values.put(Data.DATA5, "new5");
+        values.put(Data.DATA6, "new6");
+        values.put(Data.DATA7, "new7");
+        values.put(Data.DATA8, "new8");
+        values.put(Data.DATA9, "new9");
+        values.put(Data.DATA10, "new10");
+        values.put(Data.DATA11, "new11");
+        values.put(Data.DATA12, "new12");
+        values.put(Data.DATA13, "new13");
+        values.put(Data.DATA14, "new14");
+        values.put(Data.DATA15, "new15");
+        mResolver.update(Data.CONTENT_URI, values, Data.RAW_CONTACT_ID + "=" + rawContactId +
+                " AND " + Data.MIMETYPE + "='testmimetype'", null);
+
+        // Should not be able to change IS_PRIMARY and IS_SUPER_PRIMARY by the above update
+        values.put(Data.IS_PRIMARY, 1);
+        values.put(Data.IS_SUPER_PRIMARY, 1);
+        assertStoredValues(uri, values);
+
+        int count = mResolver.delete(Data.CONTENT_URI, Data.RAW_CONTACT_ID + "=" + rawContactId
+                + " AND " + Data.MIMETYPE + "='testmimetype'", null);
+        assertEquals(1, count);
+        assertEquals(0, getCount(Data.CONTENT_URI, Data.RAW_CONTACT_ID + "=" + rawContactId
+                        + " AND " + Data.MIMETYPE + "='testmimetype'", null));
+    }
+
+    public void testRawContactDeletion() {
+        long rawContactId = createRawContact();
+        Uri uri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId);
+
+        insertImHandle(rawContactId, Im.PROTOCOL_GOOGLE_TALK, "deleteme@android.com");
+        insertPresence(Im.PROTOCOL_GOOGLE_TALK, "deleteme@android.com", Presence.AVAILABLE);
+        assertEquals(1, getCount(Uri.withAppendedPath(uri, RawContacts.Data.CONTENT_DIRECTORY),
+                null, null));
+        assertEquals(1, getCount(Presence.CONTENT_URI, Presence.RAW_CONTACT_ID + "=" + rawContactId,
+                null));
+
+        mResolver.delete(uri, null, null);
+
+        assertStoredValues(uri, RawContacts.DELETED, "1");
+
+        Uri permanentDeletionUri = uri.buildUpon().appendQueryParameter(
+                RawContacts.DELETE_PERMANENTLY, "true").build();
+        mResolver.delete(permanentDeletionUri, null, null);
+        assertEquals(0, getCount(uri, null, null));
+        assertEquals(0, getCount(Uri.withAppendedPath(uri, RawContacts.Data.CONTENT_DIRECTORY),
+                null, null));
+        assertEquals(0, getCount(Presence.CONTENT_URI, Presence.RAW_CONTACT_ID + "=" + rawContactId,
+                null));
+    }
+
+    public void testRawContactDirtySetOnChange() {
+        Uri uri = ContentUris.withAppendedId(ContactsContract.RawContacts.CONTENT_URI,
+                createRawContact(mAccount));
+        assertDirty(uri, true);
+        clearDirty(uri);
+        assertDirty(uri, false);
+    }
+
+    public void testRawContactDirtyAndVersion() {
+        final long rawContactId = createRawContact(mAccount);
+        Uri uri = ContentUris.withAppendedId(ContactsContract.RawContacts.CONTENT_URI, rawContactId);
+        assertDirty(uri, true);
+        long version = getVersion(uri);
+
+        ContentValues values = new ContentValues();
+        values.put(ContactsContract.RawContacts.DIRTY, 0);
+        values.put(ContactsContract.RawContacts.SEND_TO_VOICEMAIL, 1);
+        values.put(ContactsContract.RawContacts.AGGREGATION_MODE,
+                RawContacts.AGGREGATION_MODE_IMMEDITATE);
+        values.put(ContactsContract.RawContacts.STARRED, 1);
+        assertEquals(1, mResolver.update(uri, values, null, null));
+        assertEquals(version, getVersion(uri));
+
+        assertDirty(uri, false);
+
+        Uri emailUri = insertEmail(rawContactId, "goo@woo.com");
+        assertDirty(uri, true);
+        ++version;
+        assertEquals(version, getVersion(uri));
+        clearDirty(uri);
+
+        values = new ContentValues();
+        values.put(Email.DATA, "goo@hoo.com");
+        mResolver.update(emailUri, values, null, null);
+        assertDirty(uri, true);
+        ++version;
+        assertEquals(version, getVersion(uri));
+        clearDirty(uri);
+
+        mResolver.delete(emailUri, null, null);
+        assertDirty(uri, true);
+        ++version;
+        assertEquals(version, getVersion(uri));
+    }
+
+    public void testRawContactClearDirty() {
+        final long rawContactId = createRawContact(mAccount);
+        Uri uri = ContentUris.withAppendedId(ContactsContract.RawContacts.CONTENT_URI,
+                rawContactId);
+        long version = getVersion(uri);
+        insertEmail(rawContactId, "goo@woo.com");
+        assertDirty(uri, true);
+        version++;
+        assertEquals(version, getVersion(uri));
+
+        clearDirty(uri);
+        assertDirty(uri, false);
+        assertEquals(version, getVersion(uri));
+    }
+
+    public void testRawContactDeletionSetsDirty() {
+        final long rawContactId = createRawContact(mAccount);
+        Uri uri = ContentUris.withAppendedId(ContactsContract.RawContacts.CONTENT_URI,
+                rawContactId);
+        long version = getVersion(uri);
+        clearDirty(uri);
+        assertDirty(uri, false);
+
+        mResolver.delete(uri, null, null);
+        assertStoredValues(uri, RawContacts.DELETED, "1");
+        assertDirty(uri, true);
+        version++;
+        assertEquals(version, getVersion(uri));
+    }
+}
+
diff --git a/tests/src/com/android/providers/contacts/GlobalSearchSupportTest.java b/tests/src/com/android/providers/contacts/GlobalSearchSupportTest.java
new file mode 100644
index 0000000..8921d41
--- /dev/null
+++ b/tests/src/com/android/providers/contacts/GlobalSearchSupportTest.java
@@ -0,0 +1,245 @@
+/*
+ * 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.app.SearchManager;
+import android.content.ContentUris;
+import android.content.ContentValues;
+import android.database.Cursor;
+import android.database.DatabaseUtils;
+import android.net.Uri;
+import android.provider.ContactsContract;
+import android.provider.Contacts.Intents;
+import android.provider.ContactsContract.Data;
+import android.provider.ContactsContract.Presence;
+import android.provider.ContactsContract.RawContacts;
+import android.provider.ContactsContract.CommonDataKinds.Email;
+import android.provider.ContactsContract.CommonDataKinds.Im;
+import android.provider.ContactsContract.CommonDataKinds.Organization;
+import android.provider.ContactsContract.CommonDataKinds.Phone;
+import android.provider.ContactsContract.CommonDataKinds.Photo;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import java.io.IOException;
+
+/**
+ * Unit tests for {@link GlobalSearchSupport}.
+ *
+ * Run the test like this:
+ * <code>
+ * adb shell am instrument -w \
+ *         com.android.providers.contacts.tests/android.test.InstrumentationTestRunner
+ * </code>
+ */
+@LargeTest
+public class GlobalSearchSupportTest extends BaseContactsProvider2Test {
+    public void testSearchSuggestionsNotInVisibleGroup() throws Exception {
+        long rawContactId = createRawContact();
+        insertStructuredName(rawContactId, "Deer", "Dough");
+
+        Uri searchUri = new Uri.Builder().scheme("content").authority(ContactsContract.AUTHORITY)
+                .appendPath(SearchManager.SUGGEST_URI_PATH_QUERY).appendPath("D").build();
+
+        // If the contact is not in the "my contacts" group, nothing should be found
+        Cursor c = mResolver.query(searchUri, null, null, null, null);
+        assertEquals(0, c.getCount());
+        c.close();
+    }
+
+    public void testSearchSuggestionsByName() throws Exception {
+        long groupId = createGroup(mAccount, "gsid1", "title1");
+
+        assertSearchSuggestion(groupId,
+                true,  // name
+                true,  // photo
+                false, // organization
+                false, // phone
+                false, // email
+                "D",   // query
+                true,  // expect icon URI
+                null, "Deer Dough", null);
+
+        assertSearchSuggestion(groupId,
+                true,  // name
+                true,  // photo
+                true,  // organization
+                false, // phone
+                false, // email
+                "D",   // query
+                true,  // expect icon URI
+                null, "Deer Dough", "Google");
+
+        assertSearchSuggestion(groupId,
+                true,  // name
+                true,  // photo
+                false, // organization
+                true,  // phone
+                false, // email
+                "D",   // query
+                true,  // expect icon URI
+                null, "Deer Dough", "1-800-4664-411");
+
+        assertSearchSuggestion(groupId,
+                true,  // name
+                true,  // photo
+                false, // organization
+                false, // phone
+                true,  // email
+                "D",   // query
+                true,  // expect icon URI
+                String.valueOf(Presence.getPresenceIconResourceId(Presence.OFFLINE)),
+                "Deer Dough", "foo@acme.com");
+
+        assertSearchSuggestion(groupId,
+                true,  // name
+                false, // photo
+                true,  // organization
+                false, // phone
+                false, // email
+                "D",   // query
+                false, // expect icon URI
+                null, "Deer Dough", "Google");
+    }
+
+    private void assertSearchSuggestion(long groupId, boolean name, boolean photo,
+            boolean organization, boolean phone, boolean email, String query,
+            boolean expectIcon1Uri, String expectedIcon2, String expectedText1, String expectedText2)
+            throws IOException {
+        ContentValues values = new ContentValues();
+
+        long rawContactId = createRawContact();
+        insertGroupMembership(rawContactId, groupId);
+
+        if (name) {
+            insertStructuredName(rawContactId, "Deer", "Dough");
+        }
+
+        final Uri rawContactUri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId);
+        if (photo) {
+            values.clear();
+            byte[] photoData = loadTestPhoto();
+            values.put(Data.RAW_CONTACT_ID, rawContactId);
+            values.put(Data.MIMETYPE, Photo.CONTENT_ITEM_TYPE);
+            values.put(Photo.PHOTO, photoData);
+            mResolver.insert(Data.CONTENT_URI, values);
+        }
+
+        if (organization) {
+            values.clear();
+            values.put(Data.RAW_CONTACT_ID, rawContactId);
+            values.put(Data.MIMETYPE, Organization.CONTENT_ITEM_TYPE);
+            values.put(Organization.TYPE, Organization.TYPE_WORK);
+            values.put(Organization.COMPANY, "Google");
+            mResolver.insert(Data.CONTENT_URI, values);
+        }
+
+        if (email) {
+            values.clear();
+            values.put(Data.RAW_CONTACT_ID, rawContactId);
+            values.put(Data.MIMETYPE, Email.CONTENT_ITEM_TYPE);
+            values.put(Email.TYPE, Email.TYPE_WORK);
+            values.put(Email.DATA, "foo@acme.com");
+            mResolver.insert(Data.CONTENT_URI, values);
+
+            int protocol = Im.PROTOCOL_GOOGLE_TALK;
+
+            values.clear();
+            values.put(Presence.IM_PROTOCOL, protocol);
+            values.put(Presence.IM_HANDLE, "foo@acme.com");
+            values.put(Presence.IM_ACCOUNT, "foo");
+            values.put(Presence.PRESENCE_STATUS, Presence.OFFLINE);
+            values.put(Presence.PRESENCE_CUSTOM_STATUS, "Coding for Android");
+            mResolver.insert(Presence.CONTENT_URI, values);
+        }
+
+        if (phone) {
+            values.clear();
+            values.put(Data.RAW_CONTACT_ID, rawContactId);
+            values.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
+            values.put(Data.IS_PRIMARY, 1);
+            values.put(Phone.TYPE, Phone.TYPE_HOME);
+            values.put(Phone.NUMBER, "1-800-4664-411");
+            mResolver.insert(Data.CONTENT_URI, values);
+        }
+
+        long contactId = queryContactId(rawContactId);
+        Uri searchUri = new Uri.Builder().scheme("content").authority(ContactsContract.AUTHORITY)
+                .appendPath(SearchManager.SUGGEST_URI_PATH_QUERY).appendPath(query).build();
+
+        Cursor c = mResolver.query(searchUri, null, null, null, null);
+        assertEquals(1, c.getCount());
+        c.moveToFirst();
+        values.clear();
+
+        // SearchManager does not declare a constant for _id
+        values.put("_id", contactId);
+        values.put(SearchManager.SUGGEST_COLUMN_TEXT_1, expectedText1);
+        values.put(SearchManager.SUGGEST_COLUMN_TEXT_2, expectedText2);
+
+        String icon1 = c.getString(c.getColumnIndex(SearchManager.SUGGEST_COLUMN_ICON_1));
+        if (expectIcon1Uri) {
+            assertTrue(icon1.startsWith("content:"));
+        } else {
+            assertEquals(String.valueOf(com.android.internal.R.drawable.ic_contact_picture), icon1);
+        }
+
+        values.put(SearchManager.SUGGEST_COLUMN_ICON_2, expectedIcon2);
+        values.put(SearchManager.SUGGEST_COLUMN_INTENT_DATA_ID, contactId);
+        values.put(SearchManager.SUGGEST_COLUMN_SHORTCUT_ID, contactId);
+        assertCursorValues(c, values);
+        c.close();
+
+        // Cleanup
+        mResolver.delete(rawContactUri, null, null);
+    }
+
+    public void testSearchSuggestionsByPhoneNumber() throws Exception {
+        ContentValues values = new ContentValues();
+
+        Uri searchUri = new Uri.Builder().scheme("content").authority(ContactsContract.AUTHORITY)
+                .appendPath(SearchManager.SUGGEST_URI_PATH_QUERY).appendPath("12345").build();
+
+        Cursor c = mResolver.query(searchUri, null, null, null, null);
+        DatabaseUtils.dumpCursor(c);
+        assertEquals(2, c.getCount());
+        c.moveToFirst();
+
+        values.put(SearchManager.SUGGEST_COLUMN_TEXT_1, "Dial number");
+        values.put(SearchManager.SUGGEST_COLUMN_TEXT_2, "using 12345");
+        values.put(SearchManager.SUGGEST_COLUMN_ICON_1,
+                String.valueOf(com.android.internal.R.drawable.call_contact));
+        values.put(SearchManager.SUGGEST_COLUMN_INTENT_ACTION,
+                Intents.SEARCH_SUGGESTION_DIAL_NUMBER_CLICKED);
+        values.put(SearchManager.SUGGEST_COLUMN_INTENT_DATA, "tel:12345");
+        values.putNull(SearchManager.SUGGEST_COLUMN_SHORTCUT_ID);
+        assertCursorValues(c, values);
+
+        c.moveToNext();
+        values.clear();
+        values.put(SearchManager.SUGGEST_COLUMN_TEXT_1, "Create contact");
+        values.put(SearchManager.SUGGEST_COLUMN_TEXT_2, "using 12345");
+        values.put(SearchManager.SUGGEST_COLUMN_ICON_1,
+                String.valueOf(com.android.internal.R.drawable.create_contact));
+        values.put(SearchManager.SUGGEST_COLUMN_INTENT_ACTION,
+                Intents.SEARCH_SUGGESTION_CREATE_CONTACT_CLICKED);
+        values.put(SearchManager.SUGGEST_COLUMN_INTENT_DATA, "tel:12345");
+        values.put(SearchManager.SUGGEST_COLUMN_SHORTCUT_ID,
+                SearchManager.SUGGEST_NEVER_MAKE_SHORTCUT);
+        assertCursorValues(c, values);
+        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..38715b5
--- /dev/null
+++ b/tests/src/com/android/providers/contacts/GroupsTest.java
@@ -0,0 +1,181 @@
+/*
+ * 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.database.Cursor;
+import android.net.Uri;
+import android.provider.ContactsContract.Groups;
+import android.provider.ContactsContract.CommonDataKinds.GroupMembership;
+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 BaseContactsProvider2Test {
+
+    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
+        // TODO make the provider wipe data automatically
+        ((SynchronousContactsProvider2)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.getContactForRawContact(contactCharlie);
+            long aggCharlieDupe = mActor.getContactForRawContact(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");
+            }
+        }
+
+    }
+
+    public void testGroupDirtySetOnChange() {
+        Uri uri = ContentUris.withAppendedId(Groups.CONTENT_URI,
+                createGroup(mAccount, "gsid1", "title1"));
+        assertDirty(uri, true);
+        clearDirty(uri);
+        assertDirty(uri, false);
+    }
+
+    public void testGroupDirtyClearedWhenSetExplicitly() {
+        Uri uri = ContentUris.withAppendedId(Groups.CONTENT_URI,
+                createGroup(mAccount, "gsid1", "title1"));
+        assertDirty(uri, true);
+
+        ContentValues values = new ContentValues();
+        values.put(Groups.DIRTY, 0);
+        values.put(Groups.NOTES, "other notes");
+        assertEquals(1, mResolver.update(uri, values, null, null));
+
+        assertDirty(uri, false);
+    }
+
+    public void testGroupVersionUpdates() {
+        Uri uri = ContentUris.withAppendedId(Groups.CONTENT_URI,
+                createGroup(mAccount, "gsid1", "title1"));
+        long version = getVersion(uri);
+        ContentValues values = new ContentValues();
+        values.put(Groups.TITLE, "title2");
+        mResolver.update(uri, values, null, null);
+        assertEquals(version + 1, getVersion(uri));
+    }
+
+    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/LegacyContactsProviderTest.java b/tests/src/com/android/providers/contacts/LegacyContactsProviderTest.java
new file mode 100644
index 0000000..870c7d2
--- /dev/null
+++ b/tests/src/com/android/providers/contacts/LegacyContactsProviderTest.java
@@ -0,0 +1,849 @@
+/*
+ * 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.app.SearchManager;
+import android.content.ContentProvider;
+import android.content.ContentUris;
+import android.content.ContentValues;
+import android.content.res.Resources;
+import android.database.Cursor;
+import android.net.Uri;
+import android.provider.Contacts;
+import android.provider.Contacts.ContactMethods;
+import android.provider.Contacts.Extensions;
+import android.provider.Contacts.GroupMembership;
+import android.provider.Contacts.Groups;
+import android.provider.Contacts.Intents;
+import android.provider.Contacts.Organizations;
+import android.provider.Contacts.People;
+import android.provider.Contacts.Phones;
+import android.provider.Contacts.Photos;
+import android.provider.Contacts.Presence;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Tests for legacy contacts APIs.
+ */
+@LargeTest
+public class LegacyContactsProviderTest extends BaseContactsProvider2Test {
+
+    private static final boolean USE_LEGACY_PROVIDER = false;
+
+    @Override
+    protected Class<? extends ContentProvider> getProviderClass() {
+       return USE_LEGACY_PROVIDER ? ContactsProvider.class : SynchronousContactsProvider2.class;
+    }
+
+    @Override
+    protected String getAuthority() {
+        return Contacts.AUTHORITY;
+    }
+
+    public void testPeopleInsert() {
+        ContentValues values = new ContentValues();
+        putContactValues(values);
+
+        Uri uri = mResolver.insert(People.CONTENT_URI, values);
+        assertStoredValues(uri, values);
+        assertSelection(People.CONTENT_URI, values, People._ID, ContentUris.parseId(uri));
+    }
+
+    public void testPeopleDelete() {
+        ContentValues values = new ContentValues();
+        values.put(People.NAME, "John Doe");
+        Uri personId = mResolver.insert(People.CONTENT_URI, values);
+        mResolver.delete(personId, null, null);
+
+        Cursor c = mResolver.query(personId, null, People.NAME + "='John Doe'" , null, null);
+        assertEquals("Record count after deletion", 0, c.getCount());
+        c.close();
+
+        try {
+            mResolver.query(People.DELETED_CONTENT_URI, null, null, null, null);
+        } catch (UnsupportedOperationException e) {
+            // Expected exception
+        }
+    }
+
+    public void testPeopleFilter() {
+        ContentValues values = new ContentValues();
+        values.put(People.NAME, "Deer Doe");
+        mResolver.insert(People.CONTENT_URI, values);
+
+        values.clear();
+        values.put(People.NAME, "Dear Dough");
+        mResolver.insert(People.CONTENT_URI, values);
+
+        values.clear();
+        values.put(People.NAME, "D.R. Dauwe");
+        mResolver.insert(People.CONTENT_URI, values);
+
+        assertFilteredContacts("d", "Deer Doe", "Dear Dough", "D.R. Dauwe");
+        assertFilteredContacts("de", "Deer Doe", "Dear Dough");
+        assertFilteredContacts("dee", "Deer Doe");
+        assertFilteredContacts("der");
+    }
+
+    public void testDefaultDisplayName() {
+        ContentValues values = new ContentValues();
+        values.put(People.NAME, "John Doe");
+        Uri personUri = mResolver.insert(People.CONTENT_URI, values);
+        assertStoredValues(personUri, People.DISPLAY_NAME, "John Doe");
+    }
+
+    public void testPrimaryOrganization() {
+        ContentValues values = new ContentValues();
+        final Uri personUri = mResolver.insert(People.CONTENT_URI, values);
+        long personId = ContentUris.parseId(personUri);
+
+        // Primary
+        values.clear();
+        values.put(Organizations.ISPRIMARY, 1);
+        values.put(Organizations.COMPANY, "Google");
+        values.put(Organizations.TYPE, Organizations.TYPE_WORK);
+        values.put(Organizations.PERSON_ID, personId);
+        Uri orgUri1 = mResolver.insert(Organizations.CONTENT_URI, values);
+
+        // Non-primary
+        values.clear();
+        values.put(Organizations.COMPANY, "Acme");
+        values.put(Organizations.TYPE, Organizations.TYPE_WORK);
+        values.put(Organizations.PERSON_ID, personId);
+        Uri orgUri2 = mResolver.insert(Organizations.CONTENT_URI, values);
+
+        values.clear();
+        values.put(People.PRIMARY_ORGANIZATION_ID, ContentUris.parseId(orgUri1));
+        values.put(People.DISPLAY_NAME, "Google");
+        assertStoredValues(personUri, values);
+
+        // Remove the original primary organization
+        mResolver.delete(orgUri1, null, null);
+
+        values.clear();
+        values.put(People.PRIMARY_ORGANIZATION_ID, ContentUris.parseId(orgUri2));
+        values.put(People.DISPLAY_NAME, "Acme");
+        assertStoredValues(personUri, values);
+
+        // Remove the remaining organization
+        mResolver.delete(orgUri2, null, null);
+
+        values.clear();
+        values.putNull(People.PRIMARY_ORGANIZATION_ID);
+        values.putNull(People.DISPLAY_NAME);
+        assertStoredValues(personUri, values);
+    }
+
+    public void testPrimaryPhone() {
+        ContentValues values = new ContentValues();
+        Uri personUri = mResolver.insert(People.CONTENT_URI, values);
+        long personId = ContentUris.parseId(personUri);
+
+        // Primary
+        values.clear();
+        values.put(Phones.ISPRIMARY, 1);
+        values.put(Phones.TYPE, Phones.TYPE_WORK);
+        values.put(Phones.PERSON_ID, personId);
+        values.put(Phones.NUMBER, "12345");
+        Uri phoneUri1 = mResolver.insert(Phones.CONTENT_URI, values);
+
+        // Non-primary
+        values.clear();
+        values.put(Phones.TYPE, Phones.TYPE_WORK);
+        values.put(Phones.PERSON_ID, personId);
+        values.put(Phones.NUMBER, "67890");
+        Uri phoneUri2 = mResolver.insert(Phones.CONTENT_URI, values);
+
+        values.clear();
+        values.put(People.PRIMARY_PHONE_ID, ContentUris.parseId(phoneUri1));
+        values.put(People.DISPLAY_NAME, "12345");
+        assertStoredValues(personUri, values);
+
+        // Remove the primary phone number
+        mResolver.delete(phoneUri1, null, null);
+
+        values.clear();
+        values.put(People.PRIMARY_PHONE_ID, ContentUris.parseId(phoneUri2));
+        values.put(People.DISPLAY_NAME, "67890");
+        assertStoredValues(personUri, values);
+
+        // Remove the remaining phone number
+        mResolver.delete(phoneUri2, null, null);
+
+        values.clear();
+        values.putNull(People.PRIMARY_PHONE_ID);
+        values.putNull(People.DISPLAY_NAME);
+        assertStoredValues(personUri, values);
+    }
+
+    public void testPrimaryEmail() {
+        ContentValues values = new ContentValues();
+        Uri personUri = mResolver.insert(People.CONTENT_URI, values);
+        long personId = ContentUris.parseId(personUri);
+
+        // Primary
+        values.clear();
+        values.put(ContactMethods.PERSON_ID, personId);
+        values.put(ContactMethods.KIND, Contacts.KIND_EMAIL);
+        values.put(ContactMethods.TYPE, ContactMethods.TYPE_HOME);
+        values.put(ContactMethods.DATA, "foo@acme.com");
+        values.put(ContactMethods.ISPRIMARY, 1);
+        Uri emailUri1 = mResolver.insert(ContactMethods.CONTENT_URI, values);
+
+        // Non-primary
+        values.clear();
+        values.put(ContactMethods.PERSON_ID, personId);
+        values.put(ContactMethods.KIND, Contacts.KIND_EMAIL);
+        values.put(ContactMethods.TYPE, ContactMethods.TYPE_WORK);
+        values.put(ContactMethods.DATA, "bar@acme.com");
+        Uri emailUri2 = mResolver.insert(ContactMethods.CONTENT_URI, values);
+
+        values.clear();
+        values.put(People.PRIMARY_EMAIL_ID, ContentUris.parseId(emailUri1));
+        values.put(People.DISPLAY_NAME, "foo@acme.com");
+        assertStoredValues(personUri, values);
+
+        // Remove the primary email
+        mResolver.delete(emailUri1, null, null);
+
+        values.clear();
+        values.put(People.PRIMARY_EMAIL_ID, ContentUris.parseId(emailUri2));
+        values.put(People.DISPLAY_NAME, "bar@acme.com");
+        assertStoredValues(personUri, values);
+
+        // Remove the remaining email
+        mResolver.delete(emailUri2, null, null);
+
+        values.clear();
+        values.putNull(People.PRIMARY_EMAIL_ID);
+        values.putNull(People.DISPLAY_NAME);
+        assertStoredValues(personUri, values);
+    }
+
+    public void testMarkAsContacted() {
+        ContentValues values = new ContentValues();
+        Uri personUri = mResolver.insert(People.CONTENT_URI, values);
+        long personId = ContentUris.parseId(personUri);
+
+        int timesContactedBefore =
+                Integer.parseInt(getStoredValue(personUri, People.TIMES_CONTACTED));
+        long timeBefore = System.currentTimeMillis();
+        People.markAsContacted(mResolver, personId);
+        long timeAfter = System.currentTimeMillis();
+
+        long lastContacted = Long.parseLong(getStoredValue(personUri, People.LAST_TIME_CONTACTED));
+        int timesContactedAfter =
+            Integer.parseInt(getStoredValue(personUri, People.TIMES_CONTACTED));
+
+        assertTrue(lastContacted >= timeBefore);
+        assertTrue(lastContacted <= timeAfter);
+        assertEquals(timesContactedAfter, timesContactedBefore + 1);
+    }
+
+    public void testOrganizationsInsert() {
+        ContentValues values = new ContentValues();
+        Uri personUri = mResolver.insert(People.CONTENT_URI, values);
+        long personId = ContentUris.parseId(personUri);
+
+        values.clear();
+        values.put(Organizations.COMPANY, "Sierra");
+        values.put(Organizations.PERSON_ID, personId);
+        values.put(Organizations.TYPE, Organizations.TYPE_CUSTOM);
+        values.put(Organizations.LABEL, "Club");
+        values.put(Organizations.TITLE, "Member");
+        values.put(Organizations.ISPRIMARY, 1);
+
+        Uri uri = mResolver.insert(Organizations.CONTENT_URI, values);
+        assertStoredValues(uri, values);
+        assertSelection(Organizations.CONTENT_URI, values,
+                Organizations._ID, ContentUris.parseId(uri));
+
+        assertPersonIdConstraint(Organizations.CONTENT_URI, Organizations.TYPE,
+                Organizations.TYPE_WORK);
+
+        assertTypeAndLabelConstraints(Organizations.CONTENT_URI, Organizations.PERSON_ID, personId,
+                Organizations.TYPE, Organizations.TYPE_CUSTOM, Organizations.TYPE_OTHER,
+                Organizations.LABEL);
+    }
+
+    public void testPhonesInsert() {
+        ContentValues values = new ContentValues();
+        putContactValues(values);
+        Uri personUri = mResolver.insert(People.CONTENT_URI, values);
+        long personId = ContentUris.parseId(personUri);
+
+        values.clear();
+        values.put(Phones.PERSON_ID, personId);
+        values.put(Phones.TYPE, Phones.TYPE_CUSTOM);
+        values.put(Phones.LABEL, "Directory");
+        values.put(Phones.NUMBER, "1-800-4664-411");
+        values.put(Phones.ISPRIMARY, 1);
+
+        Uri uri = mResolver.insert(Phones.CONTENT_URI, values);
+
+        // Adding another value to assert
+        values.put(Phones.NUMBER_KEY, "11446640081");
+
+        // The result is joined with People
+        putContactValues(values);
+        assertStoredValues(uri, values);
+        assertSelection(Phones.CONTENT_URI, values,
+                Phones._ID, ContentUris.parseId(uri));
+
+        // Access the phone through People
+        Uri twigUri = Uri.withAppendedPath(personUri, People.Phones.CONTENT_DIRECTORY);
+        assertStoredValues(twigUri, values);
+
+        // Now the person should be joined with Phone
+        values.clear();
+        putContactValues(values);
+        values.put(People.TYPE, Phones.TYPE_CUSTOM);
+        values.put(People.LABEL, "Directory");
+        values.put(People.NUMBER, "1-800-4664-411");
+        assertStoredValues(personUri, values);
+
+        assertPersonIdConstraint(Phones.CONTENT_URI, Phones.TYPE, Phones.TYPE_WORK);
+
+        assertTypeAndLabelConstraints(Phones.CONTENT_URI, Phones.PERSON_ID, personId, Phones.TYPE,
+                Phones.TYPE_CUSTOM, Phones.TYPE_OTHER, Phones.LABEL);
+    }
+
+    public void testEmailInsert() {
+        assertContactMethodInsert(Contacts.KIND_EMAIL, ContactMethods.TYPE_CUSTOM,
+                "Some other way", "foo@acme.com", null, true);
+    }
+
+    public void testImInsert() {
+        assertContactMethodInsert(Contacts.KIND_IM, ContactMethods.TYPE_CUSTOM, "Some other way",
+                "Foo", "Bar", true);
+    }
+
+    public void testPostalInsert() {
+        assertContactMethodInsert(Contacts.KIND_POSTAL, ContactMethods.TYPE_CUSTOM,
+                "Some other way", "Foo", "Bar", true);
+    }
+
+    private void assertContactMethodInsert(int kind, int type, String label, String data,
+            String auxData, boolean primary) {
+        ContentValues values = new ContentValues();
+        putContactValues(values);
+        final Uri personUri = mResolver.insert(People.CONTENT_URI, values);
+        long personId = ContentUris.parseId(personUri);
+
+        values.clear();
+        values.put(ContactMethods.PERSON_ID, personId);
+        values.put(ContactMethods.KIND, kind);
+        values.put(ContactMethods.TYPE, type);
+        values.put(ContactMethods.LABEL, label);
+        values.put(ContactMethods.DATA, data);
+        values.put(ContactMethods.AUX_DATA, auxData);
+        values.put(ContactMethods.ISPRIMARY, primary ? 1 : 0);
+
+        Uri uri = mResolver.insert(ContactMethods.CONTENT_URI, values);
+
+        // The result is joined with People
+        putContactValues(values);
+        assertStoredValues(uri, values);
+        assertSelection(ContactMethods.CONTENT_URI, values,
+                ContactMethods._ID, ContentUris.parseId(uri));
+
+        // Access the contact method through People
+        Uri twigUri = Uri.withAppendedPath(personUri, People.ContactMethods.CONTENT_DIRECTORY);
+        assertStoredValues(twigUri, values);
+
+        assertPersonIdConstraint(ContactMethods.CONTENT_URI, ContactMethods.TYPE,
+                ContactMethods.TYPE_WORK);
+
+        assertTypeAndLabelConstraints(ContactMethods.CONTENT_URI, ContactMethods.PERSON_ID,
+                personId, ContactMethods.TYPE, ContactMethods.TYPE_CUSTOM,
+                ContactMethods.TYPE_OTHER, ContactMethods.LABEL);
+    }
+
+    public void testExtensionsInsert() {
+        ContentValues values = new ContentValues();
+        final Uri personUri = mResolver.insert(People.CONTENT_URI, values);
+        long personId = ContentUris.parseId(personUri);
+
+        values.clear();
+        values.put(Extensions.PERSON_ID, personId);
+        values.put(Extensions.NAME, "Foo");
+        values.put(Extensions.VALUE, "Bar");
+
+        Uri uri = mResolver.insert(Extensions.CONTENT_URI, values);
+        assertStoredValues(uri, values);
+        assertSelection(Extensions.CONTENT_URI, values,
+                Extensions._ID, ContentUris.parseId(uri));
+
+        // Access the extensions through People
+        Uri twigUri = Uri.withAppendedPath(personUri, People.Extensions.CONTENT_DIRECTORY);
+        assertStoredValues(twigUri, values);
+    }
+
+    public void testGroupsInsert() {
+        ContentValues values = new ContentValues();
+        values.put(Groups.NAME, "Galois");
+        values.put(Groups.NOTES, "Abel");
+        values.put(Groups.SYSTEM_ID, "12345");
+
+        Uri groupUri = mResolver.insert(Groups.CONTENT_URI, values);
+        assertStoredValues(groupUri, values);
+    }
+
+    public void testGroupMembershipsInsert() {
+        ContentValues values = new ContentValues();
+        values.put(Groups.NAME, "Galois");
+        values.put(Groups.NOTES, "Abel");
+        Uri groupUri = mResolver.insert(Groups.CONTENT_URI, values);
+
+        values.clear();
+        values.put(People.NAME, "Klein");
+        Uri personUri = mResolver.insert(People.CONTENT_URI, values);
+
+        long groupId = ContentUris.parseId(groupUri);
+        long personId = ContentUris.parseId(personUri);
+
+        values.clear();
+        values.put(GroupMembership.GROUP_ID, groupId);
+        values.put(GroupMembership.PERSON_ID, personId);
+        Uri membershipUri = mResolver.insert(GroupMembership.CONTENT_URI, values);
+        assertStoredValues(membershipUri, values);
+        assertSelection(GroupMembership.CONTENT_URI, values,
+                GroupMembership._ID, ContentUris.parseId(membershipUri));
+
+        Uri personsGroupsUri = Uri.withAppendedPath(personUri, GroupMembership.CONTENT_DIRECTORY);
+        assertStoredValues(personsGroupsUri, values);
+    }
+
+    public void testAddToGroup() {
+        ContentValues values = new ContentValues();
+        Uri personUri = mResolver.insert(People.CONTENT_URI, values);
+        long personId = ContentUris.parseId(personUri);
+
+        values.clear();
+        values.put(Groups.NAME, "Galois");
+        Uri groupUri = mResolver.insert(Groups.CONTENT_URI, values);
+
+        People.addToGroup(mResolver, personId, "Galois");
+
+        values.clear();
+        values.put(GroupMembership.GROUP_ID, ContentUris.parseId(groupUri));
+        values.put(GroupMembership.PERSON_ID, personId);
+
+        Uri personsGroupsUri = Uri.withAppendedPath(personUri, GroupMembership.CONTENT_DIRECTORY);
+        assertStoredValues(personsGroupsUri, values);
+    }
+
+    public void testPresenceInsertMatchOnHandle() {
+        ContentValues values = new ContentValues();
+        putContactValues(values);
+        Uri personUri = mResolver.insert(People.CONTENT_URI, values);
+        long personId = ContentUris.parseId(personUri);
+
+        String encodedProtocol =
+                ContactMethods.encodePredefinedImProtocol(ContactMethods.PROTOCOL_GOOGLE_TALK);
+
+        values.clear();
+        values.put(ContactMethods.PERSON_ID, personId);
+        values.put(ContactMethods.KIND, Contacts.KIND_IM);
+        values.put(ContactMethods.TYPE, ContactMethods.TYPE_HOME);
+        values.put(ContactMethods.DATA, "Android");
+        values.put(ContactMethods.AUX_DATA, encodedProtocol);
+        mResolver.insert(ContactMethods.CONTENT_URI, values);
+
+        values.clear();
+        values.put(Presence.IM_PROTOCOL, encodedProtocol);
+        values.put(Presence.IM_HANDLE, "Android");
+        values.put(Presence.IM_ACCOUNT, "foo");
+        values.put(Presence.PRESENCE_STATUS, Presence.OFFLINE);
+        values.put(Presence.PRESENCE_CUSTOM_STATUS, "Coding for Android");
+
+        Uri presenceUri = mResolver.insert(Presence.CONTENT_URI, values);
+        assertSelection(Presence.CONTENT_URI, values,
+                Presence._ID, ContentUris.parseId(presenceUri));
+
+        values.put(Presence.PERSON_ID, personId);
+        assertStoredValues(presenceUri, values);
+
+        // Now the person should be joined with Presence
+        values.clear();
+        putContactValues(values);
+        values.put(People.IM_PROTOCOL, encodedProtocol);
+        values.put(People.IM_HANDLE, "Android");
+        values.put(People.IM_ACCOUNT, "foo");
+        values.put(People.PRESENCE_STATUS, Presence.OFFLINE);
+        values.put(People.PRESENCE_CUSTOM_STATUS, "Coding for Android");
+        assertStoredValues(personUri, values);
+    }
+
+    public void testPresenceInsertMatchOnEmail() {
+        ContentValues values = new ContentValues();
+        putContactValues(values);
+        Uri personUri = mResolver.insert(People.CONTENT_URI, values);
+        long personId = ContentUris.parseId(personUri);
+
+        String protocol =
+            ContactMethods.encodePredefinedImProtocol(ContactMethods.PROTOCOL_GOOGLE_TALK);
+
+        values.clear();
+        values.put(ContactMethods.PERSON_ID, personId);
+        values.put(ContactMethods.KIND, Contacts.KIND_EMAIL);
+        values.put(ContactMethods.TYPE, ContactMethods.TYPE_HOME);
+        values.put(ContactMethods.DATA, "Android@android.com");
+        mResolver.insert(ContactMethods.CONTENT_URI, values);
+
+        values.clear();
+        values.put(Presence.IM_PROTOCOL, protocol);
+        values.put(Presence.IM_HANDLE, "Android@android.com");
+        values.put(Presence.IM_ACCOUNT, "foo");
+        values.put(Presence.PRESENCE_STATUS, Presence.OFFLINE);
+        values.put(Presence.PRESENCE_CUSTOM_STATUS, "Coding for Android");
+
+        Uri presenceUri = mResolver.insert(Presence.CONTENT_URI, values);
+
+        // FIXME person_id was not available in legacy ContactsProvider
+        // values.put(Presence.PERSON_ID, personId);
+        assertStoredValues(presenceUri, values);
+        assertSelection(Presence.CONTENT_URI, values,
+                Presence._ID, ContentUris.parseId(presenceUri));
+
+        // Now the person should be joined with Presence
+        values.clear();
+        putContactValues(values);
+        values.put(People.IM_PROTOCOL, protocol);
+        values.put(People.IM_HANDLE, "Android@android.com");
+        values.put(People.IM_ACCOUNT, "foo");
+        values.put(People.PRESENCE_STATUS, Presence.OFFLINE);
+        values.put(People.PRESENCE_CUSTOM_STATUS, "Coding for Android");
+        assertStoredValues(personUri, values);
+    }
+
+    public void testPhotoUpdate() throws Exception {
+        byte[] photo = loadTestPhoto();
+
+        ContentValues values = new ContentValues();
+        Uri personUri = mResolver.insert(People.CONTENT_URI, values);
+
+        values.clear();
+        values.put(Photos.DATA, photo);
+        values.put(Photos.LOCAL_VERSION, "10");
+        // FIXME this column was unavailable for update in legacy ContactsProvider
+        // values.put(Photos.DOWNLOAD_REQUIRED, 1);
+        values.put(Photos.EXISTS_ON_SERVER, 1);
+        values.put(Photos.SYNC_ERROR, "404 does not exist");
+
+        Uri photoUri = Uri.withAppendedPath(personUri, Photos.CONTENT_DIRECTORY);
+        mResolver.update(photoUri, values, null, null);
+        assertStoredValues(photoUri, values);
+    }
+
+    /**
+     * Capturing the search suggestion requirements in test cases as a reference.
+     */
+    public void testSearchSuggestionsNotInMyContacts() throws Exception {
+
+        // We don't provide compatibility for search suggestions
+        if (!USE_LEGACY_PROVIDER) {
+            return;
+        }
+
+        ContentValues values = new ContentValues();
+        putContactValues(values);
+        mResolver.insert(People.CONTENT_URI, values);
+
+        Uri searchUri = new Uri.Builder().scheme("content").authority(Contacts.AUTHORITY)
+                .appendPath(SearchManager.SUGGEST_URI_PATH_QUERY).appendPath("D").build();
+
+        // If the contact is not in the "my contacts" group, nothing should be found
+        Cursor c = mResolver.query(searchUri, null, null, null, null);
+        assertEquals(0, c.getCount());
+        c.close();
+    }
+
+    /**
+     * Capturing the search suggestion requirements in test cases as a reference.
+     */
+    public void testSearchSuggestionsByName() throws Exception {
+
+        // We don't provide compatibility for search suggestions
+        if (!USE_LEGACY_PROVIDER) {
+            return;
+        }
+
+        assertSearchSuggestion(
+                true,  // name
+                true,  // photo
+                true,  // organization
+                false, // phone
+                false, // email
+                "D",   // query
+                true,  // expect icon URI
+                null, "Deer Dough", "Google");
+
+        assertSearchSuggestion(
+                true,  // name
+                true,  // photo
+                false, // organization
+                true,  // phone
+                false, // email
+                "D",   // query
+                true,  // expect icon URI
+                null, "Deer Dough", "1-800-4664-411");
+
+        assertSearchSuggestion(
+                true,  // name
+                true,  // photo
+                false, // organization
+                false, // phone
+                true,  // email
+                "D",   // query
+                true,  // expect icon URI
+                String.valueOf(Presence.getPresenceIconResourceId(Presence.OFFLINE)),
+                "Deer Dough", "foo@acme.com");
+
+        assertSearchSuggestion(
+                true,  // name
+                false, // photo
+                true,  // organization
+                false, // phone
+                false, // email
+                "D",   // query
+                false, // expect icon URI
+                null, "Deer Dough", "Google");
+    }
+
+    private void assertSearchSuggestion(boolean name, boolean photo, boolean organization,
+            boolean phone, boolean email, String query, boolean expectIcon1Uri, String expectedIcon2,
+            String expectedText1, String expectedText2) throws IOException {
+        ContentValues values = new ContentValues();
+
+        if (name) {
+            values.put(People.NAME, "Deer Dough");
+        }
+
+        final Uri personUri = mResolver.insert(People.CONTENT_URI, values);
+        long personId = ContentUris.parseId(personUri);
+
+        People.addToMyContactsGroup(mResolver, personId);
+
+        if (photo) {
+            values.clear();
+            byte[] photoData = loadTestPhoto();
+            values.put(Photos.DATA, photoData);
+            values.put(Photos.LOCAL_VERSION, "1");
+            values.put(Photos.EXISTS_ON_SERVER, 0);
+            Uri photoUri = Uri.withAppendedPath(personUri, Photos.CONTENT_DIRECTORY);
+            mResolver.update(photoUri, values, null, null);
+        }
+
+        if (organization) {
+            values.clear();
+            values.put(Organizations.ISPRIMARY, 1);
+            values.put(Organizations.COMPANY, "Google");
+            values.put(Organizations.TYPE, Organizations.TYPE_WORK);
+            values.put(Organizations.PERSON_ID, personId);
+            mResolver.insert(Organizations.CONTENT_URI, values);
+        }
+
+        if (email) {
+            values.clear();
+            values.put(ContactMethods.PERSON_ID, personId);
+            values.put(ContactMethods.KIND, Contacts.KIND_EMAIL);
+            values.put(ContactMethods.TYPE, ContactMethods.TYPE_HOME);
+            values.put(ContactMethods.DATA, "foo@acme.com");
+            values.put(ContactMethods.ISPRIMARY, 1);
+            mResolver.insert(ContactMethods.CONTENT_URI, values);
+
+
+            String protocol = ContactMethods
+                    .encodePredefinedImProtocol(ContactMethods.PROTOCOL_GOOGLE_TALK);
+            values.clear();
+            values.put(Presence.IM_PROTOCOL, protocol);
+            values.put(Presence.IM_HANDLE, "foo@acme.com");
+            values.put(Presence.IM_ACCOUNT, "foo");
+            values.put(Presence.PRESENCE_STATUS, Presence.OFFLINE);
+            values.put(Presence.PRESENCE_CUSTOM_STATUS, "Coding for Android");
+            mResolver.insert(Presence.CONTENT_URI, values);
+        }
+
+        if (phone) {
+            values.clear();
+            values.put(Phones.PERSON_ID, personId);
+            values.put(Phones.TYPE, Phones.TYPE_HOME);
+            values.put(Phones.NUMBER, "1-800-4664-411");
+            values.put(Phones.ISPRIMARY, 1);
+            mResolver.insert(Phones.CONTENT_URI, values);
+        }
+
+        Uri searchUri = new Uri.Builder().scheme("content").authority(Contacts.AUTHORITY)
+                .appendPath(SearchManager.SUGGEST_URI_PATH_QUERY).appendPath(query).build();
+
+        Cursor c = mResolver.query(searchUri, null, null, null, null);
+        assertEquals(1, c.getCount());
+        c.moveToFirst();
+        values.clear();
+
+        String icon1 = c.getString(c.getColumnIndex(SearchManager.SUGGEST_COLUMN_ICON_1));
+        if (expectIcon1Uri) {
+            assertTrue(icon1.startsWith("content:"));
+        } else {
+            assertEquals(String.valueOf(com.android.internal.R.drawable.ic_contact_picture), icon1);
+        }
+
+        // SearchManager does not declare a constant for _id
+        values.put("_id", personId);
+        values.put(SearchManager.SUGGEST_COLUMN_ICON_2, expectedIcon2);
+        values.put(SearchManager.SUGGEST_COLUMN_INTENT_DATA_ID, personId);
+        values.put(SearchManager.SUGGEST_COLUMN_SHORTCUT_ID, personId);
+        values.put(SearchManager.SUGGEST_COLUMN_TEXT_1, expectedText1);
+        values.put(SearchManager.SUGGEST_COLUMN_TEXT_2, expectedText2);
+        assertCursorValues(c, values);
+        c.close();
+
+        // Cleanup
+        mResolver.delete(personUri, null, null);
+    }
+
+    /**
+     * Capturing the search suggestion requirements in test cases as a reference.
+     */
+    public void testSearchSuggestionsByPhoneNumber() throws Exception {
+
+        // We don't provide compatibility for search suggestions
+        if (!USE_LEGACY_PROVIDER) {
+            return;
+        }
+
+        ContentValues values = new ContentValues();
+
+        Uri searchUri = new Uri.Builder().scheme("content").authority(Contacts.AUTHORITY)
+                .appendPath(SearchManager.SUGGEST_URI_PATH_QUERY).appendPath("12345").build();
+
+        Cursor c = mResolver.query(searchUri, null, null, null, null);
+        assertEquals(2, c.getCount());
+        c.moveToFirst();
+
+        values.put(SearchManager.SUGGEST_COLUMN_TEXT_1, "Execute");
+        values.put(SearchManager.SUGGEST_COLUMN_TEXT_2, "");
+        values.put(SearchManager.SUGGEST_COLUMN_ICON_1,
+                String.valueOf(com.android.internal.R.drawable.call_contact));
+        values.put(SearchManager.SUGGEST_COLUMN_INTENT_ACTION,
+                Intents.SEARCH_SUGGESTION_DIAL_NUMBER_CLICKED);
+        values.put(SearchManager.SUGGEST_COLUMN_INTENT_DATA, "tel:12345");
+        values.putNull(SearchManager.SUGGEST_COLUMN_SHORTCUT_ID);
+        assertCursorValues(c, values);
+
+        c.moveToNext();
+        values.clear();
+        values.put(SearchManager.SUGGEST_COLUMN_TEXT_1, "Dial number");
+        values.put(SearchManager.SUGGEST_COLUMN_TEXT_2, "using 12345");
+        values.put(SearchManager.SUGGEST_COLUMN_ICON_1,
+                String.valueOf(com.android.internal.R.drawable.create_contact));
+        values.put(SearchManager.SUGGEST_COLUMN_INTENT_ACTION,
+                Intents.SEARCH_SUGGESTION_CREATE_CONTACT_CLICKED);
+        values.put(SearchManager.SUGGEST_COLUMN_INTENT_DATA, "tel:12345");
+        values.put(SearchManager.SUGGEST_COLUMN_SHORTCUT_ID,
+                SearchManager.SUGGEST_NEVER_MAKE_SHORTCUT);
+        assertCursorValues(c, values);
+        c.close();
+    }
+
+    private void putContactValues(ContentValues values) {
+        // Populating only unhidden columns
+        values.put(People.NAME, "Deer Dough");
+        values.put(People.PHONETIC_NAME, "Dear Doe");
+        values.put(People.NOTES, "Cash Cow");
+        values.put(People.TIMES_CONTACTED, 3);
+        values.put(People.LAST_TIME_CONTACTED, 10);
+        values.put(People.CUSTOM_RINGTONE, "ringtone");
+        values.put(People.SEND_TO_VOICEMAIL, 1);
+        values.put(People.STARRED, 1);
+    }
+
+    private void assertFilteredContacts(String filter, String... expectedNames) {
+        Uri filterUri = Uri.withAppendedPath(People.CONTENT_FILTER_URI, filter);
+        Cursor c = mResolver.query(filterUri, null, null, null, null);
+        try {
+            assertEquals("Record count", expectedNames.length, c.getCount());
+            int column = c.getColumnIndex(People.NAME);
+            for (int i = 0; i < expectedNames.length; i++) {
+                c.moveToNext();
+                assertEquals(expectedNames[i], c.getString(column));
+            }
+        } finally {
+            c.close();
+        }
+    }
+
+    private void assertPersonIdConstraint(Uri uri, String typeColumn, int defaultType) {
+        ContentValues values = new ContentValues();
+        values.put(typeColumn, defaultType);
+        try {
+            mResolver.insert(uri, values);
+            fail("Inserted row without person ID");
+        } catch (Exception e) {
+            // Exception expected
+        }
+    }
+
+    private void assertTypeAndLabelConstraints(Uri uri, String personIdColumn, long personId,
+            String typeColumn, int defaultType, int otherType, String labelColumn) {
+        ContentValues values = new ContentValues();
+        values.put(personIdColumn, personId);
+        values.put(typeColumn, defaultType);
+        try {
+            mResolver.insert(uri, values);
+            fail("Inserted row with custom type but without label");
+        } catch (Exception e) {
+            // Exception expected
+        }
+
+        values.clear();
+        values.put(personIdColumn, personId);
+        try {
+            mResolver.insert(uri, values);
+            fail("Inserted row without either type or label");
+        } catch (Exception e) {
+            // Exception expected
+        }
+
+        values.clear();
+        values.put(personIdColumn, personId);
+        values.put(typeColumn, otherType);
+        values.put(labelColumn, "Foo");
+        try {
+            mResolver.insert(uri, values);
+            fail("Inserted row with both type and label");
+        } catch (Exception e) {
+            // Exception expected
+        }
+    }
+
+    @Override
+    protected void assertSelection(Uri uri, ContentValues values, String idColumn, long id) {
+        if (USE_LEGACY_PROVIDER) {
+            // A bug in the legacy ContactsProvider prevents us from using the
+            // _id column in selection.
+            super.assertSelection(uri, values, null, 0);
+        } else {
+            super.assertSelection(uri, values, idColumn, id);
+        }
+    }
+}
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..1263fe7
--- /dev/null
+++ b/tests/src/com/android/providers/contacts/RestrictionExceptionsTest.java
@@ -0,0 +1,345 @@
+/*
+ * 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;
+import android.provider.ContactsContract.Contacts;
+import android.provider.ContactsContract.RawContacts;
+import android.provider.ContactsContract.Data;
+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,
+                SynchronousContactsProvider2.class, ContactsContract.AUTHORITY);
+        mRed = new ContactsActor(overallContext, PACKAGE_RED,
+                SynchronousContactsProvider2.class, ContactsContract.AUTHORITY);
+        mGreen = new ContactsActor(overallContext, PACKAGE_GREEN,
+                SynchronousContactsProvider2.class, ContactsContract.AUTHORITY);
+        mBlue = new ContactsActor(overallContext, PACKAGE_BLUE,
+                SynchronousContactsProvider2.class, ContactsContract.AUTHORITY);
+
+        // TODO make the provider wipe data automatically
+        ((SynchronousContactsProvider2)mGrey.provider).wipeData();
+    }
+
+    /**
+     * 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() {
+
+        // Grey creates an unprotected contact
+        long greyContact = mGrey.createContact(false);
+        long greyData = mGrey.createPhone(greyContact, PHONE_GREY);
+        long greyAgg = mGrey.getContactForRawContact(greyContact);
+
+        // Assert that both Grey and Blue can read contact
+        assertTrue("Owner of unrestricted contact unable to read",
+                (mGrey.getDataCountForContact(greyAgg) == 1));
+        assertTrue("Non-owner of unrestricted contact unable to read",
+                (mBlue.getDataCountForContact(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.getContactForRawContact(redContact);
+
+        // Assert that only Red can read contact
+        assertTrue("Owner of restricted contact unable to read",
+                (mRed.getDataCountForContact(redAgg) == 1));
+        assertTrue("Non-owner of restricted contact able to read",
+                (mBlue.getDataCountForContact(redAgg) == 0));
+        assertTrue("Non-owner of restricted contact able to read",
+                (mGreen.getDataCountForContact(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.getDataCountForContact(redAgg) == 1));
+        assertTrue("Non-owner with restriction exception unable to read",
+                (mBlue.getDataCountForContact(redAgg) == 1));
+        assertTrue("Non-owner of restricted contact able to read",
+                (mGreen.getDataCountForContact(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.getDataCountForContact(redAgg) == 1));
+        assertTrue("Non-owner of restricted contact able to read",
+                (mBlue.getDataCountForContact(redAgg) == 0));
+        assertTrue("Non-owner of restricted contact able to read",
+                (mGreen.getDataCountForContact(redAgg) == 0));
+
+    }
+
+    /**
+     * Create an aggregate that has multiple contacts with various levels of
+     * protected data, and ensure that {@link Contacts#CONTENT_SUMMARY_URI}
+     * details don't expose {@link Contacts#IS_RESTRICTED} data.
+     */
+    public void __testAggregateSummary() {
+
+        // 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.getContactForRawContact(redContact);
+            long blueAgg = mBlue.getContactForRawContact(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.getContactForRawContact(redContact);
+            long blueAgg = mBlue.getContactForRawContact(blueContact);
+            long greyAgg = mGrey.getContactForRawContact(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;
+
+        // 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.getContactForRawContact(greenContact);
+
+        // AGGREGATES
+        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) != greenAgg));
+        }
+        cursor.close();
+
+        // AGGREGATES_ID
+        cursor = mRed.resolver.query(ContentUris.withAppendedId(Contacts.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(
+                Contacts.CONTENT_URI, greenAgg), Contacts.Data.CONTENT_DIRECTORY),
+                Projections.PROJ_ID, null, null, null);
+        assertTrue("Discovered restricted contact", (cursor.getCount() == 0));
+        cursor.close();
+
+        // AGGREGATES_SUMMARY
+        cursor = mRed.resolver.query(Contacts.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(Contacts.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(RawContacts.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(RawContacts.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(
+                RawContacts.CONTENT_URI, greenContact), RawContacts.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();
+        }
+
+    }
+}
