diff --git a/Android.mk b/Android.mk
new file mode 100644
index 0000000..8b34359
--- /dev/null
+++ b/Android.mk
@@ -0,0 +1,13 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := user development
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+LOCAL_JAVA_LIBRARIES := ext
+
+LOCAL_PACKAGE_NAME := ContactsProvider
+LOCAL_CERTIFICATE := shared
+
+include $(BUILD_PACKAGE)
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
new file mode 100644
index 0000000..0194108
--- /dev/null
+++ b/AndroidManifest.xml
@@ -0,0 +1,23 @@
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+        package="com.android.providers.contacts"
+        android:sharedUserId="android.uid.shared">
+
+    <uses-permission android:name="android.permission.READ_CONTACTS" />
+    <uses-permission android:name="android.permission.WRITE_CONTACTS" />
+    <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="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" />
+    </application>
+</manifest>
diff --git a/MODULE_LICENSE_APACHE2 b/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/MODULE_LICENSE_APACHE2
diff --git a/NOTICE b/NOTICE
new file mode 100644
index 0000000..c5b1efa
--- /dev/null
+++ b/NOTICE
@@ -0,0 +1,190 @@
+
+   Copyright (c) 2005-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.
+
+   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.
+
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
diff --git a/res/drawable/app_icon.png b/res/drawable/app_icon.png
new file mode 100644
index 0000000..826656f
--- /dev/null
+++ b/res/drawable/app_icon.png
Binary files differ
diff --git a/res/values/strings.xml b/res/values/strings.xml
new file mode 100644
index 0000000..799a73c
--- /dev/null
+++ b/res/values/strings.xml
@@ -0,0 +1,26 @@
+<?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.
+-->
+
+<resources 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>
+
+    <!-- Strings for search suggestions -->
+    <string name="dialNumber">Dial number</string>
+    <string name="createNewContact">New contact</string>
+    <string name="usingNumber">Using <xliff:g id="number">%s</xliff:g></string>    
+</resources>
diff --git a/src/com/android/providers/contacts/ContactsProvider.java b/src/com/android/providers/contacts/ContactsProvider.java
new file mode 100644
index 0000000..209a98c
--- /dev/null
+++ b/src/com/android/providers/contacts/ContactsProvider.java
@@ -0,0 +1,4121 @@
+/*
+ * Copyright (C) 2006 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.AbstractSyncableContentProvider;
+import android.content.AbstractTableMerger;
+import android.content.ContentProvider;
+import android.content.ContentResolver;
+import android.content.ContentUris;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.content.UriMatcher;
+import android.database.Cursor;
+import android.database.CursorJoiner;
+import android.database.DatabaseUtils;
+import android.database.SQLException;
+import android.database.sqlite.SQLiteCursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteDoneException;
+import android.database.sqlite.SQLiteException;
+import android.database.sqlite.SQLiteQueryBuilder;
+import android.database.sqlite.SQLiteStatement;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.ParcelFileDescriptor;
+import android.provider.CallLog;
+import android.provider.CallLog.Calls;
+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.GroupsColumns;
+import android.provider.Contacts.Intents;
+import android.provider.Contacts.Organizations;
+import android.provider.Contacts.People;
+import android.provider.Contacts.PeopleColumns;
+import android.provider.Contacts.Phones;
+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.telephony.PhoneNumberUtils;
+import android.text.TextUtils;
+import android.util.Config;
+import android.util.Log;
+import com.android.internal.database.ArrayListCursor;
+import com.google.android.collect.Maps;
+import com.google.android.collect.Sets;
+
+import java.io.FileNotFoundException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+public class ContactsProvider extends AbstractSyncableContentProvider {
+    private static final String STREQUENT_ORDER_BY = "times_contacted DESC, display_name ASC";
+    private static final String STREQUENT_LIMIT =
+            "(SELECT COUNT(*) FROM people WHERE starred = 1) + 25";
+
+    private static final String PEOPLE_PHONES_JOIN =
+            "people LEFT OUTER JOIN phones ON people.primary_phone=phones._id "
+            + "LEFT OUTER JOIN presence ON (presence." + Presence.PERSON_ID + "=people._id)";
+
+    private static final String GTALK_PROTOCOL_STRING =
+            ContactMethods.encodePredefinedImProtocol(ContactMethods.PROTOCOL_GOOGLE_TALK);
+
+    private static final String[] ID_TYPE_PROJECTION = new String[]{"_id", "type"};
+
+    private static final String[] sIsPrimaryProjectionWithoutKind =
+            new String[]{"isprimary", "person", "_id"};
+    private static final String[] sIsPrimaryProjectionWithKind =
+            new String[]{"isprimary", "person", "_id", "kind"};
+
+    private static final String WHERE_ID = "_id=?";
+
+    private static final String sGroupsJoinString;
+
+    private static final String PREFS_NAME_OWNER = "owner-info";
+    private static final String PREF_OWNER_ID = "owner-id";
+
+    /** this is suitable for use by insert/update/delete/query and may be passed
+     * as a method call parameter. Only insert/update/delete/query should call .clear() on it */
+    private final ContentValues mValues = new ContentValues();
+
+    /** this is suitable for local use in methods and should never be passed as a parameter to
+     * other methods (other than the DB layer) */
+    private final ContentValues mValuesLocal = new ContentValues();
+
+    private String[] mAccounts = new String[0];
+    private final Object mAccountsLock = new Object();
+
+    private DatabaseUtils.InsertHelper mDeletedPeopleInserter;
+    private DatabaseUtils.InsertHelper mPeopleInserter;
+    private int mIndexPeopleSyncId;
+    private int mIndexPeopleSyncTime;
+    private int mIndexPeopleSyncVersion;
+    private int mIndexPeopleSyncDirty;
+    private int mIndexPeopleSyncAccount;
+    private int mIndexPeopleName;
+    private int mIndexPeoplePhoneticName;
+    private int mIndexPeopleNotes;
+    private DatabaseUtils.InsertHelper mGroupsInserter;
+    private DatabaseUtils.InsertHelper mPhotosInserter;
+    private int mIndexPhotosPersonId;
+    private int mIndexPhotosSyncId;
+    private int mIndexPhotosSyncTime;
+    private int mIndexPhotosSyncVersion;
+    private int mIndexPhotosSyncDirty;
+    private int mIndexPhotosSyncAccount;
+    private int mIndexPhotosExistsOnServer;
+    private int mIndexPhotosSyncError;
+    private DatabaseUtils.InsertHelper mContactMethodsInserter;
+    private int mIndexContactMethodsPersonId;
+    private int mIndexContactMethodsLabel;
+    private int mIndexContactMethodsKind;
+    private int mIndexContactMethodsType;
+    private int mIndexContactMethodsData;
+    private int mIndexContactMethodsAuxData;
+    private int mIndexContactMethodsIsPrimary;
+    private DatabaseUtils.InsertHelper mOrganizationsInserter;
+    private int mIndexOrganizationsPersonId;
+    private int mIndexOrganizationsLabel;
+    private int mIndexOrganizationsType;
+    private int mIndexOrganizationsCompany;
+    private int mIndexOrganizationsTitle;
+    private int mIndexOrganizationsIsPrimary;
+    private DatabaseUtils.InsertHelper mExtensionsInserter;
+    private int mIndexExtensionsPersonId;
+    private int mIndexExtensionsName;
+    private int mIndexExtensionsValue;
+    private DatabaseUtils.InsertHelper mGroupMembershipInserter;
+    private int mIndexGroupMembershipPersonId;
+    private int mIndexGroupMembershipGroupSyncAccount;
+    private int mIndexGroupMembershipGroupSyncId;
+    private DatabaseUtils.InsertHelper mCallsInserter;
+    private DatabaseUtils.InsertHelper mPhonesInserter;
+    private int mIndexPhonesPersonId;
+    private int mIndexPhonesLabel;
+    private int mIndexPhonesType;
+    private int mIndexPhonesNumber;
+    private int mIndexPhonesNumberKey;
+    private int mIndexPhonesIsPrimary;
+
+    public ContactsProvider() {
+        super(DATABASE_NAME, DATABASE_VERSION, Contacts.CONTENT_URI);
+    }
+
+    @Override
+    protected void onDatabaseOpened(SQLiteDatabase db) {
+        maybeCreatePresenceTable(db);
+
+        // Mark all the tables as syncable
+        db.markTableSyncable(sPeopleTable, sDeletedPeopleTable);
+        db.markTableSyncable(sPhonesTable, Phones.PERSON_ID, sPeopleTable);
+        db.markTableSyncable(sContactMethodsTable, ContactMethods.PERSON_ID, sPeopleTable);
+        db.markTableSyncable(sOrganizationsTable, Organizations.PERSON_ID, sPeopleTable);
+        db.markTableSyncable(sGroupmembershipTable, GroupMembership.PERSON_ID, sPeopleTable);
+        db.markTableSyncable(sExtensionsTable, Extensions.PERSON_ID, sPeopleTable);
+        db.markTableSyncable(sGroupsTable, sDeletedGroupsTable);
+
+        mDeletedPeopleInserter = new DatabaseUtils.InsertHelper(db, sDeletedPeopleTable);
+        mPeopleInserter = new DatabaseUtils.InsertHelper(db, sPeopleTable);
+        mIndexPeopleSyncId = mPeopleInserter.getColumnIndex(People._SYNC_ID);
+        mIndexPeopleSyncTime = mPeopleInserter.getColumnIndex(People._SYNC_TIME);
+        mIndexPeopleSyncVersion = mPeopleInserter.getColumnIndex(People._SYNC_VERSION);
+        mIndexPeopleSyncDirty = mPeopleInserter.getColumnIndex(People._SYNC_DIRTY);
+        mIndexPeopleSyncAccount = mPeopleInserter.getColumnIndex(People._SYNC_ACCOUNT);
+        mIndexPeopleName = mPeopleInserter.getColumnIndex(People.NAME);
+        mIndexPeoplePhoneticName = mPeopleInserter.getColumnIndex(People.PHONETIC_NAME);
+        mIndexPeopleNotes = mPeopleInserter.getColumnIndex(People.NOTES);
+
+        mGroupsInserter = new DatabaseUtils.InsertHelper(db, sGroupsTable);
+
+        mPhotosInserter = new DatabaseUtils.InsertHelper(db, sPhotosTable);
+        mIndexPhotosPersonId = mPhotosInserter.getColumnIndex(Photos.PERSON_ID);
+        mIndexPhotosSyncId = mPhotosInserter.getColumnIndex(Photos._SYNC_ID);
+        mIndexPhotosSyncTime = mPhotosInserter.getColumnIndex(Photos._SYNC_TIME);
+        mIndexPhotosSyncVersion = mPhotosInserter.getColumnIndex(Photos._SYNC_VERSION);
+        mIndexPhotosSyncDirty = mPhotosInserter.getColumnIndex(Photos._SYNC_DIRTY);
+        mIndexPhotosSyncAccount = mPhotosInserter.getColumnIndex(Photos._SYNC_ACCOUNT);
+        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);
+        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);
+
+        mOrganizationsInserter = new DatabaseUtils.InsertHelper(db, sOrganizationsTable);
+        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);
+
+        mExtensionsInserter = new DatabaseUtils.InsertHelper(db, sExtensionsTable);
+        mIndexExtensionsPersonId = mExtensionsInserter.getColumnIndex(Extensions.PERSON_ID);
+        mIndexExtensionsName = mExtensionsInserter.getColumnIndex(Extensions.NAME);
+        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);
+
+        mCallsInserter = new DatabaseUtils.InsertHelper(db, sCallsTable);
+
+        mPhonesInserter = new DatabaseUtils.InsertHelper(db, sPhonesTable);
+        mIndexPhonesPersonId = mPhonesInserter.getColumnIndex(Phones.PERSON_ID);
+        mIndexPhonesLabel = mPhonesInserter.getColumnIndex(Phones.LABEL);
+        mIndexPhonesType = mPhonesInserter.getColumnIndex(Phones.TYPE);
+        mIndexPhonesNumber = mPhonesInserter.getColumnIndex(Phones.NUMBER);
+        mIndexPhonesNumberKey = mPhonesInserter.getColumnIndex(Phones.NUMBER_KEY);
+        mIndexPhonesIsPrimary = mPhonesInserter.getColumnIndex(Phones.ISPRIMARY);
+    }
+
+    @Override
+    protected boolean upgradeDatabase(SQLiteDatabase db, int oldVersion, int newVersion) {
+        boolean upgradeWasLossless = true;
+        if (oldVersion < 71) {
+            Log.w(TAG, "Upgrading database from version " + oldVersion + " to " +
+                    newVersion + ", which will destroy all old data");
+            dropTables(db);
+            bootstrapDatabase(db);
+            return false; // this was lossy
+        }
+        if (oldVersion == 71) {
+            Log.i(TAG, "Upgrading contacts database from version " + oldVersion + " to " +
+                    newVersion + ", which will preserve existing data");
+
+            db.delete("_sync_state", null, null);
+            mValuesLocal.clear();
+            mValuesLocal.putNull(Photos._SYNC_VERSION);
+            mValuesLocal.putNull(Photos._SYNC_TIME);
+            db.update(sPhotosTable, mValuesLocal, null, null);
+            getContext().getContentResolver().startSync(Contacts.CONTENT_URI, new Bundle());
+            oldVersion = 72;
+        }
+        if (oldVersion == 72) {
+            Log.i(TAG, "Upgrading contacts database from version " + oldVersion + " to " +
+                    newVersion + ", which will preserve existing data");
+
+            // use new token format from 73
+            db.execSQL("delete from peopleLookup");
+            try {
+                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
+            }
+            oldVersion = 73;
+        }
+        // There was a bug for a while in the upgrade logic where going from 72 to 74 would skip
+        // the step from 73 to 74, so 74 to 75 just tries the same steps, and gracefully handles
+        // errors in case the device was started freshly at 74.
+        if (oldVersion == 73 || oldVersion == 74) {
+            Log.i(TAG, "Upgrading contacts database from version " + oldVersion + " to " +
+                    newVersion + ", which will preserve existing data");
+
+            try {
+                db.execSQL("ALTER TABLE calls ADD name TEXT;");
+                db.execSQL("ALTER TABLE calls ADD numbertype INTEGER;");
+                db.execSQL("ALTER TABLE calls ADD numberlabel TEXT;");
+            } catch (SQLiteException sqle) {
+                // Maybe the table was altered already... Shouldn't be an issue.
+            }
+            oldVersion = 75;
+        }
+        // There were some indices added in version 76
+        if (oldVersion == 75) {
+            Log.i(TAG, "Upgrading contacts database from version " + oldVersion + " to " +
+                    newVersion + ", which will preserve existing data");
+
+            // add the new indices
+            db.execSQL("CREATE INDEX IF NOT EXISTS groupsSyncDirtyIndex"
+                    + " ON groups (" + Groups._SYNC_DIRTY + ");");
+            db.execSQL("CREATE INDEX IF NOT EXISTS photosSyncDirtyIndex"
+                    + " ON photos (" + Photos._SYNC_DIRTY + ");");
+            db.execSQL("CREATE INDEX IF NOT EXISTS peopleSyncDirtyIndex"
+                    + " ON people (" + People._SYNC_DIRTY + ");");
+            oldVersion = 76;
+        }
+
+        if (oldVersion == 76 || oldVersion == 77) {
+            db.execSQL("DELETE FROM people");
+            db.execSQL("DELETE FROM groups");
+            db.execSQL("DELETE FROM photos");
+            db.execSQL("DELETE FROM _deleted_people");
+            db.execSQL("DELETE FROM _deleted_groups");
+            upgradeWasLossless = false;
+            oldVersion = 78;
+        }
+
+        if (oldVersion == 78) {
+            db.execSQL("UPDATE photos SET _sync_dirty=0 where _sync_dirty is null;");
+            oldVersion = 79;
+        }
+
+        if (oldVersion == 79) {
+            try {
+                db.execSQL("ALTER TABLE people ADD phonetic_name TEXT COLLATE LOCALIZED;");
+            } catch (SQLiteException sqle) {
+                // Maybe the table was altered already... Shouldn't be an issue.
+            }
+            oldVersion = 80;
+        }
+
+        return upgradeWasLossless;
+    }
+
+    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 _deleted_people");
+        db.execSQL("DROP TABLE IF EXISTS phones");
+        db.execSQL("DROP TABLE IF EXISTS contact_methods");
+        db.execSQL("DROP TABLE IF EXISTS calls");
+        db.execSQL("DROP TABLE IF EXISTS organizations");
+        db.execSQL("DROP TABLE IF EXISTS voice_dialer_timestamp");
+        db.execSQL("DROP TABLE IF EXISTS groups");
+        db.execSQL("DROP TABLE IF EXISTS _deleted_groups");
+        db.execSQL("DROP TABLE IF EXISTS groupmembership");
+        db.execSQL("DROP TABLE IF EXISTS photos");
+        db.execSQL("DROP TABLE IF EXISTS extensions");
+        db.execSQL("DROP TABLE IF EXISTS settings");
+    }
+
+    @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_ID + " TEXT," + // From the sync source
+                    People._SYNC_TIME + " TEXT," + // From the sync source
+                    People._SYNC_VERSION + " TEXT," + // From the sync source
+                    People._SYNC_LOCAL_ID + " INTEGER," + // Used while syncing, not persistent
+                    People._SYNC_DIRTY + " INTEGER NOT NULL DEFAULT 0," +
+                                                       // if syncable, non-zero if the record
+                                                       // has local, unsynced, changes
+                    People._SYNC_MARK + " INTEGER," + // Used to filter out new rows
+
+                    People.NAME + " TEXT COLLATE LOCALIZED," +
+                    People.NOTES + " TEXT COLLATE LOCALIZED," +
+                    People.TIMES_CONTACTED + " INTEGER NOT NULL DEFAULT 0," +
+                    People.LAST_TIME_CONTACTED + " INTEGER," +
+                    People.STARRED + " INTEGER NOT NULL DEFAULT 0," +
+                    People.PRIMARY_PHONE_ID + " INTEGER REFERENCES phones(_id)," +
+                    People.PRIMARY_ORGANIZATION_ID + " INTEGER REFERENCES organizations(_id)," +
+                    People.PRIMARY_EMAIL_ID + " INTEGER REFERENCES contact_methods(_id)," +
+                    People.PHOTO_VERSION + " TEXT," +
+                    People.CUSTOM_RINGTONE + " TEXT," +
+                    People.SEND_TO_VOICEMAIL + " INTEGER," +
+                    People.PHONETIC_NAME + " TEXT COLLATE LOCALIZED" +
+                    ");");
+
+        db.execSQL("CREATE INDEX peopleNameIndex ON people (" + People.NAME + ");");
+        db.execSQL("CREATE INDEX peopleSyncDirtyIndex ON people (" + People._SYNC_DIRTY + ");");
+        db.execSQL("CREATE INDEX peopleSyncIdIndex ON people (" + People._SYNC_ID + ");");
+        
+        db.execSQL("CREATE TRIGGER people_timesContacted UPDATE OF last_time_contacted ON people " +
+                    "BEGIN " +
+                        "UPDATE people SET "
+                            + People.TIMES_CONTACTED + " = (new." + People.TIMES_CONTACTED + " + 1)"
+                            + " WHERE _id = new._id;" +
+                    "END");
+
+        // table of all the groups that exist for an account
+        db.execSQL("CREATE TABLE groups (" +
+                Groups._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
+                Groups._SYNC_ACCOUNT + " 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
+                Groups._SYNC_LOCAL_ID + " INTEGER," + // Used while syncing, not persistent
+                Groups._SYNC_DIRTY + " INTEGER NOT NULL DEFAULT 0," +
+                                                          // if syncable, non-zero if the record
+                                                          // has local, unsynced, changes
+                Groups._SYNC_MARK + " INTEGER," + // Used to filter out new rows
+
+                Groups.NAME + " TEXT NOT NULL," +
+                Groups.NOTES + " TEXT," +
+                Groups.SHOULD_SYNC + " INTEGER NOT NULL DEFAULT 0," +
+                Groups.SYSTEM_ID + " TEXT," +
+                "UNIQUE(" +
+                Groups.NAME + ","  + Groups.SYSTEM_ID + "," + Groups._SYNC_ACCOUNT + ")" +
+                ");");
+
+        db.execSQL("CREATE INDEX groupsSyncDirtyIndex ON groups (" + Groups._SYNC_DIRTY + ");");
+
+        if (!isTemporary()) {
+            // Add the system groups, since we always need them.
+            db.execSQL("INSERT INTO groups (" + Groups.NAME + ", " + Groups.SYSTEM_ID + ") VALUES "
+                    + "('" + Groups.GROUP_MY_CONTACTS + "', '" + Groups.GROUP_MY_CONTACTS + "')");
+        }
+
+        db.execSQL("CREATE TABLE peopleLookup (" +
+                    "token TEXT," +
+                    "source INTEGER REFERENCES people(_id)" +
+                    ");");
+        db.execSQL("CREATE INDEX peopleLookupIndex ON peopleLookup (" +
+                    "token," +
+                    "source" +
+                    ");");
+
+        db.execSQL("CREATE TABLE photos ("
+                + Photos._ID + " INTEGER PRIMARY KEY AUTOINCREMENT,"
+                + Photos.EXISTS_ON_SERVER + " INTEGER NOT NULL DEFAULT 0,"
+                + Photos.PERSON_ID + " INTEGER REFERENCES people(_id), "
+                + Photos.LOCAL_VERSION + " TEXT,"
+                + Photos.DATA + " BLOB,"
+                + Photos.SYNC_ERROR + " TEXT,"
+                + Photos._SYNC_ACCOUNT + " TEXT,"
+                + Photos._SYNC_ID + " TEXT,"
+                + Photos._SYNC_TIME + " TEXT,"
+                + Photos._SYNC_VERSION + " TEXT,"
+                + Photos._SYNC_LOCAL_ID + " INTEGER,"
+                + Photos._SYNC_DIRTY + " INTEGER NOT NULL DEFAULT 0,"
+                + Photos._SYNC_MARK + " INTEGER,"
+                + "UNIQUE(" + Photos.PERSON_ID + ") "
+                + ")");
+
+        db.execSQL("CREATE INDEX photosSyncDirtyIndex ON photos (" + Photos._SYNC_DIRTY + ");");
+        db.execSQL("CREATE INDEX photoPersonIndex ON photos (person);");
+
+        // Delete the photo row when the people row is deleted
+        db.execSQL(""
+                + " CREATE TRIGGER peopleDeleteAndPhotos DELETE ON people "
+                + " BEGIN"
+                + "   DELETE FROM photos WHERE person=OLD._id;"
+                + " END");
+
+        db.execSQL("CREATE TABLE _deleted_people (" +
+                    "_sync_version TEXT," + // From the sync source
+                    "_sync_id TEXT," +
+                    (isTemporary() ? "_sync_local_id INTEGER," : "") + // Used while syncing,
+                    "_sync_account TEXT," +
+                    "_sync_mark INTEGER)"); // Used to filter out new rows
+
+        db.execSQL("CREATE TABLE _deleted_groups (" +
+                    "_sync_version TEXT," + // From the sync source
+                    "_sync_id TEXT," +
+                    (isTemporary() ? "_sync_local_id INTEGER," : "") + // Used while syncing,
+                    "_sync_account TEXT," +
+                    "_sync_mark INTEGER)"); // Used to filter out new rows
+
+        db.execSQL("CREATE TABLE phones (" +
+                    "_id INTEGER PRIMARY KEY AUTOINCREMENT," +
+                    "person INTEGER REFERENCES people(_id)," +
+                    "type INTEGER NOT NULL," + // kind specific (home, work, etc)
+                    "number TEXT," +
+                    "number_key TEXT," +
+                    "label TEXT," +
+                    "isprimary INTEGER NOT NULL DEFAULT 0" +
+                    ");");
+        db.execSQL("CREATE INDEX phonesIndex1 ON phones (person);");
+        db.execSQL("CREATE INDEX phonesIndex2 ON phones (number_key);");
+
+        db.execSQL("CREATE TABLE contact_methods (" +
+                    "_id INTEGER PRIMARY KEY AUTOINCREMENT," +
+                    "person INTEGER REFERENCES people(_id)," +
+                    "kind INTEGER NOT NULL," + // the kind of contact method
+                    "data TEXT," +
+                    "aux_data TEXT," +
+                    "type INTEGER NOT NULL," + // kind specific (home, work, etc)
+                    "label TEXT," +
+                    "isprimary INTEGER NOT NULL DEFAULT 0" +
+                    ");");
+        db.execSQL("CREATE INDEX contactMethodsPeopleIndex "
+                + "ON contact_methods (person);");
+
+        // 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 calls (" +
+                    "_id INTEGER PRIMARY KEY AUTOINCREMENT," +
+                    "number TEXT," +
+                    "date INTEGER," +
+                    "duration INTEGER," +
+                    "type INTEGER," +
+                    "new INTEGER," +
+                    "name TEXT," +
+                    "numbertype INTEGER," +
+                    "numberlabel TEXT" +
+                    ");");
+
+        // Various settings for the contacts sync adapter. The _sync_account column may
+        // be null, but it must not be the empty string.
+        db.execSQL("CREATE TABLE settings (" +
+                    "_id INTEGER PRIMARY KEY," +
+                    "_sync_account TEXT," +
+                    "key STRING NOT NULL," +
+                    "value STRING " +
+                    ");");
+
+        // The table for the organizations of a person.
+        db.execSQL("CREATE TABLE organizations (" +
+                    "_id INTEGER PRIMARY KEY AUTOINCREMENT," +
+                    "company TEXT," +
+                    "title TEXT," +
+                    "isprimary INTEGER NOT NULL DEFAULT 0," +
+                    "type INTEGER NOT NULL," + // kind specific (home, work, etc)
+                    "label TEXT," +
+                    "person INTEGER REFERENCES people(_id)" +
+                    ");");
+        db.execSQL("CREATE INDEX organizationsIndex1 ON organizations (person);");
+
+        // The table for the extensions of a person.
+        db.execSQL("CREATE TABLE extensions (" +
+                    "_id INTEGER PRIMARY KEY AUTOINCREMENT," +
+                    "name TEXT NOT NULL," +
+                    "value TEXT NOT NULL," +
+                    "person INTEGER REFERENCES people(_id)," +
+                    "UNIQUE(person, name)" +
+                    ");");
+        db.execSQL("CREATE INDEX extensionsIndex1 ON extensions (person, name);");
+
+        // The table for the groups of a person.
+        db.execSQL("CREATE TABLE groupmembership (" +
+                "_id INTEGER PRIMARY KEY," +
+                "person INTEGER REFERENCES people(_id)," +
+                "group_id INTEGER REFERENCES groups(_id)," +
+                "group_sync_account 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);");
+
+        // 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 phones WHERE person = old._id;" +
+                        "DELETE FROM contact_methods WHERE person = old._id;" +
+                        "DELETE FROM organizations WHERE person = old._id;" +
+                        "DELETE FROM groupmembership WHERE person = old._id;" +
+                        "DELETE FROM extensions WHERE person = old._id;" +
+                    "END");
+
+        // Trigger to disassociate the groupmembership from the groups when an
+        // groups entry is deleted
+        db.execSQL("CREATE TRIGGER groups_cleanup DELETE ON groups " +
+                    "BEGIN " +
+                        "UPDATE groupmembership SET group_id = null WHERE group_id = old._id;" +
+                    "END");
+
+        // Trigger to move an account_people row to _deleted_account_people when it is 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_version) " +
+                            "VALUES (old._sync_id, old._sync_account, " +
+                            "old._sync_version);" +
+                    "END");
+
+        // 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, ' ');" +
+                    "END");
+        db.execSQL("CREATE TRIGGER peopleLookup_insert AFTER INSERT ON people " +
+                    "BEGIN " +
+                        "SELECT _TOKENIZE('peopleLookup', new._id, new.name, ' ');" +
+                    "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 " +
+                    "BEGIN " +
+                        "UPDATE people SET _sync_dirty=1 WHERE people._id=old.person;" +
+                    "END");
+        db.execSQL("CREATE TRIGGER phones_insert INSERT ON phones " +
+                    "BEGIN " +
+                        "UPDATE people SET _sync_dirty=1 WHERE people._id=new.person;" +
+                    "END");
+        db.execSQL("CREATE TRIGGER phones_delete DELETE ON phones " +
+                    "BEGIN " +
+                        "UPDATE people SET _sync_dirty=1 WHERE people._id=old.person;" +
+                    "END");
+
+        // Triggers to set the _sync_dirty flag when a contact_method is
+        // changed, inserted or deleted
+        db.execSQL("CREATE TRIGGER contact_methods_update UPDATE ON contact_methods " +
+                    "BEGIN " +
+                        "UPDATE people SET _sync_dirty=1 WHERE people._id=old.person;" +
+                    "END");
+        db.execSQL("CREATE TRIGGER contact_methods_insert INSERT ON contact_methods " +
+                    "BEGIN " +
+                        "UPDATE people SET _sync_dirty=1 WHERE people._id=new.person;" +
+                    "END");
+        db.execSQL("CREATE TRIGGER contact_methods_delete DELETE ON contact_methods " +
+                    "BEGIN " +
+                        "UPDATE people SET _sync_dirty=1 WHERE people._id=old.person;" +
+                    "END");
+
+        // Triggers for when an organization is changed, inserted or deleted
+        db.execSQL("CREATE TRIGGER organizations_update AFTER UPDATE ON organizations " +
+                    "BEGIN " +
+                        "UPDATE people SET _sync_dirty=1 WHERE people._id=old.person; " +
+                    "END");
+        db.execSQL("CREATE TRIGGER organizations_insert INSERT ON organizations " +
+                    "BEGIN " +
+                        "UPDATE people SET _sync_dirty=1 WHERE people._id=new.person; " +
+                    "END");
+        db.execSQL("CREATE TRIGGER organizations_delete DELETE ON organizations " +
+                    "BEGIN " +
+                        "UPDATE people SET _sync_dirty=1 WHERE people._id=old.person;" +
+                    "END");
+
+        // Triggers for when an groupmembership is changed, inserted or deleted
+        db.execSQL("CREATE TRIGGER groupmembership_update AFTER UPDATE ON groupmembership " +
+                    "BEGIN " +
+                        "UPDATE people SET _sync_dirty=1 WHERE people._id=old.person; " +
+                    "END");
+        db.execSQL("CREATE TRIGGER groupmembership_insert INSERT ON groupmembership " +
+                    "BEGIN " +
+                        "UPDATE people SET _sync_dirty=1 WHERE people._id=new.person; " +
+                    "END");
+        db.execSQL("CREATE TRIGGER groupmembership_delete DELETE ON groupmembership " +
+                    "BEGIN " +
+                        "UPDATE people SET _sync_dirty=1 WHERE people._id=old.person;" +
+                    "END");
+
+        // Triggers for when an extension is changed, inserted or deleted
+        db.execSQL("CREATE TRIGGER extensions_update AFTER UPDATE ON extensions " +
+                    "BEGIN " +
+                        "UPDATE people SET _sync_dirty=1 WHERE people._id=old.person; " +
+                    "END");
+        db.execSQL("CREATE TRIGGER extensions_insert INSERT ON extensions " +
+                    "BEGIN " +
+                        "UPDATE people SET _sync_dirty=1 WHERE people._id=new.person; " +
+                    "END");
+        db.execSQL("CREATE TRIGGER extensions_delete DELETE ON extensions " +
+                    "BEGIN " +
+                        "UPDATE people SET _sync_dirty=1 WHERE people._id=old.person;" +
+                    "END");
+
+        createTypeLabelTrigger(db, sPhonesTable, "INSERT");
+        createTypeLabelTrigger(db, sPhonesTable, "UPDATE");
+        createTypeLabelTrigger(db, sOrganizationsTable, "INSERT");
+        createTypeLabelTrigger(db, sOrganizationsTable, "UPDATE");
+        createTypeLabelTrigger(db, sContactMethodsTable, "INSERT");
+        createTypeLabelTrigger(db, sContactMethodsTable, "UPDATE");
+
+        // Temporary table that holds a time stamp of the last time data the voice
+        // dialer is interested in has changed so the grammar won't need to be
+        // recompiled when unused data is changed.
+        db.execSQL("CREATE TABLE voice_dialer_timestamp (" +
+                   "_id INTEGER PRIMARY KEY," +
+                   "timestamp INTEGER" +
+                   ");");
+        db.execSQL("INSERT INTO voice_dialer_timestamp (_id, timestamp) VALUES " +
+                       "(1, strftime('%s', 'now'));");
+        db.execSQL("CREATE TRIGGER timestamp_trigger1 AFTER UPDATE ON phones " +
+                   "BEGIN " +
+                       "UPDATE voice_dialer_timestamp SET timestamp=strftime('%s', 'now') "+
+                           "WHERE _id=1;" +
+                   "END");
+        db.execSQL("CREATE TRIGGER timestamp_trigger2 AFTER UPDATE OF name ON people " +
+                   "BEGIN " +
+                       "UPDATE voice_dialer_timestamp SET timestamp=strftime('%s', 'now') " +
+                           "WHERE _id=1;" +
+                   "END");
+    }
+
+    private void createTypeLabelTrigger(SQLiteDatabase db, String table, String operation) {
+        final String name = table + "_" + operation + "_typeAndLabel";
+        db.execSQL("CREATE TRIGGER " + name + " AFTER " + operation + " ON " + table
+                + "   WHEN (NEW.type != 0 AND NEW.label IS NOT NULL) OR "
+                + "        (NEW.type = 0 AND NEW.label IS NULL)"
+                + "   BEGIN "
+                + "     SELECT RAISE (ABORT, 'exactly one of type or label must be set'); "
+                + "   END");
+    }
+
+    private void maybeCreatePresenceTable(SQLiteDatabase db) {
+        // Load the presence table from the presence_db. Just create the table
+        // if we are
+        String cpDbName;
+        if (!isTemporary()) {
+            db.execSQL("ATTACH DATABASE ':memory:' AS presence_db;");
+            cpDbName = "presence_db.";
+        } else {
+            cpDbName = "";
+        }
+        db.execSQL("CREATE TABLE IF NOT EXISTS " + cpDbName + "presence ("+
+                    Presence._ID + " INTEGER PRIMARY KEY," +
+                    Presence.PERSON_ID + " INTEGER REFERENCES people(_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 " + cpDbName + "presenceIndex ON presence ("
+                + Presence.PERSON_ID + ");");
+    }
+
+    @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.
+        DatabaseUtils.appendEscapedSQLString(filter, 
+                DatabaseUtils.getHexCollationKey(filterParam) + "*");
+        filter.append(')');
+        return filter.toString();
+    }
+
+    @Override
+    public Cursor queryInternal(Uri url, String[] projectionIn,
+            String selection, String[] selectionArgs, String sort) {
+
+        SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
+        Uri notificationUri = Contacts.CONTENT_URI;
+
+        // Generate the body of the query
+        int match = sURIMatcher.match(url);
+
+        if (Config.LOGV) Log.v(TAG, "ContactsProvider.query: url=" + url + ", match is " + match);
+
+        switch (match) {
+            case DELETED_GROUPS:
+                if (!isTemporary()) {
+                    throw new UnsupportedOperationException();
+                }
+
+                qb.setTables(sDeletedGroupsTable);
+                break;
+
+            case GROUPS_ID:
+                qb.appendWhere("_id=");
+                qb.appendWhere(url.getPathSegments().get(1));
+                // fall through
+            case GROUPS:
+                qb.setTables(sGroupsTable);
+                qb.setProjectionMap(sGroupsProjectionMap);
+                break;
+
+            case SETTINGS:
+                qb.setTables(sSettingsTable);
+                break;
+
+            case PEOPLE_GROUPMEMBERSHIP_ID:
+                qb.appendWhere("groupmembership._id=");
+                qb.appendWhere(url.getPathSegments().get(3));
+                qb.appendWhere(" AND ");
+                // fall through
+            case PEOPLE_GROUPMEMBERSHIP:
+                qb.appendWhere(sGroupsJoinString + " AND ");
+                qb.appendWhere("person=" + url.getPathSegments().get(1));
+                qb.setTables("groups, groupmembership");
+                qb.setProjectionMap(sGroupMembershipProjectionMap);
+                break;
+
+            case GROUPMEMBERSHIP_ID:
+                qb.appendWhere("groupmembership._id=");
+                qb.appendWhere(url.getPathSegments().get(1));
+                qb.appendWhere(" AND ");
+                // fall through
+            case GROUPMEMBERSHIP:
+                qb.setTables("groups, groupmembership");
+                qb.setProjectionMap(sGroupMembershipProjectionMap);
+                qb.appendWhere(sGroupsJoinString);
+                break;
+
+            case GROUPMEMBERSHIP_RAW:
+                qb.setTables("groupmembership");
+                break;
+
+            case GROUP_NAME_MEMBERS_FILTER:
+                if (url.getPathSegments().size() > 5) {
+                    qb.appendWhere(buildPeopleLookupWhereClause(url.getLastPathSegment()));
+                    qb.appendWhere(" AND ");
+                }
+                // fall through
+            case GROUP_NAME_MEMBERS:
+                qb.setTables(PEOPLE_PHONES_JOIN);
+                qb.setProjectionMap(sPeopleProjectionMap);
+                qb.appendWhere("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)) "+
+                        "WHERE " + Groups.NAME + "="
+                        + DatabaseUtils.sqlEscapeString(url.getPathSegments().get(2)) + ")");
+                break;
+                
+            case GROUP_SYSTEM_ID_MEMBERS_FILTER:
+                if (url.getPathSegments().size() > 5) {
+                    qb.appendWhere(buildPeopleLookupWhereClause(url.getLastPathSegment()));
+                    qb.appendWhere(" AND ");
+                }
+                // fall through
+            case GROUP_SYSTEM_ID_MEMBERS:
+                qb.setTables(PEOPLE_PHONES_JOIN);
+                qb.setProjectionMap(sPeopleProjectionMap);
+                qb.appendWhere("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)) "+
+                        "WHERE " + Groups.SYSTEM_ID + "="
+                        + DatabaseUtils.sqlEscapeString(url.getPathSegments().get(2)) + ")");
+                break;
+
+            case PEOPLE:
+                qb.setTables(PEOPLE_PHONES_JOIN);
+                qb.setProjectionMap(sPeopleProjectionMap);
+                break;
+            case PEOPLE_RAW:
+                qb.setTables(sPeopleTable);
+                break;
+
+            case PEOPLE_OWNER:
+                return queryOwner(projectionIn);
+
+            case PEOPLE_WITH_PHONES_FILTER:
+
+                qb.appendWhere("number IS NOT NULL AND ");
+
+                // Fall through.
+
+            case PEOPLE_FILTER: {
+                qb.setTables(PEOPLE_PHONES_JOIN);
+                qb.setProjectionMap(sPeopleProjectionMap);
+                if (url.getPathSegments().size() > 2) {
+                    qb.appendWhere(buildPeopleLookupWhereClause(url.getLastPathSegment()));
+                }
+                break;
+            }
+
+            case PHOTOS_ID:
+                qb.appendWhere("_id="+url.getPathSegments().get(1));
+                // Fall through.
+            case PHOTOS:
+                qb.setTables(sPhotosTable);
+                qb.setProjectionMap(sPhotosProjectionMap);
+                break;
+
+            case PEOPLE_PHOTO:
+                qb.appendWhere("person="+url.getPathSegments().get(1));
+                qb.setTables(sPhotosTable);
+                qb.setProjectionMap(sPhotosProjectionMap);
+                break;
+
+            case SEARCH_SUGGESTIONS: {
+                // Force the default sort order, since the SearchManage doesn't ask for things
+                // sorted, though they should be
+                if (sort != null && !People.DEFAULT_SORT_ORDER.equals(sort)) {
+                    throw new IllegalArgumentException("Sort ordering not allowed for this URI");
+                }
+                sort = SearchManager.SUGGEST_COLUMN_TEXT_1 + " COLLATE LOCALIZED ASC";
+
+                // This will either setup the query builder so we can run the proper query below
+                // and return null, or it will return a cursor with the results already in it.
+                Cursor c = handleSearchSuggestionsQuery(url, qb);
+                if (c != null) {
+                    return c;
+                }
+                break;
+            }
+            case PEOPLE_STREQUENT: {
+                // Build the first query for starred
+                qb.setTables(PEOPLE_PHONES_JOIN);
+                qb.setProjectionMap(sPeopleWithMaxTimesContactedProjectionMap);
+                final String starredQuery = qb.buildQuery(projectionIn, "starred = 1",
+                        null, null, null, null,
+                        null /* limit */);
+
+                qb = new SQLiteQueryBuilder();
+                qb.setTables(PEOPLE_PHONES_JOIN);
+                qb.setProjectionMap(sPeopleProjectionMap);
+                final String frequentQuery = qb.buildQuery(projectionIn,
+                        "times_contacted > 0 AND starred = 0", null, null, null, null, null);
+
+                final String query = qb.buildUnionQuery(new String[] {starredQuery, frequentQuery},
+                        STREQUENT_ORDER_BY, STREQUENT_LIMIT);
+                final SQLiteDatabase db = getDatabase();
+                Cursor c = db.rawQueryWithFactory(null, query, null, "people");
+                if ((c != null) && !isTemporary()) {
+                    c.setNotificationUri(getContext().getContentResolver(), url);
+                }
+                return c;
+            }
+            case PEOPLE_STREQUENT_FILTER: {
+                // Build the first query for starred
+                qb.setTables(PEOPLE_PHONES_JOIN);
+                qb.setProjectionMap(sPeopleWithMaxTimesContactedProjectionMap);
+                if (url.getPathSegments().size() > 3) {
+                    qb.appendWhere(buildPeopleLookupWhereClause(url.getLastPathSegment()));
+                }
+                qb.appendWhere(" AND starred = 1");
+                final String starredQuery = qb.buildQuery(projectionIn, null, null, null, null,
+                        null, null);
+
+                qb = new SQLiteQueryBuilder();
+                qb.setTables(PEOPLE_PHONES_JOIN);
+                qb.setProjectionMap(sPeopleProjectionMap);
+                if (url.getPathSegments().size() > 3) {
+                    qb.appendWhere(buildPeopleLookupWhereClause(url.getLastPathSegment()));
+                }
+                qb.appendWhere(" AND times_contacted > 0 AND starred = 0");
+                final String frequentQuery = qb.buildQuery(projectionIn, null, null, null, null,
+                        null, null);
+
+                final String query = qb.buildUnionQuery(new String[] {starredQuery, frequentQuery},
+                        STREQUENT_ORDER_BY, null);
+                final SQLiteDatabase db = getDatabase();
+                Cursor c = db.rawQueryWithFactory(null, query, null, sPeopleTable);
+                if ((c != null) && !isTemporary()) {
+                    c.setNotificationUri(getContext().getContentResolver(), url);
+                }
+                return c;
+            }
+            case DELETED_PEOPLE:
+                if (isTemporary()) {
+                    qb.setTables("_deleted_people");
+                    break;
+                }
+                throw new UnsupportedOperationException();
+            case PEOPLE_ID:
+                qb.setTables("people LEFT OUTER JOIN phones ON people.primary_phone=phones._id "
+                        + "LEFT OUTER JOIN presence ON (presence." + Presence.PERSON_ID
+                        + "=people._id)");
+                qb.setProjectionMap(sPeopleProjectionMap);
+                qb.appendWhere("people._id=");
+                qb.appendWhere(url.getPathSegments().get(1));
+                break;
+            case PEOPLE_PHONES:
+                qb.setTables("phones, people");
+                qb.setProjectionMap(sPhonesProjectionMap);
+                qb.appendWhere("people._id = phones.person AND person=");
+                qb.appendWhere(url.getPathSegments().get(1));
+                break;
+            case PEOPLE_PHONES_ID:
+                qb.setTables("phones, people");
+                qb.setProjectionMap(sPhonesProjectionMap);
+                qb.appendWhere("people._id = phones.person AND person=");
+                qb.appendWhere(url.getPathSegments().get(1));
+                qb.appendWhere(" AND phones._id=");
+                qb.appendWhere(url.getPathSegments().get(3));
+                break;
+
+            case PEOPLE_PHONES_WITH_PRESENCE:
+                qb.appendWhere("people._id=?");
+                selectionArgs = appendSelectionArg(selectionArgs, url.getPathSegments().get(1));
+                // Fall through.
+
+            case PHONES_WITH_PRESENCE:
+                qb.setTables("phones JOIN people ON (phones.person = people._id)"
+                        + " LEFT OUTER JOIN presence ON (presence.person = people._id)");
+                qb.setProjectionMap(sPhonesWithPresenceProjectionMap);
+                break;
+
+            case PEOPLE_CONTACTMETHODS:
+                qb.setTables("contact_methods, people");
+                qb.setProjectionMap(sContactMethodsProjectionMap);
+                qb.appendWhere("people._id = contact_methods.person AND person=");
+                qb.appendWhere(url.getPathSegments().get(1));
+                break;
+            case PEOPLE_CONTACTMETHODS_ID:
+                qb.setTables("contact_methods, people");
+                qb.setProjectionMap(sContactMethodsProjectionMap);
+                qb.appendWhere("people._id = contact_methods.person AND person=");
+                qb.appendWhere(url.getPathSegments().get(1));
+                qb.appendWhere(" AND contact_methods._id=");
+                qb.appendWhere(url.getPathSegments().get(3));
+                break;
+            case PEOPLE_ORGANIZATIONS:
+                qb.setTables("organizations, people");
+                qb.setProjectionMap(sOrganizationsProjectionMap);
+                qb.appendWhere("people._id = organizations.person AND person=");
+                qb.appendWhere(url.getPathSegments().get(1));
+                break;
+            case PEOPLE_ORGANIZATIONS_ID:
+                qb.setTables("organizations, people");
+                qb.setProjectionMap(sOrganizationsProjectionMap);
+                qb.appendWhere("people._id = organizations.person AND person=");
+                qb.appendWhere(url.getPathSegments().get(1));
+                qb.appendWhere(" AND organizations._id=");
+                qb.appendWhere(url.getPathSegments().get(3));
+                break;
+            case PHONES:
+                qb.setTables("phones, people");
+                qb.appendWhere("people._id = phones.person");
+                qb.setProjectionMap(sPhonesProjectionMap);
+                break;
+            case PHONES_ID:
+                qb.setTables("phones, people");
+                qb.appendWhere("people._id = phones.person AND phones._id="
+                        + url.getPathSegments().get(1));
+                qb.setProjectionMap(sPhonesProjectionMap);
+                break;
+            case ORGANIZATIONS:
+                qb.setTables("organizations, people");
+                qb.appendWhere("people._id = organizations.person");
+                qb.setProjectionMap(sOrganizationsProjectionMap);
+                break;
+            case ORGANIZATIONS_ID:
+                qb.setTables("organizations, people");
+                qb.appendWhere("people._id = organizations.person AND organizations._id="
+                        + url.getPathSegments().get(1));
+                qb.setProjectionMap(sOrganizationsProjectionMap);
+                break;
+            case PHONES_MOBILE_FILTER_NAME:
+                qb.appendWhere("type=" + Contacts.PhonesColumns.TYPE_MOBILE + " AND ");
+
+                // Fall through.
+
+            case PHONES_FILTER_NAME:
+                qb.setTables("phones JOIN people ON (people._id = phones.person)");
+                qb.setProjectionMap(sPhonesProjectionMap);
+                if (url.getPathSegments().size() > 2) {
+                    qb.appendWhere(buildPeopleLookupWhereClause(url.getLastPathSegment()));
+                }
+                break;
+
+            case PHONES_FILTER: {
+                String phoneNumber = url.getPathSegments().get(2);
+                String indexable = PhoneNumberUtils.toCallerIDMinMatch(phoneNumber);
+                StringBuilder subQuery = new StringBuilder();
+                if (TextUtils.isEmpty(sort)) {
+                    // Default the sort order to something reasonable so we get consistent
+                    // results when callers don't request an ordering
+                    sort = People.DEFAULT_SORT_ORDER;
+                }
+
+                subQuery.append("people, (SELECT * FROM phones WHERE (phones.number_key GLOB '");
+                subQuery.append(indexable);
+                subQuery.append("*')) AS phones");
+                qb.setTables(subQuery.toString());
+                qb.appendWhere("phones.person=people._id AND PHONE_NUMBERS_EQUAL(phones.number, ");
+                qb.appendWhereEscapeString(phoneNumber);
+                qb.appendWhere(")");
+                qb.setProjectionMap(sPhonesProjectionMap);
+                break;
+            }
+            case CONTACTMETHODS:
+                qb.setTables("contact_methods, people");
+                qb.setProjectionMap(sContactMethodsProjectionMap);
+                qb.appendWhere("people._id = contact_methods.person");
+                break;
+            case CONTACTMETHODS_ID:
+                qb.setTables("contact_methods LEFT OUTER JOIN people ON contact_methods.person = people._id");
+                qb.setProjectionMap(sContactMethodsProjectionMap);
+                qb.appendWhere("contact_methods._id=");
+                qb.appendWhere(url.getPathSegments().get(1));
+                break;
+            case CONTACTMETHODS_EMAIL_FILTER:
+                String pattern = url.getPathSegments().get(2);
+                StringBuilder whereClause = new StringBuilder();
+
+                // TODO This is going to be REALLY slow.  Come up with
+                // something faster.
+                whereClause.append(ContactMethods.KIND);
+                whereClause.append('=');
+                whereClause.append('\'');
+                whereClause.append(Contacts.KIND_EMAIL);
+                whereClause.append("' AND (UPPER(");
+                whereClause.append(ContactMethods.NAME);
+                whereClause.append(") GLOB ");
+                DatabaseUtils.appendEscapedSQLString(whereClause, pattern + "*");
+                whereClause.append(" OR UPPER(");
+                whereClause.append(ContactMethods.NAME);
+                whereClause.append(") GLOB ");
+                DatabaseUtils.appendEscapedSQLString(whereClause, "* " + pattern + "*");
+                whereClause.append(") AND ");
+                qb.appendWhere(whereClause.toString());
+
+                // Fall through.
+
+            case CONTACTMETHODS_EMAIL:
+                qb.setTables("contact_methods INNER JOIN people on (contact_methods.person = people._id)");
+                qb.setProjectionMap(sEmailSearchProjectionMap);
+                qb.appendWhere("kind = " + Contacts.KIND_EMAIL);
+                qb.setDistinct(true);
+                break;
+
+            case PEOPLE_CONTACTMETHODS_WITH_PRESENCE:
+                qb.appendWhere("people._id=?");
+                selectionArgs = appendSelectionArg(selectionArgs, url.getPathSegments().get(1));
+                // Fall through.
+
+            case CONTACTMETHODS_WITH_PRESENCE:
+                qb.setTables("contact_methods JOIN people ON (contact_methods.person = people._id)"
+                        + " LEFT OUTER JOIN presence ON "
+                        // Match gtalk presence items
+                        + "((kind=" + Contacts.KIND_EMAIL +
+                            " AND im_protocol='"
+                            + ContactMethods.encodePredefinedImProtocol(
+                                    ContactMethods.PROTOCOL_GOOGLE_TALK)
+                            + "' AND data=im_handle)"
+                        + " OR "
+                        // Match IM presence items
+                        + "(kind=" + Contacts.KIND_IM
+                            + " AND data=im_handle AND aux_data=im_protocol))");
+                qb.setProjectionMap(sContactMethodsWithPresenceProjectionMap);
+                break;
+
+            case CALLS:
+                qb.setTables("calls");
+                qb.setProjectionMap(sCallsProjectionMap);
+                notificationUri = CallLog.CONTENT_URI;
+                break;
+            case CALLS_ID:
+                qb.setTables("calls");
+                qb.setProjectionMap(sCallsProjectionMap);
+                qb.appendWhere("calls._id=");
+                qb.appendWhere(url.getPathSegments().get(1));
+                notificationUri = CallLog.CONTENT_URI;
+                break;
+            case CALLS_FILTER: {
+                qb.setTables("calls");
+                qb.setProjectionMap(sCallsProjectionMap);
+
+                String phoneNumber = url.getPathSegments().get(2);
+                qb.appendWhere("PHONE_NUMBERS_EQUAL(number, ");
+                qb.appendWhereEscapeString(phoneNumber);
+                qb.appendWhere(")");
+                notificationUri = CallLog.CONTENT_URI;
+                break;
+            }
+
+            case PRESENCE:
+                qb.setTables("presence LEFT OUTER JOIN people on (presence." + Presence.PERSON_ID
+                        + "= people._id)");
+                qb.setProjectionMap(sPresenceProjectionMap);
+                break;
+            case PRESENCE_ID:
+                qb.setTables("presence LEFT OUTER JOIN people on (presence." + Presence.PERSON_ID
+                        + "= people._id)");
+                qb.appendWhere("presence._id=");
+                qb.appendWhere(url.getLastPathSegment());
+                break;
+            case VOICE_DIALER_TIMESTAMP:
+                qb.setTables("voice_dialer_timestamp");
+                qb.appendWhere("_id=1");
+                break;
+
+            case PEOPLE_EXTENSIONS_ID:
+                qb.appendWhere("extensions._id=" + url.getPathSegments().get(3) + " AND ");
+                // fall through
+            case PEOPLE_EXTENSIONS:
+                qb.appendWhere("person=" + url.getPathSegments().get(1));
+                qb.setTables(sExtensionsTable);
+                qb.setProjectionMap(sExtensionsProjectionMap);
+                break;
+
+            case EXTENSIONS_ID:
+                qb.appendWhere("extensions._id=" + url.getPathSegments().get(1));
+                // fall through
+            case EXTENSIONS:
+                qb.setTables(sExtensionsTable);
+                qb.setProjectionMap(sExtensionsProjectionMap);
+                break;
+
+            case LIVE_FOLDERS_PEOPLE:
+                qb.setTables("people LEFT OUTER JOIN photos ON (people._id = photos.person)");
+                qb.setProjectionMap(sLiveFoldersProjectionMap);
+                break;
+                
+            case LIVE_FOLDERS_PEOPLE_WITH_PHONES:
+                qb.setTables("people LEFT OUTER JOIN photos ON (people._id = photos.person)");
+                qb.setProjectionMap(sLiveFoldersProjectionMap);
+                qb.appendWhere(People.PRIMARY_PHONE_ID + " IS NOT NULL");
+                break;
+
+            case LIVE_FOLDERS_PEOPLE_FAVORITES:
+                qb.setTables("people LEFT OUTER JOIN photos ON (people._id = photos.person)");
+                qb.setProjectionMap(sLiveFoldersProjectionMap);
+                qb.appendWhere(People.STARRED + " <> 0");
+                break;
+
+            case LIVE_FOLDERS_PEOPLE_GROUP_NAME:
+                qb.setTables("people LEFT OUTER JOIN photos ON (people._id = photos.person)");
+                qb.setProjectionMap(sLiveFoldersProjectionMap);
+                qb.appendWhere("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)) "+
+                        "WHERE " + Groups.NAME + "="
+                        + DatabaseUtils.sqlEscapeString(url.getLastPathSegment()) + ")");
+                break;
+
+            default:
+                throw new IllegalArgumentException("Unknown URL " + url);
+        }
+
+        // run the query
+        final SQLiteDatabase db = getDatabase();
+        Cursor c = qb.query(db, projectionIn, selection, selectionArgs,
+                null, null, sort);
+        if ((c != null) && !isTemporary()) {
+            c.setNotificationUri(getContext().getContentResolver(), notificationUri);
+        }
+        return c;
+    }
+
+    private Cursor queryOwner(String[] projection) {
+        // Check the permissions
+        getContext().enforceCallingPermission("android.permission.READ_OWNER_DATA",
+                "No permission to access owner info");
+
+        // Read the owner id
+        SharedPreferences prefs = getContext().getSharedPreferences(PREFS_NAME_OWNER,
+                Context.MODE_PRIVATE);
+        long ownerId = prefs.getLong(PREF_OWNER_ID, 0);
+
+        // Run the query
+        return queryInternal(ContentUris.withAppendedId(People.CONTENT_URI, ownerId), projection,
+                null, null, null);
+    }
+
+    /**
+     * Append a string to a selection args array
+     *
+     * @param selectionArgs the old arg
+     * @param newArg the new arg to append
+     * @return a new string array with all of the args
+     */
+    private String[] appendSelectionArg(String[] selectionArgs, String newArg) {
+        if (selectionArgs == null || selectionArgs.length == 0) {
+            return new String[] { newArg };
+        } else {
+            int length = selectionArgs.length;
+            String[] newArgs = new String[length + 1];
+            System.arraycopy(selectionArgs, 0, newArgs, 0, length);
+            newArgs[length] = newArg;
+            return newArgs;
+        }
+    }
+
+    /**
+     * 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.
+     *
+     * @param url the URL passed for the suggestion
+     * @param qb the query builder to use if a query needs to be run on the database
+     * @return null with qb configured for a query, a cursor with the results already in it.
+     */
+    private Cursor handleSearchSuggestionsQuery(Uri url, SQLiteQueryBuilder qb) {
+        qb.setTables("people");
+        qb.setProjectionMap(sSearchSuggestionsProjectionMap);
+        if (url.getPathSegments().size() > 1) {
+            // A search term was entered, use it to filter
+            final String searchClause = url.getLastPathSegment();
+            if (!TextUtils.isDigitsOnly(searchClause)) {
+                qb.appendWhere(buildPeopleLookupWhereClause(searchClause));
+            } else {
+                final String[] columnNames = new String[] {
+                        SearchManager.SUGGEST_COLUMN_TEXT_1,
+                        SearchManager.SUGGEST_COLUMN_TEXT_2,
+                        SearchManager.SUGGEST_COLUMN_INTENT_DATA,
+                        SearchManager.SUGGEST_COLUMN_INTENT_ACTION,
+                };
+
+/*
+ *  TODO: figure out how to localize things so myFaves can read the constants when sub classing
+ */
+                ArrayList dialNumber = new ArrayList();
+                dialNumber.add("Dial number");
+                dialNumber.add("Using " + searchClause);
+                dialNumber.add("tel:" + searchClause);
+                dialNumber.add(Intents.SEARCH_SUGGESTION_DIAL_NUMBER_CLICKED);
+
+                ArrayList createContact = new ArrayList();
+                createContact.add("Create contact");
+                createContact.add("Using " + searchClause);
+                createContact.add("tel:" + searchClause);
+                createContact.add(Intents.SEARCH_SUGGESTION_CREATE_CONTACT_CLICKED);
+
+                ArrayList<ArrayList> rows = new ArrayList<ArrayList>();
+                rows.add(dialNumber);
+                rows.add(createContact);
+
+                ArrayListCursor cursor = new ArrayListCursor(columnNames, rows);
+                return cursor;
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public String getType(Uri url) {
+        int match = sURIMatcher.match(url);
+        switch (match) {
+            case EXTENSIONS:
+            case PEOPLE_EXTENSIONS:
+                return Extensions.CONTENT_TYPE;
+            case EXTENSIONS_ID:
+            case PEOPLE_EXTENSIONS_ID:
+                return Extensions.CONTENT_ITEM_TYPE;
+            case PEOPLE:
+                return "vnd.android.cursor.dir/person";
+            case PEOPLE_ID:
+                return "vnd.android.cursor.item/person";
+            case PEOPLE_PHONES:
+                return "vnd.android.cursor.dir/phone";
+            case PEOPLE_PHONES_ID:
+                return "vnd.android.cursor.item/phone";
+            case PEOPLE_CONTACTMETHODS:
+                return "vnd.android.cursor.dir/contact-methods";
+            case PEOPLE_CONTACTMETHODS_ID:
+                return getContactMethodType(url);
+            case PHONES:
+                return "vnd.android.cursor.dir/phone";
+            case PHONES_ID:
+                return "vnd.android.cursor.item/phone";
+            case PHONES_FILTER:
+            case PHONES_FILTER_NAME:
+            case PHONES_MOBILE_FILTER_NAME:
+                return "vnd.android.cursor.dir/phone";
+            case CONTACTMETHODS:
+                return "vnd.android.cursor.dir/contact-methods";
+            case CONTACTMETHODS_ID:
+                return getContactMethodType(url);
+            case CONTACTMETHODS_EMAIL:
+            case CONTACTMETHODS_EMAIL_FILTER:
+                return "vnd.android.cursor.dir/email";
+            case CALLS:
+                return "vnd.android.cursor.dir/calls";
+            case CALLS_ID:
+                return "vnd.android.cursor.item/calls";
+            case ORGANIZATIONS:
+                return "vnd.android.cursor.dir/organizations";
+            case ORGANIZATIONS_ID:
+                return "vnd.android.cursor.item/organization";
+            case CALLS_FILTER:
+                return "vnd.android.cursor.dir/calls";
+            default:
+                throw new IllegalArgumentException("Unknown URL");
+        }
+    }
+
+    private String getContactMethodType(Uri url)
+    {
+        String mime = null;
+
+        Cursor c = query(url, new String[] {ContactMethods.KIND}, null, null, null);
+        if (c != null) {
+            try {
+                if (c.moveToFirst()) {
+                    int kind = c.getInt(0);
+                    switch (kind) {
+                    case Contacts.KIND_EMAIL:
+                        mime = "vnd.android.cursor.item/email";
+                        break;
+
+                    case Contacts.KIND_IM:
+                        mime = "vnd.android.cursor.item/jabber-im";
+                        break;
+
+                    case Contacts.KIND_POSTAL:
+                        mime = "vnd.android.cursor.item/postal-address";
+                        break;
+                    }
+                }
+            } finally {
+                c.close();
+            }
+        }
+        return mime;
+    }
+
+    private ContentValues queryAndroidStarredGroupId(String account) {
+        String whereString;
+        String[] whereArgs;
+        if (!TextUtils.isEmpty(account)) {
+            whereString = "_sync_account=? AND name=?";
+            whereArgs = new String[]{account, 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},
+                whereString, whereArgs, null, null, null);
+        try {
+            if (cursor.moveToNext()) {
+                ContentValues result = new ContentValues();
+                result.put(Groups._ID, cursor.getLong(0));
+                result.put(Groups._SYNC_ID, cursor.getString(1));
+                result.put(Groups._SYNC_ACCOUNT, cursor.getString(2));
+                return result;
+            }
+            return null;
+        } finally {
+            cursor.close();
+        }
+    }
+
+    @Override
+    public Uri insertInternal(Uri url, ContentValues initialValues) {
+        Uri resultUri = null;
+        long rowID;
+
+        final SQLiteDatabase db = getDatabase();
+        int match = sURIMatcher.match(url);
+        switch (match) {
+            case PEOPLE_GROUPMEMBERSHIP:
+            case GROUPMEMBERSHIP: {
+                mValues.clear();
+                mValues.putAll(initialValues);
+                if (match == PEOPLE_GROUPMEMBERSHIP) {
+                    mValues.put(GroupMembership.PERSON_ID,
+                            Long.valueOf(url.getPathSegments().get(1)));
+                }
+                resultUri = insertIntoGroupmembership(mValues);
+            }
+            break;
+
+            case PEOPLE_OWNER:
+                return insertOwner(initialValues);
+
+            case PEOPLE_EXTENSIONS:
+            case EXTENSIONS: {
+                ContentValues newMap = new ContentValues(initialValues);
+                if (match == PEOPLE_EXTENSIONS) {
+                    newMap.put(Extensions.PERSON_ID,
+                            Long.valueOf(url.getPathSegments().get(1)));
+                }
+                rowID = mExtensionsInserter.insert(newMap);
+                if (rowID > 0) {
+                    resultUri = ContentUris.withAppendedId(Extensions.CONTENT_URI, rowID);
+                }
+            }
+            break;
+
+            case PHOTOS: {
+                if (!isTemporary()) {
+                    throw new UnsupportedOperationException();
+                }
+                rowID = mPhotosInserter.insert(initialValues);
+                if (rowID > 0) {
+                    resultUri = ContentUris.withAppendedId(Photos.CONTENT_URI, rowID);
+                }
+            }
+            break;
+
+            case GROUPS: {
+                ContentValues newMap = new ContentValues(initialValues);
+                ensureSyncAccountIsSet(newMap);
+                newMap.put(Groups._SYNC_DIRTY, 1);
+                // Insert into the groups table
+                rowID = mGroupsInserter.insert(newMap);
+                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 ContentResolver cr = getContext().getContentResolver();
+                            onLocalChangesForAccount(cr, account, false);
+                        }
+                    }
+                }
+            }
+            break;
+
+            case PEOPLE_RAW:
+            case PEOPLE: {
+                mValues.clear();
+                mValues.putAll(initialValues);
+                ensureSyncAccountIsSet(mValues);
+                mValues.put(People._SYNC_DIRTY, 1);
+                // Insert into the people table
+                rowID = mPeopleInserter.insert(mValues);
+                if (rowID > 0) {
+                    resultUri = ContentUris.withAppendedId(People.CONTENT_URI, rowID);
+                    if (!isTemporary()) {
+                        String account = mValues.getAsString(People._SYNC_ACCOUNT);
+                        Long starredValue = mValues.getAsLong(People.STARRED);
+                        final String syncId = mValues.getAsString(People._SYNC_ID);
+                        boolean isStarred = starredValue != null && starredValue != 0;
+                        fixupGroupMembershipAfterPeopleUpdate(account, rowID, isStarred);
+                        // create a photo row for this person
+                        mDb.delete(sPhotosTable, "person=" + rowID, null);
+                        mValues.clear();
+                        mValues.put(Photos.PERSON_ID, rowID);
+                        mValues.put(Photos._SYNC_ACCOUNT, account);
+                        mValues.put(Photos._SYNC_ID, syncId);
+                        mValues.put(Photos._SYNC_DIRTY, 0);
+                        mPhotosInserter.insert(mValues);
+                    }
+                }
+            }
+            break;
+
+            case DELETED_PEOPLE: {
+                if (isTemporary()) {
+                    // Insert into the people table
+                    rowID = db.insert("_deleted_people", "_sync_id", initialValues);
+                    if (rowID > 0) {
+                        resultUri = Uri.parse("content://contacts/_deleted_people/" + rowID);
+                    }
+                } else {
+                    throw new UnsupportedOperationException();
+                }
+            }
+            break;
+
+            case DELETED_GROUPS: {
+                if (isTemporary()) {
+                    rowID = db.insert(sDeletedGroupsTable, Groups._SYNC_ID,
+                            initialValues);
+                    if (rowID > 0) {
+                        resultUri =ContentUris.withAppendedId(
+                                Groups.DELETED_CONTENT_URI, rowID);
+                    }
+                } else {
+                    throw new UnsupportedOperationException();
+                }
+            }
+            break;
+
+            case PEOPLE_PHONES:
+            case PHONES: {
+                mValues.clear();
+                mValues.putAll(initialValues);
+                if (match == PEOPLE_PHONES) {
+                    mValues.put(Contacts.Phones.PERSON_ID,
+                            Long.valueOf(url.getPathSegments().get(1)));
+                }
+                String number = mValues.getAsString(Contacts.Phones.NUMBER);
+                if (number != null) {
+                    mValues.put("number_key", PhoneNumberUtils.getStrippedReversed(number));
+                }
+
+                rowID = insertAndFixupPrimary(Contacts.KIND_PHONE, mValues);
+                resultUri = ContentUris.withAppendedId(Phones.CONTENT_URI, rowID);
+            }
+            break;
+
+            case CONTACTMETHODS:
+            case PEOPLE_CONTACTMETHODS: {
+                mValues.clear();
+                mValues.putAll(initialValues);
+                if (match == PEOPLE_CONTACTMETHODS) {
+                    mValues.put("person", url.getPathSegments().get(1));
+                }
+                Integer kind = mValues.getAsInteger(ContactMethods.KIND);
+                if (kind == null) {
+                    throw new IllegalArgumentException("you must specify the ContactMethods.KIND");
+                }
+                rowID = insertAndFixupPrimary(kind, mValues);
+                if (rowID > 0) {
+                    resultUri = ContentUris.withAppendedId(ContactMethods.CONTENT_URI, rowID);
+                }
+            }
+            break;
+
+            case CALLS: {
+                rowID = mCallsInserter.insert(initialValues);
+                if (rowID > 0) {
+                    resultUri = Uri.parse("content://call_log/calls/" + rowID);
+                }
+            }
+            break;
+
+            case PRESENCE: {
+                final String handle = initialValues.getAsString(Presence.IM_HANDLE);
+                final String protocol = initialValues.getAsString(Presence.IM_PROTOCOL);
+                if (TextUtils.isEmpty(handle) || TextUtils.isEmpty(protocol)) {
+                    throw new IllegalArgumentException("IM_PROTOCOL and IM_HANDLE are required");
+                }
+
+                // Look for the contact for this presence update
+                StringBuilder query = new StringBuilder("SELECT ");
+                query.append(ContactMethods.PERSON_ID);
+                query.append(" FROM contact_methods WHERE (kind=");
+                query.append(Contacts.KIND_IM);
+                query.append(" AND ");
+                query.append(ContactMethods.DATA);
+                query.append("=? AND ");
+                query.append(ContactMethods.AUX_DATA);
+                query.append("=?)");
+
+                String[] selectionArgs;
+                if (GTALK_PROTOCOL_STRING.equals(protocol)) {
+                    // For gtalk accounts we usually don't have an explicit IM
+                    // entry, so also look for the email address as well
+                    query.append(" OR (");
+                    query.append("kind=");
+                    query.append(Contacts.KIND_EMAIL);
+                    query.append(" AND ");
+                    query.append(ContactMethods.DATA);
+                    query.append("=?)");
+                    selectionArgs = new String[] { handle, protocol, handle };
+                } else {
+                    selectionArgs = new String[] { handle, protocol };
+                }
+
+                Cursor c = db.rawQueryWithFactory(null, query.toString(), selectionArgs, null);
+
+                long personId = 0;
+                try {
+                    if (c.moveToFirst()) {
+                        personId = c.getLong(0);
+                    } else {
+                        // No contact found, return a null URI
+                        return null;
+                    }
+                } finally {
+                    c.close();
+                }
+
+                mValues.clear();
+                mValues.putAll(initialValues);
+                mValues.put(Presence.PERSON_ID, personId);
+
+                // Insert the presence update
+                rowID = db.replace("presence", null, mValues);
+                if (rowID > 0) {
+                    resultUri = Uri.parse("content://contacts/presence/" + rowID);
+                }
+            }
+            break;
+
+            case PEOPLE_ORGANIZATIONS:
+            case ORGANIZATIONS: {
+                ContentValues newMap = new ContentValues(initialValues);
+                if (match == PEOPLE_ORGANIZATIONS) {
+                    newMap.put(Contacts.Phones.PERSON_ID,
+                            Long.valueOf(url.getPathSegments().get(1)));
+                }
+                rowID = insertAndFixupPrimary(Contacts.KIND_ORGANIZATION, newMap);
+                if (rowID > 0) {
+                    resultUri = Uri.parse("content://contacts/organizations/" + rowID);
+                }
+            }
+            break;
+            default:
+                throw new UnsupportedOperationException("Cannot insert into URL: " + url);
+        }
+
+        return resultUri;
+    }
+
+    @Override
+    protected void onAccountsChanged(String[] accountsArray) {
+        super.onAccountsChanged(accountsArray);
+        synchronized (mAccountsLock) {
+            mAccounts = new String[accountsArray.length];
+            System.arraycopy(accountsArray, 0, mAccounts, 0, mAccounts.length);
+        }
+    }
+
+    private void ensureSyncAccountIsSet(ContentValues values) {
+        synchronized (mAccountsLock) {
+            String account = values.getAsString(SyncConstValue._SYNC_ACCOUNT);
+            if (account == null && mAccounts.length > 0) {
+                values.put(SyncConstValue._SYNC_ACCOUNT, mAccounts[0]);
+            }
+        }
+    }
+
+    private Uri insertOwner(ContentValues values) {
+        // Check the permissions
+        getContext().enforceCallingPermission("android.permission.WRITE_OWNER_DATA",
+                "No permission to set owner info");
+
+        // Insert the owner info
+        Uri uri = insertInternal(People.CONTENT_URI, values);
+
+        // Record which person is the owner
+        long id = ContentUris.parseId(uri);
+        SharedPreferences.Editor prefs = getContext().getSharedPreferences(PREFS_NAME_OWNER,
+                Context.MODE_PRIVATE).edit();
+        prefs.putLong(PREF_OWNER_ID, id);
+        prefs.commit();
+        return uri;
+    }
+
+    private Uri insertIntoGroupmembership(ContentValues values) {
+        String groupSyncAccount = values.getAsString(GroupMembership.GROUP_SYNC_ACCOUNT);
+        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)) {
+                throw new IllegalArgumentException(
+                        "insertIntoGroupmembership: no GROUP_ID wasn't specified and non-empty "
+                        + "GROUP_SYNC_ID and GROUP_SYNC_ACCOUNT 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)})) {
+                final String errorMessage =
+                        "insertIntoGroupmembership: a row with this server key already exists, "
+                                + values;
+                if (Config.LOGD) Log.d(TAG, errorMessage);
+                return null;
+            }
+        } else {
+            long groupId = values.getAsLong(GroupMembership.GROUP_ID);
+            if (!TextUtils.isEmpty(groupSyncAccount) || !TextUtils.isEmpty(groupSyncId)) {
+                throw new IllegalArgumentException(
+                        "insertIntoGroupmembership: GROUP_ID was specified but "
+                        + "GROUP_SYNC_ID and GROUP_SYNC_ACCOUNT fields were also specifid, "
+                        + values);
+            }
+            if (0 != DatabaseUtils.longForQuery(getDatabase(),
+                    "SELECT COUNT(*) FROM groupmembership where group_id=? AND person=?",
+                    new String[]{String.valueOf(groupId), String.valueOf(personId)})) {
+                final String errorMessage =
+                        "insertIntoGroupmembership: a row with this local key already exists, "
+                                + values;
+                if (Config.LOGD) Log.d(TAG, errorMessage);
+                return null;
+            }
+        }
+
+        long rowId = mGroupMembershipInserter.insert(values);
+        if (rowId <= 0) {
+            final String errorMessage = "insertIntoGroupmembership: the insert failed, values are "
+                    + values;
+            if (Config.LOGD) Log.d(TAG, errorMessage);
+            return null;
+        }
+
+        // set the STARRED column in the people row if this group is the GROUP_ANDROID_STARRED
+        if (!isTemporary() && queryGroupMembershipContainsStarred(personId)) {
+            fixupPeopleStarred(personId, true);
+        }
+
+        return ContentUris.withAppendedId(GroupMembership.CONTENT_URI, rowId);
+    }
+
+    private void fixupGroupMembershipAfterPeopleUpdate(String account, long personId,
+            boolean makeStarred) {
+        ContentValues starredGroupInfo = queryAndroidStarredGroupId(account);
+        if (makeStarred) {
+            if (starredGroupInfo == null) {
+                // we need to add the starred group
+                mValuesLocal.clear();
+                mValuesLocal.put(Groups.NAME, Groups.GROUP_ANDROID_STARRED);
+                mValuesLocal.put(Groups._SYNC_DIRTY, 1);
+                mValuesLocal.put(Groups._SYNC_ACCOUNT, account);
+                long groupId = mGroupsInserter.insert(mValuesLocal);
+                starredGroupInfo = new ContentValues();
+                starredGroupInfo.put(Groups._ID, groupId);
+                starredGroupInfo.put(Groups._SYNC_ACCOUNT, account);
+                // 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);
+
+            // check that either groupId is set or the syncId/Account is set
+            final boolean hasSyncId = !TextUtils.isEmpty(syncId);
+            final boolean hasGroupId = groupId != null;
+            if (!hasGroupId && !hasSyncId) {
+                throw new IllegalStateException("at least one of the groupId or "
+                        + "the syncId must be set, " + starredGroupInfo);
+            }
+            
+            // now add this person to the group
+            mValuesLocal.clear();
+            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);
+            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 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});
+                } else {
+                    mDb.delete(sGroupmembershipTable, "person=? AND group_id=?",
+                            new String[]{
+                                    Long.toString(personId),
+                                    Long.toString(starredGroupInfo.getAsLong(Groups._ID))});
+                }
+            }
+        }
+    }
+
+    private int fixupPeopleStarred(long personId, boolean inStarredGroup) {
+        mValuesLocal.clear();
+        mValuesLocal.put(People.STARRED, inStarredGroup ? 1 : 0);
+        return getDatabase().update(sPeopleTable, mValuesLocal, WHERE_ID,
+                new String[]{String.valueOf(personId)});
+    }
+
+    private String kindToTable(int kind) {
+        switch (kind) {
+            case Contacts.KIND_EMAIL: return sContactMethodsTable;
+            case Contacts.KIND_POSTAL: return sContactMethodsTable;
+            case Contacts.KIND_IM: return sContactMethodsTable;
+            case Contacts.KIND_PHONE: return sPhonesTable;
+            case Contacts.KIND_ORGANIZATION: return sOrganizationsTable;
+            default: throw new IllegalArgumentException("unknown kind, " + kind);
+        }
+    }
+
+    private DatabaseUtils.InsertHelper kindToInserter(int kind) {
+        switch (kind) {
+            case Contacts.KIND_EMAIL: return mContactMethodsInserter;
+            case Contacts.KIND_POSTAL: return mContactMethodsInserter;
+            case Contacts.KIND_IM: return mContactMethodsInserter;
+            case Contacts.KIND_PHONE: return mPhonesInserter;
+            case Contacts.KIND_ORGANIZATION: return mOrganizationsInserter;
+            default: throw new IllegalArgumentException("unknown kind, " + kind);
+        }
+    }
+
+    private long insertAndFixupPrimary(int kind, ContentValues values) {
+        final String table = kindToTable(kind);
+        boolean isPrimary = false;
+        Long personId = null;
+
+        if (!isTemporary()) {
+            // when you add a item, if isPrimary or if there is no primary,
+            // make this it, set the isPrimary flag, and clear other primary flags
+            isPrimary = values.containsKey("isprimary")
+                    && (values.getAsInteger("isprimary") != 0);
+            personId = values.getAsLong("person");
+            if (!isPrimary) {
+                // make it primary anyway if this person doesn't have any rows of this type yet
+                StringBuilder sb = new StringBuilder("person=" + personId);
+                if (sContactMethodsTable.equals(table)) {
+                    sb.append(" AND kind=");
+                    sb.append(kind);
+                }
+                final boolean isFirstRowOfType = DatabaseUtils.longForQuery(getDatabase(),
+                        "SELECT count(*) FROM " + table + " where " + sb.toString(), null) == 0;
+                isPrimary = isFirstRowOfType;
+            }
+
+            values.put("isprimary", isPrimary ? 1 : 0);
+        }
+
+        // do the actual insert
+        long newRowId = kindToInserter(kind).insert(values);
+
+        if (newRowId <= 0) {
+            throw new RuntimeException("error while inserting into " + table + ", " + values);
+        }
+
+        if (!isTemporary()) {
+            // If this row was made the primary then clear the other isprimary flags and update
+            // corresponding people row, if necessary.
+            if (isPrimary) {
+                clearOtherIsPrimary(kind, personId, newRowId);
+                if (kind == Contacts.KIND_PHONE) {
+                    updatePeoplePrimary(personId, People.PRIMARY_PHONE_ID, newRowId);
+                } else if (kind == Contacts.KIND_EMAIL) {
+                    updatePeoplePrimary(personId, People.PRIMARY_EMAIL_ID, newRowId);
+                } else if (kind == Contacts.KIND_ORGANIZATION) {
+                    updatePeoplePrimary(personId, People.PRIMARY_ORGANIZATION_ID, newRowId);
+                }
+            }
+        }
+
+        return newRowId;
+    }
+
+    @Override
+    public int deleteInternal(Uri url, String userWhere, String[] whereArgs) {
+        String tableToChange;
+        String changedItemId;
+
+        final int matchedUriId = sURIMatcher.match(url);
+        switch (matchedUriId) {
+            case GROUPMEMBERSHIP_ID:
+                return deleteFromGroupMembership(Long.parseLong(url.getPathSegments().get(1)),
+                        userWhere, whereArgs);
+            case GROUPS:
+                return deleteFromGroups(userWhere, whereArgs);
+            case GROUPS_ID:
+                changedItemId = url.getPathSegments().get(1);
+                return deleteFromGroups(addIdToWhereClause(changedItemId, userWhere), whereArgs);
+            case EXTENSIONS:
+                tableToChange = sExtensionsTable;
+                changedItemId = null;
+                break;
+            case EXTENSIONS_ID:
+                tableToChange = sExtensionsTable;
+                changedItemId = url.getPathSegments().get(1);
+                break;
+            case PEOPLE_RAW:
+            case PEOPLE:
+                return deleteFromPeople(null, userWhere, whereArgs);
+            case PEOPLE_ID:
+                return deleteFromPeople(url.getPathSegments().get(1), userWhere, whereArgs);
+            case PEOPLE_PHONES_ID:
+                tableToChange = sPhonesTable;
+                changedItemId = url.getPathSegments().get(3);
+                break;
+            case PEOPLE_CONTACTMETHODS_ID:
+                tableToChange = sContactMethodsTable;
+                changedItemId = url.getPathSegments().get(3);
+                break;
+            case PHONES_ID:
+                tableToChange = sPhonesTable;
+                changedItemId = url.getPathSegments().get(1);
+                break;
+            case ORGANIZATIONS_ID:
+                tableToChange = sOrganizationsTable;
+                changedItemId = url.getPathSegments().get(1);
+                break;
+            case CONTACTMETHODS_ID:
+                tableToChange = sContactMethodsTable;
+                changedItemId = url.getPathSegments().get(1);
+                break;
+            case PRESENCE:
+                tableToChange = "presence";
+                changedItemId = null;
+                break;
+            case CALLS:
+                tableToChange = "calls";
+                changedItemId = null;
+                break;
+            default:
+                throw new UnsupportedOperationException("Cannot delete that URL: " + url);
+        }
+
+        String where = addIdToWhereClause(changedItemId, userWhere);
+        IsPrimaryInfo oldPrimaryInfo = null;
+        switch (matchedUriId) {
+            case PEOPLE_PHONES_ID:
+            case PHONES_ID:
+            case ORGANIZATIONS_ID:
+                oldPrimaryInfo = lookupIsPrimaryInfo(tableToChange,
+                        sIsPrimaryProjectionWithoutKind, where, whereArgs);
+                break;
+
+            case PEOPLE_CONTACTMETHODS_ID:
+            case CONTACTMETHODS_ID:
+                oldPrimaryInfo = lookupIsPrimaryInfo(tableToChange,
+                        sIsPrimaryProjectionWithKind, where, whereArgs);
+                break;
+        }
+
+        final SQLiteDatabase db = getDatabase();
+        int count = db.delete(tableToChange, where, whereArgs);
+        if (count > 0) {
+            if (oldPrimaryInfo != null && oldPrimaryInfo.isPrimary) {
+                fixupPrimaryAfterDelete(oldPrimaryInfo.kind,
+                        oldPrimaryInfo.id, oldPrimaryInfo.person);
+            }
+        }
+
+        return count;
+    }
+
+    @Override
+    public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
+        int match = sURIMatcher.match(uri);
+        switch (match) {
+            default:
+                throw new UnsupportedOperationException(uri.toString());
+        }
+    }
+
+    private int deleteFromGroupMembership(long rowId, String where, String[] whereArgs) {
+        SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
+        qb.setTables("groups, groupmembership");
+        qb.setProjectionMap(sGroupMembershipProjectionMap);
+        qb.appendWhere(sGroupsJoinString);
+        qb.appendWhere(" AND groupmembership._id=" + rowId);
+        Cursor cursor = qb.query(getDatabase(), null, where, whereArgs, null, null, null);
+        try {
+            final int indexPersonId = cursor.getColumnIndexOrThrow(GroupMembership.PERSON_ID);
+            final int indexName = cursor.getColumnIndexOrThrow(GroupMembership.NAME);
+            while (cursor.moveToNext()) {
+                if (Groups.GROUP_ANDROID_STARRED.equals(cursor.getString(indexName))) {
+                    fixupPeopleStarred(cursor.getLong(indexPersonId), false);
+                }
+            }
+        } finally {
+            cursor.close();
+        }
+
+        return mDb.delete(sGroupmembershipTable,
+                addIdToWhereClause(String.valueOf(rowId), where),
+                whereArgs);
+    }
+
+    private int deleteFromPeople(String rowId, String where, String[] whereArgs) {
+        final SQLiteDatabase db = getDatabase();
+        where = addIdToWhereClause(rowId, where);
+        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 idxSyncVersion = cursor.getColumnIndexOrThrow(People._SYNC_VERSION);
+            final int dstIdxSyncId = mDeletedPeopleInserter.getColumnIndex(SyncConstValue._SYNC_ID);
+            final int dstIdxSyncAccount =
+                    mDeletedPeopleInserter.getColumnIndex(SyncConstValue._SYNC_ACCOUNT);
+            final int dstIdxSyncVersion =
+                    mDeletedPeopleInserter.getColumnIndex(SyncConstValue._SYNC_VERSION);
+            while (cursor.moveToNext()) {
+                final String syncId = cursor.getString(idxSyncId);
+                if (TextUtils.isEmpty(syncId)) continue;
+                // insert into deleted table
+                mDeletedPeopleInserter.prepareForInsert();
+                mDeletedPeopleInserter.bind(dstIdxSyncId, syncId);
+                mDeletedPeopleInserter.bind(dstIdxSyncAccount, cursor.getString(idxSyncAccount));
+                mDeletedPeopleInserter.bind(dstIdxSyncVersion, cursor.getString(idxSyncVersion));
+                mDeletedPeopleInserter.execute();
+            }
+        } finally {
+            cursor.close();
+        }
+
+        // perform the actual delete
+        return db.delete(sPeopleTable, where, whereArgs);
+    }
+
+    private int deleteFromGroups(String where, String[] whereArgs) {
+        HashSet<String> 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 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 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(syncAccount) && shouldSync) {
+                    modifiedAccounts.add(syncAccount);
+                }
+            }
+        } finally {
+            cursor.close();
+        }
+
+        int numRows = mDb.delete(sGroupsTable, where, whereArgs);
+        if (numRows > 0) {
+            if (!isTemporary()) {
+                final ContentResolver cr = getContext().getContentResolver();
+                for (String account : modifiedAccounts) {
+                    onLocalChangesForAccount(cr, account, true);
+                }
+            }
+        }
+        return numRows;
+    }
+
+    /**
+     * Called when local changes are made, so subclasses have
+     * an opportunity to react as they see fit.
+     *
+     * @param resolver the content resolver to use
+     * @param account the account the changes are tied to
+     */
+    protected void onLocalChangesForAccount(final ContentResolver resolver, String account,
+            boolean groupsModified) {
+        // Do nothing
+    }
+
+    private void fixupPrimaryAfterDelete(int kind, Long itemId, Long personId) {
+        final String table = kindToTable(kind);
+        // when you delete an item with isPrimary,
+        // select a new one as isPrimary and clear the primary if no more items
+        Long newPrimaryId = findNewPrimary(kind, personId, itemId);
+
+        // we found a new primary, set its isprimary flag
+        if (newPrimaryId != null) {
+            mValuesLocal.clear();
+            mValuesLocal.put("isprimary", 1);
+            if (getDatabase().update(table, mValuesLocal, "_id=" + newPrimaryId, null) != 1) {
+                throw new RuntimeException("error updating " + table + ", _id "
+                        + newPrimaryId + ", values " + mValuesLocal);
+            }
+        }
+
+        // if this kind's primary status should be reflected in the people row, update it
+        if (kind == Contacts.KIND_PHONE) {
+            updatePeoplePrimary(personId, People.PRIMARY_PHONE_ID, newPrimaryId);
+        } else if (kind == Contacts.KIND_EMAIL) {
+            updatePeoplePrimary(personId, People.PRIMARY_EMAIL_ID, newPrimaryId);
+        } else if (kind == Contacts.KIND_ORGANIZATION) {
+            updatePeoplePrimary(personId, People.PRIMARY_ORGANIZATION_ID, newPrimaryId);
+        }
+    }
+
+    @Override
+    public int updateInternal(Uri url, ContentValues values, String userWhere, String[] whereArgs) {
+        final SQLiteDatabase db = getDatabase();
+        String tableToChange;
+        String changedItemId;
+        final int matchedUriId = sURIMatcher.match(url);
+        switch (matchedUriId) {
+            case GROUPS_ID:
+                changedItemId = url.getPathSegments().get(1);
+                return updateGroups(values,
+                        addIdToWhereClause(changedItemId, userWhere), whereArgs);
+
+            case PEOPLE_EXTENSIONS_ID:
+                tableToChange = sExtensionsTable;
+                changedItemId = url.getPathSegments().get(3);
+                break;
+
+            case EXTENSIONS_ID:
+                tableToChange = sExtensionsTable;
+                changedItemId = url.getPathSegments().get(1);
+                break;
+
+            case PEOPLE_UPDATE_CONTACT_TIME:
+                if (values.size() != 1 || !values.containsKey(People.LAST_TIME_CONTACTED)) {
+                    throw new IllegalArgumentException(
+                            "You may only use " + url + " to update People.LAST_TIME_CONTACTED");
+                }
+                tableToChange = sPeopleTable;
+                changedItemId = url.getPathSegments().get(1);
+                break;
+
+            case PEOPLE_ID:
+                mValues.clear();
+                mValues.putAll(values);
+                mValues.put(Photos._SYNC_DIRTY, 1);
+                values = mValues;
+                tableToChange = sPeopleTable;
+                changedItemId = url.getPathSegments().get(1);
+                break;
+
+            case PEOPLE_PHONES_ID:
+                tableToChange = sPhonesTable;
+                changedItemId = url.getPathSegments().get(3);
+                break;
+
+            case PEOPLE_CONTACTMETHODS_ID:
+                tableToChange = sContactMethodsTable;
+                changedItemId = url.getPathSegments().get(3);
+                break;
+
+            case PHONES_ID:
+                tableToChange = sPhonesTable;
+                changedItemId = url.getPathSegments().get(1);
+                break;
+
+            case PEOPLE_PHOTO:
+            case PHOTOS_ID:
+                mValues.clear();
+                mValues.putAll(values);
+
+                // The _SYNC_DIRTY flag should only be set if the data was modified and if
+                // it isn't already provided. 
+                if (!mValues.containsKey(Photos._SYNC_DIRTY) && mValues.containsKey(Photos.DATA)) {
+                    mValues.put(Photos._SYNC_DIRTY, 1);
+                }
+                StringBuilder where;
+                if (matchedUriId == PEOPLE_PHOTO) {
+                    where = new StringBuilder("_id=" + url.getPathSegments().get(1));
+                } else {
+                    where = new StringBuilder("person=" + url.getPathSegments().get(1));
+                }
+                if (!TextUtils.isEmpty(userWhere)) {
+                    where.append(" AND (");
+                    where.append(userWhere);
+                    where.append(')');
+                }
+                return db.update(sPhotosTable, mValues, where.toString(), whereArgs);
+
+            case ORGANIZATIONS_ID:
+                tableToChange = sOrganizationsTable;
+                changedItemId = url.getPathSegments().get(1);
+                break;
+
+            case CONTACTMETHODS_ID:
+                tableToChange = sContactMethodsTable;
+                changedItemId = url.getPathSegments().get(1);
+                break;
+
+            case SETTINGS:
+                if (whereArgs != null) {
+                    throw new IllegalArgumentException(
+                            "you aren't allowed to specify where args when updating settings");
+                }
+                if (userWhere != null) {
+                    throw new IllegalArgumentException(
+                            "you aren't allowed to specify a where string when updating settings");
+                }
+                return updateSettings(values);
+
+            case CALLS:
+                tableToChange = "calls";
+                changedItemId = null;
+                break;
+
+            case CALLS_ID:
+                tableToChange = "calls";
+                changedItemId = url.getPathSegments().get(1);
+                break;
+
+            default:
+                throw new UnsupportedOperationException("Cannot update URL: " + url);
+        }
+
+        String where = addIdToWhereClause(changedItemId, userWhere);
+        int numRowsUpdated = db.update(tableToChange, values, where, whereArgs);
+
+        if (numRowsUpdated > 0 && changedItemId != null) {
+            long itemId = Long.parseLong(changedItemId);
+            switch (matchedUriId) {
+                case ORGANIZATIONS_ID:
+                    fixupPrimaryAfterUpdate(
+                            Contacts.KIND_ORGANIZATION, null, itemId,
+                            values.getAsInteger(Organizations.ISPRIMARY));
+                    break;
+
+                case PHONES_ID:
+                case PEOPLE_PHONES_ID:
+                    fixupPrimaryAfterUpdate(
+                            Contacts.KIND_PHONE, matchedUriId == PEOPLE_PHONES_ID
+                                    ? Long.parseLong(url.getPathSegments().get(1))
+                                    : null, itemId,
+                            values.getAsInteger(Phones.ISPRIMARY));
+                    break;
+
+                case CONTACTMETHODS_ID:
+                case PEOPLE_CONTACTMETHODS_ID:
+                    IsPrimaryInfo isPrimaryInfo = lookupIsPrimaryInfo(sContactMethodsTable,
+                            sIsPrimaryProjectionWithKind, where, whereArgs);
+                    fixupPrimaryAfterUpdate(
+                            isPrimaryInfo.kind, isPrimaryInfo.person, itemId,
+                            values.getAsInteger(ContactMethods.ISPRIMARY));
+                    break;
+
+                case PEOPLE_ID:
+                    boolean hasStarred = values.containsKey(People.STARRED);
+                    boolean hasPrimaryPhone = values.containsKey(People.PRIMARY_PHONE_ID);
+                    boolean hasPrimaryOrganization =
+                            values.containsKey(People.PRIMARY_ORGANIZATION_ID);
+                    boolean hasPrimaryEmail = values.containsKey(People.PRIMARY_EMAIL_ID);
+                    if (hasStarred || hasPrimaryPhone || hasPrimaryOrganization
+                            || hasPrimaryEmail) {
+                        Cursor c = mDb.query(sPeopleTable, null,
+                                where, whereArgs, null, null, null);
+                        try {
+                            int indexAccount = c.getColumnIndexOrThrow(People._SYNC_ACCOUNT);
+                            int indexId = c.getColumnIndexOrThrow(People._ID);
+                            Long starredValue = values.getAsLong(People.STARRED);
+                            Long primaryPhone = values.getAsLong(People.PRIMARY_PHONE_ID);
+                            Long primaryOrganization =
+                                    values.getAsLong(People.PRIMARY_ORGANIZATION_ID);
+                            Long primaryEmail = values.getAsLong(People.PRIMARY_EMAIL_ID);
+                            while (c.moveToNext()) {
+                                final long personId = c.getLong(indexId);
+                                if (hasStarred) {
+                                    fixupGroupMembershipAfterPeopleUpdate(c.getString(indexAccount),
+                                            personId, starredValue != null && starredValue != 0);
+                                }
+
+                                if (hasPrimaryPhone) {
+                                    if (primaryPhone == null) {
+                                        throw new IllegalArgumentException(
+                                                "the value of PRIMARY_PHONE_ID must not be null");
+                                    }
+                                    setIsPrimary(Contacts.KIND_PHONE, personId, primaryPhone);
+                                }
+                                if (hasPrimaryOrganization) {
+                                    if (primaryOrganization == null) {
+                                        throw new IllegalArgumentException(
+                                                "the value of PRIMARY_ORGANIZATION_ID must "
+                                                        + "not be null");
+                                    }
+                                    setIsPrimary(Contacts.KIND_ORGANIZATION, personId,
+                                            primaryOrganization);
+                                }
+                                if (hasPrimaryEmail) {
+                                    if (primaryEmail == null) {
+                                        throw new IllegalArgumentException(
+                                                "the value of PRIMARY_EMAIL_ID must not be null");
+                                    }
+                                    setIsPrimary(Contacts.KIND_EMAIL, personId, primaryEmail);
+                                }
+                            }
+                        } finally {
+                            c.close();
+                        }
+                    }
+                    break;
+            }
+        }
+
+        return numRowsUpdated;
+    }
+
+    private int updateSettings(ContentValues values) {
+        final SQLiteDatabase db = getDatabase();
+        final String account = values.getAsString(Contacts.Settings._SYNC_ACCOUNT);
+        final String key = values.getAsString(Contacts.Settings.KEY);
+        if (key == null) {
+            throw new IllegalArgumentException("you must specify the key when updating settings");
+        }
+        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});
+        }
+        long rowId = db.insert(sSettingsTable, Contacts.Settings.KEY, values);
+        if (rowId < 0) {
+            throw new SQLException("error updating settings with " + values);
+        }
+        return 1;
+    }
+
+    private int updateGroups(ContentValues values, String where, String[] whereArgs) {
+        for (Map.Entry<String, Object> entry : values.valueSet()) {
+            final String column = entry.getKey();
+            if (!Groups.NAME.equals(column) && !Groups.NOTES.equals(column)
+                    && !Groups.SYSTEM_ID.equals(column) && !Groups.SHOULD_SYNC.equals(column)) {
+                throw new IllegalArgumentException(
+                        "you are not allowed to change column " + column);
+            }
+        }
+
+        Set<String> modifiedAccounts = Sets.newHashSet();
+        final SQLiteDatabase db = getDatabase();
+        if (values.containsKey(Groups.NAME) || values.containsKey(Groups.SHOULD_SYNC)) {
+            String newName = values.getAsString(Groups.NAME);
+            Cursor cursor = db.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 indexSyncId = cursor.getColumnIndexOrThrow(Groups._SYNC_ID);
+                final int indexId = cursor.getColumnIndexOrThrow(Groups._ID);
+                while (cursor.moveToNext()) {
+                    String syncAccount = cursor.getString(indexSyncAccount);
+                    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(syncAccount) && values.containsKey(Groups.SHOULD_SYNC)) {
+                        modifiedAccounts.add(syncAccount);
+                    }
+                }
+            } finally {
+                cursor.close();
+            }
+        }
+
+        int numRows = db.update(sGroupsTable, values, where, whereArgs);
+        if (numRows > 0) {
+            if (!isTemporary()) {
+                final ContentResolver cr = getContext().getContentResolver();
+                for (String account : modifiedAccounts) {
+                    onLocalChangesForAccount(cr, account, true);
+                }
+            }
+        }
+        return numRows;
+    }
+
+    void fixupPeopleStarredOnGroupRename(String oldName, String newName,
+            String where, String[] whereArgs) {
+        if (TextUtils.equals(oldName, newName)) return;
+
+        int starredValue;
+        if (Groups.GROUP_ANDROID_STARRED.equals(newName)) {
+            starredValue = 1;
+        } else if (Groups.GROUP_ANDROID_STARRED.equals(oldName)) {
+            starredValue = 0;
+        } else {
+            return;
+        }
+
+        getDatabase().execSQL("UPDATE people SET starred=" + starredValue + " WHERE _id in ("
+                + "SELECT person "
+                + "FROM groups, groupmembership "
+                + "WHERE " + where + " AND " + sGroupsJoinString + ")",
+                whereArgs);
+    }
+
+    void fixupPeopleStarredOnGroupRename(String oldName, String newName,
+            String syncAccount, String syncId) {
+        fixupPeopleStarredOnGroupRename(oldName, newName, "_sync_account=? AND _sync_id=?",
+                new String[]{syncAccount, syncId});
+    }
+
+    void fixupPeopleStarredOnGroupRename(String oldName, String newName, long groupId) {
+        fixupPeopleStarredOnGroupRename(oldName, newName, "group_id=?",
+                new String[]{String.valueOf(groupId)});
+    }
+
+    private void fixupPrimaryAfterUpdate(int kind, Long personId, Long changedItemId,
+            Integer isPrimaryValue) {
+        final String table = kindToTable(kind);
+
+        // - when you update isPrimary to true,
+        //   make the changed item the primary, clear others
+        // - when you update isPrimary to false,
+        //   select a new one as isPrimary, clear the primary if no more phones
+        if (isPrimaryValue != null) {
+            if (personId == null) {
+                personId = lookupPerson(table, changedItemId);
+            }
+            
+            boolean isPrimary = isPrimaryValue != 0;
+            Long newPrimary = changedItemId;
+            if (!isPrimary) {
+                newPrimary = findNewPrimary(kind, personId, changedItemId);
+            }
+            clearOtherIsPrimary(kind, personId, changedItemId);
+
+            if (kind == Contacts.KIND_PHONE) {
+                updatePeoplePrimary(personId, People.PRIMARY_PHONE_ID, newPrimary);
+            } else if (kind == Contacts.KIND_EMAIL) {
+                updatePeoplePrimary(personId, People.PRIMARY_EMAIL_ID, newPrimary);
+            } else if (kind == Contacts.KIND_ORGANIZATION) {
+                updatePeoplePrimary(personId, People.PRIMARY_ORGANIZATION_ID, newPrimary);
+            }
+        }
+    }
+
+    /**
+     * Queries table to find the value of the person column for the row with _id. There must
+     * be exactly one row that matches this id.
+     * @param table the table to query
+     * @param id the id of the row to query
+     * @return the value of the person column for the specified row, returned as a String.
+     */
+    private long lookupPerson(String table, long id) {
+        return DatabaseUtils.longForQuery(
+                getDatabase(),
+                "SELECT person FROM " + table + " where _id=" + id,
+                null);
+    }
+
+    /**
+     * Used to pass around information about a row that has the isprimary column.
+     */
+    private class IsPrimaryInfo {
+        boolean isPrimary;
+        Long person;
+        Long id;
+        Integer kind;
+    }
+
+    /**
+     * Queries the table to determine the state of the row's isprimary column and the kind.
+     * The where and whereArgs must be sufficient to match either 0 or 1 row.
+     * @param table the table of rows to consider, supports "phones" and "contact_methods"
+     * @param projection the projection to use to get the columns that pertain to table
+     * @param where used in conjunction with the whereArgs to identify the row
+     * @param where used in conjunction with the where string to identify the row
+     * @return the IsPrimaryInfo about the matched row, or null if no row was matched
+     */
+    private IsPrimaryInfo lookupIsPrimaryInfo(String table, String[] projection, String where,
+            String[] whereArgs) {
+        Cursor cursor = getDatabase().query(table, projection, where, whereArgs, null, null, null);
+        try {
+            if (!(cursor.getCount() <= 1)) {
+                throw new IllegalArgumentException("expected only zero or one rows, got "
+                        + DatabaseUtils.dumpCursorToString(cursor));
+            }
+            if (!cursor.moveToFirst()) return null;
+            IsPrimaryInfo info = new IsPrimaryInfo();
+            info.isPrimary = cursor.getInt(0) != 0;
+            info.person = cursor.getLong(1);
+            info.id = cursor.getLong(2);
+            if (projection == sIsPrimaryProjectionWithKind) {
+                info.kind = cursor.getInt(3);
+            } else {
+                if (sPhonesTable.equals(table)) {
+                    info.kind = Contacts.KIND_PHONE;
+                } else if (sOrganizationsTable.equals(table)) {
+                    info.kind = Contacts.KIND_ORGANIZATION;
+                } else {
+                    throw new IllegalArgumentException("unexpected table, " + table);
+                }
+            }
+            return info;
+        } finally {
+            cursor.close();
+        }
+    }
+
+    /**
+     * Returns the rank of the table-specific type, used when deciding which row
+     * should be primary when none are primary. The lower the rank the better the type.
+     * @param table supports "phones", "contact_methods" and "organizations"
+     * @param type the table-specific type from the TYPE column
+     * @return the rank of the table-specific type, the lower the better
+     */
+    private int getRankOfType(String table, int type) {
+        if (table.equals(sPhonesTable)) {
+            switch (type) {
+                case Contacts.Phones.TYPE_MOBILE: return 0;
+                case Contacts.Phones.TYPE_WORK: return 1;
+                case Contacts.Phones.TYPE_HOME: return 2;
+                case Contacts.Phones.TYPE_PAGER: return 3;
+                case Contacts.Phones.TYPE_CUSTOM: return 4;
+                case Contacts.Phones.TYPE_OTHER: return 5;
+                case Contacts.Phones.TYPE_FAX_WORK: return 6;
+                case Contacts.Phones.TYPE_FAX_HOME: return 7;
+                default: return 1000;
+            }
+        }
+
+        if (table.equals(sContactMethodsTable)) {
+            switch (type) {
+                case Contacts.ContactMethods.TYPE_HOME: return 0;
+                case Contacts.ContactMethods.TYPE_WORK: return 1;
+                case Contacts.ContactMethods.TYPE_CUSTOM: return 2;
+                case Contacts.ContactMethods.TYPE_OTHER: return 3;
+                default: return 1000;
+            }
+        }
+
+        if (table.equals(sOrganizationsTable)) {
+            switch (type) {
+                case Organizations.TYPE_WORK: return 0;
+                case Organizations.TYPE_CUSTOM: return 1;
+                case Organizations.TYPE_OTHER: return 2;
+                default: return 1000;
+            }
+        }
+
+        throw new IllegalArgumentException("unexpected table, " + table);
+    }
+
+    /**
+     * Determines which of the rows in table for the personId should be picked as the primary
+     * row based on the rank of the row's type.
+     * @param kind the kind of contact
+     * @param personId used to limit the rows to those pertaining to this person
+     * @param itemId optional, a row to ignore
+     * @return the _id of the row that should be the new primary. Is null if there are no
+     *   matching rows.
+     */
+    private Long findNewPrimary(int kind, Long personId, Long itemId) {
+        final String table = kindToTable(kind);
+        if (personId == null) throw new IllegalArgumentException("personId must not be null");
+        StringBuilder sb = new StringBuilder();
+        sb.append("person=");
+        sb.append(personId);
+        if (itemId != null) {
+            sb.append(" and _id!=");
+            sb.append(itemId);
+        }
+        if (sContactMethodsTable.equals(table)) {
+            sb.append(" and ");
+            sb.append(ContactMethods.KIND);
+            sb.append("=");
+            sb.append(kind);
+        }
+
+        Cursor cursor = getDatabase().query(table, ID_TYPE_PROJECTION, sb.toString(),
+                null, null, null, null);
+        try {
+            Long newPrimaryId = null;
+            int bestRank = -1;
+            while (cursor.moveToNext()) {
+                final int rank = getRankOfType(table, cursor.getInt(1));
+                if (bestRank == -1 || rank < bestRank) {
+                    newPrimaryId = cursor.getLong(0);
+                    bestRank = rank;
+                }
+            }
+            return newPrimaryId;
+        } finally {
+            cursor.close();
+        }
+    }
+
+    private void setIsPrimary(int kind, long personId, long itemId) {
+        final String table = kindToTable(kind);
+        StringBuilder sb = new StringBuilder();
+        sb.append("person=");
+        sb.append(personId);
+
+        if (sContactMethodsTable.equals(table)) {
+            sb.append(" and ");
+            sb.append(ContactMethods.KIND);
+            sb.append("=");
+            sb.append(kind);
+        }
+
+        final String where = sb.toString();
+        getDatabase().execSQL(
+                "UPDATE " + table + " SET isprimary=(_id=" + itemId + ") WHERE " + where);
+    }
+
+    /**
+     * Clears the isprimary flag for all rows other than the itemId.
+     * @param kind the kind of item
+     * @param personId used to limit the updates to rows pertaining to this person
+     * @param itemId which row to leave untouched
+     */
+    private void clearOtherIsPrimary(int kind, Long personId, Long itemId) {
+        final String table = kindToTable(kind);
+        if (personId == null) throw new IllegalArgumentException("personId must not be null");
+        StringBuilder sb = new StringBuilder();
+        sb.append("person=");
+        sb.append(personId);
+        if (itemId != null) {
+            sb.append(" and _id!=");
+            sb.append(itemId);
+        }
+        if (sContactMethodsTable.equals(table)) {
+            sb.append(" and ");
+            sb.append(ContactMethods.KIND);
+            sb.append("=");
+            sb.append(kind);
+        }
+
+        mValuesLocal.clear();
+        mValuesLocal.put("isprimary", 0);
+        getDatabase().update(table, mValuesLocal, sb.toString(), null);
+    }
+
+    /**
+     * Set the specified primary column for the person. This is used to make the people
+     * row reflect the isprimary flag in the people or contactmethods tables, which is
+     * authoritative.
+     * @param personId the person to modify
+     * @param column the name of the primary column (phone or email)
+     * @param primaryId the new value to write into the primary column
+     */
+    private void updatePeoplePrimary(Long personId, String column, Long primaryId) {
+        mValuesLocal.clear();
+        mValuesLocal.put(column, primaryId);
+        getDatabase().update(sPeopleTable, mValuesLocal, "_id=" + personId, null);
+    }
+
+    private static String addIdToWhereClause(String id, String where) {
+        if (id != null) {
+            StringBuilder whereSb = new StringBuilder("_id=");
+            whereSb.append(id);
+            if (!TextUtils.isEmpty(where)) {
+                whereSb.append(" AND (");
+                whereSb.append(where);
+                whereSb.append(')');
+            }
+            return whereSb.toString();
+        } else {
+            return where;
+        }
+    }
+
+    private boolean queryGroupMembershipContainsStarred(long personId) {
+        // TODO: Part 1 of 2 part hack to work around a bug in reusing SQLiteStatements
+        SQLiteStatement mGroupsMembershipQuery = null;
+
+        if (mGroupsMembershipQuery == null) {
+            String query =
+                "SELECT COUNT(*) FROM groups, groupmembership WHERE "
+                + sGroupsJoinString + " AND person=? AND groups.name=?";
+            mGroupsMembershipQuery = getDatabase().compileStatement(query);
+        }
+        long result = DatabaseUtils.longForQuery(mGroupsMembershipQuery,
+                new String[]{String.valueOf(personId), Groups.GROUP_ANDROID_STARRED});
+
+        // TODO: Part 2 of 2 part hack to work around a bug in reusing SQLiteStatements
+        mGroupsMembershipQuery.close();
+
+        return result != 0;
+    }
+
+    @Override
+    public boolean changeRequiresLocalSync(Uri uri) {
+        final int match = sURIMatcher.match(uri);
+        switch (match) {
+            // Changes to these URIs cannot cause syncable data to be changed, so don't
+            // bother trying to sync them.
+            case CALLS:
+            case CALLS_FILTER:
+            case CALLS_ID:
+            case PRESENCE:
+            case PRESENCE_ID:
+            case PEOPLE_UPDATE_CONTACT_TIME:
+                return false;
+
+            default:
+                return true;
+        }
+    }
+
+    @Override
+    protected Iterable<? extends AbstractTableMerger> getMergers() {
+        ArrayList<AbstractTableMerger> list = new ArrayList<AbstractTableMerger> ();
+        list.add(new PersonMerger());
+        list.add(new GroupMerger());
+        list.add(new PhotoMerger());
+        return list;
+    }
+
+    protected static String sPeopleTable = "people";
+    protected static Uri sPeopleRawURL = Uri.parse("content://contacts/people/raw/");
+    protected static String sDeletedPeopleTable = "_deleted_people";
+    protected static Uri sDeletedPeopleURL = Uri.parse("content://contacts/deleted_people/");
+    protected static String sGroupsTable = "groups";
+    protected static String sSettingsTable = "settings";
+    protected static Uri sGroupsURL = Uri.parse("content://contacts/groups/");
+    protected static String sDeletedGroupsTable = "_deleted_groups";
+    protected static Uri sDeletedGroupsURL =
+            Uri.parse("content://contacts/deleted_groups/");
+    protected static String sPhonesTable = "phones";
+    protected static String sOrganizationsTable = "organizations";
+    protected static String sContactMethodsTable = "contact_methods";
+    protected static String sGroupmembershipTable = "groupmembership";
+    protected static String sPhotosTable = "photos";
+    protected static Uri sPhotosURL = Uri.parse("content://contacts/photos/");
+    protected static String sExtensionsTable = "extensions";
+    protected static String sCallsTable = "calls";
+
+    protected class PersonMerger extends AbstractTableMerger
+    {
+        private ContentValues mValues = new ContentValues();
+        Map<String, SQLiteCursor> mCursorMap = Maps.newHashMap();
+        public PersonMerger()
+        {
+            super(getDatabase(),
+                    sPeopleTable, sPeopleRawURL, sDeletedPeopleTable, sDeletedPeopleURL);
+        }
+
+        @Override
+        protected void notifyChanges() {
+            // notify that a change has occurred.
+            getContext().getContentResolver().notifyChange(Contacts.CONTENT_URI,
+                    null /* observer */, false /* do not sync to network */);
+        }
+
+        @Override
+        public void insertRow(ContentProvider diffs, Cursor diffsCursor) {
+            final SQLiteDatabase db = getDatabase();
+
+            Long localPrimaryPhoneId = null;
+            Long localPrimaryEmailId = null;
+            Long localPrimaryOrganizationId = null;
+
+            // 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);
+            long localPersonID = mPeopleInserter.execute();
+
+            Cursor c;
+            final SQLiteDatabase diffsDb = ((ContactsProvider) diffs).getDatabase();
+            long diffsPersonID = diffsCursor.getLong(diffsCursor.getColumnIndexOrThrow(People._ID));
+
+            // Copy the Photo info
+            c = doSubQuery(diffsDb, sPhotosTable, null, diffsPersonID, null);
+            try {
+                if (c.moveToNext()) {
+                    mDb.delete(sPhotosTable, "person=" + localPersonID, null);
+                    mPhotosInserter.prepareForInsert();
+                    DatabaseUtils.cursorStringToInsertHelper(c, Photos._SYNC_ID,
+                            mPhotosInserter, mIndexPhotosSyncId);
+                    DatabaseUtils.cursorStringToInsertHelper(c, Photos._SYNC_TIME,
+                            mPhotosInserter, mIndexPhotosSyncTime);
+                    DatabaseUtils.cursorStringToInsertHelper(c, Photos._SYNC_VERSION,
+                            mPhotosInserter, mIndexPhotosSyncVersion);
+                    DatabaseUtils.cursorStringToInsertHelper(c, Photos._SYNC_ACCOUNT,
+                            mPhotosInserter, mIndexPhotosSyncAccount);
+                    DatabaseUtils.cursorStringToInsertHelper(c, Photos.EXISTS_ON_SERVER,
+                            mPhotosInserter, mIndexPhotosExistsOnServer);
+                    mPhotosInserter.bind(mIndexPhotosSyncError, (String)null);
+                    mPhotosInserter.bind(mIndexPhotosSyncDirty, 0);
+                    mPhotosInserter.bind(mIndexPhotosPersonId, localPersonID);
+                    mPhotosInserter.execute();
+                }
+            } finally {
+                c.deactivate();
+            }
+
+            // Copy all phones
+            c = doSubQuery(diffsDb, sPhonesTable, null, diffsPersonID, sPhonesTable + "._id");
+            if (c != null) {
+                Long newPrimaryId = null;
+                int bestRank = -1;
+                final int labelIndex = c.getColumnIndexOrThrow(Phones.LABEL);
+                final int typeIndex = c.getColumnIndexOrThrow(Phones.TYPE);
+                final int numberIndex = c.getColumnIndexOrThrow(Phones.NUMBER);
+                final int keyIndex = c.getColumnIndexOrThrow(Phones.NUMBER_KEY);
+                final int primaryIndex = c.getColumnIndexOrThrow(Phones.ISPRIMARY);
+                while(c.moveToNext()) {
+                    final int type = c.getInt(typeIndex);
+                    final int isPrimaryValue = c.getInt(primaryIndex);
+                    mPhonesInserter.prepareForInsert();
+                    mPhonesInserter.bind(mIndexPhonesPersonId, localPersonID);
+                    mPhonesInserter.bind(mIndexPhonesLabel, c.getString(labelIndex));
+                    mPhonesInserter.bind(mIndexPhonesType, type);
+                    mPhonesInserter.bind(mIndexPhonesNumber, c.getString(numberIndex));
+                    mPhonesInserter.bind(mIndexPhonesNumberKey, c.getString(keyIndex));
+                    mPhonesInserter.bind(mIndexPhonesIsPrimary, isPrimaryValue);
+                    long rowId = mPhonesInserter.execute();
+
+                    if (isPrimaryValue != 0) {
+                        if (localPrimaryPhoneId != null) {
+                            throw new IllegalArgumentException(
+                                    "more than one phone was marked as primary, "
+                                            + DatabaseUtils.dumpCursorToString(c));
+                        }
+                        localPrimaryPhoneId = rowId;
+                    }
+
+                    if (localPrimaryPhoneId == null) {
+                        final int rank = getRankOfType(sPhonesTable, type);
+                        if (bestRank == -1 || rank < bestRank) {
+                            newPrimaryId = rowId;
+                            bestRank = rank;
+                        }
+                    }
+                }
+                c.deactivate();
+
+                if (localPrimaryPhoneId == null) {
+                    localPrimaryPhoneId = newPrimaryId;
+                }
+            }
+
+            // Copy all contact_methods
+            c = doSubQuery(diffsDb, sContactMethodsTable, null, diffsPersonID,
+                    sContactMethodsTable + "._id");
+            if (c != null) {
+                Long newPrimaryId = null;
+                int bestRank = -1;
+                final int labelIndex = c.getColumnIndexOrThrow(ContactMethods.LABEL);
+                final int kindIndex = c.getColumnIndexOrThrow(ContactMethods.KIND);
+                final int typeIndex = c.getColumnIndexOrThrow(ContactMethods.TYPE);
+                final int dataIndex = c.getColumnIndexOrThrow(ContactMethods.DATA);
+                final int auxDataIndex = c.getColumnIndexOrThrow(ContactMethods.AUX_DATA);
+                final int primaryIndex = c.getColumnIndexOrThrow(ContactMethods.ISPRIMARY);
+                while(c.moveToNext()) {
+                    final int type = c.getInt(typeIndex);
+                    final int kind = c.getInt(kindIndex);
+                    final int isPrimaryValue = c.getInt(primaryIndex);
+                    mContactMethodsInserter.prepareForInsert();
+                    mContactMethodsInserter.bind(mIndexContactMethodsPersonId, localPersonID);
+                    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(mIndexContactMethodsIsPrimary, isPrimaryValue);
+                    long rowId = mContactMethodsInserter.execute();
+                    if ((kind == Contacts.KIND_EMAIL) && (isPrimaryValue != 0)) {
+                        if (localPrimaryEmailId != null) {
+                            throw new IllegalArgumentException(
+                                    "more than one email was marked as primary, "
+                                            + DatabaseUtils.dumpCursorToString(c));
+                        }
+                        localPrimaryEmailId = rowId;
+                    }
+
+                    if (localPrimaryEmailId == null) {
+                        final int rank = getRankOfType(sContactMethodsTable, type);
+                        if (bestRank == -1 || rank < bestRank) {
+                            newPrimaryId = rowId;
+                            bestRank = rank;
+                        }
+                    }
+                }
+                c.deactivate();
+
+                if (localPrimaryEmailId == null) {
+                    localPrimaryEmailId = newPrimaryId;
+                }
+            }
+
+            // Copy all organizations
+            c = doSubQuery(diffsDb, sOrganizationsTable, null, diffsPersonID,
+                    sOrganizationsTable + "._id");
+            try {
+                Long newPrimaryId = null;
+                int bestRank = -1;
+                final int labelIndex = c.getColumnIndexOrThrow(Organizations.LABEL);
+                final int typeIndex = c.getColumnIndexOrThrow(Organizations.TYPE);
+                final int companyIndex = c.getColumnIndexOrThrow(Organizations.COMPANY);
+                final int titleIndex = c.getColumnIndexOrThrow(Organizations.TITLE);
+                final int primaryIndex = c.getColumnIndexOrThrow(Organizations.ISPRIMARY);
+                while(c.moveToNext()) {
+                    final int type = c.getInt(typeIndex);
+                    final int isPrimaryValue = c.getInt(primaryIndex);
+                    mOrganizationsInserter.prepareForInsert();
+                    mOrganizationsInserter.bind(mIndexOrganizationsPersonId, localPersonID);
+                    mOrganizationsInserter.bind(mIndexOrganizationsLabel, c.getString(labelIndex));
+                    mOrganizationsInserter.bind(mIndexOrganizationsType, type);
+                    mOrganizationsInserter.bind(mIndexOrganizationsCompany, c.getString(companyIndex));
+                    mOrganizationsInserter.bind(mIndexOrganizationsTitle, c.getString(titleIndex));
+                    mOrganizationsInserter.bind(mIndexOrganizationsIsPrimary, isPrimaryValue);
+                    long rowId = mOrganizationsInserter.execute();
+                    if (isPrimaryValue != 0) {
+                        if (localPrimaryOrganizationId != null) {
+                            throw new IllegalArgumentException(
+                                    "more than one organization was marked as primary, "
+                                            + DatabaseUtils.dumpCursorToString(c));
+                        }
+                        localPrimaryOrganizationId = rowId;
+                    }
+
+                    if (localPrimaryOrganizationId == null) {
+                        final int rank = getRankOfType(sOrganizationsTable, type);
+                        if (bestRank == -1 || rank < bestRank) {
+                            newPrimaryId = rowId;
+                            bestRank = rank;
+                        }
+                    }
+                }
+
+                if (localPrimaryOrganizationId == null) {
+                    localPrimaryOrganizationId = newPrimaryId;
+                }
+            } finally {
+                c.deactivate();
+            }
+
+            // Copy all groupmembership rows
+            c = doSubQuery(diffsDb, sGroupmembershipTable, null, diffsPersonID,
+                    sGroupmembershipTable + "._id");
+            try {
+                final int accountIndex =
+                    c.getColumnIndexOrThrow(GroupMembership.GROUP_SYNC_ACCOUNT);
+                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.execute();
+                }
+            } finally {
+                c.deactivate();
+            }
+
+            // Copy all extensions rows
+            c = doSubQuery(diffsDb, sExtensionsTable, null, diffsPersonID, sExtensionsTable + "._id");
+            try {
+                final int nameIndex = c.getColumnIndexOrThrow(Extensions.NAME);
+                final int valueIndex = c.getColumnIndexOrThrow(Extensions.VALUE);
+                while(c.moveToNext()) {
+                    mExtensionsInserter.prepareForInsert();
+                    mExtensionsInserter.bind(mIndexExtensionsPersonId, localPersonID);
+                    mExtensionsInserter.bind(mIndexExtensionsName, c.getString(nameIndex));
+                    mExtensionsInserter.bind(mIndexExtensionsValue, c.getString(valueIndex));
+                    mExtensionsInserter.execute();
+                }
+            } finally {
+                c.deactivate();
+            }
+
+            // Update the _SYNC_DIRTY flag of the person. We have to do this
+            // after inserting since the updated of the phones, contact
+            // methods and organizations will fire a sql trigger that will
+            // cause this flag to be set.
+            mValues.clear();
+            mValues.put(People._SYNC_DIRTY, 0);
+            mValues.put(People.PRIMARY_PHONE_ID, localPrimaryPhoneId);
+            mValues.put(People.PRIMARY_EMAIL_ID, localPrimaryEmailId);
+            mValues.put(People.PRIMARY_ORGANIZATION_ID, localPrimaryOrganizationId);
+            final boolean isStarred = queryGroupMembershipContainsStarred(localPersonID);
+            mValues.put(People.STARRED, isStarred ? 1 : 0);
+            db.update(mTable, mValues, People._ID + '=' + localPersonID, null);
+        }
+
+        @Override
+        public void updateRow(long localPersonID, ContentProvider diffs, Cursor diffsCursor) {
+            updateOrResolveRow(localPersonID, null, diffs, diffsCursor, false);
+        }
+
+        @Override
+        public void resolveRow(long localPersonID, String syncID,
+                ContentProvider diffs, Cursor diffsCursor) {
+            updateOrResolveRow(localPersonID, syncID, diffs, diffsCursor, true);
+        }
+
+        protected void updateOrResolveRow(long localPersonID, String syncID,
+                ContentProvider diffs, Cursor diffsCursor, boolean conflicts) {
+            final SQLiteDatabase db = getDatabase();
+            // The local version of localPersonId's record has changed. This
+            // person also has a changed record in the diffs. Merge the changes
+            // in the following way:
+            //  - if any fields in the people table changed use the server's
+            //    version
+            //  - for phones, emails, addresses, compute the join of all unique
+            //    subrecords. If any of the subrecords has changes in both
+            //    places then choose the server version of the subrecord
+            //
+            // Limitation: deletes of phones, emails, or addresses are ignored
+            // when the record has changed on both the client and the server
+
+            long diffsPersonID = diffsCursor.getLong(diffsCursor.getColumnIndexOrThrow("_id"));
+
+            // Join the server phones, organizations, and contact_methods with the local ones.
+            //  - Add locally any that exist only on the server.
+            //  - If the row conflicts, delete locally any that exist only on the client.
+            //  - If the row doesn't conflict, ignore any that exist only on the client.
+            //  - Update any that exist in both places.
+
+            Map<Integer, Long> primaryLocal = new HashMap<Integer, Long>();
+            Map<Integer, Long> primaryDiffs = new HashMap<Integer, Long>();
+
+            Cursor cRemote;
+            Cursor cLocal;
+
+            // Phones
+            cRemote = null;
+            cLocal = null;
+            final SQLiteDatabase diffsDb = ((ContactsProvider) diffs).getDatabase();
+            try {
+                cLocal = doSubQuery(db, sPhonesTable, null, localPersonID, sPhonesKeyOrderBy);
+                cRemote = doSubQuery(diffsDb, sPhonesTable,
+                        null, diffsPersonID, sPhonesKeyOrderBy);
+
+                final int idColLocal = cLocal.getColumnIndexOrThrow(Phones._ID);
+                final int isPrimaryColLocal = cLocal.getColumnIndexOrThrow(Phones.ISPRIMARY);
+                final int isPrimaryColRemote = cRemote.getColumnIndexOrThrow(Phones.ISPRIMARY);
+
+                CursorJoiner joiner =
+                        new CursorJoiner(cLocal, sPhonesKeyColumns, cRemote, sPhonesKeyColumns);
+                for (CursorJoiner.Result joinResult : joiner) {
+                    switch(joinResult) {
+                        case LEFT:
+                            if (!conflicts) {
+                                db.delete(sPhonesTable,
+                                        Phones._ID + "=" + cLocal.getLong(idColLocal), null);
+                            } else {
+                                if (cLocal.getLong(isPrimaryColLocal) != 0) {
+                                    savePrimaryId(primaryLocal, Contacts.KIND_PHONE,
+                                            cLocal.getLong(idColLocal));
+                                }
+                            }
+                            break;
+
+                        case RIGHT:
+                        case BOTH:
+                            mValues.clear();
+                            DatabaseUtils.cursorIntToContentValues(
+                                    cRemote, Phones.TYPE, mValues);
+                            DatabaseUtils.cursorStringToContentValues(
+                                    cRemote, Phones.LABEL, mValues);
+                            DatabaseUtils.cursorStringToContentValues(
+                                    cRemote, Phones.NUMBER, mValues);
+                            DatabaseUtils.cursorStringToContentValues(
+                                    cRemote, Phones.NUMBER_KEY, mValues);
+                            DatabaseUtils.cursorIntToContentValues(
+                                    cRemote, Phones.ISPRIMARY, mValues);
+
+                            long localId;
+                            if (joinResult == CursorJoiner.Result.RIGHT) {
+                                mValues.put(Phones.PERSON_ID, localPersonID);
+                                localId = mPhonesInserter.insert(mValues);
+                            } else {
+                                localId = cLocal.getLong(idColLocal);
+                                db.update(sPhonesTable, mValues, "_id =" + localId, null);
+                            }
+                            if (cRemote.getLong(isPrimaryColRemote) != 0) {
+                                savePrimaryId(primaryDiffs, Contacts.KIND_PHONE, localId);
+                            }
+                            break;
+                    }
+                }
+            } finally {
+                if (cRemote != null) cRemote.deactivate();
+                if (cLocal != null) cLocal.deactivate();
+            }
+
+            // Contact methods
+            cRemote = null;
+            cLocal = null;
+            try {
+                cLocal = doSubQuery(db,
+                        sContactMethodsTable, null, localPersonID, sContactMethodsKeyOrderBy);
+                cRemote = doSubQuery(diffsDb,
+                        sContactMethodsTable, null, diffsPersonID, sContactMethodsKeyOrderBy);
+
+                final int idColLocal = cLocal.getColumnIndexOrThrow(ContactMethods._ID);
+                final int kindColLocal = cLocal.getColumnIndexOrThrow(ContactMethods.KIND);
+                final int kindColRemote = cRemote.getColumnIndexOrThrow(ContactMethods.KIND);
+                final int isPrimaryColLocal =
+                        cLocal.getColumnIndexOrThrow(ContactMethods.ISPRIMARY);
+                final int isPrimaryColRemote =
+                        cRemote.getColumnIndexOrThrow(ContactMethods.ISPRIMARY);
+
+                CursorJoiner joiner = new CursorJoiner(
+                        cLocal, sContactMethodsKeyColumns, cRemote, sContactMethodsKeyColumns);
+                for (CursorJoiner.Result joinResult : joiner) {
+                    switch(joinResult) {
+                        case LEFT:
+                            if (!conflicts) {
+                                db.delete(sContactMethodsTable, ContactMethods._ID + "="
+                                        + cLocal.getLong(idColLocal), null);
+                            } else {
+                                if (cLocal.getLong(isPrimaryColLocal) != 0) {
+                                    savePrimaryId(primaryLocal, cLocal.getInt(kindColLocal),
+                                            cLocal.getLong(idColLocal));
+                                }
+                            }
+                            break;
+
+                        case RIGHT:
+                        case BOTH:
+                            mValues.clear();
+                            DatabaseUtils.cursorStringToContentValues(cRemote,
+                                    ContactMethods.LABEL, mValues);
+                            DatabaseUtils.cursorIntToContentValues(cRemote,
+                                    ContactMethods.TYPE, mValues);
+                            DatabaseUtils.cursorIntToContentValues(cRemote,
+                                    ContactMethods.KIND, mValues);
+                            DatabaseUtils.cursorStringToContentValues(cRemote,
+                                    ContactMethods.DATA, mValues);
+                            DatabaseUtils.cursorStringToContentValues(cRemote,
+                                    ContactMethods.AUX_DATA, mValues);
+                            DatabaseUtils.cursorIntToContentValues(cRemote,
+                                    ContactMethods.ISPRIMARY, mValues);
+
+                            long localId;
+                            if (joinResult == CursorJoiner.Result.RIGHT) {
+                                mValues.put(ContactMethods.PERSON_ID, localPersonID);
+                                localId = mContactMethodsInserter.insert(mValues);
+                            } else {
+                                localId = cLocal.getLong(idColLocal);
+                                db.update(sContactMethodsTable, mValues, "_id =" + localId, null);
+                            }
+                            if (cRemote.getLong(isPrimaryColRemote) != 0) {
+                                savePrimaryId(primaryDiffs, cRemote.getInt(kindColRemote), localId);
+                            }
+                            break;
+                    }
+                }
+            } finally {
+                if (cRemote != null) cRemote.deactivate();
+                if (cLocal != null) cLocal.deactivate();
+            }
+
+            // Organizations
+            cRemote = null;
+            cLocal = null;
+            try {
+                cLocal = doSubQuery(db,
+                        sOrganizationsTable, null, localPersonID, sOrganizationsKeyOrderBy);
+                cRemote = doSubQuery(diffsDb,
+                        sOrganizationsTable, null, diffsPersonID, sOrganizationsKeyOrderBy);
+
+                final int idColLocal = cLocal.getColumnIndexOrThrow(Organizations._ID);
+                final int isPrimaryColLocal =
+                        cLocal.getColumnIndexOrThrow(ContactMethods.ISPRIMARY);
+                final int isPrimaryColRemote =
+                        cRemote.getColumnIndexOrThrow(ContactMethods.ISPRIMARY);
+                CursorJoiner joiner = new CursorJoiner(
+                        cLocal, sOrganizationsKeyColumns, cRemote, sOrganizationsKeyColumns);
+                for (CursorJoiner.Result joinResult : joiner) {
+                    switch(joinResult) {
+                        case LEFT:
+                            if (!conflicts) {
+                                db.delete(sOrganizationsTable,
+                                        Phones._ID + "=" + cLocal.getLong(idColLocal), null);
+                            } else {
+                                if (cLocal.getLong(isPrimaryColLocal) != 0) {
+                                    savePrimaryId(primaryLocal, Contacts.KIND_ORGANIZATION,
+                                            cLocal.getLong(idColLocal));
+                                }
+                            }
+                            break;
+
+                        case RIGHT:
+                        case BOTH:
+                            mValues.clear();
+                            DatabaseUtils.cursorStringToContentValues(cRemote,
+                                    Organizations.LABEL, mValues);
+                            DatabaseUtils.cursorIntToContentValues(cRemote,
+                                    Organizations.TYPE, mValues);
+                            DatabaseUtils.cursorStringToContentValues(cRemote,
+                                    Organizations.COMPANY, mValues);
+                            DatabaseUtils.cursorStringToContentValues(cRemote,
+                                    Organizations.TITLE, mValues);
+                            DatabaseUtils.cursorIntToContentValues(cRemote,
+                                    Organizations.ISPRIMARY, mValues);
+                            long localId;
+                            if (joinResult == CursorJoiner.Result.RIGHT) {
+                                mValues.put(Organizations.PERSON_ID, localPersonID);
+                                localId = mOrganizationsInserter.insert(mValues);
+                            } else {
+                                localId = cLocal.getLong(idColLocal);
+                                db.update(sOrganizationsTable, mValues,
+                                        "_id =" + localId, null /* whereArgs */);
+                            }
+                            if (cRemote.getLong(isPrimaryColRemote) != 0) {
+                                savePrimaryId(primaryDiffs, Contacts.KIND_ORGANIZATION, localId);
+                            }
+                            break;
+                    }
+                }
+            } finally {
+                if (cRemote != null) cRemote.deactivate();
+                if (cLocal != null) cLocal.deactivate();
+            }
+
+            // Groupmembership
+            cRemote = null;
+            cLocal = null;
+            try {
+                cLocal = doSubQuery(db,
+                        sGroupmembershipTable, null, localPersonID, sGroupmembershipKeyOrderBy);
+                cRemote = doSubQuery(diffsDb,
+                        sGroupmembershipTable, null, diffsPersonID, sGroupmembershipKeyOrderBy);
+
+                final int idColLocal = cLocal.getColumnIndexOrThrow(GroupMembership._ID);
+                CursorJoiner joiner = new CursorJoiner(
+                        cLocal, sGroupmembershipKeyColumns, cRemote, sGroupmembershipKeyColumns);
+                for (CursorJoiner.Result joinResult : joiner) {
+                    switch(joinResult) {
+                        case LEFT:
+                            if (!conflicts) {
+                                db.delete(sGroupmembershipTable,
+                                        Phones._ID + "=" + cLocal.getLong(idColLocal), null);
+                            }
+                            break;
+
+                        case RIGHT:
+                        case BOTH:
+                            mValues.clear();
+                            DatabaseUtils.cursorStringToContentValues(cRemote,
+                                    GroupMembership.GROUP_SYNC_ACCOUNT, mValues);
+                            DatabaseUtils.cursorStringToContentValues(cRemote,
+                                    GroupMembership.GROUP_SYNC_ID, mValues);
+                            if (joinResult == CursorJoiner.Result.RIGHT) {
+                                mValues.put(GroupMembership.PERSON_ID, localPersonID);
+                                mGroupMembershipInserter.insert(mValues);
+                            } else {
+                                db.update(sGroupmembershipTable, mValues,
+                                        "_id =" + cLocal.getLong(idColLocal), null /* whereArgs */);
+                            }
+                            break;
+                    }
+                }
+            } finally {
+                if (cRemote != null) cRemote.deactivate();
+                if (cLocal != null) cLocal.deactivate();
+            }
+
+            // Extensions
+            cRemote = null;
+            cLocal = null;
+            try {
+                cLocal = doSubQuery(db,
+                        sExtensionsTable, null, localPersonID, Extensions.NAME);
+                cRemote = doSubQuery(diffsDb,
+                        sExtensionsTable, null, diffsPersonID, Extensions.NAME);
+
+                final int idColLocal = cLocal.getColumnIndexOrThrow(Extensions._ID);
+                CursorJoiner joiner = new CursorJoiner(
+                        cLocal, sExtensionsKeyColumns, cRemote, sExtensionsKeyColumns);
+                for (CursorJoiner.Result joinResult : joiner) {
+                    switch(joinResult) {
+                        case LEFT:
+                            if (!conflicts) {
+                                db.delete(sExtensionsTable,
+                                        Phones._ID + "=" + cLocal.getLong(idColLocal), null);
+                            }
+                            break;
+
+                        case RIGHT:
+                        case BOTH:
+                            mValues.clear();
+                            DatabaseUtils.cursorStringToContentValues(cRemote,
+                                    Extensions.NAME, mValues);
+                            DatabaseUtils.cursorStringToContentValues(cRemote,
+                                    Extensions.VALUE, mValues);
+                            if (joinResult == CursorJoiner.Result.RIGHT) {
+                                mValues.put(Extensions.PERSON_ID, localPersonID);
+                                mExtensionsInserter.insert(mValues);
+                            } else {
+                                db.update(sExtensionsTable, mValues,
+                                        "_id =" + cLocal.getLong(idColLocal), null /* whereArgs */);
+                            }
+                            break;
+                    }
+                }
+            } finally {
+                if (cRemote != null) cRemote.deactivate();
+                if (cLocal != null) cLocal.deactivate();
+            }
+
+            // Copy the Photo's server id and account so that the merger will find it
+            cRemote = doSubQuery(diffsDb, sPhotosTable, null, diffsPersonID, null);
+            try {
+                if(cRemote.moveToNext()) {
+                    mValues.clear();
+                    DatabaseUtils.cursorStringToContentValues(cRemote, Photos._SYNC_ID, mValues);
+                    DatabaseUtils.cursorStringToContentValues(cRemote, Photos._SYNC_ACCOUNT, mValues);
+                    db.update(sPhotosTable, mValues, Photos.PERSON_ID + '=' + localPersonID, null);
+                }
+            } finally {
+                cRemote.deactivate();
+            }
+
+            // make sure there is exactly one primary set for each of these types
+            Long primaryPhoneId = setSinglePrimary(
+                    primaryDiffs, primaryLocal, localPersonID, Contacts.KIND_PHONE);
+
+            Long primaryEmailId = setSinglePrimary(
+                    primaryDiffs, primaryLocal, localPersonID, Contacts.KIND_EMAIL);
+
+            Long primaryOrganizationId = setSinglePrimary(
+                    primaryDiffs, primaryLocal, localPersonID, Contacts.KIND_ORGANIZATION);
+
+            setSinglePrimary(primaryDiffs, primaryLocal, localPersonID, Contacts.KIND_IM);
+
+            setSinglePrimary(primaryDiffs, primaryLocal, localPersonID, Contacts.KIND_POSTAL);
+
+            // Update the person
+            mValues.clear();
+            DatabaseUtils.cursorStringToContentValues(diffsCursor, People._SYNC_ID, mValues);
+            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.NAME, mValues);
+            DatabaseUtils.cursorStringToContentValues(diffsCursor, People.PHONETIC_NAME, mValues);
+            DatabaseUtils.cursorStringToContentValues(diffsCursor, People.NOTES, mValues);
+            mValues.put(People.PRIMARY_PHONE_ID, primaryPhoneId);
+            mValues.put(People.PRIMARY_EMAIL_ID, primaryEmailId);
+            mValues.put(People.PRIMARY_ORGANIZATION_ID, primaryOrganizationId);
+            final boolean isStarred = queryGroupMembershipContainsStarred(localPersonID);
+            mValues.put(People.STARRED, isStarred ? 1 : 0);
+            mValues.put(People._SYNC_DIRTY, conflicts ? 1 : 0);
+            db.update(mTable, mValues, People._ID + '=' + localPersonID, null);
+        }
+
+        private void savePrimaryId(Map<Integer, Long> primaryDiffs, Integer kind, long localId) {
+            if (primaryDiffs.containsKey(kind)) {
+                throw new IllegalArgumentException("more than one of kind "
+                        + kind + " was marked as primary");
+            }
+            primaryDiffs.put(kind, localId);
+        }
+
+        private Long setSinglePrimary(
+                Map<Integer, Long> diffsMap,
+                Map<Integer, Long> localMap,
+                long localPersonID, int kind) {
+            Long primaryId = diffsMap.containsKey(kind) ? diffsMap.get(kind) : null;
+            if (primaryId == null) {
+                primaryId = localMap.containsKey(kind) ? localMap.get(kind) : null;
+            }
+            if (primaryId == null) {
+                primaryId = findNewPrimary(kind, localPersonID, null);
+            }
+            clearOtherIsPrimary(kind, localPersonID, primaryId);
+            return primaryId;
+        }
+
+        /**
+         * Returns a cursor on the specified table that selects rows where
+         * the "person" column is equal to the personId parameter. The cursor
+         * is also saved and may be returned in future calls where db and table
+         * parameter are the same. In that case the projection and orderBy parameters
+         * are ignored, so one must take care to not change those parameters across
+         * multiple calls to the same db/table.
+         * <p>
+         * Since the cursor may be saced by this call, the caller must be sure to not
+         * close the cursor, though they still must deactivate it when they are done
+         * with it.
+         */
+        private Cursor doSubQuery(SQLiteDatabase db, String table, String[] projection,
+                long personId, String orderBy) {
+            final String[] selectArgs = new String[]{Long.toString(personId)};
+            final String key = (db == getDatabase() ? "local_" : "remote_") + table;
+            SQLiteCursor cursor = mCursorMap.get(key);
+
+            // don't use the cached cursor if it is from a different DB
+            if (cursor != null && cursor.getDatabase() != db) {
+                cursor.close();
+                cursor = null;
+            }
+
+            // If we can't find a cached cursor then create a new one and add it to the cache.
+            // Otherwise just change the selection arguments and requery it.
+            if (cursor == null) {
+                cursor = (SQLiteCursor)db.query(table, projection, "person=?", selectArgs,
+                        null, null, orderBy);
+                mCursorMap.put(key, cursor);
+            } else {
+                cursor.setSelectionArguments(selectArgs);
+                cursor.requery();
+            }
+            return cursor;
+        }
+    }
+
+    protected class GroupMerger extends AbstractTableMerger {
+        private ContentValues mValues = new ContentValues();
+
+        private static final String UNSYNCED_GROUP_BY_NAME_WHERE_CLAUSE =
+                Groups._SYNC_ID + " is null AND "
+                        + Groups._SYNC_ACCOUNT + " is null AND "
+                        + Groups.NAME + "=?";
+
+        private static final String UNSYNCED_GROUP_BY_SYSTEM_ID_WHERE_CLAUSE =
+                Groups._SYNC_ID + " is null AND "
+                        + Groups._SYNC_ACCOUNT + " is null AND "
+                        + Groups.SYSTEM_ID + "=?";
+
+        public GroupMerger()
+        {
+            super(getDatabase(), sGroupsTable, sGroupsURL, sDeletedGroupsTable, sDeletedGroupsURL);
+        }
+
+        @Override
+        protected void notifyChanges() {
+            // notify that a change has occurred.
+            getContext().getContentResolver().notifyChange(Contacts.CONTENT_URI,
+                    null /* observer */, false /* do not sync to network */);
+        }
+
+        @Override
+        public void insertRow(ContentProvider diffs, Cursor cursor) {
+            // if an unsynced group with this name already exists then update it, otherwise
+            // insert a new group
+            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.NAME, mValues);
+            DatabaseUtils.cursorStringToContentValues(cursor, Groups.NOTES, mValues);
+            DatabaseUtils.cursorStringToContentValues(cursor, Groups.SYSTEM_ID, mValues);
+            mValues.put(Groups._SYNC_DIRTY, 0);
+
+            final String systemId = mValues.getAsString(Groups.SYSTEM_ID);
+            boolean rowUpdated = false;
+            if (TextUtils.isEmpty(systemId)) {
+                rowUpdated = getDatabase().update(mTable, mValues,
+                    UNSYNCED_GROUP_BY_NAME_WHERE_CLAUSE,
+                    new String[]{mValues.getAsString(Groups.NAME)}) > 0;
+            } else {
+                rowUpdated = getDatabase().update(mTable, mValues,
+                    UNSYNCED_GROUP_BY_SYSTEM_ID_WHERE_CLAUSE,
+                    new String[]{systemId}) > 0;
+            }
+            if (!rowUpdated) {
+                mGroupsInserter.insert(mValues);
+            } else {
+                // 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);
+            }
+
+            String oldName = null;
+            String newName = cursor.getString(cursor.getColumnIndexOrThrow(Groups.NAME));
+            String account = cursor.getString(cursor.getColumnIndexOrThrow(Groups._SYNC_ACCOUNT));
+            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);
+        }
+
+        @Override
+        public void updateRow(long localId, ContentProvider diffs, Cursor diffsCursor) {
+            updateOrResolveRow(localId, null, diffs, diffsCursor, false);
+        }
+
+        @Override
+        public void resolveRow(long localId, String syncID,
+                ContentProvider diffs, Cursor diffsCursor) {
+            updateOrResolveRow(localId, syncID, diffs, diffsCursor, true);
+        }
+
+        protected void updateOrResolveRow(long localRowId, String syncID,
+                ContentProvider diffs, Cursor cursor, boolean conflicts) {
+            final SQLiteDatabase db = getDatabase();
+
+            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 syncId = cursor.getString(cursor.getColumnIndexOrThrow(Groups._SYNC_ID));
+            // this can come before or after the delete
+            fixupPeopleStarredOnGroupRename(oldName, newName, account, 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.NAME, mValues);
+            DatabaseUtils.cursorStringToContentValues(cursor, Groups.NOTES, mValues);
+            DatabaseUtils.cursorStringToContentValues(cursor, Groups.SYSTEM_ID, mValues);
+            mValues.put(Groups._SYNC_DIRTY, 0);
+            db.update(mTable, mValues, Groups._ID + '=' + localRowId, null);
+        }
+
+        @Override
+        public void deleteRow(Cursor cursor) {
+            // we have to read this row from the DB since the projection that is used
+            // by cursor doesn't necessarily contain the columns we need
+            Cursor c = getDatabase().query(sGroupsTable, null,
+                    "_id=" + cursor.getLong(cursor.getColumnIndexOrThrow(Groups._ID)),
+                    null, null, null, null);
+            try {
+                c.moveToNext();
+                String oldName = c.getString(c.getColumnIndexOrThrow(Groups.NAME));
+                String newName = null;
+                String account = c.getString(c.getColumnIndexOrThrow(Groups._SYNC_ACCOUNT));
+                String syncId = c.getString(c.getColumnIndexOrThrow(Groups._SYNC_ID));
+                String systemId = c.getString(c.getColumnIndexOrThrow(Groups.SYSTEM_ID));
+                if (!TextUtils.isEmpty(systemId)) {
+                    // We don't support deleting of system groups, but due to a server bug they
+                    // occasionally get sent. Ignore the delete.
+                    Log.w(TAG, "ignoring a delete for a system group: " +
+                            DatabaseUtils.dumpCurrentRowToString(c));
+                    cursor.moveToNext();
+                    return;
+                }
+
+                // this must come before the delete, since the join won't work once this row is gone
+                fixupPeopleStarredOnGroupRename(oldName, newName, account, syncId);
+            } finally {
+                c.close();
+            }
+
+            cursor.deleteRow();
+        }
+    }
+
+    protected class PhotoMerger extends AbstractTableMerger {
+        private ContentValues mValues = new ContentValues();
+
+        public PhotoMerger() {
+            super(getDatabase(), sPhotosTable, sPhotosURL, null, null);
+        }
+
+        @Override
+        protected void notifyChanges() {
+            // notify that a change has occurred.
+            getContext().getContentResolver().notifyChange(Contacts.CONTENT_URI,
+                    null /* observer */, false /* do not sync to network */);
+        }
+
+        @Override
+        public void insertRow(ContentProvider diffs, Cursor cursor) {
+            // This photo may correspond to a contact that is in the delete table. If so then
+            // ignore this insert.
+            String syncId = cursor.getString(cursor.getColumnIndexOrThrow(Photos._SYNC_ID));
+            boolean contactIsDeleted = DatabaseUtils.longForQuery(getDatabase(),
+                    "select count(*) from _deleted_people where _sync_id=?",
+                    new String[]{syncId}) > 0;
+            if (contactIsDeleted) {
+                return;
+            }
+
+            throw new UnsupportedOperationException(
+                    "the photo row is inserted by PersonMerger.insertRow");
+        }
+
+        @Override
+        public void updateRow(long localId, ContentProvider diffs, Cursor diffsCursor) {
+            updateOrResolveRow(localId, null, diffs, diffsCursor, false);
+        }
+
+        @Override
+        public void resolveRow(long localId, String syncID,
+                ContentProvider diffs, Cursor diffsCursor) {
+            updateOrResolveRow(localId, syncID, diffs, diffsCursor, true);
+        }
+
+        protected void updateOrResolveRow(long localRowId, String syncID,
+                ContentProvider diffs, Cursor cursor, boolean conflicts) {
+            if (Log.isLoggable(TAG, Log.VERBOSE)) {
+                Log.v(TAG, "PhotoMerger.updateOrResolveRow: localRowId " + localRowId
+                        + ", syncId " + syncID + ", conflicts " + conflicts
+                        + ", server row " + DatabaseUtils.dumpCurrentRowToString(cursor));
+            }
+            mValues.clear();
+            DatabaseUtils.cursorStringToContentValues(cursor, Photos._SYNC_TIME, mValues);
+            DatabaseUtils.cursorStringToContentValues(cursor, Photos._SYNC_VERSION, mValues);
+            DatabaseUtils.cursorStringToContentValues(cursor, Photos.EXISTS_ON_SERVER, mValues);
+            // reset the error field to allow the phone to attempt to redownload the photo.
+            mValues.put(Photos.SYNC_ERROR, (String)null);
+
+            // If the photo didn't change locally and the server doesn't have a photo for this
+            // contact then delete the local photo.
+            long syncDirty = DatabaseUtils.longForQuery(getDatabase(),
+                    "SELECT _sync_dirty FROM photos WHERE _id=" + localRowId
+                            + " UNION SELECT 0 AS _sync_dirty ORDER BY _sync_dirty DESC LIMIT 1",
+                    null);
+            if (syncDirty == 0) {
+                if (mValues.getAsInteger(Photos.EXISTS_ON_SERVER) == 0) {
+                    mValues.put(Photos.DATA, (String)null);
+                    mValues.put(Photos.LOCAL_VERSION, mValues.getAsString(Photos.LOCAL_VERSION));
+                }
+                // if it does exist on the server then we will attempt to download it later
+            }
+            // if it does conflict then we will send the client version of the photo to
+            // the server later. That will trigger a new sync of the photo data which will
+            // cause this method to be called again, at which time the row will no longer
+            // conflict. We will then download the photo we just sent to the server and
+            // set the LOCAL_VERSION to match the data we just downloaded.
+
+            getDatabase().update(mTable, mValues, Photos._ID + '=' + localRowId, null);
+        }
+
+        @Override
+        public void deleteRow(Cursor cursor) {
+            // this row is never deleted explicitly, instead it is deleted by a trigger on
+            // the people table
+            cursor.moveToNext();
+        }
+    }
+
+    private static final String TAG = "ContactsProvider";
+
+    /* package private */ static final String DATABASE_NAME = "contacts.db";
+    /* package private */ static final int DATABASE_VERSION = 80;
+
+    protected static final String CONTACTS_AUTHORITY = "contacts";
+    protected static final String CALL_LOG_AUTHORITY = "call_log";
+
+    private static final int PEOPLE_BASE = 0;
+    private static final int PEOPLE = PEOPLE_BASE;
+    private static final int PEOPLE_FILTER = PEOPLE_BASE + 1;
+    private static final int PEOPLE_ID = PEOPLE_BASE + 2;
+    private static final int PEOPLE_PHONES = PEOPLE_BASE + 3;
+    private static final int PEOPLE_PHONES_ID = PEOPLE_BASE + 4;
+    private static final int PEOPLE_CONTACTMETHODS = PEOPLE_BASE + 5;
+    private static final int PEOPLE_CONTACTMETHODS_ID = PEOPLE_BASE + 6;
+    private static final int PEOPLE_RAW = PEOPLE_BASE + 7;
+    private static final int PEOPLE_WITH_PHONES_FILTER = PEOPLE_BASE + 8;
+    private static final int PEOPLE_STREQUENT = PEOPLE_BASE + 9;
+    private static final int PEOPLE_STREQUENT_FILTER = PEOPLE_BASE + 10;
+    private static final int PEOPLE_ORGANIZATIONS = PEOPLE_BASE + 11;
+    private static final int PEOPLE_ORGANIZATIONS_ID = PEOPLE_BASE + 12;
+    private static final int PEOPLE_GROUPMEMBERSHIP = PEOPLE_BASE + 13;
+    private static final int PEOPLE_GROUPMEMBERSHIP_ID = PEOPLE_BASE + 14;
+    private static final int PEOPLE_PHOTO = PEOPLE_BASE + 15;
+    private static final int PEOPLE_EXTENSIONS = PEOPLE_BASE + 16;
+    private static final int PEOPLE_EXTENSIONS_ID = PEOPLE_BASE + 17;
+    private static final int PEOPLE_CONTACTMETHODS_WITH_PRESENCE = PEOPLE_BASE + 18;
+    private static final int PEOPLE_OWNER = PEOPLE_BASE + 19;
+    private static final int PEOPLE_UPDATE_CONTACT_TIME = PEOPLE_BASE + 20;
+    private static final int PEOPLE_PHONES_WITH_PRESENCE = PEOPLE_BASE + 21;
+
+    private static final int DELETED_BASE = 1000;
+    private static final int DELETED_PEOPLE = DELETED_BASE;
+    private static final int DELETED_GROUPS = DELETED_BASE + 1;
+
+    private static final int PHONES_BASE = 2000;
+    private static final int PHONES = PHONES_BASE;
+    private static final int PHONES_ID = PHONES_BASE + 1;
+    private static final int PHONES_FILTER = PHONES_BASE + 2;
+    private static final int PHONES_FILTER_NAME = PHONES_BASE + 3;
+    private static final int PHONES_MOBILE_FILTER_NAME = PHONES_BASE + 4;
+    private static final int PHONES_WITH_PRESENCE = PHONES_BASE + 5;
+
+    private static final int CONTACTMETHODS_BASE = 3000;
+    private static final int CONTACTMETHODS = CONTACTMETHODS_BASE;
+    private static final int CONTACTMETHODS_ID = CONTACTMETHODS_BASE + 1;
+    private static final int CONTACTMETHODS_EMAIL = CONTACTMETHODS_BASE + 2;
+    private static final int CONTACTMETHODS_EMAIL_FILTER = CONTACTMETHODS_BASE + 3;
+    private static final int CONTACTMETHODS_WITH_PRESENCE = CONTACTMETHODS_BASE + 4;
+
+    private static final int CALLS_BASE = 4000;
+    private static final int CALLS = CALLS_BASE;
+    private static final int CALLS_ID = CALLS_BASE + 1;
+    private static final int CALLS_FILTER = CALLS_BASE + 2;
+
+    private static final int PRESENCE_BASE = 5000;
+    private static final int PRESENCE = PRESENCE_BASE;
+    private static final int PRESENCE_ID = PRESENCE_BASE + 1;
+
+    private static final int ORGANIZATIONS_BASE = 6000;
+    private static final int ORGANIZATIONS = ORGANIZATIONS_BASE;
+    private static final int ORGANIZATIONS_ID = ORGANIZATIONS_BASE + 1;
+
+    private static final int VOICE_DIALER_TIMESTAMP = 7000;
+    private static final int SEARCH_SUGGESTIONS = 7001;
+
+    private static final int GROUPS_BASE = 8000;
+    private static final int GROUPS = GROUPS_BASE;
+    private static final int GROUPS_ID = GROUPS_BASE + 2;
+    private static final int GROUP_NAME_MEMBERS = GROUPS_BASE + 3;
+    private static final int GROUP_NAME_MEMBERS_FILTER = GROUPS_BASE + 4;
+    private static final int GROUP_SYSTEM_ID_MEMBERS = GROUPS_BASE + 5;
+    private static final int GROUP_SYSTEM_ID_MEMBERS_FILTER = GROUPS_BASE + 6;
+
+    private static final int GROUPMEMBERSHIP_BASE = 9000;
+    private static final int GROUPMEMBERSHIP = GROUPMEMBERSHIP_BASE;
+    private static final int GROUPMEMBERSHIP_ID = GROUPMEMBERSHIP_BASE + 2;
+    private static final int GROUPMEMBERSHIP_RAW = GROUPMEMBERSHIP_BASE + 3;
+
+    private static final int PHOTOS_BASE = 10000;
+    private static final int PHOTOS = PHOTOS_BASE;
+    private static final int PHOTOS_ID = PHOTOS_BASE + 1;
+
+    private static final int EXTENSIONS_BASE = 11000;
+    private static final int EXTENSIONS = EXTENSIONS_BASE;
+    private static final int EXTENSIONS_ID = EXTENSIONS_BASE + 2;
+
+    private static final int SETTINGS = 12000;
+    
+    private static final int LIVE_FOLDERS_BASE = 13000;
+    private static final int LIVE_FOLDERS_PEOPLE = LIVE_FOLDERS_BASE + 1;
+    private static final int LIVE_FOLDERS_PEOPLE_GROUP_NAME = LIVE_FOLDERS_BASE + 2;
+    private static final int LIVE_FOLDERS_PEOPLE_WITH_PHONES = LIVE_FOLDERS_BASE + 3;
+    private static final int LIVE_FOLDERS_PEOPLE_FAVORITES = LIVE_FOLDERS_BASE + 4;
+
+    private static final UriMatcher sURIMatcher = new UriMatcher(UriMatcher.NO_MATCH);
+
+    private static final HashMap<String, String> sGroupsProjectionMap;
+    private static final HashMap<String, String> sPeopleProjectionMap;
+    /** Used to force items to the top of a times_contacted list */
+    private static final HashMap<String, String> sPeopleWithMaxTimesContactedProjectionMap;
+    private static final HashMap<String, String> sCallsProjectionMap;
+    private static final HashMap<String, String> sPhonesProjectionMap;
+    private static final HashMap<String, String> sPhonesWithPresenceProjectionMap;
+    private static final HashMap<String, String> sContactMethodsProjectionMap;
+    private static final HashMap<String, String> sContactMethodsWithPresenceProjectionMap;
+    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;
+    private static final HashMap<String, String> sLiveFoldersProjectionMap;
+
+    private static final String sPhonesKeyOrderBy;
+    private static final String sContactMethodsKeyOrderBy;
+    private static final String sOrganizationsKeyOrderBy;
+    private static final String sGroupmembershipKeyOrderBy;
+
+    private static final String DISPLAY_NAME_SQL
+            = "(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) ";
+    
+    private static final String[] sPhonesKeyColumns;
+    private static final String[] sContactMethodsKeyColumns;
+    private static final String[] sOrganizationsKeyColumns;
+    private static final String[] sGroupmembershipKeyColumns;
+    private static final String[] sExtensionsKeyColumns;
+
+    static private String buildOrderBy(String table, String... columns) {
+        StringBuilder sb = null;
+        for (String column : columns) {
+            if (sb == null) {
+                sb = new StringBuilder();
+            } else {
+                sb.append(", ");
+            }
+            sb.append(table);
+            sb.append('.');
+            sb.append(column);
+        }
+        return (sb == null) ? "" : sb.toString();
+    }
+
+    static {
+        // Contacts URI matching table
+        UriMatcher matcher = sURIMatcher;
+        matcher.addURI(CONTACTS_AUTHORITY, "extensions", EXTENSIONS);
+        matcher.addURI(CONTACTS_AUTHORITY, "extensions/#", EXTENSIONS_ID);
+        matcher.addURI(CONTACTS_AUTHORITY, "groups", GROUPS);
+        matcher.addURI(CONTACTS_AUTHORITY, "groups/#", GROUPS_ID);
+        matcher.addURI(CONTACTS_AUTHORITY, "groups/name/*/members", GROUP_NAME_MEMBERS);
+        matcher.addURI(CONTACTS_AUTHORITY, "groups/name/*/members/filter/*",
+                GROUP_NAME_MEMBERS_FILTER);
+        matcher.addURI(CONTACTS_AUTHORITY, "groups/system_id/*/members", GROUP_SYSTEM_ID_MEMBERS);
+        matcher.addURI(CONTACTS_AUTHORITY, "groups/system_id/*/members/filter/*",
+                GROUP_SYSTEM_ID_MEMBERS_FILTER);
+        matcher.addURI(CONTACTS_AUTHORITY, "groupmembership", GROUPMEMBERSHIP);
+        matcher.addURI(CONTACTS_AUTHORITY, "groupmembership/#", GROUPMEMBERSHIP_ID);
+        matcher.addURI(CONTACTS_AUTHORITY, "groupmembershipraw", GROUPMEMBERSHIP_RAW);
+        matcher.addURI(CONTACTS_AUTHORITY, "people", PEOPLE);
+        matcher.addURI(CONTACTS_AUTHORITY, "people/strequent", PEOPLE_STREQUENT);
+        matcher.addURI(CONTACTS_AUTHORITY, "people/strequent/filter/*", PEOPLE_STREQUENT_FILTER);
+        matcher.addURI(CONTACTS_AUTHORITY, "people/filter/*", PEOPLE_FILTER);
+        matcher.addURI(CONTACTS_AUTHORITY, "people/with_phones_filter/*",
+                PEOPLE_WITH_PHONES_FILTER);
+        matcher.addURI(CONTACTS_AUTHORITY, "people/#", PEOPLE_ID);
+        matcher.addURI(CONTACTS_AUTHORITY, "people/#/extensions", PEOPLE_EXTENSIONS);
+        matcher.addURI(CONTACTS_AUTHORITY, "people/#/extensions/#", PEOPLE_EXTENSIONS_ID);
+        matcher.addURI(CONTACTS_AUTHORITY, "people/#/phones", PEOPLE_PHONES);
+        matcher.addURI(CONTACTS_AUTHORITY, "people/#/phones_with_presence",
+                PEOPLE_PHONES_WITH_PRESENCE);
+        matcher.addURI(CONTACTS_AUTHORITY, "people/#/photo", PEOPLE_PHOTO);
+        matcher.addURI(CONTACTS_AUTHORITY, "people/#/phones/#", PEOPLE_PHONES_ID);
+        matcher.addURI(CONTACTS_AUTHORITY, "people/#/contact_methods", PEOPLE_CONTACTMETHODS);
+        matcher.addURI(CONTACTS_AUTHORITY, "people/#/contact_methods_with_presence",
+                PEOPLE_CONTACTMETHODS_WITH_PRESENCE);
+        matcher.addURI(CONTACTS_AUTHORITY, "people/#/contact_methods/#", PEOPLE_CONTACTMETHODS_ID);
+        matcher.addURI(CONTACTS_AUTHORITY, "people/#/organizations", PEOPLE_ORGANIZATIONS);
+        matcher.addURI(CONTACTS_AUTHORITY, "people/#/organizations/#", PEOPLE_ORGANIZATIONS_ID);
+        matcher.addURI(CONTACTS_AUTHORITY, "people/#/groupmembership", PEOPLE_GROUPMEMBERSHIP);
+        matcher.addURI(CONTACTS_AUTHORITY, "people/#/groupmembership/#", PEOPLE_GROUPMEMBERSHIP_ID);
+        matcher.addURI(CONTACTS_AUTHORITY, "people/raw", PEOPLE_RAW);
+        matcher.addURI(CONTACTS_AUTHORITY, "people/owner", PEOPLE_OWNER);
+        matcher.addURI(CONTACTS_AUTHORITY, "people/#/update_contact_time",
+                PEOPLE_UPDATE_CONTACT_TIME);
+        matcher.addURI(CONTACTS_AUTHORITY, "deleted_people", DELETED_PEOPLE);
+        matcher.addURI(CONTACTS_AUTHORITY, "deleted_groups", DELETED_GROUPS);
+        matcher.addURI(CONTACTS_AUTHORITY, "phones", PHONES);
+        matcher.addURI(CONTACTS_AUTHORITY, "phones_with_presence", PHONES_WITH_PRESENCE);
+        matcher.addURI(CONTACTS_AUTHORITY, "phones/filter/*", PHONES_FILTER);
+        matcher.addURI(CONTACTS_AUTHORITY, "phones/filter_name/*", PHONES_FILTER_NAME);
+        matcher.addURI(CONTACTS_AUTHORITY, "phones/mobile_filter_name/*",
+                PHONES_MOBILE_FILTER_NAME);
+        matcher.addURI(CONTACTS_AUTHORITY, "phones/#", PHONES_ID);
+        matcher.addURI(CONTACTS_AUTHORITY, "photos", PHOTOS);
+        matcher.addURI(CONTACTS_AUTHORITY, "photos/#", PHOTOS_ID);
+        matcher.addURI(CONTACTS_AUTHORITY, "contact_methods", CONTACTMETHODS);
+        matcher.addURI(CONTACTS_AUTHORITY, "contact_methods/email", CONTACTMETHODS_EMAIL);
+        matcher.addURI(CONTACTS_AUTHORITY, "contact_methods/email/*", CONTACTMETHODS_EMAIL_FILTER);
+        matcher.addURI(CONTACTS_AUTHORITY, "contact_methods/#", CONTACTMETHODS_ID);
+        matcher.addURI(CONTACTS_AUTHORITY, "contact_methods/with_presence",
+                CONTACTMETHODS_WITH_PRESENCE);
+        matcher.addURI(CONTACTS_AUTHORITY, "presence", PRESENCE);
+        matcher.addURI(CONTACTS_AUTHORITY, "presence/#", PRESENCE_ID);
+        matcher.addURI(CONTACTS_AUTHORITY, "organizations", ORGANIZATIONS);
+        matcher.addURI(CONTACTS_AUTHORITY, "organizations/#", ORGANIZATIONS_ID);
+        matcher.addURI(CONTACTS_AUTHORITY, "voice_dialer_timestamp", VOICE_DIALER_TIMESTAMP);
+        matcher.addURI(CONTACTS_AUTHORITY, SearchManager.SUGGEST_URI_PATH_QUERY,
+                SEARCH_SUGGESTIONS);
+        matcher.addURI(CONTACTS_AUTHORITY, SearchManager.SUGGEST_URI_PATH_QUERY + "/*",
+                SEARCH_SUGGESTIONS);
+        matcher.addURI(CONTACTS_AUTHORITY, "settings", SETTINGS);
+
+        matcher.addURI(CONTACTS_AUTHORITY, "live_folders/people", LIVE_FOLDERS_PEOPLE);
+        matcher.addURI(CONTACTS_AUTHORITY, "live_folders/people/*",
+                LIVE_FOLDERS_PEOPLE_GROUP_NAME);
+        matcher.addURI(CONTACTS_AUTHORITY, "live_folders/people_with_phones",
+                LIVE_FOLDERS_PEOPLE_WITH_PHONES);
+        matcher.addURI(CONTACTS_AUTHORITY, "live_folders/favorites",
+                LIVE_FOLDERS_PEOPLE_FAVORITES);
+
+        // Call log URI matching table
+        matcher.addURI(CALL_LOG_AUTHORITY, "calls", CALLS);
+        matcher.addURI(CALL_LOG_AUTHORITY, "calls/filter/*", CALLS_FILTER);
+        matcher.addURI(CALL_LOG_AUTHORITY, "calls/#", CALLS_ID);
+
+        HashMap<String, String> map;
+
+        // Create the common people columns
+        HashMap<String, String> peopleColumns = new HashMap<String, String>();
+        peopleColumns.put(PeopleColumns.NAME, People.NAME);
+        peopleColumns.put(PeopleColumns.NOTES, People.NOTES);
+        peopleColumns.put(PeopleColumns.TIMES_CONTACTED, People.TIMES_CONTACTED);
+        peopleColumns.put(PeopleColumns.LAST_TIME_CONTACTED, People.LAST_TIME_CONTACTED);
+        peopleColumns.put(PeopleColumns.STARRED, People.STARRED);
+        peopleColumns.put(PeopleColumns.CUSTOM_RINGTONE, People.CUSTOM_RINGTONE);
+        peopleColumns.put(PeopleColumns.SEND_TO_VOICEMAIL, People.SEND_TO_VOICEMAIL);
+        peopleColumns.put(PeopleColumns.PHONETIC_NAME, People.PHONETIC_NAME);
+        peopleColumns.put(PeopleColumns.DISPLAY_NAME,
+                DISPLAY_NAME_SQL + " AS " + People.DISPLAY_NAME);
+
+        // Create the common groups columns
+        HashMap<String, String> groupsColumns = new HashMap<String, String>();
+        groupsColumns.put(GroupsColumns.NAME, Groups.NAME);
+        groupsColumns.put(GroupsColumns.NOTES, Groups.NOTES);
+        groupsColumns.put(GroupsColumns.SYSTEM_ID, Groups.SYSTEM_ID);
+        groupsColumns.put(GroupsColumns.SHOULD_SYNC, Groups.SHOULD_SYNC);
+
+        // Create the common presence columns
+        HashMap<String, String> presenceColumns = new HashMap<String, String>();
+        presenceColumns.put(PresenceColumns.IM_PROTOCOL, PresenceColumns.IM_PROTOCOL);
+        presenceColumns.put(PresenceColumns.IM_HANDLE, PresenceColumns.IM_HANDLE);
+        presenceColumns.put(PresenceColumns.IM_ACCOUNT, PresenceColumns.IM_ACCOUNT);
+        presenceColumns.put(PresenceColumns.PRESENCE_STATUS, PresenceColumns.PRESENCE_STATUS);
+        presenceColumns.put(PresenceColumns.PRESENCE_CUSTOM_STATUS,
+                PresenceColumns.PRESENCE_CUSTOM_STATUS);
+
+        // Create the common sync columns
+        HashMap<String, String> syncColumns = new HashMap<String, String>();
+        syncColumns.put(SyncConstValue._SYNC_ID, SyncConstValue._SYNC_ID);
+        syncColumns.put(SyncConstValue._SYNC_TIME, SyncConstValue._SYNC_TIME);
+        syncColumns.put(SyncConstValue._SYNC_VERSION, SyncConstValue._SYNC_VERSION);
+        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);
+
+        // Phones columns
+        HashMap<String, String> phonesColumns = new HashMap<String, String>();
+        phonesColumns.put(Phones.NUMBER, Phones.NUMBER);
+        phonesColumns.put(Phones.NUMBER_KEY, Phones.NUMBER_KEY);
+        phonesColumns.put(Phones.TYPE, Phones.TYPE);
+        phonesColumns.put(Phones.LABEL, Phones.LABEL);
+
+        // People projection map
+        map = new HashMap<String, String>();
+        map.put(People._ID, "people._id AS " + People._ID);
+        peopleColumns.put(People.PRIMARY_PHONE_ID, People.PRIMARY_PHONE_ID);
+        peopleColumns.put(People.PRIMARY_EMAIL_ID, People.PRIMARY_EMAIL_ID);
+        peopleColumns.put(People.PRIMARY_ORGANIZATION_ID, People.PRIMARY_ORGANIZATION_ID);
+        map.putAll(peopleColumns);
+        map.putAll(phonesColumns);
+        map.putAll(syncColumns);
+        map.putAll(presenceColumns);
+        sPeopleProjectionMap = map;
+
+        // Groups projection map
+        map = new HashMap<String, String>();
+        map.put(Groups._ID, Groups._ID);
+        map.putAll(groupsColumns);
+        map.putAll(syncColumns);
+        sGroupsProjectionMap = map;
+
+        // Group Membership projection map
+        map = new HashMap<String, String>();
+        map.put(GroupMembership._ID, "groupmembership._id AS " + GroupMembership._ID);
+        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_ID, GroupMembership.GROUP_SYNC_ID);
+        map.putAll(groupsColumns);
+        sGroupMembershipProjectionMap = map;
+
+        // Use this when you need to force items to the top of a times_contacted list
+        map = new HashMap<String, String>(sPeopleProjectionMap);
+        map.put(People.TIMES_CONTACTED, Long.MAX_VALUE + " AS " + People.TIMES_CONTACTED);
+        sPeopleWithMaxTimesContactedProjectionMap = map;
+
+        // Calls projection map
+        map = new HashMap<String, String>();
+        map.put(Calls._ID, Calls._ID);
+        map.put(Calls.NUMBER, Calls.NUMBER);
+        map.put(Calls.DATE, Calls.DATE);
+        map.put(Calls.DURATION, Calls.DURATION);
+        map.put(Calls.TYPE, Calls.TYPE);
+        map.put(Calls.NEW, Calls.NEW);
+        map.put(Calls.CACHED_NAME, Calls.CACHED_NAME);
+        map.put(Calls.CACHED_NUMBER_TYPE, Calls.CACHED_NUMBER_TYPE);
+        map.put(Calls.CACHED_NUMBER_LABEL, Calls.CACHED_NUMBER_LABEL);
+        sCallsProjectionMap = map;
+
+        // Phones projection map
+        map = new HashMap<String, String>();
+        map.put(Phones._ID, "phones._id AS " + Phones._ID);
+        map.putAll(phonesColumns);
+        map.put(Phones.PERSON_ID, "phones.person AS " + Phones.PERSON_ID);
+        map.put(Phones.ISPRIMARY, Phones.ISPRIMARY);
+        map.putAll(peopleColumns);
+        sPhonesProjectionMap = map;
+
+        // Phones with presence projection map
+        map = new HashMap<String, String>(sPhonesProjectionMap);
+        map.putAll(presenceColumns);
+        sPhonesWithPresenceProjectionMap = map;
+
+        // Organizations projection map
+        map = new HashMap<String, String>();
+        map.put(Organizations._ID, "organizations._id AS " + Organizations._ID);
+        map.put(Organizations.LABEL, Organizations.LABEL);
+        map.put(Organizations.TYPE, Organizations.TYPE);
+        map.put(Organizations.PERSON_ID, Organizations.PERSON_ID);
+        map.put(Organizations.COMPANY, Organizations.COMPANY);
+        map.put(Organizations.TITLE, Organizations.TITLE);
+        map.put(Organizations.ISPRIMARY, Organizations.ISPRIMARY);
+        sOrganizationsProjectionMap = map;
+
+        // Extensions projection map
+        map = new HashMap<String, String>();
+        map.put(Extensions._ID, Extensions._ID);
+        map.put(Extensions.NAME, Extensions.NAME);
+        map.put(Extensions.VALUE, Extensions.VALUE);
+        map.put(Extensions.PERSON_ID, Extensions.PERSON_ID);
+        sExtensionsProjectionMap = map;
+
+        // Contact methods projection map
+        map = new HashMap<String, String>();
+        map.put(ContactMethods._ID, "contact_methods._id AS " + ContactMethods._ID);
+        map.put(ContactMethods.KIND, ContactMethods.KIND);
+        map.put(ContactMethods.TYPE, ContactMethods.TYPE);
+        map.put(ContactMethods.LABEL, ContactMethods.LABEL);
+        map.put(ContactMethods.DATA, ContactMethods.DATA);
+        map.put(ContactMethods.AUX_DATA, ContactMethods.AUX_DATA);
+        map.put(ContactMethods.PERSON_ID, ContactMethods.PERSON_ID);
+        map.put(ContactMethods.ISPRIMARY, ContactMethods.ISPRIMARY);
+        map.putAll(peopleColumns);
+        sContactMethodsProjectionMap = map;
+
+        // Contact methods with presence projection map
+        map = new HashMap<String, String>(sContactMethodsProjectionMap);
+        map.putAll(presenceColumns);
+        sContactMethodsWithPresenceProjectionMap = map;
+
+        // Email search projection map
+        map = new HashMap<String, String>();
+        map.put(ContactMethods.NAME, ContactMethods.NAME);
+        map.put(ContactMethods.DATA, ContactMethods.DATA);
+        map.put(ContactMethods._ID, "contact_methods._id AS " + ContactMethods._ID);
+        sEmailSearchProjectionMap = map;
+
+        // Presence projection map
+        map = new HashMap<String, String>();
+        map.put(Presence._ID, "presence._id AS " + Presence._ID);
+        map.putAll(presenceColumns);
+        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_INTENT_DATA_ID,
+                People._ID + " AS " + SearchManager.SUGGEST_COLUMN_INTENT_DATA_ID);
+        map.put(People._ID, People._ID);
+        sSearchSuggestionsProjectionMap = map;
+
+        // Photos projection map
+        map = new HashMap<String, String>();
+        map.put(Photos._ID, Photos._ID);
+        map.put(Photos.LOCAL_VERSION, Photos.LOCAL_VERSION);
+        map.put(Photos.EXISTS_ON_SERVER, Photos.EXISTS_ON_SERVER);
+        map.put(Photos.SYNC_ERROR, Photos.SYNC_ERROR);
+        map.put(Photos.PERSON_ID, Photos.PERSON_ID);
+        map.put(Photos.DATA, Photos.DATA);
+        map.put(Photos.DOWNLOAD_REQUIRED, ""
+                + "(exists_on_server!=0 "
+                + " AND sync_error IS NULL "
+                + " AND (local_version IS NULL OR _sync_version != local_version)) "
+                + "AS " + Photos.DOWNLOAD_REQUIRED);
+        map.putAll(syncColumns);
+        sPhotosProjectionMap = map;
+
+        // Live folder projection
+        map = new HashMap<String, String>();
+        map.put(LiveFolders._ID, "people._id AS " + LiveFolders._ID);
+        map.put(LiveFolders.NAME, DISPLAY_NAME_SQL + " AS " + LiveFolders.NAME);
+        map.put(LiveFolders.ICON_BITMAP, Photos.DATA + " AS " + LiveFolders.ICON_BITMAP);
+        sLiveFoldersProjectionMap = map;
+        
+        // Order by statements
+        sPhonesKeyOrderBy = buildOrderBy(sPhonesTable, Phones.NUMBER);
+        sContactMethodsKeyOrderBy = buildOrderBy(sContactMethodsTable,
+                ContactMethods.DATA, ContactMethods.KIND);
+        sOrganizationsKeyOrderBy = buildOrderBy(sOrganizationsTable, Organizations.COMPANY);
+        sGroupmembershipKeyOrderBy =
+                buildOrderBy(sGroupmembershipTable, 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};
+        sExtensionsKeyColumns = new String[]{Extensions.NAME};
+
+        String groupJoinByLocalId = "groups._id=groupmembership.group_id";
+        String groupJoinByServerId = "("
+                + "groups._sync_account=groupmembership.group_sync_account"
+                + " AND "
+                + "groups._sync_id=groupmembership.group_sync_id"
+                + ")";
+        sGroupsJoinString = "(" + groupJoinByLocalId + " OR " + groupJoinByServerId + ")";
+    }
+}
