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..795a5c8
--- /dev/null
+++ b/AndroidManifest.xml
@@ -0,0 +1,21 @@
+<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">
+        <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/values/strings.xml b/res/values/strings.xml
new file mode 100644
index 0000000..a0f8cb0
--- /dev/null
+++ b/res/values/strings.xml
@@ -0,0 +1,22 @@
+<?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">
+    <!-- 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..f2a9d8e
--- /dev/null
+++ b/src/com/android/providers/contacts/ContactsProvider.java
@@ -0,0 +1,3998 @@
+/*
+ * 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 com.android.internal.database.ArrayListCursor;
+import com.google.android.collect.Maps;
+import com.google.android.collect.Sets;
+
+import android.app.SearchManager;
+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.SyncableContentProvider;
+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.Contacts;
+import android.provider.SyncConstValue;
+import android.provider.CallLog.Calls;
+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.telephony.PhoneNumberUtils;
+import android.text.TextUtils;
+import android.util.Config;
+import android.util.Log;
+
+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 SyncableContentProvider {
+    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 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 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);
+        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;
+        }
+
+        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" +
+                    ");");
+
+        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,"
+                + 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," +
+                    "_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," +
+                    "_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_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;
+
+            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;
+
+        // TODO: the following commented-out code is being replaced with code that ignores
+        // the account.
+        // This is a short-term fix that is known not to work with multiple-accounts but is
+        // sufficient for V1 and safer than the real fix. This code must not be merged back into
+        // the trunk, which already contains the real fix.
+//        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};
+//        }
+        whereString = "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);
+                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);
+                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
+                        mValues.clear();
+                        mValues.put(Photos.PERSON_ID, rowID);
+                        mValues.put(Photos._SYNC_ACCOUNT, account);
+                        mValues.put(Photos._SYNC_ID, syncId);
+                        mDb.delete(sPhotosTable, "person=" + rowID, null);
+                        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;
+    }
+
+    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);
+                // 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()) {
+                // insert into deleted table
+                mDeletedPeopleInserter.prepareForInsert();
+                mDeletedPeopleInserter.bind(dstIdxSyncId, cursor.getString(idxSyncId));
+                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);
+                if (!mValues.containsKey(Photos._SYNC_DIRTY)) 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.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.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 = 78;
+
+    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 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 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 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> 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 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_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 ";
+    
+    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/#/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/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);
+
+        // 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.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_ID);
+        map.put(Phones.ISPRIMARY, Phones.ISPRIMARY);
+        map.putAll(peopleColumns);
+        sPhonesProjectionMap = 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;
+
+        // 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 + ")";
+    }
+}
+
