diff --git a/res/values/strings.xml b/res/values/strings.xml
index dd0406b..0d25bb25 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -451,12 +451,6 @@
     <!-- The button to add an organization field to a contact in the Raw Contact Editor [CHAR LIMIT=15] -->
     <string name="group_edit_field_hint_text">Group name</string>
 
-    <!-- Attribution of a contact status update, when the time of update is unknown -->
-    <string name="contact_status_update_attribution">via <xliff:g id="source" example="Google Talk">%1$s</xliff:g></string>
-
-    <!-- Attribution of a contact status update, when the time of update is known -->
-    <string name="contact_status_update_attribution_with_date"><xliff:g id="date" example="3 hours ago">%1$s</xliff:g> via <xliff:g id="source" example="Google Talk">%2$s</xliff:g></string>
-
     <!-- String describing the Star/Favorite checkbox
 
          Used by AccessibilityService to announce the purpose of the view.
diff --git a/src/com/android/contacts/ContactSaveService.java b/src/com/android/contacts/ContactSaveService.java
index 9f916fb..7a8f9f3 100644
--- a/src/com/android/contacts/ContactSaveService.java
+++ b/src/com/android/contacts/ContactSaveService.java
@@ -49,9 +49,9 @@
 
 import com.android.contacts.common.database.ContactUpdateUtils;
 import com.android.contacts.common.model.AccountTypeManager;
-import com.android.contacts.model.RawContactDelta;
-import com.android.contacts.model.RawContactDeltaList;
-import com.android.contacts.model.RawContactModifier;
+import com.android.contacts.common.model.RawContactDelta;
+import com.android.contacts.common.model.RawContactDeltaList;
+import com.android.contacts.common.model.RawContactModifier;
 import com.android.contacts.common.model.account.AccountWithDataSet;
 import com.android.contacts.util.CallerInfoCacheUtils;
 import com.android.contacts.util.ContactPhotoUtils;
diff --git a/src/com/android/contacts/ContactsActivity.java b/src/com/android/contacts/ContactsActivity.java
index f3ac147..b94a237 100644
--- a/src/com/android/contacts/ContactsActivity.java
+++ b/src/com/android/contacts/ContactsActivity.java
@@ -26,7 +26,7 @@
 import android.view.View;
 
 import com.android.contacts.common.activity.TransactionSafeActivity;
-import com.android.contacts.test.InjectedServices;
+import com.android.contacts.common.test.InjectedServices;
 
 /**
  * A common superclass for Contacts activities that handles application-wide services.
diff --git a/src/com/android/contacts/ContactsApplication.java b/src/com/android/contacts/ContactsApplication.java
index 82b2a25..95fad48 100644
--- a/src/com/android/contacts/ContactsApplication.java
+++ b/src/com/android/contacts/ContactsApplication.java
@@ -32,7 +32,7 @@
 import com.android.contacts.common.ContactPhotoManager;
 import com.android.contacts.common.list.ContactListFilterController;
 import com.android.contacts.common.model.AccountTypeManager;
-import com.android.contacts.test.InjectedServices;
+import com.android.contacts.common.test.InjectedServices;
 import com.android.contacts.common.util.Constants;
 import com.google.common.annotations.VisibleForTesting;
 
diff --git a/src/com/android/contacts/ContactsUtils.java b/src/com/android/contacts/ContactsUtils.java
deleted file mode 100644
index 6b7114c..0000000
--- a/src/com/android/contacts/ContactsUtils.java
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.contacts;
-
-import android.content.Context;
-import android.content.Intent;
-import android.database.Cursor;
-import android.provider.ContactsContract.CommonDataKinds.Im;
-import android.provider.ContactsContract.DisplayPhoto;
-import android.telephony.PhoneNumberUtils;
-import android.text.TextUtils;
-
-import com.android.contacts.common.model.account.AccountWithDataSet;
-import com.android.contacts.common.test.NeededForTesting;
-import com.android.contacts.common.model.AccountTypeManager;
-
-import java.util.List;
-
-public class ContactsUtils {
-    private static final String TAG = "ContactsUtils";
-
-    private static int sThumbnailSize = -1;
-
-    // TODO find a proper place for the canonical version of these
-    public interface ProviderNames {
-        String YAHOO = "Yahoo";
-        String GTALK = "GTalk";
-        String MSN = "MSN";
-        String ICQ = "ICQ";
-        String AIM = "AIM";
-        String XMPP = "XMPP";
-        String JABBER = "JABBER";
-        String SKYPE = "SKYPE";
-        String QQ = "QQ";
-    }
-
-    /**
-     * This looks up the provider name defined in
-     * ProviderNames from the predefined IM protocol id.
-     * This is used for interacting with the IM application.
-     *
-     * @param protocol the protocol ID
-     * @return the provider name the IM app uses for the given protocol, or null if no
-     * provider is defined for the given protocol
-     * @hide
-     */
-    public static String lookupProviderNameFromId(int protocol) {
-        switch (protocol) {
-            case Im.PROTOCOL_GOOGLE_TALK:
-                return ProviderNames.GTALK;
-            case Im.PROTOCOL_AIM:
-                return ProviderNames.AIM;
-            case Im.PROTOCOL_MSN:
-                return ProviderNames.MSN;
-            case Im.PROTOCOL_YAHOO:
-                return ProviderNames.YAHOO;
-            case Im.PROTOCOL_ICQ:
-                return ProviderNames.ICQ;
-            case Im.PROTOCOL_JABBER:
-                return ProviderNames.JABBER;
-            case Im.PROTOCOL_SKYPE:
-                return ProviderNames.SKYPE;
-            case Im.PROTOCOL_QQ:
-                return ProviderNames.QQ;
-        }
-        return null;
-    }
-
-    /**
-     * Test if the given {@link CharSequence} contains any graphic characters,
-     * first checking {@link TextUtils#isEmpty(CharSequence)} to handle null.
-     */
-    public static boolean isGraphic(CharSequence str) {
-        return !TextUtils.isEmpty(str) && TextUtils.isGraphic(str);
-    }
-
-    /**
-     * Returns true if two objects are considered equal.  Two null references are equal here.
-     */
-    @NeededForTesting
-    public static boolean areObjectsEqual(Object a, Object b) {
-        return a == b || (a != null && a.equals(b));
-    }
-
-    /**
-     * Returns true if two {@link Intent}s are both null, or have the same action.
-     */
-    public static final boolean areIntentActionEqual(Intent a, Intent b) {
-        if (a == b) {
-            return true;
-        }
-        if (a == null || b == null) {
-            return false;
-        }
-        return TextUtils.equals(a.getAction(), b.getAction());
-    }
-
-    public static boolean areContactWritableAccountsAvailable(Context context) {
-        final List<AccountWithDataSet> accounts =
-                AccountTypeManager.getInstance(context).getAccounts(true /* writeable */);
-        return !accounts.isEmpty();
-    }
-
-    public static boolean areGroupWritableAccountsAvailable(Context context) {
-        final List<AccountWithDataSet> accounts =
-                AccountTypeManager.getInstance(context).getGroupWritableAccounts();
-        return !accounts.isEmpty();
-    }
-
-    /**
-     * Returns the size (width and height) of thumbnail pictures as configured in the provider. This
-     * can safely be called from the UI thread, as the provider can serve this without performing
-     * a database access
-     */
-    public static int getThumbnailSize(Context context) {
-        if (sThumbnailSize == -1) {
-            final Cursor c = context.getContentResolver().query(
-                    DisplayPhoto.CONTENT_MAX_DIMENSIONS_URI,
-                    new String[] { DisplayPhoto.THUMBNAIL_MAX_DIM }, null, null, null);
-            try {
-                c.moveToFirst();
-                sThumbnailSize = c.getInt(0);
-            } finally {
-                c.close();
-            }
-        }
-        return sThumbnailSize;
-    }
-
-}
diff --git a/src/com/android/contacts/GroupMetaData.java b/src/com/android/contacts/GroupMetaData.java
deleted file mode 100644
index 462ac4a..0000000
--- a/src/com/android/contacts/GroupMetaData.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (C) 2010 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.contacts;
-
-/**
- * Meta-data for a contact group.  We load all groups associated with the contact's
- * constituent accounts.
- */
-public final class GroupMetaData {
-    private String mAccountName;
-    private String mAccountType;
-    private String mDataSet;
-    private long mGroupId;
-    private String mTitle;
-    private boolean mDefaultGroup;
-    private boolean mFavorites;
-
-    public GroupMetaData(String accountName, String accountType, String dataSet, long groupId,
-            String title, boolean defaultGroup, boolean favorites) {
-        this.mAccountName = accountName;
-        this.mAccountType = accountType;
-        this.mDataSet = dataSet;
-        this.mGroupId = groupId;
-        this.mTitle = title;
-        this.mDefaultGroup = defaultGroup;
-        this.mFavorites = favorites;
-    }
-
-    public String getAccountName() {
-        return mAccountName;
-    }
-
-    public String getAccountType() {
-        return mAccountType;
-    }
-
-    public String getDataSet() {
-        return mDataSet;
-    }
-
-    public long getGroupId() {
-        return mGroupId;
-    }
-
-    public String getTitle() {
-        return mTitle;
-    }
-
-    public boolean isDefaultGroup() {
-        return mDefaultGroup;
-    }
-
-    public boolean isFavorites() {
-        return mFavorites;
-    }
-}
\ No newline at end of file
diff --git a/src/com/android/contacts/TypePrecedence.java b/src/com/android/contacts/TypePrecedence.java
index 53b8343..0a193b5 100644
--- a/src/com/android/contacts/TypePrecedence.java
+++ b/src/com/android/contacts/TypePrecedence.java
@@ -23,7 +23,7 @@
 import android.provider.ContactsContract.CommonDataKinds.Phone;
 import android.provider.ContactsContract.CommonDataKinds.StructuredPostal;
 
-import com.android.contacts.model.RawContactModifier;
+import com.android.contacts.common.model.RawContactModifier;
 
 /**
  * This class contains utility functions for determining the precedence of
diff --git a/src/com/android/contacts/ViewNotificationService.java b/src/com/android/contacts/ViewNotificationService.java
index 3bc5ed2..0f2922a 100644
--- a/src/com/android/contacts/ViewNotificationService.java
+++ b/src/com/android/contacts/ViewNotificationService.java
@@ -23,8 +23,8 @@
 import android.os.IBinder;
 import android.util.Log;
 
-import com.android.contacts.model.Contact;
-import com.android.contacts.model.ContactLoader;
+import com.android.contacts.common.model.Contact;
+import com.android.contacts.common.model.ContactLoader;
 
 
 /**
diff --git a/src/com/android/contacts/activities/AttachPhotoActivity.java b/src/com/android/contacts/activities/AttachPhotoActivity.java
index 78b482e..2d9e9f5 100644
--- a/src/com/android/contacts/activities/AttachPhotoActivity.java
+++ b/src/com/android/contacts/activities/AttachPhotoActivity.java
@@ -33,12 +33,12 @@
 
 import com.android.contacts.ContactSaveService;
 import com.android.contacts.ContactsActivity;
-import com.android.contacts.ContactsUtils;
-import com.android.contacts.model.Contact;
-import com.android.contacts.model.ContactLoader;
-import com.android.contacts.model.RawContactDelta;
-import com.android.contacts.model.RawContactDeltaList;
-import com.android.contacts.model.RawContactModifier;
+import com.android.contacts.common.model.Contact;
+import com.android.contacts.common.model.ContactLoader;
+import com.android.contacts.common.model.RawContactDelta;
+import com.android.contacts.common.model.RawContactDeltaList;
+import com.android.contacts.common.model.RawContactModifier;
+import com.android.contacts.common.ContactsUtils;
 import com.android.contacts.common.model.account.AccountType;
 import com.android.contacts.common.model.ValuesDelta;
 import com.android.contacts.util.ContactPhotoUtils;
diff --git a/src/com/android/contacts/activities/ConfirmAddDetailActivity.java b/src/com/android/contacts/activities/ConfirmAddDetailActivity.java
index fd12d7f..d60cc73 100644
--- a/src/com/android/contacts/activities/ConfirmAddDetailActivity.java
+++ b/src/com/android/contacts/activities/ConfirmAddDetailActivity.java
@@ -63,11 +63,11 @@
 import com.android.contacts.editor.EditorUiUtils;
 import com.android.contacts.editor.ViewIdGenerator;
 import com.android.contacts.common.model.AccountTypeManager;
-import com.android.contacts.model.RawContact;
-import com.android.contacts.model.RawContactDelta;
+import com.android.contacts.common.model.RawContact;
+import com.android.contacts.common.model.RawContactDelta;
 import com.android.contacts.common.model.ValuesDelta;
-import com.android.contacts.model.RawContactDeltaList;
-import com.android.contacts.model.RawContactModifier;
+import com.android.contacts.common.model.RawContactDeltaList;
+import com.android.contacts.common.model.RawContactModifier;
 import com.android.contacts.common.model.account.AccountType;
 import com.android.contacts.common.model.account.AccountWithDataSet;
 import com.android.contacts.common.model.dataitem.DataKind;
diff --git a/src/com/android/contacts/activities/ContactDetailActivity.java b/src/com/android/contacts/activities/ContactDetailActivity.java
index 0f793e2..03821a7 100644
--- a/src/com/android/contacts/activities/ContactDetailActivity.java
+++ b/src/com/android/contacts/activities/ContactDetailActivity.java
@@ -46,7 +46,7 @@
 import com.android.contacts.detail.ContactLoaderFragment;
 import com.android.contacts.detail.ContactLoaderFragment.ContactLoaderFragmentListener;
 import com.android.contacts.interactions.ContactDeletionInteraction;
-import com.android.contacts.model.Contact;
+import com.android.contacts.common.model.Contact;
 import com.android.contacts.common.model.account.AccountWithDataSet;
 import com.android.contacts.util.PhoneCapabilityTester;
 
diff --git a/src/com/android/contacts/activities/PeopleActivity.java b/src/com/android/contacts/activities/PeopleActivity.java
index 2d69917..bfcd79e 100644
--- a/src/com/android/contacts/activities/PeopleActivity.java
+++ b/src/com/android/contacts/activities/PeopleActivity.java
@@ -51,7 +51,6 @@
 
 import com.android.contacts.ContactSaveService;
 import com.android.contacts.ContactsActivity;
-import com.android.contacts.ContactsUtils;
 import com.android.contacts.R;
 import com.android.contacts.activities.ActionBarAdapter.TabState;
 import com.android.contacts.detail.ContactDetailFragment;
@@ -59,6 +58,7 @@
 import com.android.contacts.detail.ContactDetailUpdatesFragment;
 import com.android.contacts.detail.ContactLoaderFragment;
 import com.android.contacts.detail.ContactLoaderFragment.ContactLoaderFragmentListener;
+import com.android.contacts.common.ContactsUtils;
 import com.android.contacts.common.dialog.ClearFrequentsDialog;
 import com.android.contacts.group.GroupBrowseListFragment;
 import com.android.contacts.group.GroupBrowseListFragment.OnGroupBrowserActionListener;
@@ -81,7 +81,7 @@
 import com.android.contacts.list.OnContactsUnavailableActionListener;
 import com.android.contacts.list.ProviderStatusWatcher;
 import com.android.contacts.list.ProviderStatusWatcher.ProviderStatusListener;
-import com.android.contacts.model.Contact;
+import com.android.contacts.common.model.Contact;
 import com.android.contacts.common.model.account.AccountWithDataSet;
 import com.android.contacts.preference.ContactsPreferenceActivity;
 import com.android.contacts.preference.DisplayOptionsPreferenceFragment;
diff --git a/src/com/android/contacts/activities/PhotoSelectionActivity.java b/src/com/android/contacts/activities/PhotoSelectionActivity.java
index 6d74863..20892d6 100644
--- a/src/com/android/contacts/activities/PhotoSelectionActivity.java
+++ b/src/com/android/contacts/activities/PhotoSelectionActivity.java
@@ -39,7 +39,7 @@
 import com.android.contacts.R;
 import com.android.contacts.detail.PhotoSelectionHandler;
 import com.android.contacts.editor.PhotoActionPopup;
-import com.android.contacts.model.RawContactDeltaList;
+import com.android.contacts.common.model.RawContactDeltaList;
 import com.android.contacts.util.ContactPhotoUtils;
 import com.android.contacts.util.SchedulingUtils;
 
diff --git a/src/com/android/contacts/datepicker/DatePickerDialog.java b/src/com/android/contacts/datepicker/DatePickerDialog.java
index 7681898..5ed143b 100644
--- a/src/com/android/contacts/datepicker/DatePickerDialog.java
+++ b/src/com/android/contacts/datepicker/DatePickerDialog.java
@@ -31,8 +31,8 @@
 import android.widget.TextView;
 
 import com.android.contacts.R;
+import com.android.contacts.common.util.DateUtils;
 import com.android.contacts.datepicker.DatePicker.OnDateChangedListener;
-import com.android.contacts.util.DateUtils;
 
 import java.text.DateFormat;
 import java.util.Calendar;
diff --git a/src/com/android/contacts/detail/ContactDetailDisplayUtils.java b/src/com/android/contacts/detail/ContactDetailDisplayUtils.java
index c856f97..e1aa217 100644
--- a/src/com/android/contacts/detail/ContactDetailDisplayUtils.java
+++ b/src/com/android/contacts/detail/ContactDetailDisplayUtils.java
@@ -42,15 +42,15 @@
 
 import com.android.contacts.common.ContactPhotoManager;
 import com.android.contacts.R;
-import com.android.contacts.model.Contact;
-import com.android.contacts.model.RawContact;
-import com.android.contacts.model.dataitem.DataItem;
-import com.android.contacts.model.dataitem.OrganizationDataItem;
+import com.android.contacts.common.model.Contact;
+import com.android.contacts.common.model.RawContact;
+import com.android.contacts.common.model.dataitem.DataItem;
+import com.android.contacts.common.model.dataitem.OrganizationDataItem;
 import com.android.contacts.common.preference.ContactsPreferences;
+import com.android.contacts.util.StreamItemEntry;
 import com.android.contacts.util.ContactBadgeUtil;
 import com.android.contacts.util.HtmlUtils;
 import com.android.contacts.util.MoreMath;
-import com.android.contacts.util.StreamItemEntry;
 import com.android.contacts.util.StreamItemPhotoEntry;
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.collect.Iterables;
@@ -233,17 +233,6 @@
 
         CharSequence snippet = null;
         String photoUri = null;
-        if (!contactData.getStreamItems().isEmpty()) {
-            StreamItemEntry firstEntry = contactData.getStreamItems().get(0);
-            snippet = HtmlUtils.fromHtml(context, firstEntry.getText());
-            if (!firstEntry.getPhotos().isEmpty()) {
-                StreamItemPhotoEntry firstPhoto = firstEntry.getPhotos().get(0);
-                photoUri = firstPhoto.getPhotoUri();
-
-                // If displaying an image, hide the snippet text.
-                snippet = null;
-            }
-        }
         setDataOrHideIfNone(snippet, statusView);
         if (photoUri != null) {
             ContactPhotoManager.getInstance(context).loadPhoto(
diff --git a/src/com/android/contacts/detail/ContactDetailFragment.java b/src/com/android/contacts/detail/ContactDetailFragment.java
index 34583dc..abaa8eb 100644
--- a/src/com/android/contacts/detail/ContactDetailFragment.java
+++ b/src/com/android/contacts/detail/ContactDetailFragment.java
@@ -70,14 +70,14 @@
 import android.widget.TextView;
 
 import com.android.contacts.ContactSaveService;
-import com.android.contacts.ContactsUtils;
-import com.android.contacts.GroupMetaData;
 import com.android.contacts.R;
 import com.android.contacts.TypePrecedence;
 import com.android.contacts.activities.ContactDetailActivity.FragmentKeyListener;
 import com.android.contacts.common.CallUtil;
 import com.android.contacts.common.ClipboardUtils;
 import com.android.contacts.common.Collapser;
+import com.android.contacts.common.ContactsUtils;
+import com.android.contacts.common.GroupMetaData;
 import com.android.contacts.common.Collapser.Collapsible;
 import com.android.contacts.common.ContactPresenceIconUtil;
 import com.android.contacts.common.GeoUtil;
@@ -91,27 +91,27 @@
 import com.android.contacts.common.model.dataitem.DataKind;
 import com.android.contacts.common.util.AccountsListAdapter.AccountListFilter;
 import com.android.contacts.common.util.ContactDisplayUtils;
-import com.android.contacts.model.Contact;
-import com.android.contacts.model.RawContact;
-import com.android.contacts.model.RawContactDelta;
-import com.android.contacts.model.RawContactDeltaList;
-import com.android.contacts.model.RawContactModifier;
-import com.android.contacts.model.dataitem.DataItem;
-import com.android.contacts.model.dataitem.EmailDataItem;
-import com.android.contacts.model.dataitem.EventDataItem;
-import com.android.contacts.model.dataitem.GroupMembershipDataItem;
-import com.android.contacts.model.dataitem.ImDataItem;
-import com.android.contacts.model.dataitem.NicknameDataItem;
-import com.android.contacts.model.dataitem.NoteDataItem;
-import com.android.contacts.model.dataitem.OrganizationDataItem;
-import com.android.contacts.model.dataitem.PhoneDataItem;
-import com.android.contacts.model.dataitem.RelationDataItem;
-import com.android.contacts.model.dataitem.SipAddressDataItem;
-import com.android.contacts.model.dataitem.StructuredNameDataItem;
-import com.android.contacts.model.dataitem.StructuredPostalDataItem;
-import com.android.contacts.model.dataitem.WebsiteDataItem;
-import com.android.contacts.util.DataStatus;
-import com.android.contacts.util.DateUtils;
+import com.android.contacts.common.util.DataStatus;
+import com.android.contacts.common.util.DateUtils;
+import com.android.contacts.common.model.Contact;
+import com.android.contacts.common.model.RawContact;
+import com.android.contacts.common.model.RawContactDelta;
+import com.android.contacts.common.model.RawContactDeltaList;
+import com.android.contacts.common.model.RawContactModifier;
+import com.android.contacts.common.model.dataitem.DataItem;
+import com.android.contacts.common.model.dataitem.EmailDataItem;
+import com.android.contacts.common.model.dataitem.EventDataItem;
+import com.android.contacts.common.model.dataitem.GroupMembershipDataItem;
+import com.android.contacts.common.model.dataitem.ImDataItem;
+import com.android.contacts.common.model.dataitem.NicknameDataItem;
+import com.android.contacts.common.model.dataitem.NoteDataItem;
+import com.android.contacts.common.model.dataitem.OrganizationDataItem;
+import com.android.contacts.common.model.dataitem.PhoneDataItem;
+import com.android.contacts.common.model.dataitem.RelationDataItem;
+import com.android.contacts.common.model.dataitem.SipAddressDataItem;
+import com.android.contacts.common.model.dataitem.StructuredNameDataItem;
+import com.android.contacts.common.model.dataitem.StructuredPostalDataItem;
+import com.android.contacts.common.model.dataitem.WebsiteDataItem;
 import com.android.contacts.util.PhoneCapabilityTester;
 import com.android.contacts.util.StructuredPostalUtils;
 import com.android.contacts.util.UiClosables;
@@ -412,9 +412,6 @@
             return;
         }
 
-        // Figure out if the contact has social updates or not
-        mContactHasSocialUpdates = !mContactData.getStreamItems().isEmpty();
-
         // Setup the photo if applicable
         if (mStaticPhotoContainer != null) {
             // The presence of a static photo container is not sufficient to determine whether or
@@ -1502,9 +1499,7 @@
         }
 
         private View getHeaderEntryView(View convertView, ViewGroup parent) {
-            final int desiredLayoutResourceId = mContactHasSocialUpdates ?
-                    R.layout.detail_header_contact_with_updates :
-                    R.layout.detail_header_contact_without_updates;
+            final int desiredLayoutResourceId = R.layout.detail_header_contact_without_updates;
             View result = null;
             HeaderViewCache viewCache = null;
 
diff --git a/src/com/android/contacts/detail/ContactDetailLayoutController.java b/src/com/android/contacts/detail/ContactDetailLayoutController.java
index 3c359ba..1ee31a5 100644
--- a/src/com/android/contacts/detail/ContactDetailLayoutController.java
+++ b/src/com/android/contacts/detail/ContactDetailLayoutController.java
@@ -37,7 +37,7 @@
 import com.android.contacts.NfcHandler;
 import com.android.contacts.R;
 import com.android.contacts.activities.ContactDetailActivity.FragmentKeyListener;
-import com.android.contacts.model.Contact;
+import com.android.contacts.common.model.Contact;
 import com.android.contacts.util.PhoneCapabilityTester;
 import com.android.contacts.common.util.UriUtils;
 import com.android.contacts.widget.FrameLayoutWithOverlay;
@@ -285,7 +285,6 @@
                     !UriUtils.areEqual(mContactData.getLookupUri(), data.getLookupUri());
         }
         mContactData = data;
-        mContactHasUpdates = !data.getStreamItems().isEmpty();
 
         if (PhoneCapabilityTester.isUsingTwoPanes(mActivity)) {
             // Tablet: If we already showed data before, we want to cross-fade from screen to screen
@@ -302,12 +301,7 @@
             }
         }
 
-        if (mContactHasUpdates) {
-            showContactWithUpdates(
-                    contactWasLoaded && contactHadUpdates == false);
-        } else {
-            showContactWithoutUpdates();
-        }
+        showContactWithoutUpdates();
     }
 
     public void showEmptyState() {
diff --git a/src/com/android/contacts/detail/ContactDetailPhotoSetter.java b/src/com/android/contacts/detail/ContactDetailPhotoSetter.java
index 2c4c2c9..112621a 100644
--- a/src/com/android/contacts/detail/ContactDetailPhotoSetter.java
+++ b/src/com/android/contacts/detail/ContactDetailPhotoSetter.java
@@ -27,8 +27,8 @@
 
 import com.android.contacts.common.ContactPhotoManager;
 import com.android.contacts.activities.PhotoSelectionActivity;
-import com.android.contacts.model.Contact;
-import com.android.contacts.model.RawContactDeltaList;
+import com.android.contacts.common.model.Contact;
+import com.android.contacts.common.model.RawContactDeltaList;
 import com.android.contacts.util.ImageViewDrawableSetter;
 
 /**
diff --git a/src/com/android/contacts/detail/ContactDetailTabCarousel.java b/src/com/android/contacts/detail/ContactDetailTabCarousel.java
index 540f001..25bcac6 100644
--- a/src/com/android/contacts/detail/ContactDetailTabCarousel.java
+++ b/src/com/android/contacts/detail/ContactDetailTabCarousel.java
@@ -30,7 +30,7 @@
 import android.widget.TextView;
 
 import com.android.contacts.R;
-import com.android.contacts.model.Contact;
+import com.android.contacts.common.model.Contact;
 import com.android.contacts.util.MoreMath;
 import com.android.contacts.util.SchedulingUtils;
 
diff --git a/src/com/android/contacts/detail/ContactDetailUpdatesFragment.java b/src/com/android/contacts/detail/ContactDetailUpdatesFragment.java
index b578d28..71186fe 100644
--- a/src/com/android/contacts/detail/ContactDetailUpdatesFragment.java
+++ b/src/com/android/contacts/detail/ContactDetailUpdatesFragment.java
@@ -31,10 +31,10 @@
 import com.android.contacts.R;
 import com.android.contacts.activities.ContactDetailActivity.FragmentKeyListener;
 import com.android.contacts.detail.ContactDetailDisplayUtils.StreamPhotoTag;
-import com.android.contacts.common.model.AccountTypeManager;
-import com.android.contacts.model.Contact;
-import com.android.contacts.common.model.account.AccountType;
 import com.android.contacts.util.StreamItemEntry;
+import com.android.contacts.common.model.AccountTypeManager;
+import com.android.contacts.common.model.Contact;
+import com.android.contacts.common.model.account.AccountType;
 
 public class ContactDetailUpdatesFragment extends ListFragment implements FragmentKeyListener {
 
@@ -111,14 +111,6 @@
                 mStreamItemPhotoItemClickListener);
         setListAdapter(mStreamItemAdapter);
         getListView().setOnScrollListener(mVerticalScrollListener);
-
-        // It is possible that the contact data was set to the fragment when it was first attached
-        // to the activity, but before this method was called because the fragment was not
-        // visible on screen yet (i.e. using a {@link ViewPager}), so display the data if we already
-        // have it.
-        if (mContactData != null) {
-            mStreamItemAdapter.setStreamItems(mContactData.getStreamItems());
-        }
     }
 
     public void setData(Uri lookupUri, Contact result) {
@@ -127,13 +119,6 @@
         }
         mLookupUri = lookupUri;
         mContactData = result;
-
-        // If the adapter has been created already, then try to set stream items. Otherwise,
-        // wait for the adapter to get initialized, after which we will try to set the stream items
-        // again.
-        if (mStreamItemAdapter != null) {
-            mStreamItemAdapter.setStreamItems(mContactData.getStreamItems());
-        }
     }
 
     /**
diff --git a/src/com/android/contacts/detail/ContactLoaderFragment.java b/src/com/android/contacts/detail/ContactLoaderFragment.java
index 5f5a137..0b420f7 100644
--- a/src/com/android/contacts/detail/ContactLoaderFragment.java
+++ b/src/com/android/contacts/detail/ContactLoaderFragment.java
@@ -44,8 +44,8 @@
 import com.android.contacts.activities.ContactDetailActivity.FragmentKeyListener;
 import com.android.contacts.common.list.ShortcutIntentBuilder;
 import com.android.contacts.common.list.ShortcutIntentBuilder.OnShortcutIntentCreatedListener;
-import com.android.contacts.model.Contact;
-import com.android.contacts.model.ContactLoader;
+import com.android.contacts.common.model.Contact;
+import com.android.contacts.common.model.ContactLoader;
 import com.android.contacts.util.PhoneCapabilityTester;
 import com.google.common.base.Objects;
 
diff --git a/src/com/android/contacts/detail/PhotoSelectionHandler.java b/src/com/android/contacts/detail/PhotoSelectionHandler.java
index 6e2d4fa..52a292b 100644
--- a/src/com/android/contacts/detail/PhotoSelectionHandler.java
+++ b/src/com/android/contacts/detail/PhotoSelectionHandler.java
@@ -37,11 +37,11 @@
 import com.android.contacts.R;
 import com.android.contacts.editor.PhotoActionPopup;
 import com.android.contacts.common.model.AccountTypeManager;
-import com.android.contacts.model.RawContactModifier;
-import com.android.contacts.model.RawContactDelta;
+import com.android.contacts.common.model.RawContactModifier;
+import com.android.contacts.common.model.RawContactDelta;
 import com.android.contacts.common.model.ValuesDelta;
 import com.android.contacts.common.model.account.AccountType;
-import com.android.contacts.model.RawContactDeltaList;
+import com.android.contacts.common.model.RawContactDeltaList;
 import com.android.contacts.util.ContactPhotoUtils;
 import com.android.contacts.util.UiClosables;
 
diff --git a/src/com/android/contacts/detail/StreamItemAdapter.java b/src/com/android/contacts/detail/StreamItemAdapter.java
index 5c827dc..6e1adc5 100644
--- a/src/com/android/contacts/detail/StreamItemAdapter.java
+++ b/src/com/android/contacts/detail/StreamItemAdapter.java
@@ -26,6 +26,7 @@
 import com.android.contacts.common.model.AccountTypeManager;
 import com.android.contacts.common.model.account.AccountType;
 import com.android.contacts.util.StreamItemEntry;
+
 import com.google.common.collect.Lists;
 
 import java.util.List;
diff --git a/src/com/android/contacts/editor/BaseRawContactEditorView.java b/src/com/android/contacts/editor/BaseRawContactEditorView.java
index c39d472..7e74cfb 100644
--- a/src/com/android/contacts/editor/BaseRawContactEditorView.java
+++ b/src/com/android/contacts/editor/BaseRawContactEditorView.java
@@ -28,9 +28,9 @@
 import android.widget.LinearLayout;
 
 import com.android.contacts.R;
-import com.android.contacts.model.RawContactDelta;
+import com.android.contacts.common.model.RawContactDelta;
 import com.android.contacts.common.model.ValuesDelta;
-import com.android.contacts.model.RawContactModifier;
+import com.android.contacts.common.model.RawContactModifier;
 import com.android.contacts.common.model.account.AccountType;
 import com.android.contacts.common.model.account.AccountType.EditType;
 
diff --git a/src/com/android/contacts/editor/ContactEditorFragment.java b/src/com/android/contacts/editor/ContactEditorFragment.java
index 767cee2..9243625 100644
--- a/src/com/android/contacts/editor/ContactEditorFragment.java
+++ b/src/com/android/contacts/editor/ContactEditorFragment.java
@@ -78,12 +78,12 @@
 import com.android.contacts.detail.PhotoSelectionHandler;
 import com.android.contacts.editor.AggregationSuggestionEngine.Suggestion;
 import com.android.contacts.editor.Editor.EditorListener;
-import com.android.contacts.model.Contact;
-import com.android.contacts.model.ContactLoader;
-import com.android.contacts.model.RawContact;
-import com.android.contacts.model.RawContactDelta;
-import com.android.contacts.model.RawContactDeltaList;
-import com.android.contacts.model.RawContactModifier;
+import com.android.contacts.common.model.Contact;
+import com.android.contacts.common.model.ContactLoader;
+import com.android.contacts.common.model.RawContact;
+import com.android.contacts.common.model.RawContactDelta;
+import com.android.contacts.common.model.RawContactDeltaList;
+import com.android.contacts.common.model.RawContactModifier;
 import com.android.contacts.util.ContactPhotoUtils;
 import com.android.contacts.util.HelpUtils;
 import com.android.contacts.util.UiClosables;
diff --git a/src/com/android/contacts/editor/Editor.java b/src/com/android/contacts/editor/Editor.java
index 12ea201..7990309 100644
--- a/src/com/android/contacts/editor/Editor.java
+++ b/src/com/android/contacts/editor/Editor.java
@@ -18,7 +18,7 @@
 
 import android.provider.ContactsContract.Data;
 
-import com.android.contacts.model.RawContactDelta;
+import com.android.contacts.common.model.RawContactDelta;
 import com.android.contacts.common.model.ValuesDelta;
 import com.android.contacts.common.model.dataitem.DataKind;
 
diff --git a/src/com/android/contacts/editor/EventFieldEditorView.java b/src/com/android/contacts/editor/EventFieldEditorView.java
index 3589c89..4d9411f 100644
--- a/src/com/android/contacts/editor/EventFieldEditorView.java
+++ b/src/com/android/contacts/editor/EventFieldEditorView.java
@@ -29,12 +29,13 @@
 import com.android.contacts.datepicker.DatePicker;
 import com.android.contacts.datepicker.DatePickerDialog;
 import com.android.contacts.datepicker.DatePickerDialog.OnDateSetListener;
-import com.android.contacts.model.RawContactDelta;
+import com.android.contacts.common.model.RawContactDelta;
 import com.android.contacts.common.model.ValuesDelta;
 import com.android.contacts.common.model.account.AccountType.EditField;
 import com.android.contacts.common.model.account.AccountType.EventEditType;
 import com.android.contacts.common.model.dataitem.DataKind;
-import com.android.contacts.util.DateUtils;
+import com.android.contacts.common.util.CommonDateUtils;
+import com.android.contacts.common.util.DateUtils;
 
 import java.text.ParsePosition;
 import java.util.Calendar;
@@ -45,10 +46,6 @@
  * Editor that allows editing Events using a {@link DatePickerDialog}
  */
 public class EventFieldEditorView extends LabeledEditorView {
-    /**
-     * Exchange requires 8:00 for birthdays
-     */
-    private final static int DEFAULT_HOUR = 8;
 
     /**
      * Default string to show when there is no date selected yet.
@@ -181,7 +178,7 @@
             // This value is missing the year. Add it now
             calendar.setTime(date2);
             calendar.set(defaultYear, calendar.get(Calendar.MONTH),
-                    calendar.get(Calendar.DAY_OF_MONTH), DEFAULT_HOUR, 0, 0);
+                    calendar.get(Calendar.DAY_OF_MONTH), CommonDateUtils.DEFAULT_HOUR, 0, 0);
 
             onFieldChanged(column, kind.dateFormatWithYear.format(calendar.getTime()));
             rebuildDateView();
@@ -237,7 +234,7 @@
                 // For formats other than Exchange, the time of the day is ignored
                 outCalendar.clear();
                 outCalendar.set(year == DatePickerDialog.NO_YEAR ? 2000 : year, monthOfYear,
-                        dayOfMonth, DEFAULT_HOUR, 0, 0);
+                        dayOfMonth, CommonDateUtils.DEFAULT_HOUR, 0, 0);
 
                 final String resultString;
                 if (year == 0) {
@@ -254,13 +251,6 @@
         return resultDialog;
     }
 
-    /**
-     * @return Default hour which should be used for birthday field.
-     */
-    public static int getDefaultHourForBirthday() {
-        return DEFAULT_HOUR;
-    }
-
     @Override
     public void clearAllFields() {
         // Update UI
diff --git a/src/com/android/contacts/editor/GroupMembershipView.java b/src/com/android/contacts/editor/GroupMembershipView.java
index d150be8..db389fb 100644
--- a/src/com/android/contacts/editor/GroupMembershipView.java
+++ b/src/com/android/contacts/editor/GroupMembershipView.java
@@ -40,9 +40,9 @@
 import com.android.contacts.common.model.dataitem.DataKind;
 import com.android.contacts.interactions.GroupCreationDialogFragment;
 import com.android.contacts.interactions.GroupCreationDialogFragment.OnGroupCreatedListener;
-import com.android.contacts.model.RawContactDelta;
+import com.android.contacts.common.model.RawContactDelta;
 import com.android.contacts.common.model.ValuesDelta;
-import com.android.contacts.model.RawContactModifier;
+import com.android.contacts.common.model.RawContactModifier;
 import com.android.contacts.util.UiClosables;
 import com.google.common.base.Objects;
 
diff --git a/src/com/android/contacts/editor/KindSectionView.java b/src/com/android/contacts/editor/KindSectionView.java
index fb9c253..261286e 100644
--- a/src/com/android/contacts/editor/KindSectionView.java
+++ b/src/com/android/contacts/editor/KindSectionView.java
@@ -28,8 +28,8 @@
 
 import com.android.contacts.R;
 import com.android.contacts.editor.Editor.EditorListener;
-import com.android.contacts.model.RawContactModifier;
-import com.android.contacts.model.RawContactDelta;
+import com.android.contacts.common.model.RawContactModifier;
+import com.android.contacts.common.model.RawContactDelta;
 import com.android.contacts.common.model.ValuesDelta;
 import com.android.contacts.common.model.dataitem.DataKind;
 
diff --git a/src/com/android/contacts/editor/LabeledEditorView.java b/src/com/android/contacts/editor/LabeledEditorView.java
index 3c0774d..0a33b6d 100644
--- a/src/com/android/contacts/editor/LabeledEditorView.java
+++ b/src/com/android/contacts/editor/LabeledEditorView.java
@@ -44,11 +44,11 @@
 import android.widget.Spinner;
 import android.widget.TextView;
 
-import com.android.contacts.ContactsUtils;
 import com.android.contacts.R;
-import com.android.contacts.model.RawContactDelta;
+import com.android.contacts.common.model.RawContactDelta;
+import com.android.contacts.common.ContactsUtils;
 import com.android.contacts.common.model.ValuesDelta;
-import com.android.contacts.model.RawContactModifier;
+import com.android.contacts.common.model.RawContactModifier;
 import com.android.contacts.common.model.account.AccountType.EditType;
 import com.android.contacts.common.model.dataitem.DataKind;
 import com.android.contacts.util.DialogManager;
diff --git a/src/com/android/contacts/editor/PhoneticNameEditorView.java b/src/com/android/contacts/editor/PhoneticNameEditorView.java
index 2836c721..69e0719 100644
--- a/src/com/android/contacts/editor/PhoneticNameEditorView.java
+++ b/src/com/android/contacts/editor/PhoneticNameEditorView.java
@@ -17,14 +17,14 @@
 package com.android.contacts.editor;
 
 import android.content.Context;
-import android.provider.ContactsContract.CommonDataKinds.StructuredName;
 import android.text.TextUtils;
 import android.util.AttributeSet;
 
-import com.android.contacts.model.RawContactDelta;
+import com.android.contacts.common.model.RawContactDelta;
 import com.android.contacts.common.model.ValuesDelta;
 import com.android.contacts.common.model.dataitem.DataKind;
-import com.android.contacts.model.dataitem.StructuredNameDataItem;
+import com.android.contacts.common.model.dataitem.StructuredNameDataItem;
+import com.android.contacts.common.util.NameConverter;
 
 /**
  * A dedicated editor for phonetic name. It is similar to {@link StructuredNameEditorView}.
@@ -61,7 +61,7 @@
         }
 
         private void parsePhoneticName(String value) {
-            StructuredNameDataItem dataItem = PhoneticNameEditorView.parsePhoneticName(value, null);
+            StructuredNameDataItem dataItem = NameConverter.parsePhoneticName(value, null);
             mValues.setPhoneticFamilyName(dataItem.getPhoneticFamilyName());
             mValues.setPhoneticMiddleName(dataItem.getPhoneticMiddleName());
             mValues.setPhoneticGivenName(dataItem.getPhoneticGivenName());
@@ -71,7 +71,7 @@
             String family = mValues.getPhoneticFamilyName();
             String middle = mValues.getPhoneticMiddleName();
             String given = mValues.getPhoneticGivenName();
-            mPhoneticName = PhoneticNameEditorView.buildPhoneticName(family, middle, given);
+            mPhoneticName = NameConverter.buildPhoneticName(family, middle, given);
         }
 
         @Override
@@ -85,74 +85,6 @@
         }
     }
 
-    /**
-     * Parses phonetic name and returns parsed data (family, middle, given) as ContentValues.
-     * Parsed data should be {@link StructuredName#PHONETIC_FAMILY_NAME},
-     * {@link StructuredName#PHONETIC_MIDDLE_NAME}, and
-     * {@link StructuredName#PHONETIC_GIVEN_NAME}.
-     * If this method cannot parse given phoneticName, null values will be stored.
-     *
-     * @param phoneticName Phonetic name to be parsed
-     * @param values ContentValues to be used for storing data. If null, new instance will be
-     * created.
-     * @return ContentValues with parsed data. Those data can be null.
-     */
-    public static StructuredNameDataItem parsePhoneticName(String phoneticName,
-            StructuredNameDataItem item) {
-        String family = null;
-        String middle = null;
-        String given = null;
-
-        if (!TextUtils.isEmpty(phoneticName)) {
-            String[] strings = phoneticName.split(" ", 3);
-            switch (strings.length) {
-                case 1:
-                    family = strings[0];
-                    break;
-                case 2:
-                    family = strings[0];
-                    given = strings[1];
-                    break;
-                case 3:
-                    family = strings[0];
-                    middle = strings[1];
-                    given = strings[2];
-                    break;
-            }
-        }
-
-        if (item == null) {
-            item = new StructuredNameDataItem();
-        }
-        item.setPhoneticFamilyName(family);
-        item.setPhoneticMiddleName(middle);
-        item.setPhoneticGivenName(given);
-        return item;
-    }
-
-    /**
-     * Constructs and returns a phonetic full name from given parts.
-     */
-    public static String buildPhoneticName(String family, String middle, String given) {
-        if (!TextUtils.isEmpty(family) || !TextUtils.isEmpty(middle)
-                || !TextUtils.isEmpty(given)) {
-            StringBuilder sb = new StringBuilder();
-            if (!TextUtils.isEmpty(family)) {
-                sb.append(family.trim()).append(' ');
-            }
-            if (!TextUtils.isEmpty(middle)) {
-                sb.append(middle.trim()).append(' ');
-            }
-            if (!TextUtils.isEmpty(given)) {
-                sb.append(given.trim()).append(' ');
-            }
-            sb.setLength(sb.length() - 1);  // Yank the last space
-            return sb.toString();
-        } else {
-            return null;
-        }
-    }
-
     public static boolean isUnstructuredPhoneticNameColumn(String column) {
         return DataKind.PSEUDO_COLUMN_PHONETIC_NAME.equals(column);
     }
diff --git a/src/com/android/contacts/editor/PhotoEditorView.java b/src/com/android/contacts/editor/PhotoEditorView.java
index 652c8e6..bee61f4 100644
--- a/src/com/android/contacts/editor/PhotoEditorView.java
+++ b/src/com/android/contacts/editor/PhotoEditorView.java
@@ -25,9 +25,9 @@
 import android.widget.ImageView;
 import android.widget.LinearLayout;
 
-import com.android.contacts.ContactsUtils;
 import com.android.contacts.R;
-import com.android.contacts.model.RawContactDelta;
+import com.android.contacts.common.model.RawContactDelta;
+import com.android.contacts.common.ContactsUtils;
 import com.android.contacts.common.model.ValuesDelta;
 import com.android.contacts.common.model.dataitem.DataKind;
 import com.android.contacts.util.ContactPhotoUtils;
diff --git a/src/com/android/contacts/editor/RawContactEditorView.java b/src/com/android/contacts/editor/RawContactEditorView.java
index b52b0b2..c9d3c33 100644
--- a/src/com/android/contacts/editor/RawContactEditorView.java
+++ b/src/com/android/contacts/editor/RawContactEditorView.java
@@ -43,9 +43,9 @@
 import com.android.contacts.common.model.account.AccountType;
 import com.android.contacts.common.model.account.AccountType.EditType;
 import com.android.contacts.common.model.dataitem.DataKind;
-import com.android.contacts.model.RawContactDelta;
+import com.android.contacts.common.model.RawContactDelta;
 import com.android.contacts.common.model.ValuesDelta;
-import com.android.contacts.model.RawContactModifier;
+import com.android.contacts.common.model.RawContactModifier;
 import com.google.common.base.Objects;
 
 import java.util.ArrayList;
diff --git a/src/com/android/contacts/editor/RawContactReadOnlyEditorView.java b/src/com/android/contacts/editor/RawContactReadOnlyEditorView.java
index 70a2b4e..d1fa282 100644
--- a/src/com/android/contacts/editor/RawContactReadOnlyEditorView.java
+++ b/src/com/android/contacts/editor/RawContactReadOnlyEditorView.java
@@ -39,8 +39,8 @@
 
 import com.android.contacts.R;
 import com.android.contacts.common.GeoUtil;
-import com.android.contacts.model.RawContactModifier;
-import com.android.contacts.model.RawContactDelta;
+import com.android.contacts.common.model.RawContactModifier;
+import com.android.contacts.common.model.RawContactDelta;
 import com.android.contacts.common.model.ValuesDelta;
 import com.android.contacts.common.model.account.AccountType;
 import com.android.contacts.common.model.account.AccountWithDataSet;
diff --git a/src/com/android/contacts/editor/StructuredNameEditorView.java b/src/com/android/contacts/editor/StructuredNameEditorView.java
index 4d72598..bf548f6 100644
--- a/src/com/android/contacts/editor/StructuredNameEditorView.java
+++ b/src/com/android/contacts/editor/StructuredNameEditorView.java
@@ -25,12 +25,12 @@
 import android.text.TextUtils;
 import android.util.AttributeSet;
 
-import com.android.contacts.model.RawContactDelta;
+import com.android.contacts.common.model.RawContactDelta;
 import com.android.contacts.common.model.ValuesDelta;
-import com.android.contacts.model.dataitem.DataItem;
+import com.android.contacts.common.model.dataitem.DataItem;
 import com.android.contacts.common.model.dataitem.DataKind;
-import com.android.contacts.model.dataitem.StructuredNameDataItem;
-import com.android.contacts.util.NameConverter;
+import com.android.contacts.common.util.NameConverter;
+import com.android.contacts.common.model.dataitem.StructuredNameDataItem;
 
 import java.util.HashMap;
 import java.util.Map;
diff --git a/src/com/android/contacts/editor/TextFieldsEditorView.java b/src/com/android/contacts/editor/TextFieldsEditorView.java
index a20ba77..85cbac8 100644
--- a/src/com/android/contacts/editor/TextFieldsEditorView.java
+++ b/src/com/android/contacts/editor/TextFieldsEditorView.java
@@ -35,9 +35,9 @@
 import android.widget.ImageView;
 import android.widget.LinearLayout;
 
-import com.android.contacts.ContactsUtils;
 import com.android.contacts.R;
-import com.android.contacts.model.RawContactDelta;
+import com.android.contacts.common.model.RawContactDelta;
+import com.android.contacts.common.ContactsUtils;
 import com.android.contacts.common.model.ValuesDelta;
 import com.android.contacts.common.model.account.AccountType.EditField;
 import com.android.contacts.common.model.dataitem.DataKind;
diff --git a/src/com/android/contacts/editor/ViewIdGenerator.java b/src/com/android/contacts/editor/ViewIdGenerator.java
index 8494e1a..e7e7948 100644
--- a/src/com/android/contacts/editor/ViewIdGenerator.java
+++ b/src/com/android/contacts/editor/ViewIdGenerator.java
@@ -20,7 +20,7 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 
-import com.android.contacts.model.RawContactDelta;
+import com.android.contacts.common.model.RawContactDelta;
 import com.android.contacts.common.model.ValuesDelta;
 import com.android.contacts.common.model.dataitem.DataKind;
 
diff --git a/src/com/android/contacts/group/GroupBrowseListFragment.java b/src/com/android/contacts/group/GroupBrowseListFragment.java
index f842db3..81cc28c 100644
--- a/src/com/android/contacts/group/GroupBrowseListFragment.java
+++ b/src/com/android/contacts/group/GroupBrowseListFragment.java
@@ -42,10 +42,10 @@
 import android.widget.ListView;
 import android.widget.TextView;
 
-import com.android.contacts.ContactsUtils;
 import com.android.contacts.GroupListLoader;
 import com.android.contacts.R;
 import com.android.contacts.group.GroupBrowseListAdapter.GroupListItemViewCache;
+import com.android.contacts.common.ContactsUtils;
 import com.android.contacts.common.list.AutoScrollListView;
 
 /**
diff --git a/src/com/android/contacts/list/ContactBrowseListFragment.java b/src/com/android/contacts/list/ContactBrowseListFragment.java
index 78bc3eb..14e8949 100644
--- a/src/com/android/contacts/list/ContactBrowseListFragment.java
+++ b/src/com/android/contacts/list/ContactBrowseListFragment.java
@@ -40,7 +40,7 @@
 import com.android.contacts.common.list.ContactListAdapter;
 import com.android.contacts.common.list.ContactListFilter;
 import com.android.contacts.common.list.DirectoryPartition;
-import com.android.contacts.util.ContactLoaderUtils;
+import com.android.contacts.common.util.ContactLoaderUtils;
 
 import java.util.List;
 
diff --git a/src/com/android/contacts/model/Contact.java b/src/com/android/contacts/model/Contact.java
deleted file mode 100644
index 9f7f217..0000000
--- a/src/com/android/contacts/model/Contact.java
+++ /dev/null
@@ -1,484 +0,0 @@
-/*
- * Copyright (C) 2012 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.contacts.model;
-
-import android.content.ContentValues;
-import android.content.Context;
-import android.net.Uri;
-import android.provider.ContactsContract.CommonDataKinds.Photo;
-import android.provider.ContactsContract.Data;
-import android.provider.ContactsContract.Directory;
-import android.provider.ContactsContract.DisplayNameSources;
-
-import com.android.contacts.GroupMetaData;
-import com.android.contacts.common.model.account.AccountType;
-import com.android.contacts.util.DataStatus;
-import com.android.contacts.util.StreamItemEntry;
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-
-import java.util.ArrayList;
-import java.util.Collections;
-
-/**
- * A Contact represents a single person or logical entity as perceived by the user.  The information
- * about a contact can come from multiple data sources, which are each represented by a RawContact
- * object.  Thus, a Contact is associated with a collection of RawContact objects.
- *
- * The aggregation of raw contacts into a single contact is performed automatically, and it is
- * also possible for users to manually split and join raw contacts into various contacts.
- *
- * Only the {@link ContactLoader} class can create a Contact object with various flags to allow
- * partial loading of contact data.  Thus, an instance of this class should be treated as
- * a read-only object.
- */
-public class Contact {
-    private enum Status {
-        /** Contact is successfully loaded */
-        LOADED,
-        /** There was an error loading the contact */
-        ERROR,
-        /** Contact is not found */
-        NOT_FOUND,
-    }
-
-    private final Uri mRequestedUri;
-    private final Uri mLookupUri;
-    private final Uri mUri;
-    private final long mDirectoryId;
-    private final String mLookupKey;
-    private final long mId;
-    private final long mNameRawContactId;
-    private final int mDisplayNameSource;
-    private final long mPhotoId;
-    private final String mPhotoUri;
-    private final String mDisplayName;
-    private final String mAltDisplayName;
-    private final String mPhoneticName;
-    private final boolean mStarred;
-    private final Integer mPresence;
-    private ImmutableList<RawContact> mRawContacts;
-    private ImmutableMap<Long,DataStatus> mStatuses;
-    private ImmutableList<AccountType> mInvitableAccountTypes;
-
-    private String mDirectoryDisplayName;
-    private String mDirectoryType;
-    private String mDirectoryAccountType;
-    private String mDirectoryAccountName;
-    private int mDirectoryExportSupport;
-
-    private ImmutableList<GroupMetaData> mGroups;
-
-    private byte[] mPhotoBinaryData;
-    private final boolean mSendToVoicemail;
-    private final String mCustomRingtone;
-    private final boolean mIsUserProfile;
-
-    private final Contact.Status mStatus;
-    private final Exception mException;
-
-    /**
-     * Constructor for special results, namely "no contact found" and "error".
-     */
-    private Contact(Uri requestedUri, Contact.Status status, Exception exception) {
-        if (status == Status.ERROR && exception == null) {
-            throw new IllegalArgumentException("ERROR result must have exception");
-        }
-        mStatus = status;
-        mException = exception;
-        mRequestedUri = requestedUri;
-        mLookupUri = null;
-        mUri = null;
-        mDirectoryId = -1;
-        mLookupKey = null;
-        mId = -1;
-        mRawContacts = null;
-        mStatuses = null;
-        mNameRawContactId = -1;
-        mDisplayNameSource = DisplayNameSources.UNDEFINED;
-        mPhotoId = -1;
-        mPhotoUri = null;
-        mDisplayName = null;
-        mAltDisplayName = null;
-        mPhoneticName = null;
-        mStarred = false;
-        mPresence = null;
-        mInvitableAccountTypes = null;
-        mSendToVoicemail = false;
-        mCustomRingtone = null;
-        mIsUserProfile = false;
-    }
-
-    public static Contact forError(Uri requestedUri, Exception exception) {
-        return new Contact(requestedUri, Status.ERROR, exception);
-    }
-
-    public static Contact forNotFound(Uri requestedUri) {
-        return new Contact(requestedUri, Status.NOT_FOUND, null);
-    }
-
-    /**
-     * Constructor to call when contact was found
-     */
-    public Contact(Uri requestedUri, Uri uri, Uri lookupUri, long directoryId, String lookupKey,
-            long id, long nameRawContactId, int displayNameSource, long photoId,
-            String photoUri, String displayName, String altDisplayName, String phoneticName,
-            boolean starred, Integer presence, boolean sendToVoicemail, String customRingtone,
-            boolean isUserProfile) {
-        mStatus = Status.LOADED;
-        mException = null;
-        mRequestedUri = requestedUri;
-        mLookupUri = lookupUri;
-        mUri = uri;
-        mDirectoryId = directoryId;
-        mLookupKey = lookupKey;
-        mId = id;
-        mRawContacts = null;
-        mStatuses = null;
-        mNameRawContactId = nameRawContactId;
-        mDisplayNameSource = displayNameSource;
-        mPhotoId = photoId;
-        mPhotoUri = photoUri;
-        mDisplayName = displayName;
-        mAltDisplayName = altDisplayName;
-        mPhoneticName = phoneticName;
-        mStarred = starred;
-        mPresence = presence;
-        mInvitableAccountTypes = null;
-        mSendToVoicemail = sendToVoicemail;
-        mCustomRingtone = customRingtone;
-        mIsUserProfile = isUserProfile;
-    }
-
-    public Contact(Uri requestedUri, Contact from) {
-        mRequestedUri = requestedUri;
-
-        mStatus = from.mStatus;
-        mException = from.mException;
-        mLookupUri = from.mLookupUri;
-        mUri = from.mUri;
-        mDirectoryId = from.mDirectoryId;
-        mLookupKey = from.mLookupKey;
-        mId = from.mId;
-        mNameRawContactId = from.mNameRawContactId;
-        mDisplayNameSource = from.mDisplayNameSource;
-        mPhotoId = from.mPhotoId;
-        mPhotoUri = from.mPhotoUri;
-        mDisplayName = from.mDisplayName;
-        mAltDisplayName = from.mAltDisplayName;
-        mPhoneticName = from.mPhoneticName;
-        mStarred = from.mStarred;
-        mPresence = from.mPresence;
-        mRawContacts = from.mRawContacts;
-        mStatuses = from.mStatuses;
-        mInvitableAccountTypes = from.mInvitableAccountTypes;
-
-        mDirectoryDisplayName = from.mDirectoryDisplayName;
-        mDirectoryType = from.mDirectoryType;
-        mDirectoryAccountType = from.mDirectoryAccountType;
-        mDirectoryAccountName = from.mDirectoryAccountName;
-        mDirectoryExportSupport = from.mDirectoryExportSupport;
-
-        mGroups = from.mGroups;
-
-        mPhotoBinaryData = from.mPhotoBinaryData;
-        mSendToVoicemail = from.mSendToVoicemail;
-        mCustomRingtone = from.mCustomRingtone;
-        mIsUserProfile = from.mIsUserProfile;
-    }
-
-    /**
-     * @param exportSupport See {@link Directory#EXPORT_SUPPORT}.
-     */
-    public void setDirectoryMetaData(String displayName, String directoryType,
-            String accountType, String accountName, int exportSupport) {
-        mDirectoryDisplayName = displayName;
-        mDirectoryType = directoryType;
-        mDirectoryAccountType = accountType;
-        mDirectoryAccountName = accountName;
-        mDirectoryExportSupport = exportSupport;
-    }
-
-    /* package */ void setPhotoBinaryData(byte[] photoBinaryData) {
-        mPhotoBinaryData = photoBinaryData;
-    }
-
-    /**
-     * Returns the URI for the contact that contains both the lookup key and the ID. This is
-     * the best URI to reference a contact.
-     * For directory contacts, this is the same a the URI as returned by {@link #getUri()}
-     */
-    public Uri getLookupUri() {
-        return mLookupUri;
-    }
-
-    public String getLookupKey() {
-        return mLookupKey;
-    }
-
-    /**
-     * Returns the contact Uri that was passed to the provider to make the query. This is
-     * the same as the requested Uri, unless the requested Uri doesn't specify a Contact:
-     * If it either references a Raw-Contact or a Person (a pre-Eclair style Uri), this Uri will
-     * always reference the full aggregate contact.
-     */
-    public Uri getUri() {
-        return mUri;
-    }
-
-    /**
-     * Returns the URI for which this {@link ContactLoader) was initially requested.
-     */
-    public Uri getRequestedUri() {
-        return mRequestedUri;
-    }
-
-    /**
-     * Instantiate a new RawContactDeltaList for this contact.
-     */
-    public RawContactDeltaList createRawContactDeltaList() {
-        return RawContactDeltaList.fromIterator(getRawContacts().iterator());
-    }
-
-    /**
-     * Returns the contact ID.
-     */
-    @VisibleForTesting
-    /* package */ long getId() {
-        return mId;
-    }
-
-    /**
-     * @return true when an exception happened during loading, in which case
-     *     {@link #getException} returns the actual exception object.
-     *     Note {@link #isNotFound()} and {@link #isError()} are mutually exclusive; If
-     *     {@link #isError()} is {@code true}, {@link #isNotFound()} is always {@code false},
-     *     and vice versa.
-     */
-    public boolean isError() {
-        return mStatus == Status.ERROR;
-    }
-
-    public Exception getException() {
-        return mException;
-    }
-
-    /**
-     * @return true when the specified contact is not found.
-     *     Note {@link #isNotFound()} and {@link #isError()} are mutually exclusive; If
-     *     {@link #isError()} is {@code true}, {@link #isNotFound()} is always {@code false},
-     *     and vice versa.
-     */
-    public boolean isNotFound() {
-        return mStatus == Status.NOT_FOUND;
-    }
-
-    /**
-     * @return true if the specified contact is successfully loaded.
-     *     i.e. neither {@link #isError()} nor {@link #isNotFound()}.
-     */
-    public boolean isLoaded() {
-        return mStatus == Status.LOADED;
-    }
-
-    public long getNameRawContactId() {
-        return mNameRawContactId;
-    }
-
-    public int getDisplayNameSource() {
-        return mDisplayNameSource;
-    }
-
-    public long getPhotoId() {
-        return mPhotoId;
-    }
-
-    public String getPhotoUri() {
-        return mPhotoUri;
-    }
-
-    public String getDisplayName() {
-        return mDisplayName;
-    }
-
-    public String getAltDisplayName() {
-        return mAltDisplayName;
-    }
-
-    public String getPhoneticName() {
-        return mPhoneticName;
-    }
-
-    public boolean getStarred() {
-        return mStarred;
-    }
-
-    public Integer getPresence() {
-        return mPresence;
-    }
-
-    /**
-     * This can return non-null invitable account types only if the {@link ContactLoader} was
-     * configured to load invitable account types in its constructor.
-     * @return
-     */
-    public ImmutableList<AccountType> getInvitableAccountTypes() {
-        return mInvitableAccountTypes;
-    }
-
-    public ImmutableList<RawContact> getRawContacts() {
-        return mRawContacts;
-    }
-
-    /**
-     * This can return non-null stream items only if the {@link ContactLoader} was
-     * configured to load stream items in its constructor.
-     * @return
-     */
-    public ImmutableList<StreamItemEntry> getStreamItems() {
-        return ImmutableList.of();
-    }
-
-    public ImmutableMap<Long, DataStatus> getStatuses() {
-        return mStatuses;
-    }
-
-    public long getDirectoryId() {
-        return mDirectoryId;
-    }
-
-    public boolean isDirectoryEntry() {
-        return mDirectoryId != -1 && mDirectoryId != Directory.DEFAULT
-                && mDirectoryId != Directory.LOCAL_INVISIBLE;
-    }
-
-    /**
-     * @return true if this is a contact (not group, etc.) with at least one
-     *         writable raw-contact, and false otherwise.
-     */
-    public boolean isWritableContact(final Context context) {
-        return getFirstWritableRawContactId(context) != -1;
-    }
-
-    /**
-     * Return the ID of the first raw-contact in the contact data that belongs to a
-     * contact-writable account, or -1 if no such entity exists.
-     */
-    public long getFirstWritableRawContactId(final Context context) {
-        // Directory entries are non-writable
-        if (isDirectoryEntry()) return -1;
-
-        // Iterate through raw-contacts; if we find a writable on, return its ID.
-        for (RawContact rawContact : getRawContacts()) {
-            AccountType accountType = rawContact.getAccountType(context);
-            if (accountType != null && accountType.areContactsWritable()) {
-                return rawContact.getId();
-            }
-        }
-        // No writable raw-contact was found.
-        return -1;
-    }
-
-    public int getDirectoryExportSupport() {
-        return mDirectoryExportSupport;
-    }
-
-    public String getDirectoryDisplayName() {
-        return mDirectoryDisplayName;
-    }
-
-    public String getDirectoryType() {
-        return mDirectoryType;
-    }
-
-    public String getDirectoryAccountType() {
-        return mDirectoryAccountType;
-    }
-
-    public String getDirectoryAccountName() {
-        return mDirectoryAccountName;
-    }
-
-    public byte[] getPhotoBinaryData() {
-        return mPhotoBinaryData;
-    }
-
-    public ArrayList<ContentValues> getContentValues() {
-        if (mRawContacts.size() != 1) {
-            throw new IllegalStateException(
-                    "Cannot extract content values from an aggregated contact");
-        }
-
-        RawContact rawContact = mRawContacts.get(0);
-        ArrayList<ContentValues> result = rawContact.getContentValues();
-
-        // If the photo was loaded using the URI, create an entry for the photo
-        // binary data.
-        if (mPhotoId == 0 && mPhotoBinaryData != null) {
-            ContentValues photo = new ContentValues();
-            photo.put(Data.MIMETYPE, Photo.CONTENT_ITEM_TYPE);
-            photo.put(Photo.PHOTO, mPhotoBinaryData);
-            result.add(photo);
-        }
-
-        return result;
-    }
-
-    /**
-     * This can return non-null group meta-data only if the {@link ContactLoader} was configured to
-     * load group metadata in its constructor.
-     * @return
-     */
-    public ImmutableList<GroupMetaData> getGroupMetaData() {
-        return mGroups;
-    }
-
-    public boolean isSendToVoicemail() {
-        return mSendToVoicemail;
-    }
-
-    public String getCustomRingtone() {
-        return mCustomRingtone;
-    }
-
-    public boolean isUserProfile() {
-        return mIsUserProfile;
-    }
-
-    @Override
-    public String toString() {
-        return "{requested=" + mRequestedUri + ",lookupkey=" + mLookupKey +
-                ",uri=" + mUri + ",status=" + mStatus + "}";
-    }
-
-    /* package */ void setRawContacts(ImmutableList<RawContact> rawContacts) {
-        mRawContacts = rawContacts;
-    }
-
-    /* package */ void setStatuses(ImmutableMap<Long, DataStatus> statuses) {
-        mStatuses = statuses;
-    }
-
-    /* package */ void setInvitableAccountTypes(ImmutableList<AccountType> accountTypes) {
-        mInvitableAccountTypes = accountTypes;
-    }
-
-    /* package */ void setGroupMetaData(ImmutableList<GroupMetaData> groups) {
-        mGroups = groups;
-    }
-}
diff --git a/src/com/android/contacts/model/ContactLoader.java b/src/com/android/contacts/model/ContactLoader.java
deleted file mode 100644
index e10fc6c..0000000
--- a/src/com/android/contacts/model/ContactLoader.java
+++ /dev/null
@@ -1,970 +0,0 @@
-/*
- * Copyright (C) 2010 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.contacts.model;
-
-import android.content.AsyncTaskLoader;
-import android.content.ContentResolver;
-import android.content.ContentUris;
-import android.content.ContentValues;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.res.AssetFileDescriptor;
-import android.content.res.Resources;
-import android.database.Cursor;
-import android.net.Uri;
-import android.provider.ContactsContract;
-import android.provider.ContactsContract.CommonDataKinds.GroupMembership;
-import android.provider.ContactsContract.Contacts;
-import android.provider.ContactsContract.Data;
-import android.provider.ContactsContract.Directory;
-import android.provider.ContactsContract.Groups;
-import android.provider.ContactsContract.RawContacts;
-import android.text.TextUtils;
-import android.util.Log;
-
-import com.android.contacts.GroupMetaData;
-import com.android.contacts.common.GeoUtil;
-import com.android.contacts.common.model.AccountTypeManager;
-import com.android.contacts.common.model.account.AccountType;
-import com.android.contacts.common.model.account.AccountTypeWithDataSet;
-import com.android.contacts.common.util.Constants;
-import com.android.contacts.common.util.UriUtils;
-import com.android.contacts.model.dataitem.DataItem;
-import com.android.contacts.model.dataitem.PhoneDataItem;
-import com.android.contacts.model.dataitem.PhotoDataItem;
-import com.android.contacts.util.ContactLoaderUtils;
-import com.android.contacts.util.DataStatus;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
-
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Loads a single Contact and all it constituent RawContacts.
- */
-public class ContactLoader extends AsyncTaskLoader<Contact> {
-
-    private static final String TAG = ContactLoader.class.getSimpleName();
-
-    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
-
-    /** A short-lived cache that can be set by {@link #cacheResult()} */
-    private static Contact sCachedResult = null;
-
-    private final Uri mRequestedUri;
-    private Uri mLookupUri;
-    private boolean mLoadGroupMetaData;
-    private boolean mLoadInvitableAccountTypes;
-    private boolean mPostViewNotification;
-    private boolean mComputeFormattedPhoneNumber;
-    private Contact mContact;
-    private ForceLoadContentObserver mObserver;
-    private final Set<Long> mNotifiedRawContactIds = Sets.newHashSet();
-
-    public ContactLoader(Context context, Uri lookupUri, boolean postViewNotification) {
-        this(context, lookupUri, false, false, postViewNotification, false);
-    }
-
-    public ContactLoader(Context context, Uri lookupUri, boolean loadGroupMetaData,
-            boolean loadInvitableAccountTypes,
-            boolean postViewNotification, boolean computeFormattedPhoneNumber) {
-        super(context);
-        mLookupUri = lookupUri;
-        mRequestedUri = lookupUri;
-        mLoadGroupMetaData = loadGroupMetaData;
-        mLoadInvitableAccountTypes = loadInvitableAccountTypes;
-        mPostViewNotification = postViewNotification;
-        mComputeFormattedPhoneNumber = computeFormattedPhoneNumber;
-    }
-
-    /**
-     * Projection used for the query that loads all data for the entire contact (except for
-     * social stream items).
-     */
-    private static class ContactQuery {
-        static final String[] COLUMNS = new String[] {
-                Contacts.NAME_RAW_CONTACT_ID,
-                Contacts.DISPLAY_NAME_SOURCE,
-                Contacts.LOOKUP_KEY,
-                Contacts.DISPLAY_NAME,
-                Contacts.DISPLAY_NAME_ALTERNATIVE,
-                Contacts.PHONETIC_NAME,
-                Contacts.PHOTO_ID,
-                Contacts.STARRED,
-                Contacts.CONTACT_PRESENCE,
-                Contacts.CONTACT_STATUS,
-                Contacts.CONTACT_STATUS_TIMESTAMP,
-                Contacts.CONTACT_STATUS_RES_PACKAGE,
-                Contacts.CONTACT_STATUS_LABEL,
-                Contacts.Entity.CONTACT_ID,
-                Contacts.Entity.RAW_CONTACT_ID,
-
-                RawContacts.ACCOUNT_NAME,
-                RawContacts.ACCOUNT_TYPE,
-                RawContacts.DATA_SET,
-                RawContacts.ACCOUNT_TYPE_AND_DATA_SET,
-                RawContacts.DIRTY,
-                RawContacts.VERSION,
-                RawContacts.SOURCE_ID,
-                RawContacts.SYNC1,
-                RawContacts.SYNC2,
-                RawContacts.SYNC3,
-                RawContacts.SYNC4,
-                RawContacts.DELETED,
-                RawContacts.NAME_VERIFIED,
-
-                Contacts.Entity.DATA_ID,
-                Data.DATA1,
-                Data.DATA2,
-                Data.DATA3,
-                Data.DATA4,
-                Data.DATA5,
-                Data.DATA6,
-                Data.DATA7,
-                Data.DATA8,
-                Data.DATA9,
-                Data.DATA10,
-                Data.DATA11,
-                Data.DATA12,
-                Data.DATA13,
-                Data.DATA14,
-                Data.DATA15,
-                Data.SYNC1,
-                Data.SYNC2,
-                Data.SYNC3,
-                Data.SYNC4,
-                Data.DATA_VERSION,
-                Data.IS_PRIMARY,
-                Data.IS_SUPER_PRIMARY,
-                Data.MIMETYPE,
-                Data.RES_PACKAGE,
-
-                GroupMembership.GROUP_SOURCE_ID,
-
-                Data.PRESENCE,
-                Data.CHAT_CAPABILITY,
-                Data.STATUS,
-                Data.STATUS_RES_PACKAGE,
-                Data.STATUS_ICON,
-                Data.STATUS_LABEL,
-                Data.STATUS_TIMESTAMP,
-
-                Contacts.PHOTO_URI,
-                Contacts.SEND_TO_VOICEMAIL,
-                Contacts.CUSTOM_RINGTONE,
-                Contacts.IS_USER_PROFILE,
-        };
-
-        public static final int NAME_RAW_CONTACT_ID = 0;
-        public static final int DISPLAY_NAME_SOURCE = 1;
-        public static final int LOOKUP_KEY = 2;
-        public static final int DISPLAY_NAME = 3;
-        public static final int ALT_DISPLAY_NAME = 4;
-        public static final int PHONETIC_NAME = 5;
-        public static final int PHOTO_ID = 6;
-        public static final int STARRED = 7;
-        public static final int CONTACT_PRESENCE = 8;
-        public static final int CONTACT_STATUS = 9;
-        public static final int CONTACT_STATUS_TIMESTAMP = 10;
-        public static final int CONTACT_STATUS_RES_PACKAGE = 11;
-        public static final int CONTACT_STATUS_LABEL = 12;
-        public static final int CONTACT_ID = 13;
-        public static final int RAW_CONTACT_ID = 14;
-
-        public static final int ACCOUNT_NAME = 15;
-        public static final int ACCOUNT_TYPE = 16;
-        public static final int DATA_SET = 17;
-        public static final int ACCOUNT_TYPE_AND_DATA_SET = 18;
-        public static final int DIRTY = 19;
-        public static final int VERSION = 20;
-        public static final int SOURCE_ID = 21;
-        public static final int SYNC1 = 22;
-        public static final int SYNC2 = 23;
-        public static final int SYNC3 = 24;
-        public static final int SYNC4 = 25;
-        public static final int DELETED = 26;
-        public static final int NAME_VERIFIED = 27;
-
-        public static final int DATA_ID = 28;
-        public static final int DATA1 = 29;
-        public static final int DATA2 = 30;
-        public static final int DATA3 = 31;
-        public static final int DATA4 = 32;
-        public static final int DATA5 = 33;
-        public static final int DATA6 = 34;
-        public static final int DATA7 = 35;
-        public static final int DATA8 = 36;
-        public static final int DATA9 = 37;
-        public static final int DATA10 = 38;
-        public static final int DATA11 = 39;
-        public static final int DATA12 = 40;
-        public static final int DATA13 = 41;
-        public static final int DATA14 = 42;
-        public static final int DATA15 = 43;
-        public static final int DATA_SYNC1 = 44;
-        public static final int DATA_SYNC2 = 45;
-        public static final int DATA_SYNC3 = 46;
-        public static final int DATA_SYNC4 = 47;
-        public static final int DATA_VERSION = 48;
-        public static final int IS_PRIMARY = 49;
-        public static final int IS_SUPERPRIMARY = 50;
-        public static final int MIMETYPE = 51;
-        public static final int RES_PACKAGE = 52;
-
-        public static final int GROUP_SOURCE_ID = 53;
-
-        public static final int PRESENCE = 54;
-        public static final int CHAT_CAPABILITY = 55;
-        public static final int STATUS = 56;
-        public static final int STATUS_RES_PACKAGE = 57;
-        public static final int STATUS_ICON = 58;
-        public static final int STATUS_LABEL = 59;
-        public static final int STATUS_TIMESTAMP = 60;
-
-        public static final int PHOTO_URI = 61;
-        public static final int SEND_TO_VOICEMAIL = 62;
-        public static final int CUSTOM_RINGTONE = 63;
-        public static final int IS_USER_PROFILE = 64;
-    }
-
-    /**
-     * Projection used for the query that loads all data for the entire contact.
-     */
-    private static class DirectoryQuery {
-        static final String[] COLUMNS = new String[] {
-            Directory.DISPLAY_NAME,
-            Directory.PACKAGE_NAME,
-            Directory.TYPE_RESOURCE_ID,
-            Directory.ACCOUNT_TYPE,
-            Directory.ACCOUNT_NAME,
-            Directory.EXPORT_SUPPORT,
-        };
-
-        public static final int DISPLAY_NAME = 0;
-        public static final int PACKAGE_NAME = 1;
-        public static final int TYPE_RESOURCE_ID = 2;
-        public static final int ACCOUNT_TYPE = 3;
-        public static final int ACCOUNT_NAME = 4;
-        public static final int EXPORT_SUPPORT = 5;
-    }
-
-    private static class GroupQuery {
-        static final String[] COLUMNS = new String[] {
-            Groups.ACCOUNT_NAME,
-            Groups.ACCOUNT_TYPE,
-            Groups.DATA_SET,
-            Groups.ACCOUNT_TYPE_AND_DATA_SET,
-            Groups._ID,
-            Groups.TITLE,
-            Groups.AUTO_ADD,
-            Groups.FAVORITES,
-        };
-
-        public static final int ACCOUNT_NAME = 0;
-        public static final int ACCOUNT_TYPE = 1;
-        public static final int DATA_SET = 2;
-        public static final int ACCOUNT_TYPE_AND_DATA_SET = 3;
-        public static final int ID = 4;
-        public static final int TITLE = 5;
-        public static final int AUTO_ADD = 6;
-        public static final int FAVORITES = 7;
-    }
-
-    @Override
-    public Contact loadInBackground() {
-        try {
-            final ContentResolver resolver = getContext().getContentResolver();
-            final Uri uriCurrentFormat = ContactLoaderUtils.ensureIsContactUri(
-                    resolver, mLookupUri);
-            final Contact cachedResult = sCachedResult;
-            sCachedResult = null;
-            // Is this the same Uri as what we had before already? In that case, reuse that result
-            final Contact result;
-            final boolean resultIsCached;
-            if (cachedResult != null &&
-                    UriUtils.areEqual(cachedResult.getLookupUri(), mLookupUri)) {
-                // We are using a cached result from earlier. Below, we should make sure
-                // we are not doing any more network or disc accesses
-                result = new Contact(mRequestedUri, cachedResult);
-                resultIsCached = true;
-            } else {
-                if (uriCurrentFormat.getLastPathSegment().equals(Constants.LOOKUP_URI_ENCODED)) {
-                    result = loadEncodedContactEntity(uriCurrentFormat);
-                } else {
-                    result = loadContactEntity(resolver, uriCurrentFormat);
-                }
-                resultIsCached = false;
-            }
-            if (result.isLoaded()) {
-                if (result.isDirectoryEntry()) {
-                    if (!resultIsCached) {
-                        loadDirectoryMetaData(result);
-                    }
-                } else if (mLoadGroupMetaData) {
-                    if (result.getGroupMetaData() == null) {
-                        loadGroupMetaData(result);
-                    }
-                }
-                if (mComputeFormattedPhoneNumber) {
-                    computeFormattedPhoneNumbers(result);
-                }
-                if (!resultIsCached) loadPhotoBinaryData(result);
-
-                // Note ME profile should never have "Add connection"
-                if (mLoadInvitableAccountTypes && result.getInvitableAccountTypes() == null) {
-                    loadInvitableAccountTypes(result);
-                }
-            }
-            return result;
-        } catch (Exception e) {
-            Log.e(TAG, "Error loading the contact: " + mLookupUri, e);
-            return Contact.forError(mRequestedUri, e);
-        }
-    }
-
-    private Contact loadEncodedContactEntity(Uri uri) throws JSONException {
-        final String jsonString = uri.getEncodedFragment();
-        final JSONObject json = new JSONObject(jsonString);
-
-        final long directoryId =
-                Long.valueOf(uri.getQueryParameter(ContactsContract.DIRECTORY_PARAM_KEY));
-
-        final String displayName = json.getString(Contacts.DISPLAY_NAME);
-        final String altDisplayName = json.optString(
-                Contacts.DISPLAY_NAME_ALTERNATIVE, displayName);
-        final int displayNameSource = json.getInt(Contacts.DISPLAY_NAME_SOURCE);
-        final String photoUri = json.optString(Contacts.PHOTO_URI, null);
-        final Contact contact = new Contact(
-                uri, uri,
-                mLookupUri,
-                directoryId,
-                null /* lookupKey */,
-                -1 /* id */,
-                -1 /* nameRawContactId */,
-                displayNameSource,
-                0 /* photoId */,
-                photoUri,
-                displayName,
-                altDisplayName,
-                null /* phoneticName */,
-                false /* starred */,
-                null /* presence */,
-                false /* sendToVoicemail */,
-                null /* customRingtone */,
-                false /* isUserProfile */);
-
-        contact.setStatuses(new ImmutableMap.Builder<Long, DataStatus>().build());
-
-        final String accountName = json.optString(RawContacts.ACCOUNT_NAME, null);
-        final String directoryName = uri.getQueryParameter(Directory.DISPLAY_NAME);
-        if (accountName != null) {
-            final String accountType = json.getString(RawContacts.ACCOUNT_TYPE);
-            contact.setDirectoryMetaData(directoryName, null, accountName, accountType,
-                    json.optInt(Directory.EXPORT_SUPPORT,
-                            Directory.EXPORT_SUPPORT_SAME_ACCOUNT_ONLY));
-        } else {
-            contact.setDirectoryMetaData(directoryName, null, null, null,
-                    json.optInt(Directory.EXPORT_SUPPORT, Directory.EXPORT_SUPPORT_ANY_ACCOUNT));
-        }
-
-        final ContentValues values = new ContentValues();
-        values.put(Data._ID, -1);
-        values.put(Data.CONTACT_ID, -1);
-        final RawContact rawContact = new RawContact(values);
-
-        final JSONObject items = json.getJSONObject(Contacts.CONTENT_ITEM_TYPE);
-        final Iterator keys = items.keys();
-        while (keys.hasNext()) {
-            final String mimetype = (String) keys.next();
-
-            // Could be single object or array.
-            final JSONObject obj = items.optJSONObject(mimetype);
-            if (obj == null) {
-                final JSONArray array = items.getJSONArray(mimetype);
-                for (int i = 0; i < array.length(); i++) {
-                    final JSONObject item = array.getJSONObject(i);
-                    processOneRecord(rawContact, item, mimetype);
-                }
-            } else {
-                processOneRecord(rawContact, obj, mimetype);
-            }
-        }
-
-        contact.setRawContacts(new ImmutableList.Builder<RawContact>()
-                .add(rawContact)
-                .build());
-        return contact;
-    }
-
-    private void processOneRecord(RawContact rawContact, JSONObject item, String mimetype)
-            throws JSONException {
-        final ContentValues itemValues = new ContentValues();
-        itemValues.put(Data.MIMETYPE, mimetype);
-        itemValues.put(Data._ID, -1);
-
-        final Iterator iterator = item.keys();
-        while (iterator.hasNext()) {
-            String name = (String) iterator.next();
-            final Object o = item.get(name);
-            if (o instanceof String) {
-                itemValues.put(name, (String) o);
-            } else if (o instanceof Integer) {
-                itemValues.put(name, (Integer) o);
-            }
-        }
-        rawContact.addDataItemValues(itemValues);
-    }
-
-    private Contact loadContactEntity(ContentResolver resolver, Uri contactUri) {
-        Uri entityUri = Uri.withAppendedPath(contactUri, Contacts.Entity.CONTENT_DIRECTORY);
-        Cursor cursor = resolver.query(entityUri, ContactQuery.COLUMNS, null, null,
-                Contacts.Entity.RAW_CONTACT_ID);
-        if (cursor == null) {
-            Log.e(TAG, "No cursor returned in loadContactEntity");
-            return Contact.forNotFound(mRequestedUri);
-        }
-
-        try {
-            if (!cursor.moveToFirst()) {
-                cursor.close();
-                return Contact.forNotFound(mRequestedUri);
-            }
-
-            // Create the loaded contact starting with the header data.
-            Contact contact = loadContactHeaderData(cursor, contactUri);
-
-            // Fill in the raw contacts, which is wrapped in an Entity and any
-            // status data.  Initially, result has empty entities and statuses.
-            long currentRawContactId = -1;
-            RawContact rawContact = null;
-            ImmutableList.Builder<RawContact> rawContactsBuilder =
-                    new ImmutableList.Builder<RawContact>();
-            ImmutableMap.Builder<Long, DataStatus> statusesBuilder =
-                    new ImmutableMap.Builder<Long, DataStatus>();
-            do {
-                long rawContactId = cursor.getLong(ContactQuery.RAW_CONTACT_ID);
-                if (rawContactId != currentRawContactId) {
-                    // First time to see this raw contact id, so create a new entity, and
-                    // add it to the result's entities.
-                    currentRawContactId = rawContactId;
-                    rawContact = new RawContact(loadRawContactValues(cursor));
-                    rawContactsBuilder.add(rawContact);
-                }
-                if (!cursor.isNull(ContactQuery.DATA_ID)) {
-                    ContentValues data = loadDataValues(cursor);
-                    rawContact.addDataItemValues(data);
-
-                    if (!cursor.isNull(ContactQuery.PRESENCE)
-                            || !cursor.isNull(ContactQuery.STATUS)) {
-                        final DataStatus status = new DataStatus(cursor);
-                        final long dataId = cursor.getLong(ContactQuery.DATA_ID);
-                        statusesBuilder.put(dataId, status);
-                    }
-                }
-            } while (cursor.moveToNext());
-
-            contact.setRawContacts(rawContactsBuilder.build());
-            contact.setStatuses(statusesBuilder.build());
-
-            return contact;
-        } finally {
-            cursor.close();
-        }
-    }
-
-    /**
-     * Looks for the photo data item in entities. If found, creates a new Bitmap instance. If
-     * not found, returns null
-     */
-    private void loadPhotoBinaryData(Contact contactData) {
-        // If we have a photo URI, try loading that first.
-        String photoUri = contactData.getPhotoUri();
-        if (photoUri != null) {
-            try {
-                final InputStream inputStream;
-                final AssetFileDescriptor fd;
-                final Uri uri = Uri.parse(photoUri);
-                final String scheme = uri.getScheme();
-                if ("http".equals(scheme) || "https".equals(scheme)) {
-                    // Support HTTP urls that might come from extended directories
-                    inputStream = new URL(photoUri).openStream();
-                    fd = null;
-                } else {
-                    fd = getContext().getContentResolver().openAssetFileDescriptor(uri, "r");
-                    inputStream = fd.createInputStream();
-                }
-                byte[] buffer = new byte[16 * 1024];
-                ByteArrayOutputStream baos = new ByteArrayOutputStream();
-                try {
-                    int size;
-                    while ((size = inputStream.read(buffer)) != -1) {
-                        baos.write(buffer, 0, size);
-                    }
-                    contactData.setPhotoBinaryData(baos.toByteArray());
-                } finally {
-                    inputStream.close();
-                    if (fd != null) {
-                        fd.close();
-                    }
-                }
-                return;
-            } catch (IOException ioe) {
-                // Just fall back to the case below.
-            }
-        }
-
-        // If we couldn't load from a file, fall back to the data blob.
-        final long photoId = contactData.getPhotoId();
-        if (photoId <= 0) {
-            // No photo ID
-            return;
-        }
-
-        for (RawContact rawContact : contactData.getRawContacts()) {
-            for (DataItem dataItem : rawContact.getDataItems()) {
-                if (dataItem.getId() == photoId) {
-                    if (!(dataItem instanceof PhotoDataItem)) {
-                        break;
-                    }
-
-                    final PhotoDataItem photo = (PhotoDataItem) dataItem;
-                    contactData.setPhotoBinaryData(photo.getPhoto());
-                    break;
-                }
-            }
-        }
-    }
-
-    /**
-     * Sets the "invitable" account types to {@link Contact#mInvitableAccountTypes}.
-     */
-    private void loadInvitableAccountTypes(Contact contactData) {
-        final ImmutableList.Builder<AccountType> resultListBuilder =
-                new ImmutableList.Builder<AccountType>();
-        if (!contactData.isUserProfile()) {
-            Map<AccountTypeWithDataSet, AccountType> invitables =
-                    AccountTypeManager.getInstance(getContext()).getUsableInvitableAccountTypes();
-            if (!invitables.isEmpty()) {
-                final Map<AccountTypeWithDataSet, AccountType> resultMap =
-                        Maps.newHashMap(invitables);
-
-                // Remove the ones that already have a raw contact in the current contact
-                for (RawContact rawContact : contactData.getRawContacts()) {
-                    final AccountTypeWithDataSet type = AccountTypeWithDataSet.get(
-                            rawContact.getAccountTypeString(),
-                            rawContact.getDataSet());
-                    resultMap.remove(type);
-                }
-
-                resultListBuilder.addAll(resultMap.values());
-            }
-        }
-
-        // Set to mInvitableAccountTypes
-        contactData.setInvitableAccountTypes(resultListBuilder.build());
-    }
-
-    /**
-     * Extracts Contact level columns from the cursor.
-     */
-    private Contact loadContactHeaderData(final Cursor cursor, Uri contactUri) {
-        final String directoryParameter =
-                contactUri.getQueryParameter(ContactsContract.DIRECTORY_PARAM_KEY);
-        final long directoryId = directoryParameter == null
-                ? Directory.DEFAULT
-                : Long.parseLong(directoryParameter);
-        final long contactId = cursor.getLong(ContactQuery.CONTACT_ID);
-        final String lookupKey = cursor.getString(ContactQuery.LOOKUP_KEY);
-        final long nameRawContactId = cursor.getLong(ContactQuery.NAME_RAW_CONTACT_ID);
-        final int displayNameSource = cursor.getInt(ContactQuery.DISPLAY_NAME_SOURCE);
-        final String displayName = cursor.getString(ContactQuery.DISPLAY_NAME);
-        final String altDisplayName = cursor.getString(ContactQuery.ALT_DISPLAY_NAME);
-        final String phoneticName = cursor.getString(ContactQuery.PHONETIC_NAME);
-        final long photoId = cursor.getLong(ContactQuery.PHOTO_ID);
-        final String photoUri = cursor.getString(ContactQuery.PHOTO_URI);
-        final boolean starred = cursor.getInt(ContactQuery.STARRED) != 0;
-        final Integer presence = cursor.isNull(ContactQuery.CONTACT_PRESENCE)
-                ? null
-                : cursor.getInt(ContactQuery.CONTACT_PRESENCE);
-        final boolean sendToVoicemail = cursor.getInt(ContactQuery.SEND_TO_VOICEMAIL) == 1;
-        final String customRingtone = cursor.getString(ContactQuery.CUSTOM_RINGTONE);
-        final boolean isUserProfile = cursor.getInt(ContactQuery.IS_USER_PROFILE) == 1;
-
-        Uri lookupUri;
-        if (directoryId == Directory.DEFAULT || directoryId == Directory.LOCAL_INVISIBLE) {
-            lookupUri = ContentUris.withAppendedId(
-                Uri.withAppendedPath(Contacts.CONTENT_LOOKUP_URI, lookupKey), contactId);
-        } else {
-            lookupUri = contactUri;
-        }
-
-        return new Contact(mRequestedUri, contactUri, lookupUri, directoryId, lookupKey,
-                contactId, nameRawContactId, displayNameSource, photoId, photoUri, displayName,
-                altDisplayName, phoneticName, starred, presence, sendToVoicemail,
-                customRingtone, isUserProfile);
-    }
-
-    /**
-     * Extracts RawContact level columns from the cursor.
-     */
-    private ContentValues loadRawContactValues(Cursor cursor) {
-        ContentValues cv = new ContentValues();
-
-        cv.put(RawContacts._ID, cursor.getLong(ContactQuery.RAW_CONTACT_ID));
-
-        cursorColumnToContentValues(cursor, cv, ContactQuery.ACCOUNT_NAME);
-        cursorColumnToContentValues(cursor, cv, ContactQuery.ACCOUNT_TYPE);
-        cursorColumnToContentValues(cursor, cv, ContactQuery.DATA_SET);
-        cursorColumnToContentValues(cursor, cv, ContactQuery.ACCOUNT_TYPE_AND_DATA_SET);
-        cursorColumnToContentValues(cursor, cv, ContactQuery.DIRTY);
-        cursorColumnToContentValues(cursor, cv, ContactQuery.VERSION);
-        cursorColumnToContentValues(cursor, cv, ContactQuery.SOURCE_ID);
-        cursorColumnToContentValues(cursor, cv, ContactQuery.SYNC1);
-        cursorColumnToContentValues(cursor, cv, ContactQuery.SYNC2);
-        cursorColumnToContentValues(cursor, cv, ContactQuery.SYNC3);
-        cursorColumnToContentValues(cursor, cv, ContactQuery.SYNC4);
-        cursorColumnToContentValues(cursor, cv, ContactQuery.DELETED);
-        cursorColumnToContentValues(cursor, cv, ContactQuery.CONTACT_ID);
-        cursorColumnToContentValues(cursor, cv, ContactQuery.STARRED);
-        cursorColumnToContentValues(cursor, cv, ContactQuery.NAME_VERIFIED);
-
-        return cv;
-    }
-
-    /**
-     * Extracts Data level columns from the cursor.
-     */
-    private ContentValues loadDataValues(Cursor cursor) {
-        ContentValues cv = new ContentValues();
-
-        cv.put(Data._ID, cursor.getLong(ContactQuery.DATA_ID));
-
-        cursorColumnToContentValues(cursor, cv, ContactQuery.DATA1);
-        cursorColumnToContentValues(cursor, cv, ContactQuery.DATA2);
-        cursorColumnToContentValues(cursor, cv, ContactQuery.DATA3);
-        cursorColumnToContentValues(cursor, cv, ContactQuery.DATA4);
-        cursorColumnToContentValues(cursor, cv, ContactQuery.DATA5);
-        cursorColumnToContentValues(cursor, cv, ContactQuery.DATA6);
-        cursorColumnToContentValues(cursor, cv, ContactQuery.DATA7);
-        cursorColumnToContentValues(cursor, cv, ContactQuery.DATA8);
-        cursorColumnToContentValues(cursor, cv, ContactQuery.DATA9);
-        cursorColumnToContentValues(cursor, cv, ContactQuery.DATA10);
-        cursorColumnToContentValues(cursor, cv, ContactQuery.DATA11);
-        cursorColumnToContentValues(cursor, cv, ContactQuery.DATA12);
-        cursorColumnToContentValues(cursor, cv, ContactQuery.DATA13);
-        cursorColumnToContentValues(cursor, cv, ContactQuery.DATA14);
-        cursorColumnToContentValues(cursor, cv, ContactQuery.DATA15);
-        cursorColumnToContentValues(cursor, cv, ContactQuery.DATA_SYNC1);
-        cursorColumnToContentValues(cursor, cv, ContactQuery.DATA_SYNC2);
-        cursorColumnToContentValues(cursor, cv, ContactQuery.DATA_SYNC3);
-        cursorColumnToContentValues(cursor, cv, ContactQuery.DATA_SYNC4);
-        cursorColumnToContentValues(cursor, cv, ContactQuery.DATA_VERSION);
-        cursorColumnToContentValues(cursor, cv, ContactQuery.IS_PRIMARY);
-        cursorColumnToContentValues(cursor, cv, ContactQuery.IS_SUPERPRIMARY);
-        cursorColumnToContentValues(cursor, cv, ContactQuery.MIMETYPE);
-        cursorColumnToContentValues(cursor, cv, ContactQuery.RES_PACKAGE);
-        cursorColumnToContentValues(cursor, cv, ContactQuery.GROUP_SOURCE_ID);
-        cursorColumnToContentValues(cursor, cv, ContactQuery.CHAT_CAPABILITY);
-
-        return cv;
-    }
-
-    private void cursorColumnToContentValues(
-            Cursor cursor, ContentValues values, int index) {
-        switch (cursor.getType(index)) {
-            case Cursor.FIELD_TYPE_NULL:
-                // don't put anything in the content values
-                break;
-            case Cursor.FIELD_TYPE_INTEGER:
-                values.put(ContactQuery.COLUMNS[index], cursor.getLong(index));
-                break;
-            case Cursor.FIELD_TYPE_STRING:
-                values.put(ContactQuery.COLUMNS[index], cursor.getString(index));
-                break;
-            case Cursor.FIELD_TYPE_BLOB:
-                values.put(ContactQuery.COLUMNS[index], cursor.getBlob(index));
-                break;
-            default:
-                throw new IllegalStateException("Invalid or unhandled data type");
-        }
-    }
-
-    private void loadDirectoryMetaData(Contact result) {
-        long directoryId = result.getDirectoryId();
-
-        Cursor cursor = getContext().getContentResolver().query(
-                ContentUris.withAppendedId(Directory.CONTENT_URI, directoryId),
-                DirectoryQuery.COLUMNS, null, null, null);
-        if (cursor == null) {
-            return;
-        }
-        try {
-            if (cursor.moveToFirst()) {
-                final String displayName = cursor.getString(DirectoryQuery.DISPLAY_NAME);
-                final String packageName = cursor.getString(DirectoryQuery.PACKAGE_NAME);
-                final int typeResourceId = cursor.getInt(DirectoryQuery.TYPE_RESOURCE_ID);
-                final String accountType = cursor.getString(DirectoryQuery.ACCOUNT_TYPE);
-                final String accountName = cursor.getString(DirectoryQuery.ACCOUNT_NAME);
-                final int exportSupport = cursor.getInt(DirectoryQuery.EXPORT_SUPPORT);
-                String directoryType = null;
-                if (!TextUtils.isEmpty(packageName)) {
-                    PackageManager pm = getContext().getPackageManager();
-                    try {
-                        Resources resources = pm.getResourcesForApplication(packageName);
-                        directoryType = resources.getString(typeResourceId);
-                    } catch (NameNotFoundException e) {
-                        Log.w(TAG, "Contact directory resource not found: "
-                                + packageName + "." + typeResourceId);
-                    }
-                }
-
-                result.setDirectoryMetaData(
-                        displayName, directoryType, accountType, accountName, exportSupport);
-            }
-        } finally {
-            cursor.close();
-        }
-    }
-
-    /**
-     * Loads groups meta-data for all groups associated with all constituent raw contacts'
-     * accounts.
-     */
-    private void loadGroupMetaData(Contact result) {
-        StringBuilder selection = new StringBuilder();
-        ArrayList<String> selectionArgs = new ArrayList<String>();
-        for (RawContact rawContact : result.getRawContacts()) {
-            final String accountName = rawContact.getAccountName();
-            final String accountType = rawContact.getAccountTypeString();
-            final String dataSet = rawContact.getDataSet();
-            if (accountName != null && accountType != null) {
-                if (selection.length() != 0) {
-                    selection.append(" OR ");
-                }
-                selection.append(
-                        "(" + Groups.ACCOUNT_NAME + "=? AND " + Groups.ACCOUNT_TYPE + "=?");
-                selectionArgs.add(accountName);
-                selectionArgs.add(accountType);
-
-                if (dataSet != null) {
-                    selection.append(" AND " + Groups.DATA_SET + "=?");
-                    selectionArgs.add(dataSet);
-                } else {
-                    selection.append(" AND " + Groups.DATA_SET + " IS NULL");
-                }
-                selection.append(")");
-            }
-        }
-        final ImmutableList.Builder<GroupMetaData> groupListBuilder =
-                new ImmutableList.Builder<GroupMetaData>();
-        final Cursor cursor = getContext().getContentResolver().query(Groups.CONTENT_URI,
-                GroupQuery.COLUMNS, selection.toString(), selectionArgs.toArray(new String[0]),
-                null);
-        try {
-            while (cursor.moveToNext()) {
-                final String accountName = cursor.getString(GroupQuery.ACCOUNT_NAME);
-                final String accountType = cursor.getString(GroupQuery.ACCOUNT_TYPE);
-                final String dataSet = cursor.getString(GroupQuery.DATA_SET);
-                final long groupId = cursor.getLong(GroupQuery.ID);
-                final String title = cursor.getString(GroupQuery.TITLE);
-                final boolean defaultGroup = cursor.isNull(GroupQuery.AUTO_ADD)
-                        ? false
-                        : cursor.getInt(GroupQuery.AUTO_ADD) != 0;
-                final boolean favorites = cursor.isNull(GroupQuery.FAVORITES)
-                        ? false
-                        : cursor.getInt(GroupQuery.FAVORITES) != 0;
-
-                groupListBuilder.add(new GroupMetaData(
-                        accountName, accountType, dataSet, groupId, title, defaultGroup,
-                        favorites));
-            }
-        } finally {
-            cursor.close();
-        }
-        result.setGroupMetaData(groupListBuilder.build());
-    }
-
-    /**
-     * Iterates over all data items that represent phone numbers are tries to calculate a formatted
-     * number. This function can safely be called several times as no unformatted data is
-     * overwritten
-     */
-    private void computeFormattedPhoneNumbers(Contact contactData) {
-        final String countryIso = GeoUtil.getCurrentCountryIso(getContext());
-        final ImmutableList<RawContact> rawContacts = contactData.getRawContacts();
-        final int rawContactCount = rawContacts.size();
-        for (int rawContactIndex = 0; rawContactIndex < rawContactCount; rawContactIndex++) {
-            final RawContact rawContact = rawContacts.get(rawContactIndex);
-            final List<DataItem> dataItems = rawContact.getDataItems();
-            final int dataCount = dataItems.size();
-            for (int dataIndex = 0; dataIndex < dataCount; dataIndex++) {
-                final DataItem dataItem = dataItems.get(dataIndex);
-                if (dataItem instanceof PhoneDataItem) {
-                    final PhoneDataItem phoneDataItem = (PhoneDataItem) dataItem;
-                    phoneDataItem.computeFormattedPhoneNumber(countryIso);
-                }
-            }
-        }
-    }
-
-    @Override
-    public void deliverResult(Contact result) {
-        unregisterObserver();
-
-        // The creator isn't interested in any further updates
-        if (isReset() || result == null) {
-            return;
-        }
-
-        mContact = result;
-
-        if (result.isLoaded()) {
-            mLookupUri = result.getLookupUri();
-
-            if (!result.isDirectoryEntry()) {
-                Log.i(TAG, "Registering content observer for " + mLookupUri);
-                if (mObserver == null) {
-                    mObserver = new ForceLoadContentObserver();
-                }
-                getContext().getContentResolver().registerContentObserver(
-                        mLookupUri, true, mObserver);
-            }
-
-            if (mPostViewNotification) {
-                // inform the source of the data that this contact is being looked at
-                postViewNotificationToSyncAdapter();
-            }
-        }
-
-        super.deliverResult(mContact);
-    }
-
-    /**
-     * Posts a message to the contributing sync adapters that have opted-in, notifying them
-     * that the contact has just been loaded
-     */
-    private void postViewNotificationToSyncAdapter() {
-        Context context = getContext();
-        for (RawContact rawContact : mContact.getRawContacts()) {
-            final long rawContactId = rawContact.getId();
-            if (mNotifiedRawContactIds.contains(rawContactId)) {
-                continue; // Already notified for this raw contact.
-            }
-            mNotifiedRawContactIds.add(rawContactId);
-            final AccountType accountType = rawContact.getAccountType(context);
-            final String serviceName = accountType.getViewContactNotifyServiceClassName();
-            final String servicePackageName = accountType.getViewContactNotifyServicePackageName();
-            if (!TextUtils.isEmpty(serviceName) && !TextUtils.isEmpty(servicePackageName)) {
-                final Uri uri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId);
-                final Intent intent = new Intent();
-                intent.setClassName(servicePackageName, serviceName);
-                intent.setAction(Intent.ACTION_VIEW);
-                intent.setDataAndType(uri, RawContacts.CONTENT_ITEM_TYPE);
-                try {
-                    context.startService(intent);
-                } catch (Exception e) {
-                    Log.e(TAG, "Error sending message to source-app", e);
-                }
-            }
-        }
-    }
-
-    private void unregisterObserver() {
-        if (mObserver != null) {
-            getContext().getContentResolver().unregisterContentObserver(mObserver);
-            mObserver = null;
-        }
-    }
-
-    /**
-     * Fully upgrades this ContactLoader to one with all lists fully loaded. When done, the
-     * new result will be delivered
-     */
-    public void upgradeToFullContact() {
-        // Everything requested already? Nothing to do, so let's bail out
-        if (mLoadGroupMetaData && mLoadInvitableAccountTypes
-                && mPostViewNotification && mComputeFormattedPhoneNumber) return;
-
-        mLoadGroupMetaData = true;
-        mLoadInvitableAccountTypes = true;
-        mPostViewNotification = true;
-        mComputeFormattedPhoneNumber = true;
-
-        // Cache the current result, so that we only load the "missing" parts of the contact.
-        cacheResult();
-
-        // Our load parameters have changed, so let's pretend the data has changed. Its the same
-        // thing, essentially.
-        onContentChanged();
-    }
-
-    public Uri getLookupUri() {
-        return mLookupUri;
-    }
-
-    @Override
-    protected void onStartLoading() {
-        if (mContact != null) {
-            deliverResult(mContact);
-        }
-
-        if (takeContentChanged() || mContact == null) {
-            forceLoad();
-        }
-    }
-
-    @Override
-    protected void onStopLoading() {
-        cancelLoad();
-    }
-
-    @Override
-    protected void onReset() {
-        super.onReset();
-        cancelLoad();
-        unregisterObserver();
-        mContact = null;
-    }
-
-    /**
-     * Caches the result, which is useful when we switch from activity to activity, using the same
-     * contact. If the next load is for a different contact, the cached result will be dropped
-     */
-    public void cacheResult() {
-        if (mContact == null || !mContact.isLoaded()) {
-            sCachedResult = null;
-        } else {
-            sCachedResult = mContact;
-        }
-    }
-}
diff --git a/src/com/android/contacts/model/RawContact.java b/src/com/android/contacts/model/RawContact.java
deleted file mode 100644
index 096e377..0000000
--- a/src/com/android/contacts/model/RawContact.java
+++ /dev/null
@@ -1,374 +0,0 @@
-/*
- * Copyright (C) 2012 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.contacts.model;
-
-import android.content.ContentValues;
-import android.content.Context;
-import android.content.Entity;
-import android.net.Uri;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.provider.ContactsContract.Contacts;
-import android.provider.ContactsContract.Data;
-import android.provider.ContactsContract.RawContacts;
-
-import com.android.contacts.common.model.AccountTypeManager;
-import com.android.contacts.common.model.account.AccountType;
-import com.android.contacts.common.model.account.AccountWithDataSet;
-import com.android.contacts.model.dataitem.DataItem;
-import com.google.common.base.Objects;
-import com.google.common.collect.Lists;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * RawContact represents a single raw contact in the raw contacts database.
- * It has specialized getters/setters for raw contact
- * items, and also contains a collection of DataItem objects.  A RawContact contains the information
- * from a single account.
- *
- * This allows RawContact objects to be thought of as a class with raw contact
- * fields (like account type, name, data set, sync state, etc.) and a list of
- * DataItem objects that represent contact information elements (like phone
- * numbers, email, address, etc.).
- */
-final public class RawContact implements Parcelable {
-
-    private AccountTypeManager mAccountTypeManager;
-    private final ContentValues mValues;
-    private final ArrayList<NamedDataItem> mDataItems;
-
-    final public static class NamedDataItem implements Parcelable {
-        public final Uri mUri;
-
-        // This use to be a DataItem. DataItem creation is now delayed until the point of request
-        // since there is no benefit to storing them here due to the multiple inheritance.
-        // Eventually instanceof still has to be used anyways to determine which sub-class of
-        // DataItem it is. And having parent DataItem's here makes it very difficult to serialize or
-        // parcelable.
-        //
-        // Instead of having a common DataItem super class, we should refactor this to be a generic
-        // Object where the object is a concrete class that no longer relies on ContentValues.
-        // (this will also make the classes easier to use).
-        // Since instanceof is used later anyways, having a list of Objects won't hurt and is no
-        // worse than having a DataItem.
-        public final ContentValues mContentValues;
-
-        public NamedDataItem(Uri uri, ContentValues values) {
-            this.mUri = uri;
-            this.mContentValues = values;
-        }
-
-        public NamedDataItem(Parcel parcel) {
-            this.mUri = parcel.readParcelable(Uri.class.getClassLoader());
-            this.mContentValues = parcel.readParcelable(ContentValues.class.getClassLoader());
-        }
-
-        @Override
-        public int describeContents() {
-            return 0;
-        }
-
-        @Override
-        public void writeToParcel(Parcel parcel, int i) {
-            parcel.writeParcelable(mUri, i);
-            parcel.writeParcelable(mContentValues, i);
-        }
-
-        public static final Parcelable.Creator<NamedDataItem> CREATOR
-                = new Parcelable.Creator<NamedDataItem>() {
-
-            @Override
-            public NamedDataItem createFromParcel(Parcel parcel) {
-                return new NamedDataItem(parcel);
-            }
-
-            @Override
-            public NamedDataItem[] newArray(int i) {
-                return new NamedDataItem[i];
-            }
-        };
-
-        @Override
-        public int hashCode() {
-            return Objects.hashCode(mUri, mContentValues);
-        }
-
-        @Override
-        public boolean equals(Object obj) {
-            if (obj == null) return false;
-            if (getClass() != obj.getClass()) return false;
-
-            final NamedDataItem other = (NamedDataItem) obj;
-            return Objects.equal(mUri, other.mUri) &&
-                    Objects.equal(mContentValues, other.mContentValues);
-        }
-    }
-
-    public static RawContact createFrom(Entity entity) {
-        final ContentValues values = entity.getEntityValues();
-        final ArrayList<Entity.NamedContentValues> subValues = entity.getSubValues();
-
-        RawContact rawContact = new RawContact(values);
-        for (Entity.NamedContentValues subValue : subValues) {
-            rawContact.addNamedDataItemValues(subValue.uri, subValue.values);
-        }
-        return rawContact;
-    }
-
-    /**
-     * A RawContact object can be created with or without a context.
-     */
-    public RawContact() {
-        this(new ContentValues());
-    }
-
-    public RawContact(ContentValues values) {
-        mValues = values;
-        mDataItems = new ArrayList<NamedDataItem>();
-    }
-
-    /**
-     * Constructor for the parcelable.
-     *
-     * @param parcel The parcel to de-serialize from.
-     */
-    private RawContact(Parcel parcel) {
-        mValues = parcel.readParcelable(ContentValues.class.getClassLoader());
-        mDataItems = Lists.newArrayList();
-        parcel.readTypedList(mDataItems, NamedDataItem.CREATOR);
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(Parcel parcel, int i) {
-        parcel.writeParcelable(mValues, i);
-        parcel.writeTypedList(mDataItems);
-    }
-
-    /**
-     * Create for building the parcelable.
-     */
-    public static final Parcelable.Creator<RawContact> CREATOR
-            = new Parcelable.Creator<RawContact>() {
-
-        @Override
-        public RawContact createFromParcel(Parcel parcel) {
-            return new RawContact(parcel);
-        }
-
-        @Override
-        public RawContact[] newArray(int i) {
-            return new RawContact[i];
-        }
-    };
-
-    public AccountTypeManager getAccountTypeManager(Context context) {
-        if (mAccountTypeManager == null) {
-            mAccountTypeManager = AccountTypeManager.getInstance(context);
-        }
-        return mAccountTypeManager;
-    }
-
-    public ContentValues getValues() {
-        return mValues;
-    }
-
-    /**
-     * Returns the id of the raw contact.
-     */
-    public Long getId() {
-        return getValues().getAsLong(RawContacts._ID);
-    }
-
-    /**
-     * Returns the account name of the raw contact.
-     */
-    public String getAccountName() {
-        return getValues().getAsString(RawContacts.ACCOUNT_NAME);
-    }
-
-    /**
-     * Returns the account type of the raw contact.
-     */
-    public String getAccountTypeString() {
-        return getValues().getAsString(RawContacts.ACCOUNT_TYPE);
-    }
-
-    /**
-     * Returns the data set of the raw contact.
-     */
-    public String getDataSet() {
-        return getValues().getAsString(RawContacts.DATA_SET);
-    }
-
-    /**
-     * Returns the account type and data set of the raw contact.
-     */
-    public String getAccountTypeAndDataSetString() {
-        return getValues().getAsString(RawContacts.ACCOUNT_TYPE_AND_DATA_SET);
-    }
-
-    public boolean isDirty() {
-        return getValues().getAsBoolean(RawContacts.DIRTY);
-    }
-
-    public String getSourceId() {
-        return getValues().getAsString(RawContacts.SOURCE_ID);
-    }
-
-    public String getSync1() {
-        return getValues().getAsString(RawContacts.SYNC1);
-    }
-
-    public String getSync2() {
-        return getValues().getAsString(RawContacts.SYNC2);
-    }
-
-    public String getSync3() {
-        return getValues().getAsString(RawContacts.SYNC3);
-    }
-
-    public String getSync4() {
-        return getValues().getAsString(RawContacts.SYNC4);
-    }
-
-    public boolean isDeleted() {
-        return getValues().getAsBoolean(RawContacts.DELETED);
-    }
-
-    public boolean isNameVerified() {
-        return getValues().getAsBoolean(RawContacts.NAME_VERIFIED);
-    }
-
-    public long getContactId() {
-        return getValues().getAsLong(Contacts.Entity.CONTACT_ID);
-    }
-
-    public boolean isStarred() {
-        return getValues().getAsBoolean(Contacts.STARRED);
-    }
-
-    public AccountType getAccountType(Context context) {
-        return getAccountTypeManager(context).getAccountType(getAccountTypeString(), getDataSet());
-    }
-
-    /**
-     * Sets the account name, account type, and data set strings.
-     * Valid combinations for account-name, account-type, data-set
-     * 1) null, null, null (local account)
-     * 2) non-null, non-null, null (valid account without data-set)
-     * 3) non-null, non-null, non-null (valid account with data-set)
-     */
-    private void setAccount(String accountName, String accountType, String dataSet) {
-        final ContentValues values = getValues();
-        if (accountName == null) {
-            if (accountType == null && dataSet == null) {
-                // This is a local account
-                values.putNull(RawContacts.ACCOUNT_NAME);
-                values.putNull(RawContacts.ACCOUNT_TYPE);
-                values.putNull(RawContacts.DATA_SET);
-                return;
-            }
-        } else {
-            if (accountType != null) {
-                // This is a valid account, either with or without a dataSet.
-                values.put(RawContacts.ACCOUNT_NAME, accountName);
-                values.put(RawContacts.ACCOUNT_TYPE, accountType);
-                if (dataSet == null) {
-                    values.putNull(RawContacts.DATA_SET);
-                } else {
-                    values.put(RawContacts.DATA_SET, dataSet);
-                }
-                return;
-            }
-        }
-        throw new IllegalArgumentException(
-                "Not a valid combination of account name, type, and data set.");
-    }
-
-    public void setAccount(AccountWithDataSet accountWithDataSet) {
-        setAccount(accountWithDataSet.name, accountWithDataSet.type, accountWithDataSet.dataSet);
-    }
-
-    public void setAccountToLocal() {
-        setAccount(null, null, null);
-    }
-
-    /**
-     * Creates and inserts a DataItem object that wraps the content values, and returns it.
-     */
-    public void addDataItemValues(ContentValues values) {
-        addNamedDataItemValues(Data.CONTENT_URI, values);
-    }
-
-    public NamedDataItem addNamedDataItemValues(Uri uri, ContentValues values) {
-        final NamedDataItem namedItem = new NamedDataItem(uri, values);
-        mDataItems.add(namedItem);
-        return namedItem;
-    }
-
-    public ArrayList<ContentValues> getContentValues() {
-        final ArrayList<ContentValues> list = Lists.newArrayListWithCapacity(mDataItems.size());
-        for (NamedDataItem dataItem : mDataItems) {
-            if (Data.CONTENT_URI.equals(dataItem.mUri)) {
-                list.add(dataItem.mContentValues);
-            }
-        }
-        return list;
-    }
-
-    public List<DataItem> getDataItems() {
-        final ArrayList<DataItem> list = Lists.newArrayListWithCapacity(mDataItems.size());
-        for (NamedDataItem dataItem : mDataItems) {
-            if (Data.CONTENT_URI.equals(dataItem.mUri)) {
-                list.add(DataItem.createFrom(dataItem.mContentValues));
-            }
-        }
-        return list;
-    }
-
-    public String toString() {
-        final StringBuilder sb = new StringBuilder();
-        sb.append("RawContact: ").append(mValues);
-        for (RawContact.NamedDataItem namedDataItem : mDataItems) {
-            sb.append("\n  ").append(namedDataItem.mUri);
-            sb.append("\n  -> ").append(namedDataItem.mContentValues);
-        }
-        return sb.toString();
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hashCode(mValues, mDataItems);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (obj == null) return false;
-        if (getClass() != obj.getClass()) return false;
-
-        RawContact other = (RawContact) obj;
-        return Objects.equal(mValues, other.mValues) &&
-                Objects.equal(mDataItems, other.mDataItems);
-    }
-}
diff --git a/src/com/android/contacts/model/RawContactDelta.java b/src/com/android/contacts/model/RawContactDelta.java
deleted file mode 100644
index 373eabd..0000000
--- a/src/com/android/contacts/model/RawContactDelta.java
+++ /dev/null
@@ -1,556 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.contacts.model;
-
-import android.content.ContentProviderOperation;
-import android.content.ContentProviderOperation.Builder;
-import android.content.ContentValues;
-import android.content.Context;
-import android.net.Uri;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.provider.BaseColumns;
-import android.provider.ContactsContract.Data;
-import android.provider.ContactsContract.Profile;
-import android.provider.ContactsContract.RawContacts;
-import android.util.Log;
-
-import com.android.contacts.common.model.AccountTypeManager;
-import com.android.contacts.common.model.ValuesDelta;
-import com.android.contacts.common.model.account.AccountType;
-import com.android.contacts.common.test.NeededForTesting;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-
-/**
- * Contains a {@link RawContact} and records any modifications separately so the
- * original {@link RawContact} can be swapped out with a newer version and the
- * changes still cleanly applied.
- * <p>
- * One benefit of this approach is that we can build changes entirely on an
- * empty {@link RawContact}, which then becomes an insert {@link RawContacts} case.
- * <p>
- * When applying modifications over an {@link RawContact}, we try finding the
- * original {@link Data#_ID} rows where the modifications took place. If those
- * rows are missing from the new {@link RawContact}, we know the original data must
- * be deleted, but to preserve the user modifications we treat as an insert.
- */
-public class RawContactDelta implements Parcelable {
-    // TODO: optimize by using contentvalues pool, since we allocate so many of them
-
-    private static final String TAG = "EntityDelta";
-    private static final boolean LOGV = false;
-
-    /**
-     * Direct values from {@link Entity#getEntityValues()}.
-     */
-    private ValuesDelta mValues;
-
-    /**
-     * URI used for contacts queries, by default it is set to query raw contacts.
-     * It can be set to query the profile's raw contact(s).
-     */
-    private Uri mContactsQueryUri = RawContacts.CONTENT_URI;
-
-    /**
-     * Internal map of children values from {@link Entity#getSubValues()}, which
-     * we store here sorted into {@link Data#MIMETYPE} bins.
-     */
-    private final HashMap<String, ArrayList<ValuesDelta>> mEntries = Maps.newHashMap();
-
-    public RawContactDelta() {
-    }
-
-    public RawContactDelta(ValuesDelta values) {
-        mValues = values;
-    }
-
-    /**
-     * Build an {@link RawContactDelta} using the given {@link RawContact} as a
-     * starting point; the "before" snapshot.
-     */
-    public static RawContactDelta fromBefore(RawContact before) {
-        final RawContactDelta rawContactDelta = new RawContactDelta();
-        rawContactDelta.mValues = ValuesDelta.fromBefore(before.getValues());
-        rawContactDelta.mValues.setIdColumn(RawContacts._ID);
-        for (final ContentValues values : before.getContentValues()) {
-            rawContactDelta.addEntry(ValuesDelta.fromBefore(values));
-        }
-        return rawContactDelta;
-    }
-
-    /**
-     * Merge the "after" values from the given {@link RawContactDelta} onto the
-     * "before" state represented by this {@link RawContactDelta}, discarding any
-     * existing "after" states. This is typically used when re-parenting changes
-     * onto an updated {@link Entity}.
-     */
-    public static RawContactDelta mergeAfter(RawContactDelta local, RawContactDelta remote) {
-        // Bail early if trying to merge delete with missing local
-        final ValuesDelta remoteValues = remote.mValues;
-        if (local == null && (remoteValues.isDelete() || remoteValues.isTransient())) return null;
-
-        // Create local version if none exists yet
-        if (local == null) local = new RawContactDelta();
-
-        if (LOGV) {
-            final Long localVersion = (local.mValues == null) ? null : local.mValues
-                    .getAsLong(RawContacts.VERSION);
-            final Long remoteVersion = remote.mValues.getAsLong(RawContacts.VERSION);
-            Log.d(TAG, "Re-parenting from original version " + remoteVersion + " to "
-                    + localVersion);
-        }
-
-        // Create values if needed, and merge "after" changes
-        local.mValues = ValuesDelta.mergeAfter(local.mValues, remote.mValues);
-
-        // Find matching local entry for each remote values, or create
-        for (ArrayList<ValuesDelta> mimeEntries : remote.mEntries.values()) {
-            for (ValuesDelta remoteEntry : mimeEntries) {
-                final Long childId = remoteEntry.getId();
-
-                // Find or create local match and merge
-                final ValuesDelta localEntry = local.getEntry(childId);
-                final ValuesDelta merged = ValuesDelta.mergeAfter(localEntry, remoteEntry);
-
-                if (localEntry == null && merged != null) {
-                    // No local entry before, so insert
-                    local.addEntry(merged);
-                }
-            }
-        }
-
-        return local;
-    }
-
-    public ValuesDelta getValues() {
-        return mValues;
-    }
-
-    public boolean isContactInsert() {
-        return mValues.isInsert();
-    }
-
-    /**
-     * Get the {@link ValuesDelta} child marked as {@link Data#IS_PRIMARY},
-     * which may return null when no entry exists.
-     */
-    public ValuesDelta getPrimaryEntry(String mimeType) {
-        final ArrayList<ValuesDelta> mimeEntries = getMimeEntries(mimeType, false);
-        if (mimeEntries == null) return null;
-
-        for (ValuesDelta entry : mimeEntries) {
-            if (entry.isPrimary()) {
-                return entry;
-            }
-        }
-
-        // When no direct primary, return something
-        return mimeEntries.size() > 0 ? mimeEntries.get(0) : null;
-    }
-
-    /**
-     * calls {@link #getSuperPrimaryEntry(String, boolean)} with true
-     * @see #getSuperPrimaryEntry(String, boolean)
-     */
-    public ValuesDelta getSuperPrimaryEntry(String mimeType) {
-        return getSuperPrimaryEntry(mimeType, true);
-    }
-
-    /**
-     * Returns the super-primary entry for the given mime type
-     * @param forceSelection if true, will try to return some value even if a super-primary
-     *     doesn't exist (may be a primary, or just a random item
-     * @return
-     */
-    @NeededForTesting
-    public ValuesDelta getSuperPrimaryEntry(String mimeType, boolean forceSelection) {
-        final ArrayList<ValuesDelta> mimeEntries = getMimeEntries(mimeType, false);
-        if (mimeEntries == null) return null;
-
-        ValuesDelta primary = null;
-        for (ValuesDelta entry : mimeEntries) {
-            if (entry.isSuperPrimary()) {
-                return entry;
-            } else if (entry.isPrimary()) {
-                primary = entry;
-            }
-        }
-
-        if (!forceSelection) {
-            return null;
-        }
-
-        // When no direct super primary, return something
-        if (primary != null) {
-            return primary;
-        }
-        return mimeEntries.size() > 0 ? mimeEntries.get(0) : null;
-    }
-
-    /**
-     * Return the AccountType that this raw-contact belongs to.
-     */
-    public AccountType getRawContactAccountType(Context context) {
-        ContentValues entityValues = getValues().getCompleteValues();
-        String type = entityValues.getAsString(RawContacts.ACCOUNT_TYPE);
-        String dataSet = entityValues.getAsString(RawContacts.DATA_SET);
-        return AccountTypeManager.getInstance(context).getAccountType(type, dataSet);
-    }
-
-    public Long getRawContactId() {
-        return getValues().getAsLong(RawContacts._ID);
-    }
-
-    public String getAccountName() {
-        return getValues().getAsString(RawContacts.ACCOUNT_NAME);
-    }
-
-    public String getAccountType() {
-        return getValues().getAsString(RawContacts.ACCOUNT_TYPE);
-    }
-
-    public String getDataSet() {
-        return getValues().getAsString(RawContacts.DATA_SET);
-    }
-
-    public AccountType getAccountType(AccountTypeManager manager) {
-        return manager.getAccountType(getAccountType(), getDataSet());
-    }
-
-    public boolean isVisible() {
-        return getValues().isVisible();
-    }
-
-    /**
-     * Return the list of child {@link ValuesDelta} from our optimized map,
-     * creating the list if requested.
-     */
-    private ArrayList<ValuesDelta> getMimeEntries(String mimeType, boolean lazyCreate) {
-        ArrayList<ValuesDelta> mimeEntries = mEntries.get(mimeType);
-        if (mimeEntries == null && lazyCreate) {
-            mimeEntries = Lists.newArrayList();
-            mEntries.put(mimeType, mimeEntries);
-        }
-        return mimeEntries;
-    }
-
-    public ArrayList<ValuesDelta> getMimeEntries(String mimeType) {
-        return getMimeEntries(mimeType, false);
-    }
-
-    public int getMimeEntriesCount(String mimeType, boolean onlyVisible) {
-        final ArrayList<ValuesDelta> mimeEntries = getMimeEntries(mimeType);
-        if (mimeEntries == null) return 0;
-
-        int count = 0;
-        for (ValuesDelta child : mimeEntries) {
-            // Skip deleted items when requesting only visible
-            if (onlyVisible && !child.isVisible()) continue;
-            count++;
-        }
-        return count;
-    }
-
-    public boolean hasMimeEntries(String mimeType) {
-        return mEntries.containsKey(mimeType);
-    }
-
-    public ValuesDelta addEntry(ValuesDelta entry) {
-        final String mimeType = entry.getMimetype();
-        getMimeEntries(mimeType, true).add(entry);
-        return entry;
-    }
-
-    public ArrayList<ContentValues> getContentValues() {
-        ArrayList<ContentValues> values = Lists.newArrayList();
-        for (ArrayList<ValuesDelta> mimeEntries : mEntries.values()) {
-            for (ValuesDelta entry : mimeEntries) {
-                if (!entry.isDelete()) {
-                    values.add(entry.getCompleteValues());
-                }
-            }
-        }
-        return values;
-    }
-
-    /**
-     * Find entry with the given {@link BaseColumns#_ID} value.
-     */
-    public ValuesDelta getEntry(Long childId) {
-        if (childId == null) {
-            // Requesting an "insert" entry, which has no "before"
-            return null;
-        }
-
-        // Search all children for requested entry
-        for (ArrayList<ValuesDelta> mimeEntries : mEntries.values()) {
-            for (ValuesDelta entry : mimeEntries) {
-                if (childId.equals(entry.getId())) {
-                    return entry;
-                }
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Return the total number of {@link ValuesDelta} contained.
-     */
-    public int getEntryCount(boolean onlyVisible) {
-        int count = 0;
-        for (String mimeType : mEntries.keySet()) {
-            count += getMimeEntriesCount(mimeType, onlyVisible);
-        }
-        return count;
-    }
-
-    @Override
-    public boolean equals(Object object) {
-        if (object instanceof RawContactDelta) {
-            final RawContactDelta other = (RawContactDelta)object;
-
-            // Equality failed if parent values different
-            if (!other.mValues.equals(mValues)) return false;
-
-            for (ArrayList<ValuesDelta> mimeEntries : mEntries.values()) {
-                for (ValuesDelta child : mimeEntries) {
-                    // Equality failed if any children unmatched
-                    if (!other.containsEntry(child)) return false;
-                }
-            }
-
-            // Passed all tests, so equal
-            return true;
-        }
-        return false;
-    }
-
-    private boolean containsEntry(ValuesDelta entry) {
-        for (ArrayList<ValuesDelta> mimeEntries : mEntries.values()) {
-            for (ValuesDelta child : mimeEntries) {
-                // Contained if we find any child that matches
-                if (child.equals(entry)) return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Mark this entire object deleted, including any {@link ValuesDelta}.
-     */
-    public void markDeleted() {
-        this.mValues.markDeleted();
-        for (ArrayList<ValuesDelta> mimeEntries : mEntries.values()) {
-            for (ValuesDelta child : mimeEntries) {
-                child.markDeleted();
-            }
-        }
-    }
-
-    @Override
-    public String toString() {
-        final StringBuilder builder = new StringBuilder();
-        builder.append("\n(");
-        builder.append("Uri=");
-        builder.append(mContactsQueryUri);
-        builder.append(", Values=");
-        builder.append(mValues != null ? mValues.toString() : "null");
-        builder.append(", Entries={");
-        for (ArrayList<ValuesDelta> mimeEntries : mEntries.values()) {
-            for (ValuesDelta child : mimeEntries) {
-                builder.append("\n\t");
-                child.toString(builder);
-            }
-        }
-        builder.append("\n})\n");
-        return builder.toString();
-    }
-
-    /**
-     * Consider building the given {@link ContentProviderOperation.Builder} and
-     * appending it to the given list, which only happens if builder is valid.
-     */
-    private void possibleAdd(ArrayList<ContentProviderOperation> diff,
-            ContentProviderOperation.Builder builder) {
-        if (builder != null) {
-            diff.add(builder.build());
-        }
-    }
-
-    /**
-     * Build a list of {@link ContentProviderOperation} that will assert any
-     * "before" state hasn't changed. This is maintained separately so that all
-     * asserts can take place before any updates occur.
-     */
-    public void buildAssert(ArrayList<ContentProviderOperation> buildInto) {
-        final boolean isContactInsert = mValues.isInsert();
-        if (!isContactInsert) {
-            // Assert version is consistent while persisting changes
-            final Long beforeId = mValues.getId();
-            final Long beforeVersion = mValues.getAsLong(RawContacts.VERSION);
-            if (beforeId == null || beforeVersion == null) return;
-
-            final ContentProviderOperation.Builder builder = ContentProviderOperation
-                    .newAssertQuery(mContactsQueryUri);
-            builder.withSelection(RawContacts._ID + "=" + beforeId, null);
-            builder.withValue(RawContacts.VERSION, beforeVersion);
-            buildInto.add(builder.build());
-        }
-    }
-
-    /**
-     * Build a list of {@link ContentProviderOperation} that will transform the
-     * current "before" {@link Entity} state into the modified state which this
-     * {@link RawContactDelta} represents.
-     */
-    public void buildDiff(ArrayList<ContentProviderOperation> buildInto) {
-        final int firstIndex = buildInto.size();
-
-        final boolean isContactInsert = mValues.isInsert();
-        final boolean isContactDelete = mValues.isDelete();
-        final boolean isContactUpdate = !isContactInsert && !isContactDelete;
-
-        final Long beforeId = mValues.getId();
-
-        Builder builder;
-
-        if (isContactInsert) {
-            // TODO: for now simply disabling aggregation when a new contact is
-            // created on the phone.  In the future, will show aggregation suggestions
-            // after saving the contact.
-            mValues.put(RawContacts.AGGREGATION_MODE, RawContacts.AGGREGATION_MODE_SUSPENDED);
-        }
-
-        // Build possible operation at Contact level
-        builder = mValues.buildDiff(mContactsQueryUri);
-        possibleAdd(buildInto, builder);
-
-        // Build operations for all children
-        for (ArrayList<ValuesDelta> mimeEntries : mEntries.values()) {
-            for (ValuesDelta child : mimeEntries) {
-                // Ignore children if parent was deleted
-                if (isContactDelete) continue;
-
-                // Use the profile data URI if the contact is the profile.
-                if (mContactsQueryUri.equals(Profile.CONTENT_RAW_CONTACTS_URI)) {
-                    builder = child.buildDiff(Uri.withAppendedPath(Profile.CONTENT_URI,
-                            RawContacts.Data.CONTENT_DIRECTORY));
-                } else {
-                    builder = child.buildDiff(Data.CONTENT_URI);
-                }
-
-                if (child.isInsert()) {
-                    if (isContactInsert) {
-                        // Parent is brand new insert, so back-reference _id
-                        builder.withValueBackReference(Data.RAW_CONTACT_ID, firstIndex);
-                    } else {
-                        // Inserting under existing, so fill with known _id
-                        builder.withValue(Data.RAW_CONTACT_ID, beforeId);
-                    }
-                } else if (isContactInsert && builder != null) {
-                    // Child must be insert when Contact insert
-                    throw new IllegalArgumentException("When parent insert, child must be also");
-                }
-                possibleAdd(buildInto, builder);
-            }
-        }
-
-        final boolean addedOperations = buildInto.size() > firstIndex;
-        if (addedOperations && isContactUpdate) {
-            // Suspend aggregation while persisting updates
-            builder = buildSetAggregationMode(beforeId, RawContacts.AGGREGATION_MODE_SUSPENDED);
-            buildInto.add(firstIndex, builder.build());
-
-            // Restore aggregation mode as last operation
-            builder = buildSetAggregationMode(beforeId, RawContacts.AGGREGATION_MODE_DEFAULT);
-            buildInto.add(builder.build());
-        } else if (isContactInsert) {
-            // Restore aggregation mode as last operation
-            builder = ContentProviderOperation.newUpdate(mContactsQueryUri);
-            builder.withValue(RawContacts.AGGREGATION_MODE, RawContacts.AGGREGATION_MODE_DEFAULT);
-            builder.withSelection(RawContacts._ID + "=?", new String[1]);
-            builder.withSelectionBackReference(0, firstIndex);
-            buildInto.add(builder.build());
-        }
-    }
-
-    /**
-     * Build a {@link ContentProviderOperation} that changes
-     * {@link RawContacts#AGGREGATION_MODE} to the given value.
-     */
-    protected Builder buildSetAggregationMode(Long beforeId, int mode) {
-        Builder builder = ContentProviderOperation.newUpdate(mContactsQueryUri);
-        builder.withValue(RawContacts.AGGREGATION_MODE, mode);
-        builder.withSelection(RawContacts._ID + "=" + beforeId, null);
-        return builder;
-    }
-
-    /** {@inheritDoc} */
-    public int describeContents() {
-        // Nothing special about this parcel
-        return 0;
-    }
-
-    /** {@inheritDoc} */
-    public void writeToParcel(Parcel dest, int flags) {
-        final int size = this.getEntryCount(false);
-        dest.writeInt(size);
-        dest.writeParcelable(mValues, flags);
-        dest.writeParcelable(mContactsQueryUri, flags);
-        for (ArrayList<ValuesDelta> mimeEntries : mEntries.values()) {
-            for (ValuesDelta child : mimeEntries) {
-                dest.writeParcelable(child, flags);
-            }
-        }
-    }
-
-    public void readFromParcel(Parcel source) {
-        final ClassLoader loader = getClass().getClassLoader();
-        final int size = source.readInt();
-        mValues = source.<ValuesDelta> readParcelable(loader);
-        mContactsQueryUri = source.<Uri> readParcelable(loader);
-        for (int i = 0; i < size; i++) {
-            final ValuesDelta child = source.<ValuesDelta> readParcelable(loader);
-            this.addEntry(child);
-        }
-    }
-
-    /**
-     * Used to set the query URI to the profile URI to store profiles.
-     */
-    public void setProfileQueryUri() {
-        mContactsQueryUri = Profile.CONTENT_RAW_CONTACTS_URI;
-    }
-
-    public static final Parcelable.Creator<RawContactDelta> CREATOR =
-            new Parcelable.Creator<RawContactDelta>() {
-        public RawContactDelta createFromParcel(Parcel in) {
-            final RawContactDelta state = new RawContactDelta();
-            state.readFromParcel(in);
-            return state;
-        }
-
-        public RawContactDelta[] newArray(int size) {
-            return new RawContactDelta[size];
-        }
-    };
-
-}
diff --git a/src/com/android/contacts/model/RawContactDeltaList.java b/src/com/android/contacts/model/RawContactDeltaList.java
deleted file mode 100644
index 1a9eb71..0000000
--- a/src/com/android/contacts/model/RawContactDeltaList.java
+++ /dev/null
@@ -1,453 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.contacts.model;
-
-import android.content.ContentProviderOperation;
-import android.content.ContentProviderOperation.Builder;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.Entity;
-import android.content.EntityIterator;
-import android.net.Uri;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.provider.ContactsContract.AggregationExceptions;
-import android.provider.ContactsContract.Contacts;
-import android.provider.ContactsContract.RawContacts;
-import android.util.Log;
-
-import com.android.contacts.common.model.ValuesDelta;
-import com.google.common.collect.Lists;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Iterator;
-
-/**
- * Container for multiple {@link RawContactDelta} objects, usually when editing
- * together as an entire aggregate. Provides convenience methods for parceling
- * and applying another {@link RawContactDeltaList} over it.
- */
-public class RawContactDeltaList extends ArrayList<RawContactDelta> implements Parcelable {
-    private static final String TAG = RawContactDeltaList.class.getSimpleName();
-    private static final boolean VERBOSE_LOGGING = Log.isLoggable(TAG, Log.VERBOSE);
-
-    private boolean mSplitRawContacts;
-    private long[] mJoinWithRawContactIds;
-
-    public RawContactDeltaList() {
-    }
-
-    /**
-     * Create an {@link RawContactDeltaList} based on {@link Contacts} specified by the
-     * given query parameters. This closes the {@link EntityIterator} when
-     * finished, so it doesn't subscribe to updates.
-     */
-    public static RawContactDeltaList fromQuery(Uri entityUri, ContentResolver resolver,
-            String selection, String[] selectionArgs, String sortOrder) {
-        final EntityIterator iterator = RawContacts.newEntityIterator(
-                resolver.query(entityUri, null, selection, selectionArgs, sortOrder));
-        try {
-            return fromIterator(iterator);
-        } finally {
-            iterator.close();
-        }
-    }
-
-    /**
-     * Create an {@link RawContactDeltaList} that contains the entities of the Iterator as before
-     * values.  This function can be passed an iterator of Entity objects or an iterator of
-     * RawContact objects.
-     */
-    public static RawContactDeltaList fromIterator(Iterator<?> iterator) {
-        final RawContactDeltaList state = new RawContactDeltaList();
-        state.addAll(iterator);
-        return state;
-    }
-
-    public void addAll(Iterator<?> iterator) {
-        // Perform background query to pull contact details
-        while (iterator.hasNext()) {
-            // Read all contacts into local deltas to prepare for edits
-            Object nextObject = iterator.next();
-            final RawContact before = nextObject instanceof Entity
-                    ? RawContact.createFrom((Entity) nextObject)
-                    : (RawContact) nextObject;
-            final RawContactDelta rawContactDelta = RawContactDelta.fromBefore(before);
-            add(rawContactDelta);
-        }
-    }
-
-    /**
-     * Merge the "after" values from the given {@link RawContactDeltaList}, discarding any
-     * previous "after" states. This is typically used when re-parenting user
-     * edits onto an updated {@link RawContactDeltaList}.
-     */
-    public static RawContactDeltaList mergeAfter(RawContactDeltaList local,
-            RawContactDeltaList remote) {
-        if (local == null) local = new RawContactDeltaList();
-
-        // For each entity in the remote set, try matching over existing
-        for (RawContactDelta remoteEntity : remote) {
-            final Long rawContactId = remoteEntity.getValues().getId();
-
-            // Find or create local match and merge
-            final RawContactDelta localEntity = local.getByRawContactId(rawContactId);
-            final RawContactDelta merged = RawContactDelta.mergeAfter(localEntity, remoteEntity);
-
-            if (localEntity == null && merged != null) {
-                // No local entry before, so insert
-                local.add(merged);
-            }
-        }
-
-        return local;
-    }
-
-    /**
-     * Build a list of {@link ContentProviderOperation} that will transform all
-     * the "before" {@link Entity} states into the modified state which all
-     * {@link RawContactDelta} objects represent. This method specifically creates
-     * any {@link AggregationExceptions} rules needed to groups edits together.
-     */
-    public ArrayList<ContentProviderOperation> buildDiff() {
-        if (VERBOSE_LOGGING) {
-            Log.v(TAG, "buildDiff: list=" + toString());
-        }
-        final ArrayList<ContentProviderOperation> diff = Lists.newArrayList();
-
-        final long rawContactId = this.findRawContactId();
-        int firstInsertRow = -1;
-
-        // First pass enforces versions remain consistent
-        for (RawContactDelta delta : this) {
-            delta.buildAssert(diff);
-        }
-
-        final int assertMark = diff.size();
-        int backRefs[] = new int[size()];
-
-        int rawContactIndex = 0;
-
-        // Second pass builds actual operations
-        for (RawContactDelta delta : this) {
-            final int firstBatch = diff.size();
-            final boolean isInsert = delta.isContactInsert();
-            backRefs[rawContactIndex++] = isInsert ? firstBatch : -1;
-
-            delta.buildDiff(diff);
-
-            // If the user chose to join with some other existing raw contact(s) at save time,
-            // add aggregation exceptions for all those raw contacts.
-            if (mJoinWithRawContactIds != null) {
-                for (Long joinedRawContactId : mJoinWithRawContactIds) {
-                    final Builder builder = beginKeepTogether();
-                    builder.withValue(AggregationExceptions.RAW_CONTACT_ID1, joinedRawContactId);
-                    if (rawContactId != -1) {
-                        builder.withValue(AggregationExceptions.RAW_CONTACT_ID2, rawContactId);
-                    } else {
-                        builder.withValueBackReference(
-                                AggregationExceptions.RAW_CONTACT_ID2, firstBatch);
-                    }
-                    diff.add(builder.build());
-                }
-            }
-
-            // Only create rules for inserts
-            if (!isInsert) continue;
-
-            // If we are going to split all contacts, there is no point in first combining them
-            if (mSplitRawContacts) continue;
-
-            if (rawContactId != -1) {
-                // Has existing contact, so bind to it strongly
-                final Builder builder = beginKeepTogether();
-                builder.withValue(AggregationExceptions.RAW_CONTACT_ID1, rawContactId);
-                builder.withValueBackReference(AggregationExceptions.RAW_CONTACT_ID2, firstBatch);
-                diff.add(builder.build());
-
-            } else if (firstInsertRow == -1) {
-                // First insert case, so record row
-                firstInsertRow = firstBatch;
-
-            } else {
-                // Additional insert case, so point at first insert
-                final Builder builder = beginKeepTogether();
-                builder.withValueBackReference(AggregationExceptions.RAW_CONTACT_ID1,
-                        firstInsertRow);
-                builder.withValueBackReference(AggregationExceptions.RAW_CONTACT_ID2, firstBatch);
-                diff.add(builder.build());
-            }
-        }
-
-        if (mSplitRawContacts) {
-            buildSplitContactDiff(diff, backRefs);
-        }
-
-        // No real changes if only left with asserts
-        if (diff.size() == assertMark) {
-            diff.clear();
-        }
-        if (VERBOSE_LOGGING) {
-            Log.v(TAG, "buildDiff: ops=" + diffToString(diff));
-        }
-        return diff;
-    }
-
-    private static String diffToString(ArrayList<ContentProviderOperation> ops) {
-        StringBuilder sb = new StringBuilder();
-        sb.append("[\n");
-        for (ContentProviderOperation op : ops) {
-            sb.append(op.toString());
-            sb.append(",\n");
-        }
-        sb.append("]\n");
-        return sb.toString();
-    }
-
-    /**
-     * Start building a {@link ContentProviderOperation} that will keep two
-     * {@link RawContacts} together.
-     */
-    protected Builder beginKeepTogether() {
-        final Builder builder = ContentProviderOperation
-                .newUpdate(AggregationExceptions.CONTENT_URI);
-        builder.withValue(AggregationExceptions.TYPE, AggregationExceptions.TYPE_KEEP_TOGETHER);
-        return builder;
-    }
-
-    /**
-     * Builds {@link AggregationExceptions} to split all constituent raw contacts into
-     * separate contacts.
-     */
-    private void buildSplitContactDiff(final ArrayList<ContentProviderOperation> diff,
-            int[] backRefs) {
-        int count = size();
-        for (int i = 0; i < count; i++) {
-            for (int j = 0; j < count; j++) {
-                if (i != j) {
-                    buildSplitContactDiff(diff, i, j, backRefs);
-                }
-            }
-        }
-    }
-
-    /**
-     * Construct a {@link AggregationExceptions#TYPE_KEEP_SEPARATE}.
-     */
-    private void buildSplitContactDiff(ArrayList<ContentProviderOperation> diff, int index1,
-            int index2, int[] backRefs) {
-        Builder builder =
-                ContentProviderOperation.newUpdate(AggregationExceptions.CONTENT_URI);
-        builder.withValue(AggregationExceptions.TYPE, AggregationExceptions.TYPE_KEEP_SEPARATE);
-
-        Long rawContactId1 = get(index1).getValues().getAsLong(RawContacts._ID);
-        int backRef1 = backRefs[index1];
-        if (rawContactId1 != null && rawContactId1 >= 0) {
-            builder.withValue(AggregationExceptions.RAW_CONTACT_ID1, rawContactId1);
-        } else if (backRef1 >= 0) {
-            builder.withValueBackReference(AggregationExceptions.RAW_CONTACT_ID1, backRef1);
-        } else {
-            return;
-        }
-
-        Long rawContactId2 = get(index2).getValues().getAsLong(RawContacts._ID);
-        int backRef2 = backRefs[index2];
-        if (rawContactId2 != null && rawContactId2 >= 0) {
-            builder.withValue(AggregationExceptions.RAW_CONTACT_ID2, rawContactId2);
-        } else if (backRef2 >= 0) {
-            builder.withValueBackReference(AggregationExceptions.RAW_CONTACT_ID2, backRef2);
-        } else {
-            return;
-        }
-
-        diff.add(builder.build());
-    }
-
-    /**
-     * Search all contained {@link RawContactDelta} for the first one with an
-     * existing {@link RawContacts#_ID} value. Usually used when creating
-     * {@link AggregationExceptions} during an update.
-     */
-    public long findRawContactId() {
-        for (RawContactDelta delta : this) {
-            final Long rawContactId = delta.getValues().getAsLong(RawContacts._ID);
-            if (rawContactId != null && rawContactId >= 0) {
-                return rawContactId;
-            }
-        }
-        return -1;
-    }
-
-    /**
-     * Find {@link RawContacts#_ID} of the requested {@link RawContactDelta}.
-     */
-    public Long getRawContactId(int index) {
-        if (index >= 0 && index < this.size()) {
-            final RawContactDelta delta = this.get(index);
-            final ValuesDelta values = delta.getValues();
-            if (values.isVisible()) {
-                return values.getAsLong(RawContacts._ID);
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Find the raw-contact (an {@link RawContactDelta}) with the specified ID.
-     */
-    public RawContactDelta getByRawContactId(Long rawContactId) {
-        final int index = this.indexOfRawContactId(rawContactId);
-        return (index == -1) ? null : this.get(index);
-    }
-
-    /**
-     * Find index of given {@link RawContacts#_ID} when present.
-     */
-    public int indexOfRawContactId(Long rawContactId) {
-        if (rawContactId == null) return -1;
-        final int size = this.size();
-        for (int i = 0; i < size; i++) {
-            final Long currentId = getRawContactId(i);
-            if (rawContactId.equals(currentId)) {
-                return i;
-            }
-        }
-        return -1;
-    }
-
-    /**
-     * Return the index of the first RawContactDelta corresponding to a writable raw-contact, or -1.
-     * */
-    public int indexOfFirstWritableRawContact(Context context) {
-        // Find the first writable entity.
-        int entityIndex = 0;
-        for (RawContactDelta delta : this) {
-            if (delta.getRawContactAccountType(context).areContactsWritable()) return entityIndex;
-            entityIndex++;
-        }
-        return -1;
-    }
-
-    /**  Return the first RawContactDelta corresponding to a writable raw-contact, or null. */
-    public RawContactDelta getFirstWritableRawContact(Context context) {
-        final int index = indexOfFirstWritableRawContact(context);
-        return (index == -1) ? null : get(index);
-    }
-
-    public ValuesDelta getSuperPrimaryEntry(final String mimeType) {
-        ValuesDelta primary = null;
-        ValuesDelta randomEntry = null;
-        for (RawContactDelta delta : this) {
-            final ArrayList<ValuesDelta> mimeEntries = delta.getMimeEntries(mimeType);
-            if (mimeEntries == null) return null;
-
-            for (ValuesDelta entry : mimeEntries) {
-                if (entry.isSuperPrimary()) {
-                    return entry;
-                } else if (primary == null && entry.isPrimary()) {
-                    primary = entry;
-                } else if (randomEntry == null) {
-                    randomEntry = entry;
-                }
-            }
-        }
-        // When no direct super primary, return something
-        if (primary != null) {
-            return primary;
-        }
-        return randomEntry;
-    }
-
-    /**
-     * Sets a flag that will split ("explode") the raw_contacts into seperate contacts
-     */
-    public void markRawContactsForSplitting() {
-        mSplitRawContacts = true;
-    }
-
-    public boolean isMarkedForSplitting() {
-        return mSplitRawContacts;
-    }
-
-    public void setJoinWithRawContacts(long[] rawContactIds) {
-        mJoinWithRawContactIds = rawContactIds;
-    }
-
-    public boolean isMarkedForJoining() {
-        return mJoinWithRawContactIds != null && mJoinWithRawContactIds.length > 0;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public int describeContents() {
-        // Nothing special about this parcel
-        return 0;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        final int size = this.size();
-        dest.writeInt(size);
-        for (RawContactDelta delta : this) {
-            dest.writeParcelable(delta, flags);
-        }
-        dest.writeLongArray(mJoinWithRawContactIds);
-        dest.writeInt(mSplitRawContacts ? 1 : 0);
-    }
-
-    @SuppressWarnings("unchecked")
-    public void readFromParcel(Parcel source) {
-        final ClassLoader loader = getClass().getClassLoader();
-        final int size = source.readInt();
-        for (int i = 0; i < size; i++) {
-            this.add(source.<RawContactDelta> readParcelable(loader));
-        }
-        mJoinWithRawContactIds = source.createLongArray();
-        mSplitRawContacts = source.readInt() != 0;
-    }
-
-    public static final Parcelable.Creator<RawContactDeltaList> CREATOR =
-            new Parcelable.Creator<RawContactDeltaList>() {
-        @Override
-        public RawContactDeltaList createFromParcel(Parcel in) {
-            final RawContactDeltaList state = new RawContactDeltaList();
-            state.readFromParcel(in);
-            return state;
-        }
-
-        @Override
-        public RawContactDeltaList[] newArray(int size) {
-            return new RawContactDeltaList[size];
-        }
-    };
-
-    @Override
-    public String toString() {
-        StringBuilder sb = new StringBuilder();
-        sb.append("(");
-        sb.append("Split=");
-        sb.append(mSplitRawContacts);
-        sb.append(", Join=[");
-        sb.append(Arrays.toString(mJoinWithRawContactIds));
-        sb.append("], Values=");
-        sb.append(super.toString());
-        sb.append(")");
-        return sb.toString();
-    }
-}
diff --git a/src/com/android/contacts/model/RawContactModifier.java b/src/com/android/contacts/model/RawContactModifier.java
deleted file mode 100644
index 5f8b410..0000000
--- a/src/com/android/contacts/model/RawContactModifier.java
+++ /dev/null
@@ -1,1429 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.contacts.model;
-
-import android.content.ContentValues;
-import android.content.Context;
-import android.database.Cursor;
-import android.net.Uri;
-import android.os.Bundle;
-import android.provider.ContactsContract;
-import android.provider.ContactsContract.CommonDataKinds.BaseTypes;
-import android.provider.ContactsContract.CommonDataKinds.Email;
-import android.provider.ContactsContract.CommonDataKinds.Event;
-import android.provider.ContactsContract.CommonDataKinds.GroupMembership;
-import android.provider.ContactsContract.CommonDataKinds.Im;
-import android.provider.ContactsContract.CommonDataKinds.Nickname;
-import android.provider.ContactsContract.CommonDataKinds.Note;
-import android.provider.ContactsContract.CommonDataKinds.Organization;
-import android.provider.ContactsContract.CommonDataKinds.Phone;
-import android.provider.ContactsContract.CommonDataKinds.Photo;
-import android.provider.ContactsContract.CommonDataKinds.Relation;
-import android.provider.ContactsContract.CommonDataKinds.SipAddress;
-import android.provider.ContactsContract.CommonDataKinds.StructuredName;
-import android.provider.ContactsContract.CommonDataKinds.StructuredPostal;
-import android.provider.ContactsContract.CommonDataKinds.Website;
-import android.provider.ContactsContract.Data;
-import android.provider.ContactsContract.Intents;
-import android.provider.ContactsContract.Intents.Insert;
-import android.provider.ContactsContract.RawContacts;
-import android.text.TextUtils;
-import android.util.Log;
-import android.util.SparseArray;
-import android.util.SparseIntArray;
-
-import com.android.contacts.ContactsUtils;
-import com.android.contacts.common.model.AccountTypeManager;
-import com.android.contacts.common.model.ValuesDelta;
-import com.android.contacts.common.util.CommonDateUtils;
-import com.android.contacts.editor.EventFieldEditorView;
-import com.android.contacts.editor.PhoneticNameEditorView;
-import com.android.contacts.common.model.account.AccountType;
-import com.android.contacts.common.model.account.AccountType.EditField;
-import com.android.contacts.common.model.account.AccountType.EditType;
-import com.android.contacts.common.model.account.AccountType.EventEditType;
-import com.android.contacts.common.model.account.GoogleAccountType;
-import com.android.contacts.common.model.dataitem.DataKind;
-import com.android.contacts.model.dataitem.PhoneDataItem;
-import com.android.contacts.model.dataitem.StructuredNameDataItem;
-import com.android.contacts.util.DateUtils;
-import com.android.contacts.util.NameConverter;
-
-import java.text.ParsePosition;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Locale;
-import java.util.Set;
-
-/**
- * Helper methods for modifying an {@link RawContactDelta}, such as inserting
- * new rows, or enforcing {@link AccountType}.
- */
-public class RawContactModifier {
-    private static final String TAG = RawContactModifier.class.getSimpleName();
-
-    /** Set to true in order to view logs on entity operations */
-    private static final boolean DEBUG = false;
-
-    /**
-     * For the given {@link RawContactDelta}, determine if the given
-     * {@link DataKind} could be inserted under specific
-     * {@link AccountType}.
-     */
-    public static boolean canInsert(RawContactDelta state, DataKind kind) {
-        // Insert possible when have valid types and under overall maximum
-        final int visibleCount = state.getMimeEntriesCount(kind.mimeType, true);
-        final boolean validTypes = hasValidTypes(state, kind);
-        final boolean validOverall = (kind.typeOverallMax == -1)
-                || (visibleCount < kind.typeOverallMax);
-        return (validTypes && validOverall);
-    }
-
-    public static boolean hasValidTypes(RawContactDelta state, DataKind kind) {
-        if (RawContactModifier.hasEditTypes(kind)) {
-            return (getValidTypes(state, kind).size() > 0);
-        } else {
-            return true;
-        }
-    }
-
-    /**
-     * Ensure that at least one of the given {@link DataKind} exists in the
-     * given {@link RawContactDelta} state, and try creating one if none exist.
-     * @return The child (either newly created or the first existing one), or null if the
-     *     account doesn't support this {@link DataKind}.
-     */
-    public static ValuesDelta ensureKindExists(
-            RawContactDelta state, AccountType accountType, String mimeType) {
-        final DataKind kind = accountType.getKindForMimetype(mimeType);
-        final boolean hasChild = state.getMimeEntriesCount(mimeType, true) > 0;
-
-        if (kind != null) {
-            if (hasChild) {
-                // Return the first entry.
-                return state.getMimeEntries(mimeType).get(0);
-            } else {
-                // Create child when none exists and valid kind
-                final ValuesDelta child = insertChild(state, kind);
-                if (kind.mimeType.equals(Photo.CONTENT_ITEM_TYPE)) {
-                    child.setFromTemplate(true);
-                }
-                return child;
-            }
-        }
-        return null;
-    }
-
-    /**
-     * For the given {@link RawContactDelta} and {@link DataKind}, return the
-     * list possible {@link EditType} options available based on
-     * {@link AccountType}.
-     */
-    public static ArrayList<EditType> getValidTypes(RawContactDelta state, DataKind kind) {
-        return getValidTypes(state, kind, null, true, null);
-    }
-
-    /**
-     * For the given {@link RawContactDelta} and {@link DataKind}, return the
-     * list possible {@link EditType} options available based on
-     * {@link AccountType}.
-     *
-     * @param forceInclude Always include this {@link EditType} in the returned
-     *            list, even when an otherwise-invalid choice. This is useful
-     *            when showing a dialog that includes the current type.
-     */
-    public static ArrayList<EditType> getValidTypes(RawContactDelta state, DataKind kind,
-            EditType forceInclude) {
-        return getValidTypes(state, kind, forceInclude, true, null);
-    }
-
-    /**
-     * For the given {@link RawContactDelta} and {@link DataKind}, return the
-     * list possible {@link EditType} options available based on
-     * {@link AccountType}.
-     *
-     * @param forceInclude Always include this {@link EditType} in the returned
-     *            list, even when an otherwise-invalid choice. This is useful
-     *            when showing a dialog that includes the current type.
-     * @param includeSecondary If true, include any valid types marked as
-     *            {@link EditType#secondary}.
-     * @param typeCount When provided, will be used for the frequency count of
-     *            each {@link EditType}, otherwise built using
-     *            {@link #getTypeFrequencies(RawContactDelta, DataKind)}.
-     */
-    private static ArrayList<EditType> getValidTypes(RawContactDelta state, DataKind kind,
-            EditType forceInclude, boolean includeSecondary, SparseIntArray typeCount) {
-        final ArrayList<EditType> validTypes = new ArrayList<EditType>();
-
-        // Bail early if no types provided
-        if (!hasEditTypes(kind)) return validTypes;
-
-        if (typeCount == null) {
-            // Build frequency counts if not provided
-            typeCount = getTypeFrequencies(state, kind);
-        }
-
-        // Build list of valid types
-        final int overallCount = typeCount.get(FREQUENCY_TOTAL);
-        for (EditType type : kind.typeList) {
-            final boolean validOverall = (kind.typeOverallMax == -1 ? true
-                    : overallCount < kind.typeOverallMax);
-            final boolean validSpecific = (type.specificMax == -1 ? true : typeCount
-                    .get(type.rawValue) < type.specificMax);
-            final boolean validSecondary = (includeSecondary ? true : !type.secondary);
-            final boolean forcedInclude = type.equals(forceInclude);
-            if (forcedInclude || (validOverall && validSpecific && validSecondary)) {
-                // Type is valid when no limit, under limit, or forced include
-                validTypes.add(type);
-            }
-        }
-
-        return validTypes;
-    }
-
-    private static final int FREQUENCY_TOTAL = Integer.MIN_VALUE;
-
-    /**
-     * Count up the frequency that each {@link EditType} appears in the given
-     * {@link RawContactDelta}. The returned {@link SparseIntArray} maps from
-     * {@link EditType#rawValue} to counts, with the total overall count stored
-     * as {@link #FREQUENCY_TOTAL}.
-     */
-    private static SparseIntArray getTypeFrequencies(RawContactDelta state, DataKind kind) {
-        final SparseIntArray typeCount = new SparseIntArray();
-
-        // Find all entries for this kind, bailing early if none found
-        final List<ValuesDelta> mimeEntries = state.getMimeEntries(kind.mimeType);
-        if (mimeEntries == null) return typeCount;
-
-        int totalCount = 0;
-        for (ValuesDelta entry : mimeEntries) {
-            // Only count visible entries
-            if (!entry.isVisible()) continue;
-            totalCount++;
-
-            final EditType type = getCurrentType(entry, kind);
-            if (type != null) {
-                final int count = typeCount.get(type.rawValue);
-                typeCount.put(type.rawValue, count + 1);
-            }
-        }
-        typeCount.put(FREQUENCY_TOTAL, totalCount);
-        return typeCount;
-    }
-
-    /**
-     * Check if the given {@link DataKind} has multiple types that should be
-     * displayed for users to pick.
-     */
-    public static boolean hasEditTypes(DataKind kind) {
-        return kind.typeList != null && kind.typeList.size() > 0;
-    }
-
-    /**
-     * Find the {@link EditType} that describes the given
-     * {@link ValuesDelta} row, assuming the given {@link DataKind} dictates
-     * the possible types.
-     */
-    public static EditType getCurrentType(ValuesDelta entry, DataKind kind) {
-        final Long rawValue = entry.getAsLong(kind.typeColumn);
-        if (rawValue == null) return null;
-        return getType(kind, rawValue.intValue());
-    }
-
-    /**
-     * Find the {@link EditType} that describes the given {@link ContentValues} row,
-     * assuming the given {@link DataKind} dictates the possible types.
-     */
-    public static EditType getCurrentType(ContentValues entry, DataKind kind) {
-        if (kind.typeColumn == null) return null;
-        final Integer rawValue = entry.getAsInteger(kind.typeColumn);
-        if (rawValue == null) return null;
-        return getType(kind, rawValue);
-    }
-
-    /**
-     * Find the {@link EditType} that describes the given {@link Cursor} row,
-     * assuming the given {@link DataKind} dictates the possible types.
-     */
-    public static EditType getCurrentType(Cursor cursor, DataKind kind) {
-        if (kind.typeColumn == null) return null;
-        final int index = cursor.getColumnIndex(kind.typeColumn);
-        if (index == -1) return null;
-        final int rawValue = cursor.getInt(index);
-        return getType(kind, rawValue);
-    }
-
-    /**
-     * Find the {@link EditType} with the given {@link EditType#rawValue}.
-     */
-    public static EditType getType(DataKind kind, int rawValue) {
-        for (EditType type : kind.typeList) {
-            if (type.rawValue == rawValue) {
-                return type;
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Return the precedence for the the given {@link EditType#rawValue}, where
-     * lower numbers are higher precedence.
-     */
-    public static int getTypePrecedence(DataKind kind, int rawValue) {
-        for (int i = 0; i < kind.typeList.size(); i++) {
-            final EditType type = kind.typeList.get(i);
-            if (type.rawValue == rawValue) {
-                return i;
-            }
-        }
-        return Integer.MAX_VALUE;
-    }
-
-    /**
-     * Find the best {@link EditType} for a potential insert. The "best" is the
-     * first primary type that doesn't already exist. When all valid types
-     * exist, we pick the last valid option.
-     */
-    public static EditType getBestValidType(RawContactDelta state, DataKind kind,
-            boolean includeSecondary, int exactValue) {
-        // Shortcut when no types
-        if (kind.typeColumn == null) return null;
-
-        // Find type counts and valid primary types, bail if none
-        final SparseIntArray typeCount = getTypeFrequencies(state, kind);
-        final ArrayList<EditType> validTypes = getValidTypes(state, kind, null, includeSecondary,
-                typeCount);
-        if (validTypes.size() == 0) return null;
-
-        // Keep track of the last valid type
-        final EditType lastType = validTypes.get(validTypes.size() - 1);
-
-        // Remove any types that already exist
-        Iterator<EditType> iterator = validTypes.iterator();
-        while (iterator.hasNext()) {
-            final EditType type = iterator.next();
-            final int count = typeCount.get(type.rawValue);
-
-            if (exactValue == type.rawValue) {
-                // Found exact value match
-                return type;
-            }
-
-            if (count > 0) {
-                // Type already appears, so don't consider
-                iterator.remove();
-            }
-        }
-
-        // Use the best remaining, otherwise the last valid
-        if (validTypes.size() > 0) {
-            return validTypes.get(0);
-        } else {
-            return lastType;
-        }
-    }
-
-    /**
-     * Insert a new child of kind {@link DataKind} into the given
-     * {@link RawContactDelta}. Tries using the best {@link EditType} found using
-     * {@link #getBestValidType(RawContactDelta, DataKind, boolean, int)}.
-     */
-    public static ValuesDelta insertChild(RawContactDelta state, DataKind kind) {
-        // First try finding a valid primary
-        EditType bestType = getBestValidType(state, kind, false, Integer.MIN_VALUE);
-        if (bestType == null) {
-            // No valid primary found, so expand search to secondary
-            bestType = getBestValidType(state, kind, true, Integer.MIN_VALUE);
-        }
-        return insertChild(state, kind, bestType);
-    }
-
-    /**
-     * Insert a new child of kind {@link DataKind} into the given
-     * {@link RawContactDelta}, marked with the given {@link EditType}.
-     */
-    public static ValuesDelta insertChild(RawContactDelta state, DataKind kind, EditType type) {
-        // Bail early if invalid kind
-        if (kind == null) return null;
-        final ContentValues after = new ContentValues();
-
-        // Our parent CONTACT_ID is provided later
-        after.put(Data.MIMETYPE, kind.mimeType);
-
-        // Fill-in with any requested default values
-        if (kind.defaultValues != null) {
-            after.putAll(kind.defaultValues);
-        }
-
-        if (kind.typeColumn != null && type != null) {
-            // Set type, if provided
-            after.put(kind.typeColumn, type.rawValue);
-        }
-
-        final ValuesDelta child = ValuesDelta.fromAfter(after);
-        state.addEntry(child);
-        return child;
-    }
-
-    /**
-     * Processing to trim any empty {@link ValuesDelta} and {@link RawContactDelta}
-     * from the given {@link RawContactDeltaList}, assuming the given {@link AccountTypeManager}
-     * dictates the structure for various fields. This method ignores rows not
-     * described by the {@link AccountType}.
-     */
-    public static void trimEmpty(RawContactDeltaList set, AccountTypeManager accountTypes) {
-        for (RawContactDelta state : set) {
-            ValuesDelta values = state.getValues();
-            final String accountType = values.getAsString(RawContacts.ACCOUNT_TYPE);
-            final String dataSet = values.getAsString(RawContacts.DATA_SET);
-            final AccountType type = accountTypes.getAccountType(accountType, dataSet);
-            trimEmpty(state, type);
-        }
-    }
-
-    public static boolean hasChanges(RawContactDeltaList set, AccountTypeManager accountTypes) {
-        if (set.isMarkedForSplitting() || set.isMarkedForJoining()) {
-            return true;
-        }
-
-        for (RawContactDelta state : set) {
-            ValuesDelta values = state.getValues();
-            final String accountType = values.getAsString(RawContacts.ACCOUNT_TYPE);
-            final String dataSet = values.getAsString(RawContacts.DATA_SET);
-            final AccountType type = accountTypes.getAccountType(accountType, dataSet);
-            if (hasChanges(state, type)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Processing to trim any empty {@link ValuesDelta} rows from the given
-     * {@link RawContactDelta}, assuming the given {@link AccountType} dictates
-     * the structure for various fields. This method ignores rows not described
-     * by the {@link AccountType}.
-     */
-    public static void trimEmpty(RawContactDelta state, AccountType accountType) {
-        boolean hasValues = false;
-
-        // Walk through entries for each well-known kind
-        for (DataKind kind : accountType.getSortedDataKinds()) {
-            final String mimeType = kind.mimeType;
-            final ArrayList<ValuesDelta> entries = state.getMimeEntries(mimeType);
-            if (entries == null) continue;
-
-            for (ValuesDelta entry : entries) {
-                // Skip any values that haven't been touched
-                final boolean touched = entry.isInsert() || entry.isUpdate();
-                if (!touched) {
-                    hasValues = true;
-                    continue;
-                }
-
-                // Test and remove this row if empty and it isn't a photo from google
-                final boolean isGoogleAccount = TextUtils.equals(GoogleAccountType.ACCOUNT_TYPE,
-                        state.getValues().getAsString(RawContacts.ACCOUNT_TYPE));
-                final boolean isPhoto = TextUtils.equals(Photo.CONTENT_ITEM_TYPE, kind.mimeType);
-                final boolean isGooglePhoto = isPhoto && isGoogleAccount;
-
-                if (RawContactModifier.isEmpty(entry, kind) && !isGooglePhoto) {
-                    if (DEBUG) {
-                        Log.v(TAG, "Trimming: " + entry.toString());
-                    }
-                    entry.markDeleted();
-                } else if (!entry.isFromTemplate()) {
-                    hasValues = true;
-                }
-            }
-        }
-        if (!hasValues) {
-            // Trim overall entity if no children exist
-            state.markDeleted();
-        }
-    }
-
-    private static boolean hasChanges(RawContactDelta state, AccountType accountType) {
-        for (DataKind kind : accountType.getSortedDataKinds()) {
-            final String mimeType = kind.mimeType;
-            final ArrayList<ValuesDelta> entries = state.getMimeEntries(mimeType);
-            if (entries == null) continue;
-
-            for (ValuesDelta entry : entries) {
-                // An empty Insert must be ignored, because it won't save anything (an example
-                // is an empty name that stays empty)
-                final boolean isRealInsert = entry.isInsert() && !isEmpty(entry, kind);
-                if (isRealInsert || entry.isUpdate() || entry.isDelete()) {
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Test if the given {@link ValuesDelta} would be considered "empty" in
-     * terms of {@link DataKind#fieldList}.
-     */
-    public static boolean isEmpty(ValuesDelta values, DataKind kind) {
-        if (Photo.CONTENT_ITEM_TYPE.equals(kind.mimeType)) {
-            return values.isInsert() && values.getAsByteArray(Photo.PHOTO) == null;
-        }
-
-        // No defined fields mean this row is always empty
-        if (kind.fieldList == null) return true;
-
-        for (EditField field : kind.fieldList) {
-            // If any field has values, we're not empty
-            final String value = values.getAsString(field.column);
-            if (ContactsUtils.isGraphic(value)) {
-                return false;
-            }
-        }
-
-        return true;
-    }
-
-    /**
-     * Compares corresponding fields in values1 and values2. Only the fields
-     * declared by the DataKind are taken into consideration.
-     */
-    protected static boolean areEqual(ValuesDelta values1, ContentValues values2, DataKind kind) {
-        if (kind.fieldList == null) return false;
-
-        for (EditField field : kind.fieldList) {
-            final String value1 = values1.getAsString(field.column);
-            final String value2 = values2.getAsString(field.column);
-            if (!TextUtils.equals(value1, value2)) {
-                return false;
-            }
-        }
-
-        return true;
-    }
-
-    /**
-     * Parse the given {@link Bundle} into the given {@link RawContactDelta} state,
-     * assuming the extras defined through {@link Intents}.
-     */
-    public static void parseExtras(Context context, AccountType accountType, RawContactDelta state,
-            Bundle extras) {
-        if (extras == null || extras.size() == 0) {
-            // Bail early if no useful data
-            return;
-        }
-
-        parseStructuredNameExtra(context, accountType, state, extras);
-        parseStructuredPostalExtra(accountType, state, extras);
-
-        {
-            // Phone
-            final DataKind kind = accountType.getKindForMimetype(Phone.CONTENT_ITEM_TYPE);
-            parseExtras(state, kind, extras, Insert.PHONE_TYPE, Insert.PHONE, Phone.NUMBER);
-            parseExtras(state, kind, extras, Insert.SECONDARY_PHONE_TYPE, Insert.SECONDARY_PHONE,
-                    Phone.NUMBER);
-            parseExtras(state, kind, extras, Insert.TERTIARY_PHONE_TYPE, Insert.TERTIARY_PHONE,
-                    Phone.NUMBER);
-        }
-
-        {
-            // Email
-            final DataKind kind = accountType.getKindForMimetype(Email.CONTENT_ITEM_TYPE);
-            parseExtras(state, kind, extras, Insert.EMAIL_TYPE, Insert.EMAIL, Email.DATA);
-            parseExtras(state, kind, extras, Insert.SECONDARY_EMAIL_TYPE, Insert.SECONDARY_EMAIL,
-                    Email.DATA);
-            parseExtras(state, kind, extras, Insert.TERTIARY_EMAIL_TYPE, Insert.TERTIARY_EMAIL,
-                    Email.DATA);
-        }
-
-        {
-            // Im
-            final DataKind kind = accountType.getKindForMimetype(Im.CONTENT_ITEM_TYPE);
-            fixupLegacyImType(extras);
-            parseExtras(state, kind, extras, Insert.IM_PROTOCOL, Insert.IM_HANDLE, Im.DATA);
-        }
-
-        // Organization
-        final boolean hasOrg = extras.containsKey(Insert.COMPANY)
-                || extras.containsKey(Insert.JOB_TITLE);
-        final DataKind kindOrg = accountType.getKindForMimetype(Organization.CONTENT_ITEM_TYPE);
-        if (hasOrg && RawContactModifier.canInsert(state, kindOrg)) {
-            final ValuesDelta child = RawContactModifier.insertChild(state, kindOrg);
-
-            final String company = extras.getString(Insert.COMPANY);
-            if (ContactsUtils.isGraphic(company)) {
-                child.put(Organization.COMPANY, company);
-            }
-
-            final String title = extras.getString(Insert.JOB_TITLE);
-            if (ContactsUtils.isGraphic(title)) {
-                child.put(Organization.TITLE, title);
-            }
-        }
-
-        // Notes
-        final boolean hasNotes = extras.containsKey(Insert.NOTES);
-        final DataKind kindNotes = accountType.getKindForMimetype(Note.CONTENT_ITEM_TYPE);
-        if (hasNotes && RawContactModifier.canInsert(state, kindNotes)) {
-            final ValuesDelta child = RawContactModifier.insertChild(state, kindNotes);
-
-            final String notes = extras.getString(Insert.NOTES);
-            if (ContactsUtils.isGraphic(notes)) {
-                child.put(Note.NOTE, notes);
-            }
-        }
-
-        // Arbitrary additional data
-        ArrayList<ContentValues> values = extras.getParcelableArrayList(Insert.DATA);
-        if (values != null) {
-            parseValues(state, accountType, values);
-        }
-    }
-
-    private static void parseStructuredNameExtra(
-            Context context, AccountType accountType, RawContactDelta state, Bundle extras) {
-        // StructuredName
-        RawContactModifier.ensureKindExists(state, accountType, StructuredName.CONTENT_ITEM_TYPE);
-        final ValuesDelta child = state.getPrimaryEntry(StructuredName.CONTENT_ITEM_TYPE);
-
-        final String name = extras.getString(Insert.NAME);
-        if (ContactsUtils.isGraphic(name)) {
-            final DataKind kind = accountType.getKindForMimetype(StructuredName.CONTENT_ITEM_TYPE);
-            boolean supportsDisplayName = false;
-            if (kind.fieldList != null) {
-                for (EditField field : kind.fieldList) {
-                    if (StructuredName.DISPLAY_NAME.equals(field.column)) {
-                        supportsDisplayName = true;
-                        break;
-                    }
-                }
-            }
-
-            if (supportsDisplayName) {
-                child.put(StructuredName.DISPLAY_NAME, name);
-            } else {
-                Uri uri = ContactsContract.AUTHORITY_URI.buildUpon()
-                        .appendPath("complete_name")
-                        .appendQueryParameter(StructuredName.DISPLAY_NAME, name)
-                        .build();
-                Cursor cursor = context.getContentResolver().query(uri,
-                        new String[]{
-                                StructuredName.PREFIX,
-                                StructuredName.GIVEN_NAME,
-                                StructuredName.MIDDLE_NAME,
-                                StructuredName.FAMILY_NAME,
-                                StructuredName.SUFFIX,
-                        }, null, null, null);
-
-                try {
-                    if (cursor.moveToFirst()) {
-                        child.put(StructuredName.PREFIX, cursor.getString(0));
-                        child.put(StructuredName.GIVEN_NAME, cursor.getString(1));
-                        child.put(StructuredName.MIDDLE_NAME, cursor.getString(2));
-                        child.put(StructuredName.FAMILY_NAME, cursor.getString(3));
-                        child.put(StructuredName.SUFFIX, cursor.getString(4));
-                    }
-                } finally {
-                    cursor.close();
-                }
-            }
-        }
-
-        final String phoneticName = extras.getString(Insert.PHONETIC_NAME);
-        if (ContactsUtils.isGraphic(phoneticName)) {
-            child.put(StructuredName.PHONETIC_GIVEN_NAME, phoneticName);
-        }
-    }
-
-    private static void parseStructuredPostalExtra(
-            AccountType accountType, RawContactDelta state, Bundle extras) {
-        // StructuredPostal
-        final DataKind kind = accountType.getKindForMimetype(StructuredPostal.CONTENT_ITEM_TYPE);
-        final ValuesDelta child = parseExtras(state, kind, extras, Insert.POSTAL_TYPE,
-                Insert.POSTAL, StructuredPostal.FORMATTED_ADDRESS);
-        String address = child == null ? null
-                : child.getAsString(StructuredPostal.FORMATTED_ADDRESS);
-        if (!TextUtils.isEmpty(address)) {
-            boolean supportsFormatted = false;
-            if (kind.fieldList != null) {
-                for (EditField field : kind.fieldList) {
-                    if (StructuredPostal.FORMATTED_ADDRESS.equals(field.column)) {
-                        supportsFormatted = true;
-                        break;
-                    }
-                }
-            }
-
-            if (!supportsFormatted) {
-                child.put(StructuredPostal.STREET, address);
-                child.putNull(StructuredPostal.FORMATTED_ADDRESS);
-            }
-        }
-    }
-
-    private static void parseValues(
-            RawContactDelta state, AccountType accountType,
-            ArrayList<ContentValues> dataValueList) {
-        for (ContentValues values : dataValueList) {
-            String mimeType = values.getAsString(Data.MIMETYPE);
-            if (TextUtils.isEmpty(mimeType)) {
-                Log.e(TAG, "Mimetype is required. Ignoring: " + values);
-                continue;
-            }
-
-            // Won't override the contact name
-            if (StructuredName.CONTENT_ITEM_TYPE.equals(mimeType)) {
-                continue;
-            } else if (Phone.CONTENT_ITEM_TYPE.equals(mimeType)) {
-                values.remove(PhoneDataItem.KEY_FORMATTED_PHONE_NUMBER);
-                final Integer type = values.getAsInteger(Phone.TYPE);
-                // If the provided phone number provides a custom phone type but not a label,
-                // replace it with mobile (by default) to avoid the "Enter custom label" from
-                // popping up immediately upon entering the ContactEditorFragment
-                if (type != null && type == Phone.TYPE_CUSTOM &&
-                        TextUtils.isEmpty(values.getAsString(Phone.LABEL))) {
-                    values.put(Phone.TYPE, Phone.TYPE_MOBILE);
-                }
-            }
-
-            DataKind kind = accountType.getKindForMimetype(mimeType);
-            if (kind == null) {
-                Log.e(TAG, "Mimetype not supported for account type "
-                        + accountType.getAccountTypeAndDataSet() + ". Ignoring: " + values);
-                continue;
-            }
-
-            ValuesDelta entry = ValuesDelta.fromAfter(values);
-            if (isEmpty(entry, kind)) {
-                continue;
-            }
-
-            ArrayList<ValuesDelta> entries = state.getMimeEntries(mimeType);
-
-            if ((kind.typeOverallMax != 1) || GroupMembership.CONTENT_ITEM_TYPE.equals(mimeType)) {
-                // Check for duplicates
-                boolean addEntry = true;
-                int count = 0;
-                if (entries != null && entries.size() > 0) {
-                    for (ValuesDelta delta : entries) {
-                        if (!delta.isDelete()) {
-                            if (areEqual(delta, values, kind)) {
-                                addEntry = false;
-                                break;
-                            }
-                            count++;
-                        }
-                    }
-                }
-
-                if (kind.typeOverallMax != -1 && count >= kind.typeOverallMax) {
-                    Log.e(TAG, "Mimetype allows at most " + kind.typeOverallMax
-                            + " entries. Ignoring: " + values);
-                    addEntry = false;
-                }
-
-                if (addEntry) {
-                    addEntry = adjustType(entry, entries, kind);
-                }
-
-                if (addEntry) {
-                    state.addEntry(entry);
-                }
-            } else {
-                // Non-list entries should not be overridden
-                boolean addEntry = true;
-                if (entries != null && entries.size() > 0) {
-                    for (ValuesDelta delta : entries) {
-                        if (!delta.isDelete() && !isEmpty(delta, kind)) {
-                            addEntry = false;
-                            break;
-                        }
-                    }
-                    if (addEntry) {
-                        for (ValuesDelta delta : entries) {
-                            delta.markDeleted();
-                        }
-                    }
-                }
-
-                if (addEntry) {
-                    addEntry = adjustType(entry, entries, kind);
-                }
-
-                if (addEntry) {
-                    state.addEntry(entry);
-                } else if (Note.CONTENT_ITEM_TYPE.equals(mimeType)){
-                    // Note is most likely to contain large amounts of text
-                    // that we don't want to drop on the ground.
-                    for (ValuesDelta delta : entries) {
-                        if (!isEmpty(delta, kind)) {
-                            delta.put(Note.NOTE, delta.getAsString(Note.NOTE) + "\n"
-                                    + values.getAsString(Note.NOTE));
-                            break;
-                        }
-                    }
-                } else {
-                    Log.e(TAG, "Will not override mimetype " + mimeType + ". Ignoring: "
-                            + values);
-                }
-            }
-        }
-    }
-
-    /**
-     * Checks if the data kind allows addition of another entry (e.g. Exchange only
-     * supports two "work" phone numbers).  If not, tries to switch to one of the
-     * unused types.  If successful, returns true.
-     */
-    private static boolean adjustType(
-            ValuesDelta entry, ArrayList<ValuesDelta> entries, DataKind kind) {
-        if (kind.typeColumn == null || kind.typeList == null || kind.typeList.size() == 0) {
-            return true;
-        }
-
-        Integer typeInteger = entry.getAsInteger(kind.typeColumn);
-        int type = typeInteger != null ? typeInteger : kind.typeList.get(0).rawValue;
-
-        if (isTypeAllowed(type, entries, kind)) {
-            entry.put(kind.typeColumn, type);
-            return true;
-        }
-
-        // Specified type is not allowed - choose the first available type that is allowed
-        int size = kind.typeList.size();
-        for (int i = 0; i < size; i++) {
-            EditType editType = kind.typeList.get(i);
-            if (isTypeAllowed(editType.rawValue, entries, kind)) {
-                entry.put(kind.typeColumn, editType.rawValue);
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    /**
-     * Checks if a new entry of the specified type can be added to the raw
-     * contact. For example, Exchange only supports two "work" phone numbers, so
-     * addition of a third would not be allowed.
-     */
-    private static boolean isTypeAllowed(int type, ArrayList<ValuesDelta> entries, DataKind kind) {
-        int max = 0;
-        int size = kind.typeList.size();
-        for (int i = 0; i < size; i++) {
-            EditType editType = kind.typeList.get(i);
-            if (editType.rawValue == type) {
-                max = editType.specificMax;
-                break;
-            }
-        }
-
-        if (max == 0) {
-            // This type is not allowed at all
-            return false;
-        }
-
-        if (max == -1) {
-            // Unlimited instances of this type are allowed
-            return true;
-        }
-
-        return getEntryCountByType(entries, kind.typeColumn, type) < max;
-    }
-
-    /**
-     * Counts occurrences of the specified type in the supplied entry list.
-     *
-     * @return The count of occurrences of the type in the entry list. 0 if entries is
-     * {@literal null}
-     */
-    private static int getEntryCountByType(ArrayList<ValuesDelta> entries, String typeColumn,
-            int type) {
-        int count = 0;
-        if (entries != null) {
-            for (ValuesDelta entry : entries) {
-                Integer typeInteger = entry.getAsInteger(typeColumn);
-                if (typeInteger != null && typeInteger == type) {
-                    count++;
-                }
-            }
-        }
-        return count;
-    }
-
-    /**
-     * Attempt to parse legacy {@link Insert#IM_PROTOCOL} values, replacing them
-     * with updated values.
-     */
-    @SuppressWarnings("deprecation")
-    private static void fixupLegacyImType(Bundle bundle) {
-        final String encodedString = bundle.getString(Insert.IM_PROTOCOL);
-        if (encodedString == null) return;
-
-        try {
-            final Object protocol = android.provider.Contacts.ContactMethods
-                    .decodeImProtocol(encodedString);
-            if (protocol instanceof Integer) {
-                bundle.putInt(Insert.IM_PROTOCOL, (Integer)protocol);
-            } else {
-                bundle.putString(Insert.IM_PROTOCOL, (String)protocol);
-            }
-        } catch (IllegalArgumentException e) {
-            // Ignore exception when legacy parser fails
-        }
-    }
-
-    /**
-     * Parse a specific entry from the given {@link Bundle} and insert into the
-     * given {@link RawContactDelta}. Silently skips the insert when missing value
-     * or no valid {@link EditType} found.
-     *
-     * @param typeExtra {@link Bundle} key that holds the incoming
-     *            {@link EditType#rawValue} value.
-     * @param valueExtra {@link Bundle} key that holds the incoming value.
-     * @param valueColumn Column to write value into {@link ValuesDelta}.
-     */
-    public static ValuesDelta parseExtras(RawContactDelta state, DataKind kind, Bundle extras,
-            String typeExtra, String valueExtra, String valueColumn) {
-        final CharSequence value = extras.getCharSequence(valueExtra);
-
-        // Bail early if account type doesn't handle this MIME type
-        if (kind == null) return null;
-
-        // Bail when can't insert type, or value missing
-        final boolean canInsert = RawContactModifier.canInsert(state, kind);
-        final boolean validValue = (value != null && TextUtils.isGraphic(value));
-        if (!validValue || !canInsert) return null;
-
-        // Find exact type when requested, otherwise best available type
-        final boolean hasType = extras.containsKey(typeExtra);
-        final int typeValue = extras.getInt(typeExtra, hasType ? BaseTypes.TYPE_CUSTOM
-                : Integer.MIN_VALUE);
-        final EditType editType = RawContactModifier.getBestValidType(state, kind, true, typeValue);
-
-        // Create data row and fill with value
-        final ValuesDelta child = RawContactModifier.insertChild(state, kind, editType);
-        child.put(valueColumn, value.toString());
-
-        if (editType != null && editType.customColumn != null) {
-            // Write down label when custom type picked
-            final String customType = extras.getString(typeExtra);
-            child.put(editType.customColumn, customType);
-        }
-
-        return child;
-    }
-
-    /**
-     * Generic mime types with type support (e.g. TYPE_HOME).
-     * Here, "type support" means if the data kind has CommonColumns#TYPE or not. Data kinds which
-     * have their own migrate methods aren't listed here.
-     */
-    private static final Set<String> sGenericMimeTypesWithTypeSupport = new HashSet<String>(
-            Arrays.asList(Phone.CONTENT_ITEM_TYPE,
-                    Email.CONTENT_ITEM_TYPE,
-                    Im.CONTENT_ITEM_TYPE,
-                    Nickname.CONTENT_ITEM_TYPE,
-                    Website.CONTENT_ITEM_TYPE,
-                    Relation.CONTENT_ITEM_TYPE,
-                    SipAddress.CONTENT_ITEM_TYPE));
-    private static final Set<String> sGenericMimeTypesWithoutTypeSupport = new HashSet<String>(
-            Arrays.asList(Organization.CONTENT_ITEM_TYPE,
-                    Note.CONTENT_ITEM_TYPE,
-                    Photo.CONTENT_ITEM_TYPE,
-                    GroupMembership.CONTENT_ITEM_TYPE));
-    // CommonColumns.TYPE cannot be accessed as it is protected interface, so use
-    // Phone.TYPE instead.
-    private static final String COLUMN_FOR_TYPE  = Phone.TYPE;
-    private static final String COLUMN_FOR_LABEL  = Phone.LABEL;
-    private static final int TYPE_CUSTOM = Phone.TYPE_CUSTOM;
-
-    /**
-     * Migrates old RawContactDelta to newly created one with a new restriction supplied from
-     * newAccountType.
-     *
-     * This is only for account switch during account creation (which must be insert operation).
-     */
-    public static void migrateStateForNewContact(Context context,
-            RawContactDelta oldState, RawContactDelta newState,
-            AccountType oldAccountType, AccountType newAccountType) {
-        if (newAccountType == oldAccountType) {
-            // Just copying all data in oldState isn't enough, but we can still rely on a lot of
-            // shortcuts.
-            for (DataKind kind : newAccountType.getSortedDataKinds()) {
-                final String mimeType = kind.mimeType;
-                // The fields with short/long form capability must be treated properly.
-                if (StructuredName.CONTENT_ITEM_TYPE.equals(mimeType)) {
-                    migrateStructuredName(context, oldState, newState, kind);
-                } else {
-                    List<ValuesDelta> entryList = oldState.getMimeEntries(mimeType);
-                    if (entryList != null && !entryList.isEmpty()) {
-                        for (ValuesDelta entry : entryList) {
-                            ContentValues values = entry.getAfter();
-                            if (values != null) {
-                                newState.addEntry(ValuesDelta.fromAfter(values));
-                            }
-                        }
-                    }
-                }
-            }
-        } else {
-            // Migrate data supported by the new account type.
-            // All the other data inside oldState are silently dropped.
-            for (DataKind kind : newAccountType.getSortedDataKinds()) {
-                if (!kind.editable) continue;
-                final String mimeType = kind.mimeType;
-                if (DataKind.PSEUDO_MIME_TYPE_DISPLAY_NAME.equals(mimeType)
-                        || DataKind.PSEUDO_MIME_TYPE_PHONETIC_NAME.equals(mimeType)) {
-                    // Ignore pseudo data.
-                    continue;
-                } else if (StructuredName.CONTENT_ITEM_TYPE.equals(mimeType)) {
-                    migrateStructuredName(context, oldState, newState, kind);
-                } else if (StructuredPostal.CONTENT_ITEM_TYPE.equals(mimeType)) {
-                    migratePostal(oldState, newState, kind);
-                } else if (Event.CONTENT_ITEM_TYPE.equals(mimeType)) {
-                    migrateEvent(oldState, newState, kind, null /* default Year */);
-                } else if (sGenericMimeTypesWithoutTypeSupport.contains(mimeType)) {
-                    migrateGenericWithoutTypeColumn(oldState, newState, kind);
-                } else if (sGenericMimeTypesWithTypeSupport.contains(mimeType)) {
-                    migrateGenericWithTypeColumn(oldState, newState, kind);
-                } else {
-                    throw new IllegalStateException("Unexpected editable mime-type: " + mimeType);
-                }
-            }
-        }
-    }
-
-    /**
-     * Checks {@link DataKind#isList} and {@link DataKind#typeOverallMax}, and restricts
-     * the number of entries (ValuesDelta) inside newState.
-     */
-    private static ArrayList<ValuesDelta> ensureEntryMaxSize(RawContactDelta newState,
-            DataKind kind, ArrayList<ValuesDelta> mimeEntries) {
-        if (mimeEntries == null) {
-            return null;
-        }
-
-        final int typeOverallMax = kind.typeOverallMax;
-        if (typeOverallMax >= 0 && (mimeEntries.size() > typeOverallMax)) {
-            ArrayList<ValuesDelta> newMimeEntries = new ArrayList<ValuesDelta>(typeOverallMax);
-            for (int i = 0; i < typeOverallMax; i++) {
-                newMimeEntries.add(mimeEntries.get(i));
-            }
-            mimeEntries = newMimeEntries;
-        }
-        return mimeEntries;
-    }
-
-    /** @hide Public only for testing. */
-    public static void migrateStructuredName(
-            Context context, RawContactDelta oldState, RawContactDelta newState,
-            DataKind newDataKind) {
-        final ContentValues values =
-                oldState.getPrimaryEntry(StructuredName.CONTENT_ITEM_TYPE).getAfter();
-        if (values == null) {
-            return;
-        }
-
-        boolean supportDisplayName = false;
-        boolean supportPhoneticFullName = false;
-        boolean supportPhoneticFamilyName = false;
-        boolean supportPhoneticMiddleName = false;
-        boolean supportPhoneticGivenName = false;
-        for (EditField editField : newDataKind.fieldList) {
-            if (StructuredName.DISPLAY_NAME.equals(editField.column)) {
-                supportDisplayName = true;
-            }
-            if (DataKind.PSEUDO_COLUMN_PHONETIC_NAME.equals(editField.column)) {
-                supportPhoneticFullName = true;
-            }
-            if (StructuredName.PHONETIC_FAMILY_NAME.equals(editField.column)) {
-                supportPhoneticFamilyName = true;
-            }
-            if (StructuredName.PHONETIC_MIDDLE_NAME.equals(editField.column)) {
-                supportPhoneticMiddleName = true;
-            }
-            if (StructuredName.PHONETIC_GIVEN_NAME.equals(editField.column)) {
-                supportPhoneticGivenName = true;
-            }
-        }
-
-        // DISPLAY_NAME <-> PREFIX, GIVEN_NAME, MIDDLE_NAME, FAMILY_NAME, SUFFIX
-        final String displayName = values.getAsString(StructuredName.DISPLAY_NAME);
-        if (!TextUtils.isEmpty(displayName)) {
-            if (!supportDisplayName) {
-                // Old data has a display name, while the new account doesn't allow it.
-                NameConverter.displayNameToStructuredName(context, displayName, values);
-
-                // We don't want to migrate unseen data which may confuse users after the creation.
-                values.remove(StructuredName.DISPLAY_NAME);
-            }
-        } else {
-            if (supportDisplayName) {
-                // Old data does not have display name, while the new account requires it.
-                values.put(StructuredName.DISPLAY_NAME,
-                        NameConverter.structuredNameToDisplayName(context, values));
-                for (String field : NameConverter.STRUCTURED_NAME_FIELDS) {
-                    values.remove(field);
-                }
-            }
-        }
-
-        // Phonetic (full) name <-> PHONETIC_FAMILY_NAME, PHONETIC_MIDDLE_NAME, PHONETIC_GIVEN_NAME
-        final String phoneticFullName = values.getAsString(DataKind.PSEUDO_COLUMN_PHONETIC_NAME);
-        if (!TextUtils.isEmpty(phoneticFullName)) {
-            if (!supportPhoneticFullName) {
-                // Old data has a phonetic (full) name, while the new account doesn't allow it.
-                final StructuredNameDataItem tmpItem =
-                        PhoneticNameEditorView.parsePhoneticName(phoneticFullName, null);
-                values.remove(DataKind.PSEUDO_COLUMN_PHONETIC_NAME);
-                if (supportPhoneticFamilyName) {
-                    values.put(StructuredName.PHONETIC_FAMILY_NAME,
-                            tmpItem.getPhoneticFamilyName());
-                } else {
-                    values.remove(StructuredName.PHONETIC_FAMILY_NAME);
-                }
-                if (supportPhoneticMiddleName) {
-                    values.put(StructuredName.PHONETIC_MIDDLE_NAME,
-                            tmpItem.getPhoneticMiddleName());
-                } else {
-                    values.remove(StructuredName.PHONETIC_MIDDLE_NAME);
-                }
-                if (supportPhoneticGivenName) {
-                    values.put(StructuredName.PHONETIC_GIVEN_NAME,
-                            tmpItem.getPhoneticGivenName());
-                } else {
-                    values.remove(StructuredName.PHONETIC_GIVEN_NAME);
-                }
-            }
-        } else {
-            if (supportPhoneticFullName) {
-                // Old data does not have a phonetic (full) name, while the new account requires it.
-                values.put(DataKind.PSEUDO_COLUMN_PHONETIC_NAME,
-                        PhoneticNameEditorView.buildPhoneticName(
-                                values.getAsString(StructuredName.PHONETIC_FAMILY_NAME),
-                                values.getAsString(StructuredName.PHONETIC_MIDDLE_NAME),
-                                values.getAsString(StructuredName.PHONETIC_GIVEN_NAME)));
-            }
-            if (!supportPhoneticFamilyName) {
-                values.remove(StructuredName.PHONETIC_FAMILY_NAME);
-            }
-            if (!supportPhoneticMiddleName) {
-                values.remove(StructuredName.PHONETIC_MIDDLE_NAME);
-            }
-            if (!supportPhoneticGivenName) {
-                values.remove(StructuredName.PHONETIC_GIVEN_NAME);
-            }
-        }
-
-        newState.addEntry(ValuesDelta.fromAfter(values));
-    }
-
-    /** @hide Public only for testing. */
-    public static void migratePostal(RawContactDelta oldState, RawContactDelta newState,
-            DataKind newDataKind) {
-        final ArrayList<ValuesDelta> mimeEntries = ensureEntryMaxSize(newState, newDataKind,
-                oldState.getMimeEntries(StructuredPostal.CONTENT_ITEM_TYPE));
-        if (mimeEntries == null || mimeEntries.isEmpty()) {
-            return;
-        }
-
-        boolean supportFormattedAddress = false;
-        boolean supportStreet = false;
-        final String firstColumn = newDataKind.fieldList.get(0).column;
-        for (EditField editField : newDataKind.fieldList) {
-            if (StructuredPostal.FORMATTED_ADDRESS.equals(editField.column)) {
-                supportFormattedAddress = true;
-            }
-            if (StructuredPostal.STREET.equals(editField.column)) {
-                supportStreet = true;
-            }
-        }
-
-        final Set<Integer> supportedTypes = new HashSet<Integer>();
-        if (newDataKind.typeList != null && !newDataKind.typeList.isEmpty()) {
-            for (EditType editType : newDataKind.typeList) {
-                supportedTypes.add(editType.rawValue);
-            }
-        }
-
-        for (ValuesDelta entry : mimeEntries) {
-            final ContentValues values = entry.getAfter();
-            if (values == null) {
-                continue;
-            }
-            final Integer oldType = values.getAsInteger(StructuredPostal.TYPE);
-            if (!supportedTypes.contains(oldType)) {
-                int defaultType;
-                if (newDataKind.defaultValues != null) {
-                    defaultType = newDataKind.defaultValues.getAsInteger(StructuredPostal.TYPE);
-                } else {
-                    defaultType = newDataKind.typeList.get(0).rawValue;
-                }
-                values.put(StructuredPostal.TYPE, defaultType);
-                if (oldType != null && oldType == StructuredPostal.TYPE_CUSTOM) {
-                    values.remove(StructuredPostal.LABEL);
-                }
-            }
-
-            final String formattedAddress = values.getAsString(StructuredPostal.FORMATTED_ADDRESS);
-            if (!TextUtils.isEmpty(formattedAddress)) {
-                if (!supportFormattedAddress) {
-                    // Old data has a formatted address, while the new account doesn't allow it.
-                    values.remove(StructuredPostal.FORMATTED_ADDRESS);
-
-                    // Unlike StructuredName we don't have logic to split it, so first
-                    // try to use street field and. If the new account doesn't have one,
-                    // then select first one anyway.
-                    if (supportStreet) {
-                        values.put(StructuredPostal.STREET, formattedAddress);
-                    } else {
-                        values.put(firstColumn, formattedAddress);
-                    }
-                }
-            } else {
-                if (supportFormattedAddress) {
-                    // Old data does not have formatted address, while the new account requires it.
-                    // Unlike StructuredName we don't have logic to join multiple address values.
-                    // Use poor join heuristics for now.
-                    String[] structuredData;
-                    final boolean useJapaneseOrder =
-                            Locale.JAPANESE.getLanguage().equals(Locale.getDefault().getLanguage());
-                    if (useJapaneseOrder) {
-                        structuredData = new String[] {
-                                values.getAsString(StructuredPostal.COUNTRY),
-                                values.getAsString(StructuredPostal.POSTCODE),
-                                values.getAsString(StructuredPostal.REGION),
-                                values.getAsString(StructuredPostal.CITY),
-                                values.getAsString(StructuredPostal.NEIGHBORHOOD),
-                                values.getAsString(StructuredPostal.STREET),
-                                values.getAsString(StructuredPostal.POBOX) };
-                    } else {
-                        structuredData = new String[] {
-                                values.getAsString(StructuredPostal.POBOX),
-                                values.getAsString(StructuredPostal.STREET),
-                                values.getAsString(StructuredPostal.NEIGHBORHOOD),
-                                values.getAsString(StructuredPostal.CITY),
-                                values.getAsString(StructuredPostal.REGION),
-                                values.getAsString(StructuredPostal.POSTCODE),
-                                values.getAsString(StructuredPostal.COUNTRY) };
-                    }
-                    final StringBuilder builder = new StringBuilder();
-                    for (String elem : structuredData) {
-                        if (!TextUtils.isEmpty(elem)) {
-                            builder.append(elem + "\n");
-                        }
-                    }
-                    values.put(StructuredPostal.FORMATTED_ADDRESS, builder.toString());
-
-                    values.remove(StructuredPostal.POBOX);
-                    values.remove(StructuredPostal.STREET);
-                    values.remove(StructuredPostal.NEIGHBORHOOD);
-                    values.remove(StructuredPostal.CITY);
-                    values.remove(StructuredPostal.REGION);
-                    values.remove(StructuredPostal.POSTCODE);
-                    values.remove(StructuredPostal.COUNTRY);
-                }
-            }
-
-            newState.addEntry(ValuesDelta.fromAfter(values));
-        }
-    }
-
-    /** @hide Public only for testing. */
-    public static void migrateEvent(RawContactDelta oldState, RawContactDelta newState,
-            DataKind newDataKind, Integer defaultYear) {
-        final ArrayList<ValuesDelta> mimeEntries = ensureEntryMaxSize(newState, newDataKind,
-                oldState.getMimeEntries(Event.CONTENT_ITEM_TYPE));
-        if (mimeEntries == null || mimeEntries.isEmpty()) {
-            return;
-        }
-
-        final SparseArray<EventEditType> allowedTypes = new SparseArray<EventEditType>();
-        for (EditType editType : newDataKind.typeList) {
-            allowedTypes.put(editType.rawValue, (EventEditType) editType);
-        }
-        for (ValuesDelta entry : mimeEntries) {
-            final ContentValues values = entry.getAfter();
-            if (values == null) {
-                continue;
-            }
-            final String dateString = values.getAsString(Event.START_DATE);
-            final Integer type = values.getAsInteger(Event.TYPE);
-            if (type != null && (allowedTypes.indexOfKey(type) >= 0)
-                    && !TextUtils.isEmpty(dateString)) {
-                EventEditType suitableType = allowedTypes.get(type);
-
-                final ParsePosition position = new ParsePosition(0);
-                boolean yearOptional = false;
-                Date date = CommonDateUtils.DATE_AND_TIME_FORMAT.parse(dateString, position);
-                if (date == null) {
-                    yearOptional = true;
-                    date = CommonDateUtils.NO_YEAR_DATE_FORMAT.parse(dateString, position);
-                }
-                if (date != null) {
-                    if (yearOptional && !suitableType.isYearOptional()) {
-                        // The new EditType doesn't allow optional year. Supply default.
-                        final Calendar calendar = Calendar.getInstance(DateUtils.UTC_TIMEZONE,
-                                Locale.US);
-                        if (defaultYear == null) {
-                            defaultYear = calendar.get(Calendar.YEAR);
-                        }
-                        calendar.setTime(date);
-                        final int month = calendar.get(Calendar.MONTH);
-                        final int day = calendar.get(Calendar.DAY_OF_MONTH);
-                        // Exchange requires 8:00 for birthdays
-                        calendar.set(defaultYear, month, day,
-                                EventFieldEditorView.getDefaultHourForBirthday(), 0, 0);
-                        values.put(Event.START_DATE,
-                                CommonDateUtils.FULL_DATE_FORMAT.format(calendar.getTime()));
-                    }
-                }
-                newState.addEntry(ValuesDelta.fromAfter(values));
-            } else {
-                // Just drop it.
-            }
-        }
-    }
-
-    /** @hide Public only for testing. */
-    public static void migrateGenericWithoutTypeColumn(
-            RawContactDelta oldState, RawContactDelta newState, DataKind newDataKind) {
-        final ArrayList<ValuesDelta> mimeEntries = ensureEntryMaxSize(newState, newDataKind,
-                oldState.getMimeEntries(newDataKind.mimeType));
-        if (mimeEntries == null || mimeEntries.isEmpty()) {
-            return;
-        }
-
-        for (ValuesDelta entry : mimeEntries) {
-            ContentValues values = entry.getAfter();
-            if (values != null) {
-                newState.addEntry(ValuesDelta.fromAfter(values));
-            }
-        }
-    }
-
-    /** @hide Public only for testing. */
-    public static void migrateGenericWithTypeColumn(
-            RawContactDelta oldState, RawContactDelta newState, DataKind newDataKind) {
-        final ArrayList<ValuesDelta> mimeEntries = oldState.getMimeEntries(newDataKind.mimeType);
-        if (mimeEntries == null || mimeEntries.isEmpty()) {
-            return;
-        }
-
-        // Note that type specified with the old account may be invalid with the new account, while
-        // we want to preserve its data as much as possible. e.g. if a user typed a phone number
-        // with a type which is valid with an old account but not with a new account, the user
-        // probably wants to have the number with default type, rather than seeing complete data
-        // loss.
-        //
-        // Specifically, this method works as follows:
-        // 1. detect defaultType
-        // 2. prepare constants & variables for iteration
-        // 3. iterate over mimeEntries:
-        // 3.1 stop iteration if total number of mimeEntries reached typeOverallMax specified in
-        //     DataKind
-        // 3.2 replace unallowed types with defaultType
-        // 3.3 check if the number of entries is below specificMax specified in AccountType
-
-        // Here, defaultType can be supplied in two ways
-        // - via kind.defaultValues
-        // - via kind.typeList.get(0).rawValue
-        Integer defaultType = null;
-        if (newDataKind.defaultValues != null) {
-            defaultType = newDataKind.defaultValues.getAsInteger(COLUMN_FOR_TYPE);
-        }
-        final Set<Integer> allowedTypes = new HashSet<Integer>();
-        // key: type, value: the number of entries allowed for the type (specificMax)
-        final SparseIntArray typeSpecificMaxMap = new SparseIntArray();
-        if (defaultType != null) {
-            allowedTypes.add(defaultType);
-            typeSpecificMaxMap.put(defaultType, -1);
-        }
-        // Note: typeList may be used in different purposes when defaultValues are specified.
-        // Especially in IM, typeList contains available protocols (e.g. PROTOCOL_GOOGLE_TALK)
-        // instead of "types" which we want to treate here (e.g. TYPE_HOME). So we don't add
-        // anything other than defaultType into allowedTypes and typeSpecificMapMax.
-        if (!Im.CONTENT_ITEM_TYPE.equals(newDataKind.mimeType) &&
-                newDataKind.typeList != null && !newDataKind.typeList.isEmpty()) {
-            for (EditType editType : newDataKind.typeList) {
-                allowedTypes.add(editType.rawValue);
-                typeSpecificMaxMap.put(editType.rawValue, editType.specificMax);
-            }
-            if (defaultType == null) {
-                defaultType = newDataKind.typeList.get(0).rawValue;
-            }
-        }
-
-        if (defaultType == null) {
-            Log.w(TAG, "Default type isn't available for mimetype " + newDataKind.mimeType);
-        }
-
-        final int typeOverallMax = newDataKind.typeOverallMax;
-
-        // key: type, value: the number of current entries.
-        final SparseIntArray currentEntryCount = new SparseIntArray();
-        int totalCount = 0;
-
-        for (ValuesDelta entry : mimeEntries) {
-            if (typeOverallMax != -1 && totalCount >= typeOverallMax) {
-                break;
-            }
-
-            final ContentValues values = entry.getAfter();
-            if (values == null) {
-                continue;
-            }
-
-            final Integer oldType = entry.getAsInteger(COLUMN_FOR_TYPE);
-            final Integer typeForNewAccount;
-            if (!allowedTypes.contains(oldType)) {
-                // The new account doesn't support the type.
-                if (defaultType != null) {
-                    typeForNewAccount = defaultType.intValue();
-                    values.put(COLUMN_FOR_TYPE, defaultType.intValue());
-                    if (oldType != null && oldType == TYPE_CUSTOM) {
-                        values.remove(COLUMN_FOR_LABEL);
-                    }
-                } else {
-                    typeForNewAccount = null;
-                    values.remove(COLUMN_FOR_TYPE);
-                }
-            } else {
-                typeForNewAccount = oldType;
-            }
-            if (typeForNewAccount != null) {
-                final int specificMax = typeSpecificMaxMap.get(typeForNewAccount, 0);
-                if (specificMax >= 0) {
-                    final int currentCount = currentEntryCount.get(typeForNewAccount, 0);
-                    if (currentCount >= specificMax) {
-                        continue;
-                    }
-                    currentEntryCount.put(typeForNewAccount, currentCount + 1);
-                }
-            }
-            newState.addEntry(ValuesDelta.fromAfter(values));
-            totalCount++;
-        }
-    }
-}
diff --git a/src/com/android/contacts/model/dataitem/DataItem.java b/src/com/android/contacts/model/dataitem/DataItem.java
deleted file mode 100644
index 36f3cb2..0000000
--- a/src/com/android/contacts/model/dataitem/DataItem.java
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Copyright (C) 2012 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.contacts.model.dataitem;
-
-import android.content.ContentValues;
-import android.content.Context;
-import android.provider.ContactsContract.CommonDataKinds.Email;
-import android.provider.ContactsContract.CommonDataKinds.Event;
-import android.provider.ContactsContract.CommonDataKinds.GroupMembership;
-import android.provider.ContactsContract.CommonDataKinds.Identity;
-import android.provider.ContactsContract.CommonDataKinds.Im;
-import android.provider.ContactsContract.CommonDataKinds.Nickname;
-import android.provider.ContactsContract.CommonDataKinds.Note;
-import android.provider.ContactsContract.CommonDataKinds.Organization;
-import android.provider.ContactsContract.CommonDataKinds.Phone;
-import android.provider.ContactsContract.CommonDataKinds.Photo;
-import android.provider.ContactsContract.CommonDataKinds.Relation;
-import android.provider.ContactsContract.CommonDataKinds.SipAddress;
-import android.provider.ContactsContract.CommonDataKinds.StructuredName;
-import android.provider.ContactsContract.CommonDataKinds.StructuredPostal;
-import android.provider.ContactsContract.CommonDataKinds.Website;
-import android.provider.ContactsContract.Contacts.Data;
-
-import com.android.contacts.common.model.dataitem.DataKind;
-
-/**
- * This is the base class for data items, which represents a row from the Data table.
- */
-public class DataItem {
-
-    private final ContentValues mContentValues;
-
-    protected DataItem(ContentValues values) {
-        mContentValues = values;
-    }
-
-    /**
-     * Factory for creating subclasses of DataItem objects based on the mimetype in the
-     * content values.  Raw contact is the raw contact that this data item is associated with.
-     */
-    public static DataItem createFrom(ContentValues values) {
-        final String mimeType = values.getAsString(Data.MIMETYPE);
-        if (GroupMembership.CONTENT_ITEM_TYPE.equals(mimeType)) {
-            return new GroupMembershipDataItem(values);
-        } else if (StructuredName.CONTENT_ITEM_TYPE.equals(mimeType)) {
-            return new StructuredNameDataItem(values);
-        } else if (Phone.CONTENT_ITEM_TYPE.equals(mimeType)) {
-            return new PhoneDataItem(values);
-        } else if (Email.CONTENT_ITEM_TYPE.equals(mimeType)) {
-            return new EmailDataItem(values);
-        } else if (StructuredPostal.CONTENT_ITEM_TYPE.equals(mimeType)) {
-            return new StructuredPostalDataItem(values);
-        } else if (Im.CONTENT_ITEM_TYPE.equals(mimeType)) {
-            return new ImDataItem(values);
-        } else if (Organization.CONTENT_ITEM_TYPE.equals(mimeType)) {
-            return new OrganizationDataItem(values);
-        } else if (Nickname.CONTENT_ITEM_TYPE.equals(mimeType)) {
-            return new NicknameDataItem(values);
-        } else if (Note.CONTENT_ITEM_TYPE.equals(mimeType)) {
-            return new NoteDataItem(values);
-        } else if (Website.CONTENT_ITEM_TYPE.equals(mimeType)) {
-            return new WebsiteDataItem(values);
-        } else if (SipAddress.CONTENT_ITEM_TYPE.equals(mimeType)) {
-            return new SipAddressDataItem(values);
-        } else if (Event.CONTENT_ITEM_TYPE.equals(mimeType)) {
-            return new EventDataItem(values);
-        } else if (Relation.CONTENT_ITEM_TYPE.equals(mimeType)) {
-            return new RelationDataItem(values);
-        } else if (Identity.CONTENT_ITEM_TYPE.equals(mimeType)) {
-            return new IdentityDataItem(values);
-        } else if (Photo.CONTENT_ITEM_TYPE.equals(mimeType)) {
-            return new PhotoDataItem(values);
-        }
-
-        // generic
-        return new DataItem(values);
-    }
-
-    public ContentValues getContentValues() {
-        return mContentValues;
-    }
-
-    public void setRawContactId(long rawContactId) {
-        mContentValues.put(Data.RAW_CONTACT_ID, rawContactId);
-    }
-
-    /**
-     * Returns the data id.
-     */
-    public long getId() {
-        return mContentValues.getAsLong(Data._ID);
-    }
-
-    /**
-     * Returns the mimetype of the data.
-     */
-    public String getMimeType() {
-        return mContentValues.getAsString(Data.MIMETYPE);
-    }
-
-    public void setMimeType(String mimeType) {
-        mContentValues.put(Data.MIMETYPE, mimeType);
-    }
-
-    public boolean isPrimary() {
-        Integer primary = mContentValues.getAsInteger(Data.IS_PRIMARY);
-        return primary != null && primary != 0;
-    }
-
-    public boolean isSuperPrimary() {
-        Integer superPrimary = mContentValues.getAsInteger(Data.IS_SUPER_PRIMARY);
-        return superPrimary != null && superPrimary != 0;
-    }
-
-    public boolean hasKindTypeColumn(DataKind kind) {
-        final String key = kind.typeColumn;
-        return key != null && mContentValues.containsKey(key) &&
-            mContentValues.getAsInteger(key) != null;
-    }
-
-    public int getKindTypeColumn(DataKind kind) {
-        final String key = kind.typeColumn;
-        return mContentValues.getAsInteger(key);
-    }
-
-    /**
-     * This builds the data string depending on the type of data item by using the generic
-     * DataKind object underneath.
-     */
-    public String buildDataString(Context context, DataKind kind) {
-        if (kind.actionBody == null) {
-            return null;
-        }
-        CharSequence actionBody = kind.actionBody.inflateUsing(context, mContentValues);
-        return actionBody == null ? null : actionBody.toString();
-    }
-
-    /**
-     * This builds the data string(intended for display) depending on the type of data item. It
-     * returns the same value as {@link #buildDataString} by default, but certain data items can
-     * override it to provide their version of formatted data strings.
-     *
-     * @return Data string representing the data item, possibly formatted for display
-     */
-    public String buildDataStringForDisplay(Context context, DataKind kind) {
-        return buildDataString(context, kind);
-    }
-}
diff --git a/src/com/android/contacts/model/dataitem/EmailDataItem.java b/src/com/android/contacts/model/dataitem/EmailDataItem.java
deleted file mode 100644
index 77ad126..0000000
--- a/src/com/android/contacts/model/dataitem/EmailDataItem.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2012 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.contacts.model.dataitem;
-
-import android.content.ContentValues;
-import android.provider.ContactsContract;
-import android.provider.ContactsContract.CommonDataKinds.Email;
-
-/**
- * Represents an email data item, wrapping the columns in
- * {@link ContactsContract.CommonDataKinds.Email}.
- */
-public class EmailDataItem extends DataItem {
-
-    /* package */ EmailDataItem(ContentValues values) {
-        super(values);
-    }
-
-    public String getAddress() {
-        return getContentValues().getAsString(Email.ADDRESS);
-    }
-
-    public String getDisplayName() {
-        return getContentValues().getAsString(Email.DISPLAY_NAME);
-    }
-
-    public String getData() {
-        return getContentValues().getAsString(Email.DATA);
-    }
-
-    public String getLabel() {
-        return getContentValues().getAsString(Email.LABEL);
-    }
-}
diff --git a/src/com/android/contacts/model/dataitem/EventDataItem.java b/src/com/android/contacts/model/dataitem/EventDataItem.java
deleted file mode 100644
index 9820c8f..0000000
--- a/src/com/android/contacts/model/dataitem/EventDataItem.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2012 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.contacts.model.dataitem;
-
-import android.content.ContentValues;
-import android.provider.ContactsContract;
-import android.provider.ContactsContract.CommonDataKinds.Event;
-
-/**
- * Represents an event data item, wrapping the columns in
- * {@link ContactsContract.CommonDataKinds.Event}.
- */
-public class EventDataItem extends DataItem {
-
-    /* package */ EventDataItem(ContentValues values) {
-        super(values);
-    }
-
-    public String getStartDate() {
-        return getContentValues().getAsString(Event.START_DATE);
-    }
-
-    public String getLabel() {
-        return getContentValues().getAsString(Event.LABEL);
-    }
-}
diff --git a/src/com/android/contacts/model/dataitem/GroupMembershipDataItem.java b/src/com/android/contacts/model/dataitem/GroupMembershipDataItem.java
deleted file mode 100644
index 00558d0..0000000
--- a/src/com/android/contacts/model/dataitem/GroupMembershipDataItem.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2012 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.contacts.model.dataitem;
-
-import android.content.ContentValues;
-import android.provider.ContactsContract;
-import android.provider.ContactsContract.CommonDataKinds.GroupMembership;
-
-/**
- * Represents a group memebership data item, wrapping the columns in
- * {@link ContactsContract.CommonDataKinds.GroupMembership}.
- */
-public class GroupMembershipDataItem extends DataItem {
-
-    /* package */ GroupMembershipDataItem(ContentValues values) {
-        super(values);
-    }
-
-    public Long getGroupRowId() {
-        return getContentValues().getAsLong(GroupMembership.GROUP_ROW_ID);
-    }
-
-    public String getGroupSourceId() {
-        return getContentValues().getAsString(GroupMembership.GROUP_SOURCE_ID);
-    }
-}
diff --git a/src/com/android/contacts/model/dataitem/IdentityDataItem.java b/src/com/android/contacts/model/dataitem/IdentityDataItem.java
deleted file mode 100644
index 045867a..0000000
--- a/src/com/android/contacts/model/dataitem/IdentityDataItem.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2012 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.contacts.model.dataitem;
-
-import android.content.ContentValues;
-import android.provider.ContactsContract;
-import android.provider.ContactsContract.CommonDataKinds.Identity;
-
-/**
- * Represents an identity data item, wrapping the columns in
- * {@link ContactsContract.CommonDataKinds.Identity}.
- */
-public class IdentityDataItem extends DataItem {
-
-    /* package */ IdentityDataItem(ContentValues values) {
-        super(values);
-    }
-
-    public String getIdentity() {
-        return getContentValues().getAsString(Identity.IDENTITY);
-    }
-
-    public String getNamespace() {
-        return getContentValues().getAsString(Identity.NAMESPACE);
-    }
-}
diff --git a/src/com/android/contacts/model/dataitem/ImDataItem.java b/src/com/android/contacts/model/dataitem/ImDataItem.java
deleted file mode 100644
index 2513b57..0000000
--- a/src/com/android/contacts/model/dataitem/ImDataItem.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2012 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.contacts.model.dataitem;
-
-import android.content.ContentValues;
-import android.provider.ContactsContract;
-import android.provider.ContactsContract.CommonDataKinds.Email;
-import android.provider.ContactsContract.CommonDataKinds.Im;
-
-/**
- * Represents an IM data item, wrapping the columns in
- * {@link ContactsContract.CommonDataKinds.Im}.
- */
-public class ImDataItem extends DataItem {
-
-    private final boolean mCreatedFromEmail;
-
-    /* package */ ImDataItem(ContentValues values) {
-        super(values);
-        mCreatedFromEmail = false;
-    }
-
-    private ImDataItem(ContentValues values, boolean createdFromEmail) {
-        super(values);
-        mCreatedFromEmail = createdFromEmail;
-    }
-
-    public static ImDataItem createFromEmail(EmailDataItem item) {
-        ImDataItem im = new ImDataItem(new ContentValues(item.getContentValues()), true);
-        im.setMimeType(Im.CONTENT_ITEM_TYPE);
-        return im;
-    }
-
-    public String getData() {
-        if (mCreatedFromEmail) {
-            return getContentValues().getAsString(Email.DATA);
-        } else {
-            return getContentValues().getAsString(Im.DATA);
-        }
-    }
-
-    public String getLabel() {
-        return getContentValues().getAsString(Im.LABEL);
-    }
-
-    /**
-     * Values are one of Im.PROTOCOL_
-     */
-    public Integer getProtocol() {
-        return getContentValues().getAsInteger(Im.PROTOCOL);
-    }
-
-    public boolean isProtocolValid() {
-        return getProtocol() != null;
-    }
-
-    public String getCustomProtocol() {
-        return getContentValues().getAsString(Im.CUSTOM_PROTOCOL);
-    }
-
-    public int getChatCapability() {
-        Integer result = getContentValues().getAsInteger(Im.CHAT_CAPABILITY);
-        return result == null ? 0 : result;
-    }
-
-    public boolean isCreatedFromEmail() {
-        return mCreatedFromEmail;
-    }
-}
diff --git a/src/com/android/contacts/model/dataitem/NicknameDataItem.java b/src/com/android/contacts/model/dataitem/NicknameDataItem.java
deleted file mode 100644
index 2d44751..0000000
--- a/src/com/android/contacts/model/dataitem/NicknameDataItem.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2012 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.contacts.model.dataitem;
-
-import android.content.ContentValues;
-import android.provider.ContactsContract;
-import android.provider.ContactsContract.CommonDataKinds.Nickname;
-
-/**
- * Represents a nickname data item, wrapping the columns in
- * {@link ContactsContract.CommonDataKinds.Nickname}.
- */
-public class NicknameDataItem extends DataItem {
-
-    public NicknameDataItem(ContentValues values) {
-        super(values);
-    }
-
-    public String getName() {
-        return getContentValues().getAsString(Nickname.NAME);
-    }
-
-    public String getLabel() {
-        return getContentValues().getAsString(Nickname.LABEL);
-    }
-}
diff --git a/src/com/android/contacts/model/dataitem/NoteDataItem.java b/src/com/android/contacts/model/dataitem/NoteDataItem.java
deleted file mode 100644
index 9a572cb..0000000
--- a/src/com/android/contacts/model/dataitem/NoteDataItem.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2012 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.contacts.model.dataitem;
-
-import android.content.ContentValues;
-import android.provider.ContactsContract;
-import android.provider.ContactsContract.CommonDataKinds.Note;
-
-/**
- * Represents a note data item, wrapping the columns in
- * {@link ContactsContract.CommonDataKinds.Note}.
- */
-public class NoteDataItem extends DataItem {
-
-    /* package */ NoteDataItem(ContentValues values) {
-        super(values);
-    }
-
-    public String getNote() {
-        return getContentValues().getAsString(Note.NOTE);
-    }
-}
diff --git a/src/com/android/contacts/model/dataitem/OrganizationDataItem.java b/src/com/android/contacts/model/dataitem/OrganizationDataItem.java
deleted file mode 100644
index e5b142e..0000000
--- a/src/com/android/contacts/model/dataitem/OrganizationDataItem.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2012 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.contacts.model.dataitem;
-
-import android.content.ContentValues;
-import android.provider.ContactsContract;
-import android.provider.ContactsContract.CommonDataKinds.Organization;
-
-/**
- * Represents an organization data item, wrapping the columns in
- * {@link ContactsContract.CommonDataKinds.Organization}.
- */
-public class OrganizationDataItem extends DataItem {
-
-    /* package */ OrganizationDataItem(ContentValues values) {
-        super(values);
-    }
-
-    public String getCompany() {
-        return getContentValues().getAsString(Organization.COMPANY);
-    }
-
-    public String getLabel() {
-        return getContentValues().getAsString(Organization.LABEL);
-    }
-
-    public String getTitle() {
-        return getContentValues().getAsString(Organization.TITLE);
-    }
-
-    public String getDepartment() {
-        return getContentValues().getAsString(Organization.DEPARTMENT);
-    }
-
-    public String getJobDescription() {
-        return getContentValues().getAsString(Organization.JOB_DESCRIPTION);
-    }
-
-    public String getSymbol() {
-        return getContentValues().getAsString(Organization.SYMBOL);
-    }
-
-    public String getPhoneticName() {
-        return getContentValues().getAsString(Organization.PHONETIC_NAME);
-    }
-
-    public String getOfficeLocation() {
-        return getContentValues().getAsString(Organization.OFFICE_LOCATION);
-    }
-
-    public String getPhoneticNameStyle() {
-        return getContentValues().getAsString(Organization.PHONETIC_NAME_STYLE);
-    }
-}
diff --git a/src/com/android/contacts/model/dataitem/PhoneDataItem.java b/src/com/android/contacts/model/dataitem/PhoneDataItem.java
deleted file mode 100644
index 9196369..0000000
--- a/src/com/android/contacts/model/dataitem/PhoneDataItem.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2012 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.contacts.model.dataitem;
-
-import android.content.ContentValues;
-import android.content.Context;
-import android.provider.ContactsContract;
-import android.provider.ContactsContract.CommonDataKinds.Phone;
-import android.telephony.PhoneNumberUtils;
-
-import com.android.contacts.common.model.dataitem.DataKind;
-
-/**
- * Represents a phone data item, wrapping the columns in
- * {@link ContactsContract.CommonDataKinds.Phone}.
- */
-public class PhoneDataItem extends DataItem {
-
-    public static final String KEY_FORMATTED_PHONE_NUMBER = "formattedPhoneNumber";
-
-    /* package */ PhoneDataItem(ContentValues values) {
-        super(values);
-    }
-
-    public String getNumber() {
-        return getContentValues().getAsString(Phone.NUMBER);
-    }
-
-    /**
-     * Returns the normalized phone number in E164 format.
-     */
-    public String getNormalizedNumber() {
-        return getContentValues().getAsString(Phone.NORMALIZED_NUMBER);
-    }
-
-    public String getFormattedPhoneNumber() {
-        return getContentValues().getAsString(KEY_FORMATTED_PHONE_NUMBER);
-    }
-
-    public String getLabel() {
-        return getContentValues().getAsString(Phone.LABEL);
-    }
-
-    public void computeFormattedPhoneNumber(String defaultCountryIso) {
-        final String phoneNumber = getNumber();
-        if (phoneNumber != null) {
-            final String formattedPhoneNumber = PhoneNumberUtils.formatNumber(phoneNumber,
-                    getNormalizedNumber(), defaultCountryIso);
-            getContentValues().put(KEY_FORMATTED_PHONE_NUMBER, formattedPhoneNumber);
-        }
-    }
-
-    /**
-     * Returns the formatted phone number (if already computed using {@link
-     * #computeFormattedPhoneNumber}). Otherwise this method returns the unformatted phone number.
-     */
-    @Override
-    public String buildDataStringForDisplay(Context context, DataKind kind) {
-        final String formatted = getFormattedPhoneNumber();
-        if (formatted != null) {
-            return formatted;
-        } else {
-            return getNumber();
-        }
-    }
-}
diff --git a/src/com/android/contacts/model/dataitem/PhotoDataItem.java b/src/com/android/contacts/model/dataitem/PhotoDataItem.java
deleted file mode 100644
index 2ba13fb..0000000
--- a/src/com/android/contacts/model/dataitem/PhotoDataItem.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2012 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.contacts.model.dataitem;
-
-import android.content.ContentValues;
-import android.provider.ContactsContract;
-import android.provider.ContactsContract.Contacts.Photo;
-
-/**
- * Represents a photo data item, wrapping the columns in
- * {@link ContactsContract.Contacts.Photo}.
- */
-public class PhotoDataItem extends DataItem {
-
-    /* package */ PhotoDataItem(ContentValues values) {
-        super(values);
-    }
-
-    public Long getPhotoFileId() {
-        return getContentValues().getAsLong(Photo.PHOTO_FILE_ID);
-    }
-
-    public byte[] getPhoto() {
-        return getContentValues().getAsByteArray(Photo.PHOTO);
-    }
-}
diff --git a/src/com/android/contacts/model/dataitem/RelationDataItem.java b/src/com/android/contacts/model/dataitem/RelationDataItem.java
deleted file mode 100644
index 4e11ecb..0000000
--- a/src/com/android/contacts/model/dataitem/RelationDataItem.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2012 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.contacts.model.dataitem;
-
-import android.content.ContentValues;
-import android.provider.ContactsContract;
-import android.provider.ContactsContract.CommonDataKinds.Relation;
-
-/**
- * Represents a relation data item, wrapping the columns in
- * {@link ContactsContract.CommonDataKinds.Relation}.
- */
-public class RelationDataItem extends DataItem {
-
-    /* package */ RelationDataItem(ContentValues values) {
-        super(values);
-    }
-
-    public String getName() {
-        return getContentValues().getAsString(Relation.NAME);
-    }
-
-    public String getLabel() {
-        return getContentValues().getAsString(Relation.LABEL);
-    }
-}
diff --git a/src/com/android/contacts/model/dataitem/SipAddressDataItem.java b/src/com/android/contacts/model/dataitem/SipAddressDataItem.java
deleted file mode 100644
index 45ebeee..0000000
--- a/src/com/android/contacts/model/dataitem/SipAddressDataItem.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2012 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.contacts.model.dataitem;
-
-import android.content.ContentValues;
-import android.provider.ContactsContract;
-import android.provider.ContactsContract.CommonDataKinds.SipAddress;
-
-/**
- * Represents a sip address data item, wrapping the columns in
- * {@link ContactsContract.CommonDataKinds.SipAddress}.
- */
-public class SipAddressDataItem extends DataItem {
-
-    /* package */ SipAddressDataItem(ContentValues values) {
-        super(values);
-    }
-
-    public String getSipAddress() {
-        return getContentValues().getAsString(SipAddress.SIP_ADDRESS);
-    }
-
-    public String getLabel() {
-        return getContentValues().getAsString(SipAddress.LABEL);
-    }
-}
diff --git a/src/com/android/contacts/model/dataitem/StructuredNameDataItem.java b/src/com/android/contacts/model/dataitem/StructuredNameDataItem.java
deleted file mode 100644
index 7d1a44d..0000000
--- a/src/com/android/contacts/model/dataitem/StructuredNameDataItem.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright (C) 2012 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.contacts.model.dataitem;
-
-import android.content.ContentValues;
-import android.provider.ContactsContract;
-import android.provider.ContactsContract.CommonDataKinds.StructuredName;
-import android.provider.ContactsContract.Contacts.Data;
-
-/**
- * Represents a structured name data item, wrapping the columns in
- * {@link ContactsContract.CommonDataKinds.StructuredName}.
- */
-public class StructuredNameDataItem extends DataItem {
-
-    public StructuredNameDataItem() {
-        super(new ContentValues());
-        getContentValues().put(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE);
-    }
-
-    /* package */ StructuredNameDataItem(ContentValues values) {
-        super(values);
-    }
-
-    public String getDisplayName() {
-        return getContentValues().getAsString(StructuredName.DISPLAY_NAME);
-    }
-
-    public void setDisplayName(String name) {
-        getContentValues().put(StructuredName.DISPLAY_NAME, name);
-    }
-
-    public String getGivenName() {
-        return getContentValues().getAsString(StructuredName.GIVEN_NAME);
-    }
-
-    public String getFamilyName() {
-        return getContentValues().getAsString(StructuredName.FAMILY_NAME);
-    }
-
-    public String getPrefix() {
-        return getContentValues().getAsString(StructuredName.PREFIX);
-    }
-
-    public String getMiddleName() {
-        return getContentValues().getAsString(StructuredName.MIDDLE_NAME);
-    }
-
-    public String getSuffix() {
-        return getContentValues().getAsString(StructuredName.SUFFIX);
-    }
-
-    public String getPhoneticGivenName() {
-        return getContentValues().getAsString(StructuredName.PHONETIC_GIVEN_NAME);
-    }
-
-    public String getPhoneticMiddleName() {
-        return getContentValues().getAsString(StructuredName.PHONETIC_MIDDLE_NAME);
-    }
-
-    public String getPhoneticFamilyName() {
-        return getContentValues().getAsString(StructuredName.PHONETIC_FAMILY_NAME);
-    }
-
-    public String getFullNameStyle() {
-        return getContentValues().getAsString(StructuredName.FULL_NAME_STYLE);
-    }
-
-    public String getPhoneticNameStyle() {
-        return getContentValues().getAsString(StructuredName.PHONETIC_NAME_STYLE);
-    }
-
-    public void setPhoneticFamilyName(String name) {
-        getContentValues().put(StructuredName.PHONETIC_FAMILY_NAME, name);
-    }
-
-    public void setPhoneticMiddleName(String name) {
-        getContentValues().put(StructuredName.PHONETIC_MIDDLE_NAME, name);
-    }
-
-    public void setPhoneticGivenName(String name) {
-        getContentValues().put(StructuredName.PHONETIC_GIVEN_NAME, name);
-    }
-}
diff --git a/src/com/android/contacts/model/dataitem/StructuredPostalDataItem.java b/src/com/android/contacts/model/dataitem/StructuredPostalDataItem.java
deleted file mode 100644
index cf46c07..0000000
--- a/src/com/android/contacts/model/dataitem/StructuredPostalDataItem.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2012 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.contacts.model.dataitem;
-
-import android.content.ContentValues;
-import android.provider.ContactsContract;
-import android.provider.ContactsContract.CommonDataKinds.StructuredPostal;
-
-/**
- * Represents a structured postal data item, wrapping the columns in
- * {@link ContactsContract.CommonDataKinds.StructuredPostal}.
- */
-public class StructuredPostalDataItem extends DataItem {
-
-    /* package */ StructuredPostalDataItem(ContentValues values) {
-        super(values);
-    }
-
-    public String getFormattedAddress() {
-        return getContentValues().getAsString(StructuredPostal.FORMATTED_ADDRESS);
-    }
-
-    public String getLabel() {
-        return getContentValues().getAsString(StructuredPostal.LABEL);
-    }
-
-    public String getStreet() {
-        return getContentValues().getAsString(StructuredPostal.STREET);
-    }
-
-    public String getPOBox() {
-        return getContentValues().getAsString(StructuredPostal.POBOX);
-    }
-
-    public String getNeighborhood() {
-        return getContentValues().getAsString(StructuredPostal.NEIGHBORHOOD);
-    }
-
-    public String getCity() {
-        return getContentValues().getAsString(StructuredPostal.CITY);
-    }
-
-    public String getRegion() {
-        return getContentValues().getAsString(StructuredPostal.REGION);
-    }
-
-    public String getPostcode() {
-        return getContentValues().getAsString(StructuredPostal.POSTCODE);
-    }
-
-    public String getCountry() {
-        return getContentValues().getAsString(StructuredPostal.COUNTRY);
-    }
-}
diff --git a/src/com/android/contacts/model/dataitem/WebsiteDataItem.java b/src/com/android/contacts/model/dataitem/WebsiteDataItem.java
deleted file mode 100644
index 4439be7..0000000
--- a/src/com/android/contacts/model/dataitem/WebsiteDataItem.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2012 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.contacts.model.dataitem;
-
-import android.content.ContentValues;
-import android.provider.ContactsContract;
-import android.provider.ContactsContract.CommonDataKinds.Website;
-
-/**
- * Represents a website data item, wrapping the columns in
- * {@link ContactsContract.CommonDataKinds.Website}.
- */
-public class WebsiteDataItem extends DataItem {
-
-    /* package */ WebsiteDataItem(ContentValues values) {
-        super(values);
-    }
-
-    public String getUrl() {
-        return getContentValues().getAsString(Website.URL);
-    }
-
-    public String getLabel() {
-        return getContentValues().getAsString(Website.LABEL);
-    }
-}
diff --git a/src/com/android/contacts/quickcontact/DataAction.java b/src/com/android/contacts/quickcontact/DataAction.java
index 0e3495c..e29b3ef 100644
--- a/src/com/android/contacts/quickcontact/DataAction.java
+++ b/src/com/android/contacts/quickcontact/DataAction.java
@@ -30,18 +30,18 @@
 import android.util.Log;
 
 import com.android.contacts.common.CallUtil;
-import com.android.contacts.ContactsUtils;
+import com.android.contacts.common.ContactsUtils;
 import com.android.contacts.R;
 import com.android.contacts.common.MoreContactUtils;
 import com.android.contacts.common.model.account.AccountType.EditType;
-import com.android.contacts.model.dataitem.DataItem;
+import com.android.contacts.common.model.dataitem.DataItem;
 import com.android.contacts.common.model.dataitem.DataKind;
-import com.android.contacts.model.dataitem.EmailDataItem;
-import com.android.contacts.model.dataitem.ImDataItem;
-import com.android.contacts.model.dataitem.PhoneDataItem;
-import com.android.contacts.model.dataitem.SipAddressDataItem;
-import com.android.contacts.model.dataitem.StructuredPostalDataItem;
-import com.android.contacts.model.dataitem.WebsiteDataItem;
+import com.android.contacts.common.model.dataitem.EmailDataItem;
+import com.android.contacts.common.model.dataitem.ImDataItem;
+import com.android.contacts.common.model.dataitem.PhoneDataItem;
+import com.android.contacts.common.model.dataitem.SipAddressDataItem;
+import com.android.contacts.common.model.dataitem.StructuredPostalDataItem;
+import com.android.contacts.common.model.dataitem.WebsiteDataItem;
 import com.android.contacts.util.PhoneCapabilityTester;
 import com.android.contacts.util.StructuredPostalUtils;
 
diff --git a/src/com/android/contacts/quickcontact/QuickContactActivity.java b/src/com/android/contacts/quickcontact/QuickContactActivity.java
index c7d6e51..0ff7a8d 100644
--- a/src/com/android/contacts/quickcontact/QuickContactActivity.java
+++ b/src/com/android/contacts/quickcontact/QuickContactActivity.java
@@ -63,17 +63,17 @@
 import com.android.contacts.common.Collapser;
 import com.android.contacts.R;
 import com.android.contacts.common.model.AccountTypeManager;
-import com.android.contacts.model.Contact;
-import com.android.contacts.model.ContactLoader;
-import com.android.contacts.model.RawContact;
+import com.android.contacts.common.model.Contact;
+import com.android.contacts.common.model.ContactLoader;
+import com.android.contacts.common.model.RawContact;
 import com.android.contacts.common.model.account.AccountType;
-import com.android.contacts.model.dataitem.DataItem;
+import com.android.contacts.common.model.dataitem.DataItem;
 import com.android.contacts.common.model.dataitem.DataKind;
-import com.android.contacts.model.dataitem.EmailDataItem;
-import com.android.contacts.model.dataitem.ImDataItem;
+import com.android.contacts.common.model.dataitem.EmailDataItem;
+import com.android.contacts.common.model.dataitem.ImDataItem;
 import com.android.contacts.common.util.Constants;
+import com.android.contacts.common.util.DataStatus;
 import com.android.contacts.common.util.UriUtils;
-import com.android.contacts.util.DataStatus;
 import com.android.contacts.util.ImageViewDrawableSetter;
 import com.android.contacts.util.SchedulingUtils;
 import com.android.contacts.common.util.StopWatch;
diff --git a/src/com/android/contacts/test/InjectedServices.java b/src/com/android/contacts/test/InjectedServices.java
deleted file mode 100644
index 4dd955f..0000000
--- a/src/com/android/contacts/test/InjectedServices.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2010 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.contacts.test;
-
-import android.content.ContentResolver;
-import android.content.SharedPreferences;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.collect.Maps;
-
-import java.util.HashMap;
-
-/**
- * A mechanism for providing alternative (mock) services to the application
- * while running tests. Activities, Services and the Application should check
- * with this class to see if a particular service has been overridden.
- */
-public class InjectedServices {
-
-    private ContentResolver mContentResolver;
-    private SharedPreferences mSharedPreferences;
-    private HashMap<String, Object> mSystemServices;
-
-    @VisibleForTesting
-    public void setContentResolver(ContentResolver contentResolver) {
-        this.mContentResolver = contentResolver;
-    }
-
-    public ContentResolver getContentResolver() {
-        return mContentResolver;
-    }
-
-    @VisibleForTesting
-    public void setSharedPreferences(SharedPreferences sharedPreferences) {
-        this.mSharedPreferences = sharedPreferences;
-    }
-
-    public SharedPreferences getSharedPreferences() {
-        return mSharedPreferences;
-    }
-
-    @VisibleForTesting
-    public void setSystemService(String name, Object service) {
-        if (mSystemServices == null) {
-            mSystemServices = Maps.newHashMap();
-        }
-
-        mSystemServices.put(name, service);
-    }
-
-    public Object getSystemService(String name) {
-        if (mSystemServices != null) {
-            return mSystemServices.get(name);
-        }
-        return null;
-    }
-}
diff --git a/src/com/android/contacts/util/ContactBadgeUtil.java b/src/com/android/contacts/util/ContactBadgeUtil.java
index fa1a60c..82a6820 100644
--- a/src/com/android/contacts/util/ContactBadgeUtil.java
+++ b/src/com/android/contacts/util/ContactBadgeUtil.java
@@ -27,6 +27,7 @@
 import android.util.Log;
 
 import com.android.contacts.common.ContactPhotoManager;
+import com.android.contacts.util.StreamItemEntry;
 import com.android.contacts.R;
 
 /**
diff --git a/src/com/android/contacts/util/ContactLoaderUtils.java b/src/com/android/contacts/util/ContactLoaderUtils.java
deleted file mode 100644
index 91c683f..0000000
--- a/src/com/android/contacts/util/ContactLoaderUtils.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (C) 2011 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.contacts.util;
-
-import android.content.ContentResolver;
-import android.content.ContentUris;
-import android.net.Uri;
-import android.provider.Contacts;
-import android.provider.ContactsContract;
-import android.provider.ContactsContract.RawContacts;
-
-/**
- * Utility methods for the {@link ContactLoader}.
- */
-public final class ContactLoaderUtils {
-
-    /** Static helper, not instantiable. */
-    private ContactLoaderUtils() {}
-
-    /**
-     * Transforms the given Uri and returns a Lookup-Uri that represents the contact.
-     * For legacy contacts, a raw-contact lookup is performed. An {@link IllegalArgumentException}
-     * can be thrown if the URI is null or the authority is not recognized.
-     *
-     * Do not call from the UI thread.
-     */
-    @SuppressWarnings("deprecation")
-    public static Uri ensureIsContactUri(final ContentResolver resolver, final Uri uri)
-            throws IllegalArgumentException {
-        if (uri == null) throw new IllegalArgumentException("uri must not be null");
-
-        final String authority = uri.getAuthority();
-
-        // Current Style Uri?
-        if (ContactsContract.AUTHORITY.equals(authority)) {
-            final String type = resolver.getType(uri);
-            // Contact-Uri? Good, return it
-            if (ContactsContract.Contacts.CONTENT_ITEM_TYPE.equals(type)) {
-                return uri;
-            }
-
-            // RawContact-Uri? Transform it to ContactUri
-            if (RawContacts.CONTENT_ITEM_TYPE.equals(type)) {
-                final long rawContactId = ContentUris.parseId(uri);
-                return RawContacts.getContactLookupUri(resolver,
-                        ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId));
-            }
-
-            // Anything else? We don't know what this is
-            throw new IllegalArgumentException("uri format is unknown");
-        }
-
-        // Legacy Style? Convert to RawContact
-        final String OBSOLETE_AUTHORITY = Contacts.AUTHORITY;
-        if (OBSOLETE_AUTHORITY.equals(authority)) {
-            // Legacy Format. Convert to RawContact-Uri and then lookup the contact
-            final long rawContactId = ContentUris.parseId(uri);
-            return RawContacts.getContactLookupUri(resolver,
-                    ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId));
-        }
-
-        throw new IllegalArgumentException("uri authority is unknown");
-    }
-}
diff --git a/src/com/android/contacts/util/DataStatus.java b/src/com/android/contacts/util/DataStatus.java
deleted file mode 100644
index f267615..0000000
--- a/src/com/android/contacts/util/DataStatus.java
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.contacts.util;
-
-import android.content.Context;
-import android.content.pm.PackageManager;
-import android.database.Cursor;
-import android.graphics.drawable.Drawable;
-import android.provider.ContactsContract.Data;
-import android.text.TextUtils;
-import android.text.format.DateUtils;
-
-import com.android.contacts.R;
-
-/**
- * Storage for a social status update. Holds a single update, but can use
- * {@link #possibleUpdate(Cursor)} to consider updating when a better status
- * exists. Statuses with timestamps, or with newer timestamps win.
- */
-public class DataStatus {
-    private int mPresence = -1;
-    private String mStatus = null;
-    private long mTimestamp = -1;
-
-    private String mResPackage = null;
-    private int mIconRes = -1;
-    private int mLabelRes = -1;
-
-    public DataStatus() {
-    }
-
-    public DataStatus(Cursor cursor) {
-        // When creating from cursor row, fill normally
-        fromCursor(cursor);
-    }
-
-    /**
-     * Attempt updating this {@link DataStatus} based on values at the
-     * current row of the given {@link Cursor}.
-     */
-    public void possibleUpdate(Cursor cursor) {
-        final boolean hasStatus = !isNull(cursor, Data.STATUS);
-        final boolean hasTimestamp = !isNull(cursor, Data.STATUS_TIMESTAMP);
-
-        // Bail early when not valid status, or when previous status was
-        // found and we can't compare this one.
-        if (!hasStatus) return;
-        if (isValid() && !hasTimestamp) return;
-
-        if (hasTimestamp) {
-            // Compare timestamps and bail if older status
-            final long newTimestamp = getLong(cursor, Data.STATUS_TIMESTAMP, -1);
-            if (newTimestamp < mTimestamp) return;
-
-            mTimestamp = newTimestamp;
-        }
-
-        // Fill in remaining details from cursor
-        fromCursor(cursor);
-    }
-
-    private void fromCursor(Cursor cursor) {
-        mPresence = getInt(cursor, Data.PRESENCE, -1);
-        mStatus = getString(cursor, Data.STATUS);
-        mTimestamp = getLong(cursor, Data.STATUS_TIMESTAMP, -1);
-        mResPackage = getString(cursor, Data.STATUS_RES_PACKAGE);
-        mIconRes = getInt(cursor, Data.STATUS_ICON, -1);
-        mLabelRes = getInt(cursor, Data.STATUS_LABEL, -1);
-    }
-
-    public boolean isValid() {
-        return !TextUtils.isEmpty(mStatus);
-    }
-
-    public int getPresence() {
-        return mPresence;
-    }
-
-    public CharSequence getStatus() {
-        return mStatus;
-    }
-
-    public long getTimestamp() {
-        return mTimestamp;
-    }
-
-    /**
-     * Build any timestamp and label into a single string.
-     */
-    public CharSequence getTimestampLabel(Context context) {
-        final PackageManager pm = context.getPackageManager();
-
-        // Use local package for resources when none requested
-        if (mResPackage == null) mResPackage = context.getPackageName();
-
-        final boolean validTimestamp = mTimestamp > 0;
-        final boolean validLabel = mResPackage != null && mLabelRes != -1;
-
-        final CharSequence timeClause = validTimestamp ? DateUtils.getRelativeTimeSpanString(
-                mTimestamp, System.currentTimeMillis(), DateUtils.MINUTE_IN_MILLIS,
-                DateUtils.FORMAT_ABBREV_RELATIVE) : null;
-        final CharSequence labelClause = validLabel ? pm.getText(mResPackage, mLabelRes,
-                null) : null;
-
-        if (validTimestamp && validLabel) {
-            return context.getString(
-                    R.string.contact_status_update_attribution_with_date,
-                    timeClause, labelClause);
-        } else if (validLabel) {
-            return context.getString(
-                    R.string.contact_status_update_attribution,
-                    labelClause);
-        } else if (validTimestamp) {
-            return timeClause;
-        } else {
-            return null;
-        }
-    }
-
-    public Drawable getIcon(Context context) {
-        final PackageManager pm = context.getPackageManager();
-
-        // Use local package for resources when none requested
-        if (mResPackage == null) mResPackage = context.getPackageName();
-
-        final boolean validIcon = mResPackage != null && mIconRes != -1;
-        return validIcon ? pm.getDrawable(mResPackage, mIconRes, null) : null;
-    }
-
-    private static String getString(Cursor cursor, String columnName) {
-        return cursor.getString(cursor.getColumnIndex(columnName));
-    }
-
-    private static int getInt(Cursor cursor, String columnName) {
-        return cursor.getInt(cursor.getColumnIndex(columnName));
-    }
-
-    private static int getInt(Cursor cursor, String columnName, int missingValue) {
-        final int columnIndex = cursor.getColumnIndex(columnName);
-        return cursor.isNull(columnIndex) ? missingValue : cursor.getInt(columnIndex);
-    }
-
-    private static long getLong(Cursor cursor, String columnName, long missingValue) {
-        final int columnIndex = cursor.getColumnIndex(columnName);
-        return cursor.isNull(columnIndex) ? missingValue : cursor.getLong(columnIndex);
-    }
-
-    private static boolean isNull(Cursor cursor, String columnName) {
-        return cursor.isNull(cursor.getColumnIndex(columnName));
-    }
-}
diff --git a/src/com/android/contacts/util/DateUtils.java b/src/com/android/contacts/util/DateUtils.java
deleted file mode 100644
index e20aadf..0000000
--- a/src/com/android/contacts/util/DateUtils.java
+++ /dev/null
@@ -1,272 +0,0 @@
-/*
- * Copyright (C) 2010 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.contacts.util;
-
-import android.content.Context;
-import android.text.format.DateFormat;
-
-import com.android.contacts.common.util.CommonDateUtils;
-
-import java.text.ParsePosition;
-import java.text.SimpleDateFormat;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.GregorianCalendar;
-import java.util.Locale;
-import java.util.TimeZone;
-
-/**
- * Utility methods for processing dates.
- */
-public class DateUtils {
-    public static final TimeZone UTC_TIMEZONE = TimeZone.getTimeZone("UTC");
-
-    /**
-     * When parsing a date without a year, the system assumes 1970, which wasn't a leap-year.
-     * Let's add a one-off hack for that day of the year
-     */
-    public static final String NO_YEAR_DATE_FEB29TH = "--02-29";
-
-    // Variations of ISO 8601 date format.  Do not change the order - it does affect the
-    // result in ambiguous cases.
-    private static final SimpleDateFormat[] DATE_FORMATS = {
-        CommonDateUtils.FULL_DATE_FORMAT,
-        CommonDateUtils.DATE_AND_TIME_FORMAT,
-        new SimpleDateFormat("yyyy-MM-dd'T'HH:mm'Z'", Locale.US),
-        new SimpleDateFormat("yyyyMMdd", Locale.US),
-        new SimpleDateFormat("yyyyMMdd'T'HHmmssSSS'Z'", Locale.US),
-        new SimpleDateFormat("yyyyMMdd'T'HHmmss'Z'", Locale.US),
-        new SimpleDateFormat("yyyyMMdd'T'HHmm'Z'", Locale.US),
-    };
-
-    static {
-        for (SimpleDateFormat format : DATE_FORMATS) {
-            format.setLenient(true);
-            format.setTimeZone(UTC_TIMEZONE);
-        }
-        CommonDateUtils.NO_YEAR_DATE_FORMAT.setTimeZone(UTC_TIMEZONE);
-    }
-
-    /**
-     * Parses the supplied string to see if it looks like a date.
-     *
-     * @param string The string representation of the provided date
-     * @param mustContainYear If true, the string is parsed as a date containing a year. If false,
-     * the string is parsed into a valid date even if the year field is missing.
-     * @return A Calendar object corresponding to the date if the string is successfully parsed.
-     * If not, null is returned.
-     */
-    public static Calendar parseDate(String string, boolean mustContainYear) {
-        ParsePosition parsePosition = new ParsePosition(0);
-        Date date;
-        if (!mustContainYear) {
-            final boolean noYearParsed;
-            // Unfortunately, we can't parse Feb 29th correctly, so let's handle this day seperately
-            if (NO_YEAR_DATE_FEB29TH.equals(string)) {
-                return getUtcDate(0, Calendar.FEBRUARY, 29);
-            } else {
-                synchronized (CommonDateUtils.NO_YEAR_DATE_FORMAT) {
-                    date = CommonDateUtils.NO_YEAR_DATE_FORMAT.parse(string, parsePosition);
-                }
-                noYearParsed = parsePosition.getIndex() == string.length();
-            }
-
-            if (noYearParsed) {
-                return getUtcDate(date, true);
-            }
-        }
-        for (int i = 0; i < DATE_FORMATS.length; i++) {
-            SimpleDateFormat f = DATE_FORMATS[i];
-            synchronized (f) {
-                parsePosition.setIndex(0);
-                date = f.parse(string, parsePosition);
-                if (parsePosition.getIndex() == string.length()) {
-                    return getUtcDate(date, false);
-                }
-            }
-        }
-        return null;
-    }
-
-    private static final Calendar getUtcDate(Date date, boolean noYear) {
-        final Calendar calendar = Calendar.getInstance(UTC_TIMEZONE, Locale.US);
-        calendar.setTime(date);
-        if (noYear) {
-            calendar.set(Calendar.YEAR, 0);
-        }
-        return calendar;
-    }
-
-    private static final Calendar getUtcDate(int year, int month, int dayOfMonth) {
-        final Calendar calendar = Calendar.getInstance(UTC_TIMEZONE, Locale.US);
-        calendar.clear();
-        calendar.set(Calendar.YEAR, year);
-        calendar.set(Calendar.MONTH, month);
-        calendar.set(Calendar.DAY_OF_MONTH, dayOfMonth);
-        return calendar;
-    }
-
-    public static boolean isYearSet(Calendar cal) {
-        // use the Calendar.YEAR field to track whether or not the year is set instead of
-        // Calendar.isSet() because doing Calendar.get() causes Calendar.isSet() to become
-        // true irregardless of what the previous value was
-        return cal.get(Calendar.YEAR) > 1;
-    }
-
-    /**
-     * Same as {@link #formatDate(Context context, String string, boolean longForm)}, with
-     * longForm set to {@code true} by default.
-     *
-     * @param context Valid context
-     * @param string String representation of a date to parse
-     * @return Returns the same date in a cleaned up format. If the supplied string does not look
-     * like a date, return it unchanged.
-     */
-
-    public static String formatDate(Context context, String string) {
-        return formatDate(context, string, true);
-    }
-
-    /**
-     * Parses the supplied string to see if it looks like a date.
-     *
-     * @param context Valid context
-     * @param string String representation of a date to parse
-     * @param longForm If true, return the date formatted into its long string representation.
-     * If false, return the date formatted using its short form representation (i.e. 12/11/2012)
-     * @return Returns the same date in a cleaned up format. If the supplied string does not look
-     * like a date, return it unchanged.
-     */
-    public static String formatDate(Context context, String string, boolean longForm) {
-        if (string == null) {
-            return null;
-        }
-
-        string = string.trim();
-        if (string.length() == 0) {
-            return string;
-        }
-        final Calendar cal = parseDate(string, false);
-
-        // we weren't able to parse the string successfully so just return it unchanged
-        if (cal == null) {
-            return string;
-        }
-
-        final boolean isYearSet = isYearSet(cal);
-        final java.text.DateFormat outFormat;
-        if (!isYearSet) {
-            outFormat = getLocalizedDateFormatWithoutYear(context);
-        } else {
-            outFormat =
-                    longForm ? DateFormat.getLongDateFormat(context) :
-                    DateFormat.getDateFormat(context);
-        }
-        synchronized (outFormat) {
-            outFormat.setTimeZone(UTC_TIMEZONE);
-            return outFormat.format(cal.getTime());
-        }
-    }
-
-    public static boolean isMonthBeforeDay(Context context) {
-        char[] dateFormatOrder = DateFormat.getDateFormatOrder(context);
-        for (int i = 0; i < dateFormatOrder.length; i++) {
-            if (dateFormatOrder[i] == DateFormat.DATE) {
-                return false;
-            }
-            if (dateFormatOrder[i] == DateFormat.MONTH) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Returns a SimpleDateFormat object without the year fields by using a regular expression
-     * to eliminate the year in the string pattern. In the rare occurence that the resulting
-     * pattern cannot be reconverted into a SimpleDateFormat, it uses the provided context to
-     * determine whether the month field should be displayed before the day field, and returns
-     * either "MMMM dd" or "dd MMMM" converted into a SimpleDateFormat.
-     */
-    public static java.text.DateFormat getLocalizedDateFormatWithoutYear(Context context) {
-        final String pattern = ((SimpleDateFormat) SimpleDateFormat.getDateInstance(
-                java.text.DateFormat.LONG)).toPattern();
-        // Determine the correct regex pattern for year.
-        // Special case handling for Spanish locale by checking for "de"
-        final String yearPattern = pattern.contains(
-                "de") ? "[^Mm]*[Yy]+[^Mm]*" : "[^DdMm]*[Yy]+[^DdMm]*";
-        try {
-         // Eliminate the substring in pattern that matches the format for that of year
-            return new SimpleDateFormat(pattern.replaceAll(yearPattern, ""));
-        } catch (IllegalArgumentException e) {
-            return new SimpleDateFormat(
-                    DateUtils.isMonthBeforeDay(context) ? "MMMM dd" : "dd MMMM");
-        }
-    }
-
-    /**
-     * Given a calendar (possibly containing only a day of the year), returns the earliest possible
-     * anniversary of the date that is equal to or after the current point in time if the date
-     * does not contain a year, or the date converted to the local time zone (if the date contains
-     * a year.
-     *
-     * @param target The date we wish to convert(in the UTC time zone).
-     * @return If date does not contain a year (year < 1900), returns the next earliest anniversary
-     * that is after the current point in time (in the local time zone). Otherwise, returns the
-     * adjusted Date in the local time zone.
-     */
-    public static Date getNextAnnualDate(Calendar target) {
-        final Calendar today = Calendar.getInstance();
-        today.setTime(new Date());
-
-        // Round the current time to the exact start of today so that when we compare
-        // today against the target date, both dates are set to exactly 0000H.
-        today.set(Calendar.HOUR_OF_DAY, 0);
-        today.set(Calendar.MINUTE, 0);
-        today.set(Calendar.SECOND, 0);
-        today.set(Calendar.MILLISECOND, 0);
-
-        final boolean isYearSet = isYearSet(target);
-        final int targetYear = target.get(Calendar.YEAR);
-        final int targetMonth = target.get(Calendar.MONTH);
-        final int targetDay = target.get(Calendar.DAY_OF_MONTH);
-        final boolean isFeb29 = (targetMonth == Calendar.FEBRUARY && targetDay == 29);
-        final GregorianCalendar anniversary = new GregorianCalendar();
-        // Convert from the UTC date to the local date. Set the year to today's year if the
-        // there is no provided year (targetYear < 1900)
-        anniversary.set(!isYearSet ? today.get(Calendar.YEAR) : targetYear,
-                targetMonth, targetDay);
-        // If the anniversary's date is before the start of today and there is no year set,
-        // increment the year by 1 so that the returned date is always equal to or greater than
-        // today. If the day is a leap year, keep going until we get the next leap year anniversary
-        // Otherwise if there is already a year set, simply return the exact date.
-        if (!isYearSet) {
-            int anniversaryYear = today.get(Calendar.YEAR);
-            if (anniversary.before(today) ||
-                    (isFeb29 && !anniversary.isLeapYear(anniversaryYear))) {
-                // If the target date is not Feb 29, then set the anniversary to the next year.
-                // Otherwise, keep going until we find the next leap year (this is not guaranteed
-                // to be in 4 years time).
-                do {
-                    anniversaryYear +=1;
-                } while (isFeb29 && !anniversary.isLeapYear(anniversaryYear));
-                anniversary.set(anniversaryYear, targetMonth, targetDay);
-            }
-        }
-        return anniversary.getTime();
-    }
-}
diff --git a/src/com/android/contacts/util/HtmlUtils.java b/src/com/android/contacts/util/HtmlUtils.java
index cea300e..edcda13 100644
--- a/src/com/android/contacts/util/HtmlUtils.java
+++ b/src/com/android/contacts/util/HtmlUtils.java
@@ -35,6 +35,7 @@
  * Specifically, it adjusts the color and padding of the vertical
  * stripe on block quotes and alignment of inlined images.
  */
+@VisibleForTesting
 public class HtmlUtils {
 
     /**
diff --git a/src/com/android/contacts/util/ImageViewDrawableSetter.java b/src/com/android/contacts/util/ImageViewDrawableSetter.java
index 91ecd61..a189f58 100644
--- a/src/com/android/contacts/util/ImageViewDrawableSetter.java
+++ b/src/com/android/contacts/util/ImageViewDrawableSetter.java
@@ -27,7 +27,7 @@
 import android.widget.ImageView;
 
 import com.android.contacts.common.ContactPhotoManager;
-import com.android.contacts.model.Contact;
+import com.android.contacts.common.model.Contact;
 
 import java.util.Arrays;
 
diff --git a/src/com/android/contacts/util/NameConverter.java b/src/com/android/contacts/util/NameConverter.java
deleted file mode 100644
index 9853821..0000000
--- a/src/com/android/contacts/util/NameConverter.java
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * Copyright (C) 2011 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.contacts.util;
-
-
-import android.content.ContentValues;
-import android.content.Context;
-import android.database.Cursor;
-import android.net.Uri;
-import android.net.Uri.Builder;
-import android.provider.ContactsContract;
-import android.provider.ContactsContract.CommonDataKinds.StructuredName;
-import android.text.TextUtils;
-
-import java.util.Map;
-import java.util.TreeMap;
-
-/**
- * Utility class for converting between a display name and structured name (and vice-versa), via
- * calls to the contact provider.
- */
-public class NameConverter {
-
-    /**
-     * The array of fields that comprise a structured name.
-     */
-    public static final String[] STRUCTURED_NAME_FIELDS = new String[] {
-            StructuredName.PREFIX,
-            StructuredName.GIVEN_NAME,
-            StructuredName.MIDDLE_NAME,
-            StructuredName.FAMILY_NAME,
-            StructuredName.SUFFIX
-    };
-
-    /**
-     * Converts the given structured name (provided as a map from {@link StructuredName} fields to
-     * corresponding values) into a display name string.
-     * <p>
-     * Note that this operates via a call back to the ContactProvider, but it does not access the
-     * database, so it should be safe to call from the UI thread.  See
-     * ContactsProvider2.completeName() for the underlying method call.
-     * @param context Activity context.
-     * @param structuredName The structured name map to convert.
-     * @return The display name computed from the structured name map.
-     */
-    public static String structuredNameToDisplayName(Context context,
-            Map<String, String> structuredName) {
-        Builder builder = ContactsContract.AUTHORITY_URI.buildUpon().appendPath("complete_name");
-        for (String key : STRUCTURED_NAME_FIELDS) {
-            if (structuredName.containsKey(key)) {
-                appendQueryParameter(builder, key, structuredName.get(key));
-            }
-        }
-        return fetchDisplayName(context, builder.build());
-    }
-
-    /**
-     * Converts the given structured name (provided as ContentValues) into a display name string.
-     * @param context Activity context.
-     * @param values The content values containing values comprising the structured name.
-     * @return
-     */
-    public static String structuredNameToDisplayName(Context context, ContentValues values) {
-        Builder builder = ContactsContract.AUTHORITY_URI.buildUpon().appendPath("complete_name");
-        for (String key : STRUCTURED_NAME_FIELDS) {
-            if (values.containsKey(key)) {
-                appendQueryParameter(builder, key, values.getAsString(key));
-            }
-        }
-        return fetchDisplayName(context, builder.build());
-    }
-
-    /**
-     * Helper method for fetching the display name via the given URI.
-     */
-    private static String fetchDisplayName(Context context, Uri uri) {
-        String displayName = null;
-        Cursor cursor = context.getContentResolver().query(uri, new String[]{
-                StructuredName.DISPLAY_NAME,
-        }, null, null, null);
-
-        try {
-            if (cursor.moveToFirst()) {
-                displayName = cursor.getString(0);
-            }
-        } finally {
-            cursor.close();
-        }
-        return displayName;
-    }
-
-    /**
-     * Converts the given display name string into a structured name (as a map from
-     * {@link StructuredName} fields to corresponding values).
-     * <p>
-     * Note that this operates via a call back to the ContactProvider, but it does not access the
-     * database, so it should be safe to call from the UI thread.
-     * @param context Activity context.
-     * @param displayName The display name to convert.
-     * @return The structured name map computed from the display name.
-     */
-    public static Map<String, String> displayNameToStructuredName(Context context,
-            String displayName) {
-        Map<String, String> structuredName = new TreeMap<String, String>();
-        Builder builder = ContactsContract.AUTHORITY_URI.buildUpon().appendPath("complete_name");
-
-        appendQueryParameter(builder, StructuredName.DISPLAY_NAME, displayName);
-        Cursor cursor = context.getContentResolver().query(builder.build(), STRUCTURED_NAME_FIELDS,
-                null, null, null);
-
-        try {
-            if (cursor.moveToFirst()) {
-                for (int i = 0; i < STRUCTURED_NAME_FIELDS.length; i++) {
-                    structuredName.put(STRUCTURED_NAME_FIELDS[i], cursor.getString(i));
-                }
-            }
-        } finally {
-            cursor.close();
-        }
-        return structuredName;
-    }
-
-    /**
-     * Converts the given display name string into a structured name (inserting the structured
-     * values into a new or existing ContentValues object).
-     * <p>
-     * Note that this operates via a call back to the ContactProvider, but it does not access the
-     * database, so it should be safe to call from the UI thread.
-     * @param context Activity context.
-     * @param displayName The display name to convert.
-     * @param contentValues The content values object to place the structured name values into.  If
-     *     null, a new one will be created and returned.
-     * @return The ContentValues object containing the structured name fields derived from the
-     *     display name.
-     */
-    public static ContentValues displayNameToStructuredName(Context context, String displayName,
-            ContentValues contentValues) {
-        if (contentValues == null) {
-            contentValues = new ContentValues();
-        }
-        Map<String, String> mapValues = displayNameToStructuredName(context, displayName);
-        for (String key : mapValues.keySet()) {
-            contentValues.put(key, mapValues.get(key));
-        }
-        return contentValues;
-    }
-
-    private static void appendQueryParameter(Builder builder, String field, String value) {
-        if (!TextUtils.isEmpty(value)) {
-            builder.appendQueryParameter(field, value);
-        }
-    }
-}
diff --git a/src/com/android/contacts/util/StreamItemEntry.java b/src/com/android/contacts/util/StreamItemEntry.java
index 2332c0e..e5696a1 100644
--- a/src/com/android/contacts/util/StreamItemEntry.java
+++ b/src/com/android/contacts/util/StreamItemEntry.java
@@ -24,6 +24,8 @@
 import com.android.contacts.detail.ContactDetailDisplayUtils;
 import com.android.contacts.common.test.NeededForTesting;
 
+import com.google.common.annotations.VisibleForTesting;
+
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
@@ -156,6 +158,7 @@
      *
      * We can't do this automatically in the getters, because it'll require a {@link Context}.
      */
+    @VisibleForTesting
     public void decodeHtml(Context context) {
         final Html.ImageGetter imageGetter = ContactDetailDisplayUtils.getImageGetter(context);
         if (mText != null) {
diff --git a/tests/src/com/android/contacts/ContactsUtilsTests.java b/tests/src/com/android/contacts/ContactsUtilsTests.java
deleted file mode 100644
index e8f05e0..0000000
--- a/tests/src/com/android/contacts/ContactsUtilsTests.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.contacts;
-
-import android.content.Intent;
-import android.provider.ContactsContract.CommonDataKinds.Phone;
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.SmallTest;
-
-import com.android.contacts.common.MoreContactUtils;
-
-/**
- * Tests for {@link ContactsUtils}.
- */
-@SmallTest
-public class ContactsUtilsTests extends AndroidTestCase {
-
-    public void testIsGraphicNull() throws Exception {
-        assertFalse(ContactsUtils.isGraphic(null));
-    }
-
-    public void testIsGraphicEmpty() throws Exception {
-        assertFalse(ContactsUtils.isGraphic(""));
-    }
-
-    public void testIsGraphicSpaces() throws Exception {
-        assertFalse(ContactsUtils.isGraphic("  "));
-    }
-
-    public void testIsGraphicPunctuation() throws Exception {
-        assertTrue(ContactsUtils.isGraphic("."));
-    }
-
-    public void testAreObjectsEqual() throws Exception {
-        assertTrue("null:null", ContactsUtils.areObjectsEqual(null, null));
-        assertTrue("1:1", ContactsUtils.areObjectsEqual(1, 1));
-
-        assertFalse("null:1", ContactsUtils.areObjectsEqual(null, 1));
-        assertFalse("1:null", ContactsUtils.areObjectsEqual(1, null));
-        assertFalse("1:2", ContactsUtils.areObjectsEqual(1, 2));
-    }
-
-    public void testAreIntentActionEqual() throws Exception {
-        assertTrue("1", ContactsUtils.areIntentActionEqual(null, null));
-        assertTrue("1", ContactsUtils.areIntentActionEqual(new Intent("a"), new Intent("a")));
-
-        assertFalse("11", ContactsUtils.areIntentActionEqual(new Intent("a"), null));
-        assertFalse("12", ContactsUtils.areIntentActionEqual(null, new Intent("a")));
-
-        assertFalse("21", ContactsUtils.areIntentActionEqual(new Intent("a"), new Intent()));
-        assertFalse("22", ContactsUtils.areIntentActionEqual(new Intent(), new Intent("b")));
-        assertFalse("23", ContactsUtils.areIntentActionEqual(new Intent("a"), new Intent("b")));
-    }
-}
diff --git a/tests/src/com/android/contacts/RawContactDeltaListTests.java b/tests/src/com/android/contacts/RawContactDeltaListTests.java
deleted file mode 100644
index 6a75b81..0000000
--- a/tests/src/com/android/contacts/RawContactDeltaListTests.java
+++ /dev/null
@@ -1,592 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.contacts;
-
-import static android.content.ContentProviderOperation.TYPE_ASSERT;
-import static android.content.ContentProviderOperation.TYPE_DELETE;
-import static android.content.ContentProviderOperation.TYPE_INSERT;
-import static android.content.ContentProviderOperation.TYPE_UPDATE;
-
-import android.content.ContentProviderOperation;
-import android.content.ContentValues;
-import android.content.Context;
-import android.net.Uri;
-import android.provider.BaseColumns;
-import android.provider.ContactsContract.AggregationExceptions;
-import android.provider.ContactsContract.CommonDataKinds.Email;
-import android.provider.ContactsContract.CommonDataKinds.Phone;
-import android.provider.ContactsContract.Data;
-import android.provider.ContactsContract.RawContacts;
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.LargeTest;
-
-import com.android.contacts.RawContactModifierTests.MockContactsSource;
-import com.android.contacts.model.RawContact;
-import com.android.contacts.model.RawContactDelta;
-import com.android.contacts.common.model.ValuesDelta;
-import com.android.contacts.model.RawContactDeltaList;
-import com.android.contacts.model.RawContactModifier;
-import com.android.contacts.common.model.account.AccountType;
-import com.google.common.collect.Lists;
-
-import java.lang.reflect.Field;
-import java.util.ArrayList;
-import java.util.Collections;
-
-/**
- * Tests for {@link RawContactDeltaList} which focus on "diff" operations that should
- * create {@link AggregationExceptions} in certain cases.
- */
-@LargeTest
-public class RawContactDeltaListTests extends AndroidTestCase {
-    public static final String TAG = RawContactDeltaListTests.class.getSimpleName();
-
-    private static final long CONTACT_FIRST = 1;
-    private static final long CONTACT_SECOND = 2;
-
-    public static final long CONTACT_BOB = 10;
-    public static final long CONTACT_MARY = 11;
-
-    public static final long PHONE_RED = 20;
-    public static final long PHONE_GREEN = 21;
-    public static final long PHONE_BLUE = 22;
-
-    public static final long EMAIL_YELLOW = 25;
-
-    public static final long VER_FIRST = 100;
-    public static final long VER_SECOND = 200;
-
-    public static final String TEST_PHONE = "555-1212";
-    public static final String TEST_ACCOUNT = "org.example.test";
-
-    public RawContactDeltaListTests() {
-        super();
-    }
-
-    @Override
-    public void setUp() {
-        mContext = getContext();
-    }
-
-    /**
-     * Build a {@link AccountType} that has various odd constraints for
-     * testing purposes.
-     */
-    protected AccountType getAccountType() {
-        return new MockContactsSource();
-    }
-
-    static ContentValues getValues(ContentProviderOperation operation)
-            throws NoSuchFieldException, IllegalAccessException {
-        final Field field = ContentProviderOperation.class.getDeclaredField("mValues");
-        field.setAccessible(true);
-        return (ContentValues) field.get(operation);
-    }
-
-    static RawContactDelta getUpdate(Context context, long rawContactId) {
-        final RawContact before = RawContactDeltaTests.getRawContact(context, rawContactId,
-                RawContactDeltaTests.TEST_PHONE_ID);
-        return RawContactDelta.fromBefore(before);
-    }
-
-    static RawContactDelta getInsert() {
-        final ContentValues after = new ContentValues();
-        after.put(RawContacts.ACCOUNT_NAME, RawContactDeltaTests.TEST_ACCOUNT_NAME);
-        after.put(RawContacts.SEND_TO_VOICEMAIL, 1);
-
-        final ValuesDelta values = ValuesDelta.fromAfter(after);
-        return new RawContactDelta(values);
-    }
-
-    static RawContactDeltaList buildSet(RawContactDelta... deltas) {
-        final RawContactDeltaList set = new RawContactDeltaList();
-        Collections.addAll(set, deltas);
-        return set;
-    }
-
-    static RawContactDelta buildBeforeEntity(Context context, long rawContactId, long version,
-            ContentValues... entries) {
-        // Build an existing contact read from database
-        final ContentValues contact = new ContentValues();
-        contact.put(RawContacts.VERSION, version);
-        contact.put(RawContacts._ID, rawContactId);
-        final RawContact before = new RawContact(contact);
-        for (ContentValues entry : entries) {
-            before.addDataItemValues(entry);
-        }
-        return RawContactDelta.fromBefore(before);
-    }
-
-    static RawContactDelta buildAfterEntity(ContentValues... entries) {
-        // Build an existing contact read from database
-        final ContentValues contact = new ContentValues();
-        contact.put(RawContacts.ACCOUNT_TYPE, TEST_ACCOUNT);
-        final RawContactDelta after = new RawContactDelta(ValuesDelta.fromAfter(contact));
-        for (ContentValues entry : entries) {
-            after.addEntry(ValuesDelta.fromAfter(entry));
-        }
-        return after;
-    }
-
-    static ContentValues buildPhone(long phoneId) {
-        return buildPhone(phoneId, Long.toString(phoneId));
-    }
-
-    static ContentValues buildPhone(long phoneId, String value) {
-        final ContentValues values = new ContentValues();
-        values.put(Data._ID, phoneId);
-        values.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
-        values.put(Phone.NUMBER, value);
-        values.put(Phone.TYPE, Phone.TYPE_HOME);
-        return values;
-    }
-
-    static ContentValues buildEmail(long emailId) {
-        final ContentValues values = new ContentValues();
-        values.put(Data._ID, emailId);
-        values.put(Data.MIMETYPE, Email.CONTENT_ITEM_TYPE);
-        values.put(Email.DATA, Long.toString(emailId));
-        values.put(Email.TYPE, Email.TYPE_HOME);
-        return values;
-    }
-
-    static void insertPhone(RawContactDeltaList set, long rawContactId, ContentValues values) {
-        final RawContactDelta match = set.getByRawContactId(rawContactId);
-        match.addEntry(ValuesDelta.fromAfter(values));
-    }
-
-    static ValuesDelta getPhone(RawContactDeltaList set, long rawContactId, long dataId) {
-        final RawContactDelta match = set.getByRawContactId(rawContactId);
-        return match.getEntry(dataId);
-    }
-
-    static void assertDiffPattern(RawContactDelta delta, ContentProviderOperation... pattern) {
-        final ArrayList<ContentProviderOperation> diff = Lists.newArrayList();
-        delta.buildAssert(diff);
-        delta.buildDiff(diff);
-        assertDiffPattern(diff, pattern);
-    }
-
-    static void assertDiffPattern(RawContactDeltaList set, ContentProviderOperation... pattern) {
-        assertDiffPattern(set.buildDiff(), pattern);
-    }
-
-    static void assertDiffPattern(ArrayList<ContentProviderOperation> diff,
-            ContentProviderOperation... pattern) {
-        assertEquals("Unexpected operations", pattern.length, diff.size());
-        for (int i = 0; i < pattern.length; i++) {
-            final ContentProviderOperation expected = pattern[i];
-            final ContentProviderOperation found = diff.get(i);
-
-            assertEquals("Unexpected uri", expected.getUri(), found.getUri());
-
-            final String expectedType = getStringForType(expected.getType());
-            final String foundType = getStringForType(found.getType());
-            assertEquals("Unexpected type", expectedType, foundType);
-
-            if (expected.getType() == TYPE_DELETE) continue;
-
-            try {
-                final ContentValues expectedValues = getValues(expected);
-                final ContentValues foundValues = getValues(found);
-
-                expectedValues.remove(BaseColumns._ID);
-                foundValues.remove(BaseColumns._ID);
-
-                assertEquals("Unexpected values", expectedValues, foundValues);
-            } catch (NoSuchFieldException e) {
-                fail(e.toString());
-            } catch (IllegalAccessException e) {
-                fail(e.toString());
-            }
-        }
-    }
-
-    static String getStringForType(int type) {
-        switch (type) {
-            case TYPE_ASSERT: return "TYPE_ASSERT";
-            case TYPE_INSERT: return "TYPE_INSERT";
-            case TYPE_UPDATE: return "TYPE_UPDATE";
-            case TYPE_DELETE: return "TYPE_DELETE";
-            default: return Integer.toString(type);
-        }
-    }
-
-    static ContentProviderOperation buildAssertVersion(long version) {
-        final ContentValues values = new ContentValues();
-        values.put(RawContacts.VERSION, version);
-        return buildOper(RawContacts.CONTENT_URI, TYPE_ASSERT, values);
-    }
-
-    static ContentProviderOperation buildAggregationModeUpdate(int mode) {
-        final ContentValues values = new ContentValues();
-        values.put(RawContacts.AGGREGATION_MODE, mode);
-        return buildOper(RawContacts.CONTENT_URI, TYPE_UPDATE, values);
-    }
-
-    static ContentProviderOperation buildUpdateAggregationSuspended() {
-        return buildAggregationModeUpdate(RawContacts.AGGREGATION_MODE_SUSPENDED);
-    }
-
-    static ContentProviderOperation buildUpdateAggregationDefault() {
-        return buildAggregationModeUpdate(RawContacts.AGGREGATION_MODE_DEFAULT);
-    }
-
-    static ContentProviderOperation buildUpdateAggregationKeepTogether(long rawContactId) {
-        final ContentValues values = new ContentValues();
-        values.put(AggregationExceptions.RAW_CONTACT_ID1, rawContactId);
-        values.put(AggregationExceptions.TYPE, AggregationExceptions.TYPE_KEEP_TOGETHER);
-        return buildOper(AggregationExceptions.CONTENT_URI, TYPE_UPDATE, values);
-    }
-
-    static ContentValues buildDataInsert(ValuesDelta values, long rawContactId) {
-        final ContentValues insertValues = values.getCompleteValues();
-        insertValues.put(Data.RAW_CONTACT_ID, rawContactId);
-        return insertValues;
-    }
-
-    static ContentProviderOperation buildDelete(Uri uri) {
-        return buildOper(uri, TYPE_DELETE, (ContentValues)null);
-    }
-
-    static ContentProviderOperation buildOper(Uri uri, int type, ValuesDelta values) {
-        return buildOper(uri, type, values.getCompleteValues());
-    }
-
-    static ContentProviderOperation buildOper(Uri uri, int type, ContentValues values) {
-        switch (type) {
-            case TYPE_ASSERT:
-                return ContentProviderOperation.newAssertQuery(uri).withValues(values).build();
-            case TYPE_INSERT:
-                return ContentProviderOperation.newInsert(uri).withValues(values).build();
-            case TYPE_UPDATE:
-                return ContentProviderOperation.newUpdate(uri).withValues(values).build();
-            case TYPE_DELETE:
-                return ContentProviderOperation.newDelete(uri).build();
-        }
-        return null;
-    }
-
-    static Long getVersion(RawContactDeltaList set, Long rawContactId) {
-        return set.getByRawContactId(rawContactId).getValues().getAsLong(RawContacts.VERSION);
-    }
-
-    /**
-     * Count number of {@link AggregationExceptions} updates contained in the
-     * given list of {@link ContentProviderOperation}.
-     */
-    static int countExceptionUpdates(ArrayList<ContentProviderOperation> diff) {
-        int updateCount = 0;
-        for (ContentProviderOperation oper : diff) {
-            if (AggregationExceptions.CONTENT_URI.equals(oper.getUri())
-                    && oper.getType() == ContentProviderOperation.TYPE_UPDATE) {
-                updateCount++;
-            }
-        }
-        return updateCount;
-    }
-
-    public void testInsert() {
-        final RawContactDelta insert = getInsert();
-        final RawContactDeltaList set = buildSet(insert);
-
-        // Inserting single shouldn't create rules
-        final ArrayList<ContentProviderOperation> diff = set.buildDiff();
-        final int exceptionCount = countExceptionUpdates(diff);
-        assertEquals("Unexpected exception updates", 0, exceptionCount);
-    }
-
-    public void testUpdateUpdate() {
-        final RawContactDelta updateFirst = getUpdate(mContext, CONTACT_FIRST);
-        final RawContactDelta updateSecond = getUpdate(mContext, CONTACT_SECOND);
-        final RawContactDeltaList set = buildSet(updateFirst, updateSecond);
-
-        // Updating two existing shouldn't create rules
-        final ArrayList<ContentProviderOperation> diff = set.buildDiff();
-        final int exceptionCount = countExceptionUpdates(diff);
-        assertEquals("Unexpected exception updates", 0, exceptionCount);
-    }
-
-    public void testUpdateInsert() {
-        final RawContactDelta update = getUpdate(mContext, CONTACT_FIRST);
-        final RawContactDelta insert = getInsert();
-        final RawContactDeltaList set = buildSet(update, insert);
-
-        // New insert should only create one rule
-        final ArrayList<ContentProviderOperation> diff = set.buildDiff();
-        final int exceptionCount = countExceptionUpdates(diff);
-        assertEquals("Unexpected exception updates", 1, exceptionCount);
-    }
-
-    public void testInsertUpdateInsert() {
-        final RawContactDelta insertFirst = getInsert();
-        final RawContactDelta update = getUpdate(mContext, CONTACT_FIRST);
-        final RawContactDelta insertSecond = getInsert();
-        final RawContactDeltaList set = buildSet(insertFirst, update, insertSecond);
-
-        // Two inserts should create two rules to bind against single existing
-        final ArrayList<ContentProviderOperation> diff = set.buildDiff();
-        final int exceptionCount = countExceptionUpdates(diff);
-        assertEquals("Unexpected exception updates", 2, exceptionCount);
-    }
-
-    public void testInsertInsertInsert() {
-        final RawContactDelta insertFirst = getInsert();
-        final RawContactDelta insertSecond = getInsert();
-        final RawContactDelta insertThird = getInsert();
-        final RawContactDeltaList set = buildSet(insertFirst, insertSecond, insertThird);
-
-        // Three new inserts should create only two binding rules
-        final ArrayList<ContentProviderOperation> diff = set.buildDiff();
-        final int exceptionCount = countExceptionUpdates(diff);
-        assertEquals("Unexpected exception updates", 2, exceptionCount);
-    }
-
-    public void testMergeDataRemoteInsert() {
-        final RawContactDeltaList first = buildSet(buildBeforeEntity(mContext, CONTACT_BOB,
-                VER_FIRST, buildPhone(PHONE_RED)));
-        final RawContactDeltaList second = buildSet(buildBeforeEntity(mContext, CONTACT_BOB,
-                VER_SECOND, buildPhone(PHONE_RED), buildPhone(PHONE_GREEN)));
-
-        // Merge in second version, verify they match
-        final RawContactDeltaList merged = RawContactDeltaList.mergeAfter(second, first);
-        assertEquals("Unexpected change when merging", second, merged);
-    }
-
-    public void testMergeDataLocalUpdateRemoteInsert() {
-        final RawContactDeltaList first = buildSet(buildBeforeEntity(mContext, CONTACT_BOB,
-                VER_FIRST, buildPhone(PHONE_RED)));
-        final RawContactDeltaList second = buildSet(buildBeforeEntity(mContext, CONTACT_BOB,
-                VER_SECOND, buildPhone(PHONE_RED), buildPhone(PHONE_GREEN)));
-
-        // Change the local number to trigger update
-        final ValuesDelta phone = getPhone(first, CONTACT_BOB, PHONE_RED);
-        phone.put(Phone.NUMBER, TEST_PHONE);
-
-        assertDiffPattern(first,
-                buildAssertVersion(VER_FIRST),
-                buildUpdateAggregationSuspended(),
-                buildOper(Data.CONTENT_URI, TYPE_UPDATE, phone.getAfter()),
-                buildUpdateAggregationDefault());
-
-        // Merge in the second version, verify diff matches
-        final RawContactDeltaList merged = RawContactDeltaList.mergeAfter(second, first);
-        assertDiffPattern(merged,
-                buildAssertVersion(VER_SECOND),
-                buildUpdateAggregationSuspended(),
-                buildOper(Data.CONTENT_URI, TYPE_UPDATE, phone.getAfter()),
-                buildUpdateAggregationDefault());
-    }
-
-    public void testMergeDataLocalUpdateRemoteDelete() {
-        final RawContactDeltaList first = buildSet(buildBeforeEntity(mContext, CONTACT_BOB,
-                VER_FIRST, buildPhone(PHONE_RED)));
-        final RawContactDeltaList second = buildSet(buildBeforeEntity(mContext, CONTACT_BOB,
-                VER_SECOND, buildPhone(PHONE_GREEN)));
-
-        // Change the local number to trigger update
-        final ValuesDelta phone = getPhone(first, CONTACT_BOB, PHONE_RED);
-        phone.put(Phone.NUMBER, TEST_PHONE);
-
-        assertDiffPattern(first,
-                buildAssertVersion(VER_FIRST),
-                buildUpdateAggregationSuspended(),
-                buildOper(Data.CONTENT_URI, TYPE_UPDATE, phone.getAfter()),
-                buildUpdateAggregationDefault());
-
-        // Merge in the second version, verify that our update changed to
-        // insert, since RED was deleted on remote side
-        final RawContactDeltaList merged = RawContactDeltaList.mergeAfter(second, first);
-        assertDiffPattern(merged,
-                buildAssertVersion(VER_SECOND),
-                buildUpdateAggregationSuspended(),
-                buildOper(Data.CONTENT_URI, TYPE_INSERT, buildDataInsert(phone, CONTACT_BOB)),
-                buildUpdateAggregationDefault());
-    }
-
-    public void testMergeDataLocalDeleteRemoteUpdate() {
-        final RawContactDeltaList first = buildSet(buildBeforeEntity(mContext, CONTACT_BOB,
-                VER_FIRST, buildPhone(PHONE_RED)));
-        final RawContactDeltaList second = buildSet(buildBeforeEntity(mContext, CONTACT_BOB,
-                VER_SECOND, buildPhone(PHONE_RED, TEST_PHONE)));
-
-        // Delete phone locally
-        final ValuesDelta phone = getPhone(first, CONTACT_BOB, PHONE_RED);
-        phone.markDeleted();
-
-        assertDiffPattern(first,
-                buildAssertVersion(VER_FIRST),
-                buildUpdateAggregationSuspended(),
-                buildDelete(Data.CONTENT_URI),
-                buildUpdateAggregationDefault());
-
-        // Merge in the second version, verify that our delete remains
-        final RawContactDeltaList merged = RawContactDeltaList.mergeAfter(second, first);
-        assertDiffPattern(merged,
-                buildAssertVersion(VER_SECOND),
-                buildUpdateAggregationSuspended(),
-                buildDelete(Data.CONTENT_URI),
-                buildUpdateAggregationDefault());
-    }
-
-    public void testMergeDataLocalInsertRemoteInsert() {
-        final RawContactDeltaList first = buildSet(buildBeforeEntity(mContext, CONTACT_BOB,
-                VER_FIRST, buildPhone(PHONE_RED)));
-        final RawContactDeltaList second = buildSet(buildBeforeEntity(mContext, CONTACT_BOB,
-                VER_SECOND, buildPhone(PHONE_RED), buildPhone(PHONE_GREEN)));
-
-        // Insert new phone locally
-        final ValuesDelta bluePhone = ValuesDelta.fromAfter(buildPhone(PHONE_BLUE));
-        first.getByRawContactId(CONTACT_BOB).addEntry(bluePhone);
-        assertDiffPattern(first,
-                buildAssertVersion(VER_FIRST),
-                buildUpdateAggregationSuspended(),
-                buildOper(Data.CONTENT_URI, TYPE_INSERT, buildDataInsert(bluePhone, CONTACT_BOB)),
-                buildUpdateAggregationDefault());
-
-        // Merge in the second version, verify that our insert remains
-        final RawContactDeltaList merged = RawContactDeltaList.mergeAfter(second, first);
-        assertDiffPattern(merged,
-                buildAssertVersion(VER_SECOND),
-                buildUpdateAggregationSuspended(),
-                buildOper(Data.CONTENT_URI, TYPE_INSERT, buildDataInsert(bluePhone, CONTACT_BOB)),
-                buildUpdateAggregationDefault());
-    }
-
-    public void testMergeRawContactLocalInsertRemoteInsert() {
-        final RawContactDeltaList first = buildSet(buildBeforeEntity(mContext, CONTACT_BOB,
-                VER_FIRST, buildPhone(PHONE_RED)));
-        final RawContactDeltaList second = buildSet(buildBeforeEntity(mContext, CONTACT_BOB,
-                VER_SECOND, buildPhone(PHONE_RED)), buildBeforeEntity(mContext, CONTACT_MARY,
-                        VER_SECOND, buildPhone(PHONE_RED)));
-
-        // Add new contact locally, should remain insert
-        final ContentValues joePhoneInsert = buildPhone(PHONE_BLUE);
-        final RawContactDelta joeContact = buildAfterEntity(joePhoneInsert);
-        final ContentValues joeContactInsert = joeContact.getValues().getCompleteValues();
-        joeContactInsert.put(RawContacts.AGGREGATION_MODE, RawContacts.AGGREGATION_MODE_SUSPENDED);
-        first.add(joeContact);
-        assertDiffPattern(first,
-                buildAssertVersion(VER_FIRST),
-                buildOper(RawContacts.CONTENT_URI, TYPE_INSERT, joeContactInsert),
-                buildOper(Data.CONTENT_URI, TYPE_INSERT, joePhoneInsert),
-                buildAggregationModeUpdate(RawContacts.AGGREGATION_MODE_DEFAULT),
-                buildUpdateAggregationKeepTogether(CONTACT_BOB));
-
-        // Merge in the second version, verify that our insert remains
-        final RawContactDeltaList merged = RawContactDeltaList.mergeAfter(second, first);
-        assertDiffPattern(merged,
-                buildAssertVersion(VER_SECOND),
-                buildAssertVersion(VER_SECOND),
-                buildOper(RawContacts.CONTENT_URI, TYPE_INSERT, joeContactInsert),
-                buildOper(Data.CONTENT_URI, TYPE_INSERT, joePhoneInsert),
-                buildAggregationModeUpdate(RawContacts.AGGREGATION_MODE_DEFAULT),
-                buildUpdateAggregationKeepTogether(CONTACT_BOB));
-    }
-
-    public void testMergeRawContactLocalDeleteRemoteDelete() {
-        final RawContactDeltaList first = buildSet(
-                buildBeforeEntity(mContext, CONTACT_BOB, VER_FIRST, buildPhone(PHONE_RED)),
-                buildBeforeEntity(mContext, CONTACT_MARY, VER_FIRST, buildPhone(PHONE_RED)));
-        final RawContactDeltaList second = buildSet(
-                buildBeforeEntity(mContext, CONTACT_BOB, VER_SECOND, buildPhone(PHONE_RED)));
-
-        // Remove contact locally
-        first.getByRawContactId(CONTACT_MARY).markDeleted();
-        assertDiffPattern(first,
-                buildAssertVersion(VER_FIRST),
-                buildAssertVersion(VER_FIRST),
-                buildDelete(RawContacts.CONTENT_URI));
-
-        // Merge in the second version, verify that our delete isn't needed
-        final RawContactDeltaList merged = RawContactDeltaList.mergeAfter(second, first);
-        assertDiffPattern(merged);
-    }
-
-    public void testMergeRawContactLocalUpdateRemoteDelete() {
-        final RawContactDeltaList first = buildSet(
-                buildBeforeEntity(mContext, CONTACT_BOB, VER_FIRST, buildPhone(PHONE_RED)),
-                buildBeforeEntity(mContext, CONTACT_MARY, VER_FIRST, buildPhone(PHONE_RED)));
-        final RawContactDeltaList second = buildSet(
-                buildBeforeEntity(mContext, CONTACT_BOB, VER_SECOND, buildPhone(PHONE_RED)));
-
-        // Perform local update
-        final ValuesDelta phone = getPhone(first, CONTACT_MARY, PHONE_RED);
-        phone.put(Phone.NUMBER, TEST_PHONE);
-        assertDiffPattern(first,
-                buildAssertVersion(VER_FIRST),
-                buildAssertVersion(VER_FIRST),
-                buildUpdateAggregationSuspended(),
-                buildOper(Data.CONTENT_URI, TYPE_UPDATE, phone.getAfter()),
-                buildUpdateAggregationDefault());
-
-        final ContentValues phoneInsert = phone.getCompleteValues();
-        final ContentValues contactInsert = first.getByRawContactId(CONTACT_MARY).getValues()
-                .getCompleteValues();
-        contactInsert.put(RawContacts.AGGREGATION_MODE, RawContacts.AGGREGATION_MODE_SUSPENDED);
-
-        // Merge and verify that update turned into insert
-        final RawContactDeltaList merged = RawContactDeltaList.mergeAfter(second, first);
-        assertDiffPattern(merged,
-                buildAssertVersion(VER_SECOND),
-                buildOper(RawContacts.CONTENT_URI, TYPE_INSERT, contactInsert),
-                buildOper(Data.CONTENT_URI, TYPE_INSERT, phoneInsert),
-                buildAggregationModeUpdate(RawContacts.AGGREGATION_MODE_DEFAULT),
-                buildUpdateAggregationKeepTogether(CONTACT_BOB));
-    }
-
-    public void testMergeUsesNewVersion() {
-        final RawContactDeltaList first = buildSet(buildBeforeEntity(mContext, CONTACT_BOB,
-                VER_FIRST, buildPhone(PHONE_RED)));
-        final RawContactDeltaList second = buildSet(buildBeforeEntity(mContext, CONTACT_BOB,
-                VER_SECOND, buildPhone(PHONE_RED)));
-
-        assertEquals((Long)VER_FIRST, getVersion(first, CONTACT_BOB));
-        assertEquals((Long)VER_SECOND, getVersion(second, CONTACT_BOB));
-
-        final RawContactDeltaList merged = RawContactDeltaList.mergeAfter(second, first);
-        assertEquals((Long)VER_SECOND, getVersion(merged, CONTACT_BOB));
-    }
-
-    public void testMergeAfterEnsureAndTrim() {
-        final RawContactDeltaList first = buildSet(buildBeforeEntity(mContext, CONTACT_BOB,
-                VER_FIRST, buildEmail(EMAIL_YELLOW)));
-        final RawContactDeltaList second = buildSet(buildBeforeEntity(mContext, CONTACT_BOB,
-                VER_SECOND, buildEmail(EMAIL_YELLOW)));
-
-        // Ensure we have at least one phone
-        final AccountType source = getAccountType();
-        final RawContactDelta bobContact = first.getByRawContactId(CONTACT_BOB);
-        RawContactModifier.ensureKindExists(bobContact, source, Phone.CONTENT_ITEM_TYPE);
-        final ValuesDelta bobPhone = bobContact.getSuperPrimaryEntry(Phone.CONTENT_ITEM_TYPE, true);
-
-        // Make sure the update would insert a row
-        assertDiffPattern(first,
-                buildAssertVersion(VER_FIRST),
-                buildUpdateAggregationSuspended(),
-                buildOper(Data.CONTENT_URI, TYPE_INSERT, buildDataInsert(bobPhone, CONTACT_BOB)),
-                buildUpdateAggregationDefault());
-
-        // Trim values and ensure that we don't insert things
-        RawContactModifier.trimEmpty(bobContact, source);
-        assertDiffPattern(first);
-
-        // Now re-parent the change, which should remain no-op
-        final RawContactDeltaList merged = RawContactDeltaList.mergeAfter(second, first);
-        assertDiffPattern(merged);
-    }
-}
diff --git a/tests/src/com/android/contacts/RawContactDeltaTests.java b/tests/src/com/android/contacts/RawContactDeltaTests.java
deleted file mode 100644
index dc4eb53..0000000
--- a/tests/src/com/android/contacts/RawContactDeltaTests.java
+++ /dev/null
@@ -1,369 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.contacts;
-
-import static android.content.ContentProviderOperation.TYPE_ASSERT;
-import static android.content.ContentProviderOperation.TYPE_DELETE;
-import static android.content.ContentProviderOperation.TYPE_INSERT;
-import static android.content.ContentProviderOperation.TYPE_UPDATE;
-
-import android.content.ContentProviderOperation;
-import android.content.ContentProviderOperation.Builder;
-import android.content.ContentValues;
-import android.content.Context;
-import android.os.Parcel;
-import android.provider.ContactsContract.CommonDataKinds.Phone;
-import android.provider.ContactsContract.Data;
-import android.provider.ContactsContract.RawContacts;
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.LargeTest;
-
-import com.android.contacts.model.RawContact;
-import com.android.contacts.model.RawContactDelta;
-import com.android.contacts.common.model.ValuesDelta;
-import com.google.common.collect.Lists;
-
-import java.util.ArrayList;
-
-/**
- * Tests for {@link RawContactDelta} and {@link ValuesDelta}. These tests
- * focus on passing changes across {@link Parcel}, and verifying that they
- * correctly build expected "diff" operations.
- */
-@LargeTest
-public class RawContactDeltaTests extends AndroidTestCase {
-    public static final String TAG = "EntityDeltaTests";
-
-    public static final long TEST_CONTACT_ID = 12;
-    public static final long TEST_PHONE_ID = 24;
-
-    public static final String TEST_PHONE_NUMBER_1 = "218-555-1111";
-    public static final String TEST_PHONE_NUMBER_2 = "218-555-2222";
-
-    public static final String TEST_ACCOUNT_NAME = "TEST";
-
-    public RawContactDeltaTests() {
-        super();
-    }
-
-    @Override
-    public void setUp() {
-        mContext = getContext();
-    }
-
-    public static RawContact getRawContact(Context context, long contactId, long phoneId) {
-        // Build an existing contact read from database
-        final ContentValues contact = new ContentValues();
-        contact.put(RawContacts.VERSION, 43);
-        contact.put(RawContacts._ID, contactId);
-
-        final ContentValues phone = new ContentValues();
-        phone.put(Data._ID, phoneId);
-        phone.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
-        phone.put(Phone.NUMBER, TEST_PHONE_NUMBER_1);
-        phone.put(Phone.TYPE, Phone.TYPE_HOME);
-
-        final RawContact before = new RawContact(contact);
-        before.addDataItemValues(phone);
-        return before;
-    }
-
-    /**
-     * Test that {@link RawContactDelta#mergeAfter(RawContactDelta)} correctly passes
-     * any changes through the {@link Parcel} object. This enforces that
-     * {@link RawContactDelta} should be identical when serialized against the same
-     * "before" {@link RawContact}.
-     */
-    public void testParcelChangesNone() {
-        final RawContact before = getRawContact(mContext, TEST_CONTACT_ID, TEST_PHONE_ID);
-        final RawContactDelta source = RawContactDelta.fromBefore(before);
-        final RawContactDelta dest = RawContactDelta.fromBefore(before);
-
-        // Merge modified values and assert they match
-        final RawContactDelta merged = RawContactDelta.mergeAfter(dest, source);
-        assertEquals("Unexpected change when merging", source, merged);
-    }
-
-    public void testParcelChangesInsert() {
-        final RawContact before = getRawContact(mContext, TEST_CONTACT_ID, TEST_PHONE_ID);
-        final RawContactDelta source = RawContactDelta.fromBefore(before);
-        final RawContactDelta dest = RawContactDelta.fromBefore(before);
-
-        // Add a new row and pass across parcel, should be same
-        final ContentValues phone = new ContentValues();
-        phone.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
-        phone.put(Phone.NUMBER, TEST_PHONE_NUMBER_2);
-        phone.put(Phone.TYPE, Phone.TYPE_WORK);
-        source.addEntry(ValuesDelta.fromAfter(phone));
-
-        // Merge modified values and assert they match
-        final RawContactDelta merged = RawContactDelta.mergeAfter(dest, source);
-        assertEquals("Unexpected change when merging", source, merged);
-    }
-
-    public void testParcelChangesUpdate() {
-        // Update existing row and pass across parcel, should be same
-        final RawContact before = getRawContact(mContext, TEST_CONTACT_ID, TEST_PHONE_ID);
-        final RawContactDelta source = RawContactDelta.fromBefore(before);
-        final RawContactDelta dest = RawContactDelta.fromBefore(before);
-
-        final ValuesDelta child = source.getEntry(TEST_PHONE_ID);
-        child.put(Phone.NUMBER, TEST_PHONE_NUMBER_2);
-
-        // Merge modified values and assert they match
-        final RawContactDelta merged = RawContactDelta.mergeAfter(dest, source);
-        assertEquals("Unexpected change when merging", source, merged);
-    }
-
-    public void testParcelChangesDelete() {
-        // Delete a row and pass across parcel, should be same
-        final RawContact before = getRawContact(mContext, TEST_CONTACT_ID, TEST_PHONE_ID);
-        final RawContactDelta source = RawContactDelta.fromBefore(before);
-        final RawContactDelta dest = RawContactDelta.fromBefore(before);
-
-        final ValuesDelta child = source.getEntry(TEST_PHONE_ID);
-        child.markDeleted();
-
-        // Merge modified values and assert they match
-        final RawContactDelta merged = RawContactDelta.mergeAfter(dest, source);
-        assertEquals("Unexpected change when merging", source, merged);
-    }
-
-    public void testValuesDiffDelete() {
-        final ContentValues before = new ContentValues();
-        before.put(Data._ID, TEST_PHONE_ID);
-        before.put(Phone.NUMBER, TEST_PHONE_NUMBER_1);
-
-        final ValuesDelta values = ValuesDelta.fromBefore(before);
-        values.markDeleted();
-
-        // Should produce a delete action
-        final Builder builder = values.buildDiff(Data.CONTENT_URI);
-        final int type = builder.build().getType();
-        assertEquals("Didn't produce delete action", TYPE_DELETE, type);
-    }
-
-    /**
-     * Test that {@link RawContactDelta#buildDiff(ArrayList)} is correctly built for
-     * insert, update, and delete cases. This only tests a subset of possible
-     * {@link Data} row changes.
-     */
-    public void testEntityDiffNone() {
-        final RawContact before = getRawContact(mContext, TEST_CONTACT_ID, TEST_PHONE_ID);
-        final RawContactDelta source = RawContactDelta.fromBefore(before);
-
-        // Assert that writing unchanged produces few operations
-        final ArrayList<ContentProviderOperation> diff = Lists.newArrayList();
-        source.buildDiff(diff);
-
-        assertTrue("Created changes when none needed", (diff.size() == 0));
-    }
-
-    public void testEntityDiffNoneInsert() {
-        final RawContact before = getRawContact(mContext, TEST_CONTACT_ID, TEST_PHONE_ID);
-        final RawContactDelta source = RawContactDelta.fromBefore(before);
-
-        // Insert a new phone number
-        final ContentValues phone = new ContentValues();
-        phone.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
-        phone.put(Phone.NUMBER, TEST_PHONE_NUMBER_2);
-        phone.put(Phone.TYPE, Phone.TYPE_WORK);
-        source.addEntry(ValuesDelta.fromAfter(phone));
-
-        // Assert two operations: insert Data row and enforce version
-        final ArrayList<ContentProviderOperation> diff = Lists.newArrayList();
-        source.buildAssert(diff);
-        source.buildDiff(diff);
-        assertEquals("Unexpected operations", 4, diff.size());
-        {
-            final ContentProviderOperation oper = diff.get(0);
-            assertEquals("Expected version enforcement", TYPE_ASSERT, oper.getType());
-        }
-        {
-            final ContentProviderOperation oper = diff.get(1);
-            assertEquals("Expected aggregation mode change", TYPE_UPDATE, oper.getType());
-            assertEquals("Incorrect target", RawContacts.CONTENT_URI, oper.getUri());
-        }
-        {
-            final ContentProviderOperation oper = diff.get(2);
-            assertEquals("Incorrect type", TYPE_INSERT, oper.getType());
-            assertEquals("Incorrect target", Data.CONTENT_URI, oper.getUri());
-        }
-        {
-            final ContentProviderOperation oper = diff.get(3);
-            assertEquals("Expected aggregation mode change", TYPE_UPDATE, oper.getType());
-            assertEquals("Incorrect target", RawContacts.CONTENT_URI, oper.getUri());
-        }
-    }
-
-    public void testEntityDiffUpdateInsert() {
-        final RawContact before = getRawContact(mContext, TEST_CONTACT_ID, TEST_PHONE_ID);
-        final RawContactDelta source = RawContactDelta.fromBefore(before);
-
-        // Update parent contact values
-        source.getValues().put(RawContacts.AGGREGATION_MODE, RawContacts.AGGREGATION_MODE_DISABLED);
-
-        // Insert a new phone number
-        final ContentValues phone = new ContentValues();
-        phone.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
-        phone.put(Phone.NUMBER, TEST_PHONE_NUMBER_2);
-        phone.put(Phone.TYPE, Phone.TYPE_WORK);
-        source.addEntry(ValuesDelta.fromAfter(phone));
-
-        // Assert three operations: update Contact, insert Data row, enforce version
-        final ArrayList<ContentProviderOperation> diff = Lists.newArrayList();
-        source.buildAssert(diff);
-        source.buildDiff(diff);
-        assertEquals("Unexpected operations", 5, diff.size());
-        {
-            final ContentProviderOperation oper = diff.get(0);
-            assertEquals("Expected version enforcement", TYPE_ASSERT, oper.getType());
-        }
-        {
-            final ContentProviderOperation oper = diff.get(1);
-            assertEquals("Expected aggregation mode change", TYPE_UPDATE, oper.getType());
-            assertEquals("Incorrect target", RawContacts.CONTENT_URI, oper.getUri());
-        }
-        {
-            final ContentProviderOperation oper = diff.get(2);
-            assertEquals("Incorrect type", TYPE_UPDATE, oper.getType());
-            assertEquals("Incorrect target", RawContacts.CONTENT_URI, oper.getUri());
-        }
-        {
-            final ContentProviderOperation oper = diff.get(3);
-            assertEquals("Incorrect type", TYPE_INSERT, oper.getType());
-            assertEquals("Incorrect target", Data.CONTENT_URI, oper.getUri());
-        }
-        {
-            final ContentProviderOperation oper = diff.get(4);
-            assertEquals("Expected aggregation mode change", TYPE_UPDATE, oper.getType());
-            assertEquals("Incorrect target", RawContacts.CONTENT_URI, oper.getUri());
-        }
-    }
-
-    public void testEntityDiffNoneUpdate() {
-        final RawContact before = getRawContact(mContext, TEST_CONTACT_ID, TEST_PHONE_ID);
-        final RawContactDelta source = RawContactDelta.fromBefore(before);
-
-        // Update existing phone number
-        final ValuesDelta child = source.getEntry(TEST_PHONE_ID);
-        child.put(Phone.NUMBER, TEST_PHONE_NUMBER_2);
-
-        // Assert that version is enforced
-        final ArrayList<ContentProviderOperation> diff = Lists.newArrayList();
-        source.buildAssert(diff);
-        source.buildDiff(diff);
-        assertEquals("Unexpected operations", 4, diff.size());
-        {
-            final ContentProviderOperation oper = diff.get(0);
-            assertEquals("Expected version enforcement", TYPE_ASSERT, oper.getType());
-        }
-        {
-            final ContentProviderOperation oper = diff.get(1);
-            assertEquals("Expected aggregation mode change", TYPE_UPDATE, oper.getType());
-            assertEquals("Incorrect target", RawContacts.CONTENT_URI, oper.getUri());
-        }
-        {
-            final ContentProviderOperation oper = diff.get(2);
-            assertEquals("Incorrect type", TYPE_UPDATE, oper.getType());
-            assertEquals("Incorrect target", Data.CONTENT_URI, oper.getUri());
-        }
-        {
-            final ContentProviderOperation oper = diff.get(3);
-            assertEquals("Expected aggregation mode change", TYPE_UPDATE, oper.getType());
-            assertEquals("Incorrect target", RawContacts.CONTENT_URI, oper.getUri());
-        }
-    }
-
-    public void testEntityDiffDelete() {
-        final RawContact before = getRawContact(mContext, TEST_CONTACT_ID, TEST_PHONE_ID);
-        final RawContactDelta source = RawContactDelta.fromBefore(before);
-
-        // Delete entire entity
-        source.getValues().markDeleted();
-
-        // Assert two operations: delete Contact and enforce version
-        final ArrayList<ContentProviderOperation> diff = Lists.newArrayList();
-        source.buildAssert(diff);
-        source.buildDiff(diff);
-        assertEquals("Unexpected operations", 2, diff.size());
-        {
-            final ContentProviderOperation oper = diff.get(0);
-            assertEquals("Expected version enforcement", TYPE_ASSERT, oper.getType());
-        }
-        {
-            final ContentProviderOperation oper = diff.get(1);
-            assertEquals("Incorrect type", TYPE_DELETE, oper.getType());
-            assertEquals("Incorrect target", RawContacts.CONTENT_URI, oper.getUri());
-        }
-    }
-
-    public void testEntityDiffInsert() {
-        // Insert a RawContact
-        final ContentValues after = new ContentValues();
-        after.put(RawContacts.ACCOUNT_NAME, TEST_ACCOUNT_NAME);
-        after.put(RawContacts.SEND_TO_VOICEMAIL, 1);
-
-        final ValuesDelta values = ValuesDelta.fromAfter(after);
-        final RawContactDelta source = new RawContactDelta(values);
-
-        // Assert two operations: delete Contact and enforce version
-        final ArrayList<ContentProviderOperation> diff = Lists.newArrayList();
-        source.buildAssert(diff);
-        source.buildDiff(diff);
-        assertEquals("Unexpected operations", 2, diff.size());
-        {
-            final ContentProviderOperation oper = diff.get(0);
-            assertEquals("Incorrect type", TYPE_INSERT, oper.getType());
-            assertEquals("Incorrect target", RawContacts.CONTENT_URI, oper.getUri());
-        }
-    }
-
-    public void testEntityDiffInsertInsert() {
-        // Insert a RawContact
-        final ContentValues after = new ContentValues();
-        after.put(RawContacts.ACCOUNT_NAME, TEST_ACCOUNT_NAME);
-        after.put(RawContacts.SEND_TO_VOICEMAIL, 1);
-
-        final ValuesDelta values = ValuesDelta.fromAfter(after);
-        final RawContactDelta source = new RawContactDelta(values);
-
-        // Insert a new phone number
-        final ContentValues phone = new ContentValues();
-        phone.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
-        phone.put(Phone.NUMBER, TEST_PHONE_NUMBER_2);
-        phone.put(Phone.TYPE, Phone.TYPE_WORK);
-        source.addEntry(ValuesDelta.fromAfter(phone));
-
-        // Assert two operations: delete Contact and enforce version
-        final ArrayList<ContentProviderOperation> diff = Lists.newArrayList();
-        source.buildAssert(diff);
-        source.buildDiff(diff);
-        assertEquals("Unexpected operations", 3, diff.size());
-        {
-            final ContentProviderOperation oper = diff.get(0);
-            assertEquals("Incorrect type", TYPE_INSERT, oper.getType());
-            assertEquals("Incorrect target", RawContacts.CONTENT_URI, oper.getUri());
-        }
-        {
-            final ContentProviderOperation oper = diff.get(1);
-            assertEquals("Incorrect type", TYPE_INSERT, oper.getType());
-            assertEquals("Incorrect target", Data.CONTENT_URI, oper.getUri());
-
-        }
-    }
-}
diff --git a/tests/src/com/android/contacts/RawContactModifierTests.java b/tests/src/com/android/contacts/RawContactModifierTests.java
deleted file mode 100644
index ce69b55..0000000
--- a/tests/src/com/android/contacts/RawContactModifierTests.java
+++ /dev/null
@@ -1,1235 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.contacts;
-
-import static android.content.ContentProviderOperation.TYPE_DELETE;
-import static android.content.ContentProviderOperation.TYPE_INSERT;
-import static android.content.ContentProviderOperation.TYPE_UPDATE;
-
-import android.content.ContentProviderOperation;
-import android.content.ContentValues;
-import android.net.Uri;
-import android.os.Bundle;
-import android.provider.ContactsContract;
-import android.provider.ContactsContract.CommonDataKinds.Email;
-import android.provider.ContactsContract.CommonDataKinds.Event;
-import android.provider.ContactsContract.CommonDataKinds.Im;
-import android.provider.ContactsContract.CommonDataKinds.Organization;
-import android.provider.ContactsContract.CommonDataKinds.Phone;
-import android.provider.ContactsContract.CommonDataKinds.StructuredName;
-import android.provider.ContactsContract.CommonDataKinds.StructuredPostal;
-import android.provider.ContactsContract.Data;
-import android.provider.ContactsContract.Intents.Insert;
-import android.provider.ContactsContract.RawContacts;
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.LargeTest;
-
-import com.android.contacts.common.model.AccountTypeManager;
-import com.android.contacts.model.RawContact;
-import com.android.contacts.model.RawContactDelta;
-import com.android.contacts.common.model.ValuesDelta;
-import com.android.contacts.model.RawContactDeltaList;
-import com.android.contacts.model.RawContactModifier;
-import com.android.contacts.common.model.account.AccountType;
-import com.android.contacts.common.model.account.AccountType.EditType;
-import com.android.contacts.common.model.account.ExchangeAccountType;
-import com.android.contacts.common.model.account.GoogleAccountType;
-import com.android.contacts.common.model.dataitem.DataKind;
-import com.android.contacts.common.test.mocks.ContactsMockContext;
-import com.android.contacts.tests.mocks.MockAccountTypeManager;
-import com.android.contacts.common.test.mocks.MockContentProvider;
-import com.google.common.collect.Lists;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Tests for {@link RawContactModifier} to verify that {@link AccountType}
- * constraints are being enforced correctly.
- */
-@LargeTest
-public class RawContactModifierTests extends AndroidTestCase {
-    public static final String TAG = "EntityModifierTests";
-
-    public static final long VER_FIRST = 100;
-
-    private static final long TEST_ID = 4;
-    private static final String TEST_PHONE = "218-555-1212";
-    private static final String TEST_NAME = "Adam Young";
-    private static final String TEST_NAME2 = "Breanne Duren";
-    private static final String TEST_IM = "example@example.com";
-    private static final String TEST_POSTAL = "1600 Amphitheatre Parkway";
-
-    private static final String TEST_ACCOUNT_NAME = "unittest@example.com";
-    private static final String TEST_ACCOUNT_TYPE = "com.example.unittest";
-
-    private static final String EXCHANGE_ACCT_TYPE = "com.android.exchange";
-
-    @Override
-    public void setUp() {
-        mContext = getContext();
-    }
-
-    public static class MockContactsSource extends AccountType {
-
-        MockContactsSource() {
-            try {
-                this.accountType = TEST_ACCOUNT_TYPE;
-
-                final DataKind nameKind = new DataKind(StructuredName.CONTENT_ITEM_TYPE,
-                        R.string.nameLabelsGroup, -1, true);
-                nameKind.typeOverallMax = 1;
-                addKind(nameKind);
-
-                // Phone allows maximum 2 home, 1 work, and unlimited other, with
-                // constraint of 5 numbers maximum.
-                final DataKind phoneKind = new DataKind(
-                        Phone.CONTENT_ITEM_TYPE, -1, 10, true);
-
-                phoneKind.typeOverallMax = 5;
-                phoneKind.typeColumn = Phone.TYPE;
-                phoneKind.typeList = Lists.newArrayList();
-                phoneKind.typeList.add(new EditType(Phone.TYPE_HOME, -1).setSpecificMax(2));
-                phoneKind.typeList.add(new EditType(Phone.TYPE_WORK, -1).setSpecificMax(1));
-                phoneKind.typeList.add(new EditType(Phone.TYPE_FAX_WORK, -1).setSecondary(true));
-                phoneKind.typeList.add(new EditType(Phone.TYPE_OTHER, -1));
-
-                phoneKind.fieldList = Lists.newArrayList();
-                phoneKind.fieldList.add(new EditField(Phone.NUMBER, -1, -1));
-                phoneKind.fieldList.add(new EditField(Phone.LABEL, -1, -1));
-
-                addKind(phoneKind);
-
-                // Email is unlimited
-                final DataKind emailKind = new DataKind(Email.CONTENT_ITEM_TYPE, -1, 10, true);
-                emailKind.typeOverallMax = -1;
-                emailKind.fieldList = Lists.newArrayList();
-                emailKind.fieldList.add(new EditField(Email.DATA, -1, -1));
-                addKind(emailKind);
-
-                // IM is only one
-                final DataKind imKind = new DataKind(Im.CONTENT_ITEM_TYPE, -1, 10, true);
-                imKind.typeOverallMax = 1;
-                imKind.fieldList = Lists.newArrayList();
-                imKind.fieldList.add(new EditField(Im.DATA, -1, -1));
-                addKind(imKind);
-
-                // Organization is only one
-                final DataKind orgKind = new DataKind(Organization.CONTENT_ITEM_TYPE, -1, 10, true);
-                orgKind.typeOverallMax = 1;
-                orgKind.fieldList = Lists.newArrayList();
-                orgKind.fieldList.add(new EditField(Organization.COMPANY, -1, -1));
-                orgKind.fieldList.add(new EditField(Organization.TITLE, -1, -1));
-                addKind(orgKind);
-            } catch (DefinitionException e) {
-                throw new RuntimeException(e);
-            }
-        }
-
-        @Override
-        public boolean isGroupMembershipEditable() {
-            return false;
-        }
-
-        @Override
-        public boolean areContactsWritable() {
-            return true;
-        }
-    }
-
-    /**
-     * Build a {@link AccountType} that has various odd constraints for
-     * testing purposes.
-     */
-    protected AccountType getAccountType() {
-        return new MockContactsSource();
-    }
-
-    /**
-     * Build {@link AccountTypeManager} instance.
-     */
-    protected AccountTypeManager getAccountTypes(AccountType... types) {
-        return new MockAccountTypeManager(types, null);
-    }
-
-    /**
-     * Build an {@link RawContact} with the requested set of phone numbers.
-     */
-    protected RawContactDelta getRawContact(Long existingId, ContentValues... entries) {
-        final ContentValues contact = new ContentValues();
-        if (existingId != null) {
-            contact.put(RawContacts._ID, existingId);
-        }
-        contact.put(RawContacts.ACCOUNT_NAME, TEST_ACCOUNT_NAME);
-        contact.put(RawContacts.ACCOUNT_TYPE, TEST_ACCOUNT_TYPE);
-
-        final RawContact before = new RawContact(contact);
-        for (ContentValues values : entries) {
-            before.addDataItemValues(values);
-        }
-        return RawContactDelta.fromBefore(before);
-    }
-
-    /**
-     * Assert this {@link List} contains the given {@link Object}.
-     */
-    protected void assertContains(List<?> list, Object object) {
-        assertTrue("Missing expected value", list.contains(object));
-    }
-
-    /**
-     * Assert this {@link List} does not contain the given {@link Object}.
-     */
-    protected void assertNotContains(List<?> list, Object object) {
-        assertFalse("Contained unexpected value", list.contains(object));
-    }
-
-    /**
-     * Insert various rows to test
-     * {@link RawContactModifier#getValidTypes(RawContactDelta, DataKind, EditType)}
-     */
-    public void testValidTypes() {
-        // Build a source and pull specific types
-        final AccountType source = getAccountType();
-        final DataKind kindPhone = source.getKindForMimetype(Phone.CONTENT_ITEM_TYPE);
-        final EditType typeHome = RawContactModifier.getType(kindPhone, Phone.TYPE_HOME);
-        final EditType typeWork = RawContactModifier.getType(kindPhone, Phone.TYPE_WORK);
-        final EditType typeOther = RawContactModifier.getType(kindPhone, Phone.TYPE_OTHER);
-
-        List<EditType> validTypes;
-
-        // Add first home, first work
-        final RawContactDelta state = getRawContact(TEST_ID);
-        RawContactModifier.insertChild(state, kindPhone, typeHome);
-        RawContactModifier.insertChild(state, kindPhone, typeWork);
-
-        // Expecting home, other
-        validTypes = RawContactModifier.getValidTypes(state, kindPhone, null);
-        assertContains(validTypes, typeHome);
-        assertNotContains(validTypes, typeWork);
-        assertContains(validTypes, typeOther);
-
-        // Add second home
-        RawContactModifier.insertChild(state, kindPhone, typeHome);
-
-        // Expecting other
-        validTypes = RawContactModifier.getValidTypes(state, kindPhone, null);
-        assertNotContains(validTypes, typeHome);
-        assertNotContains(validTypes, typeWork);
-        assertContains(validTypes, typeOther);
-
-        // Add third and fourth home (invalid, but possible)
-        RawContactModifier.insertChild(state, kindPhone, typeHome);
-        RawContactModifier.insertChild(state, kindPhone, typeHome);
-
-        // Expecting none
-        validTypes = RawContactModifier.getValidTypes(state, kindPhone, null);
-        assertNotContains(validTypes, typeHome);
-        assertNotContains(validTypes, typeWork);
-        assertNotContains(validTypes, typeOther);
-    }
-
-    /**
-     * Test {@link RawContactModifier#canInsert(RawContactDelta, DataKind)} by
-     * inserting various rows.
-     */
-    public void testCanInsert() {
-        // Build a source and pull specific types
-        final AccountType source = getAccountType();
-        final DataKind kindPhone = source.getKindForMimetype(Phone.CONTENT_ITEM_TYPE);
-        final EditType typeHome = RawContactModifier.getType(kindPhone, Phone.TYPE_HOME);
-        final EditType typeWork = RawContactModifier.getType(kindPhone, Phone.TYPE_WORK);
-        final EditType typeOther = RawContactModifier.getType(kindPhone, Phone.TYPE_OTHER);
-
-        // Add first home, first work
-        final RawContactDelta state = getRawContact(TEST_ID);
-        RawContactModifier.insertChild(state, kindPhone, typeHome);
-        RawContactModifier.insertChild(state, kindPhone, typeWork);
-        assertTrue("Unable to insert", RawContactModifier.canInsert(state, kindPhone));
-
-        // Add two other, which puts us just under "5" overall limit
-        RawContactModifier.insertChild(state, kindPhone, typeOther);
-        RawContactModifier.insertChild(state, kindPhone, typeOther);
-        assertTrue("Unable to insert", RawContactModifier.canInsert(state, kindPhone));
-
-        // Add second home, which should push to snug limit
-        RawContactModifier.insertChild(state, kindPhone, typeHome);
-        assertFalse("Able to insert", RawContactModifier.canInsert(state, kindPhone));
-    }
-
-    /**
-     * Test
-     * {@link RawContactModifier#getBestValidType(RawContactDelta, DataKind, boolean, int)}
-     * by asserting expected best options in various states.
-     */
-    public void testBestValidType() {
-        // Build a source and pull specific types
-        final AccountType source = getAccountType();
-        final DataKind kindPhone = source.getKindForMimetype(Phone.CONTENT_ITEM_TYPE);
-        final EditType typeHome = RawContactModifier.getType(kindPhone, Phone.TYPE_HOME);
-        final EditType typeWork = RawContactModifier.getType(kindPhone, Phone.TYPE_WORK);
-        final EditType typeFaxWork = RawContactModifier.getType(kindPhone, Phone.TYPE_FAX_WORK);
-        final EditType typeOther = RawContactModifier.getType(kindPhone, Phone.TYPE_OTHER);
-
-        EditType suggested;
-
-        // Default suggestion should be home
-        final RawContactDelta state = getRawContact(TEST_ID);
-        suggested = RawContactModifier.getBestValidType(state, kindPhone, false, Integer.MIN_VALUE);
-        assertEquals("Unexpected suggestion", typeHome, suggested);
-
-        // Add first home, should now suggest work
-        RawContactModifier.insertChild(state, kindPhone, typeHome);
-        suggested = RawContactModifier.getBestValidType(state, kindPhone, false, Integer.MIN_VALUE);
-        assertEquals("Unexpected suggestion", typeWork, suggested);
-
-        // Add work fax, should still suggest work
-        RawContactModifier.insertChild(state, kindPhone, typeFaxWork);
-        suggested = RawContactModifier.getBestValidType(state, kindPhone, false, Integer.MIN_VALUE);
-        assertEquals("Unexpected suggestion", typeWork, suggested);
-
-        // Add other, should still suggest work
-        RawContactModifier.insertChild(state, kindPhone, typeOther);
-        suggested = RawContactModifier.getBestValidType(state, kindPhone, false, Integer.MIN_VALUE);
-        assertEquals("Unexpected suggestion", typeWork, suggested);
-
-        // Add work, now should suggest other
-        RawContactModifier.insertChild(state, kindPhone, typeWork);
-        suggested = RawContactModifier.getBestValidType(state, kindPhone, false, Integer.MIN_VALUE);
-        assertEquals("Unexpected suggestion", typeOther, suggested);
-    }
-
-    public void testIsEmptyEmpty() {
-        final AccountType source = getAccountType();
-        final DataKind kindPhone = source.getKindForMimetype(Phone.CONTENT_ITEM_TYPE);
-
-        // Test entirely empty row
-        final ContentValues after = new ContentValues();
-        final ValuesDelta values = ValuesDelta.fromAfter(after);
-
-        assertTrue("Expected empty", RawContactModifier.isEmpty(values, kindPhone));
-    }
-
-    public void testIsEmptyDirectFields() {
-        final AccountType source = getAccountType();
-        final DataKind kindPhone = source.getKindForMimetype(Phone.CONTENT_ITEM_TYPE);
-        final EditType typeHome = RawContactModifier.getType(kindPhone, Phone.TYPE_HOME);
-
-        // Test row that has type values, but core fields are empty
-        final RawContactDelta state = getRawContact(TEST_ID);
-        final ValuesDelta values = RawContactModifier.insertChild(state, kindPhone, typeHome);
-
-        assertTrue("Expected empty", RawContactModifier.isEmpty(values, kindPhone));
-
-        // Insert some data to trigger non-empty state
-        values.put(Phone.NUMBER, TEST_PHONE);
-
-        assertFalse("Expected non-empty", RawContactModifier.isEmpty(values, kindPhone));
-    }
-
-    public void testTrimEmptySingle() {
-        final AccountType source = getAccountType();
-        final DataKind kindPhone = source.getKindForMimetype(Phone.CONTENT_ITEM_TYPE);
-        final EditType typeHome = RawContactModifier.getType(kindPhone, Phone.TYPE_HOME);
-
-        // Test row that has type values, but core fields are empty
-        final RawContactDelta state = getRawContact(TEST_ID);
-        RawContactModifier.insertChild(state, kindPhone, typeHome);
-
-        // Build diff, expecting insert for data row and update enforcement
-        final ArrayList<ContentProviderOperation> diff = Lists.newArrayList();
-        state.buildDiff(diff);
-        assertEquals("Unexpected operations", 3, diff.size());
-        {
-            final ContentProviderOperation oper = diff.get(0);
-            assertEquals("Expected aggregation mode change", TYPE_UPDATE, oper.getType());
-            assertEquals("Incorrect target", RawContacts.CONTENT_URI, oper.getUri());
-        }
-        {
-            final ContentProviderOperation oper = diff.get(1);
-            assertEquals("Incorrect type", TYPE_INSERT, oper.getType());
-            assertEquals("Incorrect target", Data.CONTENT_URI, oper.getUri());
-        }
-        {
-            final ContentProviderOperation oper = diff.get(2);
-            assertEquals("Expected aggregation mode change", TYPE_UPDATE, oper.getType());
-            assertEquals("Incorrect target", RawContacts.CONTENT_URI, oper.getUri());
-        }
-
-        // Trim empty rows and try again, expecting delete of overall contact
-        RawContactModifier.trimEmpty(state, source);
-        diff.clear();
-        state.buildDiff(diff);
-        assertEquals("Unexpected operations", 1, diff.size());
-        {
-            final ContentProviderOperation oper = diff.get(0);
-            assertEquals("Incorrect type", TYPE_DELETE, oper.getType());
-            assertEquals("Incorrect target", RawContacts.CONTENT_URI, oper.getUri());
-        }
-    }
-
-    public void testTrimEmptySpaces() {
-        final AccountType source = getAccountType();
-        final DataKind kindPhone = source.getKindForMimetype(Phone.CONTENT_ITEM_TYPE);
-        final EditType typeHome = RawContactModifier.getType(kindPhone, Phone.TYPE_HOME);
-
-        // Test row that has type values, but values are spaces
-        final RawContactDelta state = RawContactDeltaListTests.buildBeforeEntity(mContext, TEST_ID,
-                VER_FIRST);
-        final ValuesDelta values = RawContactModifier.insertChild(state, kindPhone, typeHome);
-        values.put(Phone.NUMBER, "   ");
-
-        // Build diff, expecting insert for data row and update enforcement
-        RawContactDeltaListTests.assertDiffPattern(state,
-                RawContactDeltaListTests.buildAssertVersion(VER_FIRST),
-                RawContactDeltaListTests.buildUpdateAggregationSuspended(),
-                RawContactDeltaListTests.buildOper(Data.CONTENT_URI, TYPE_INSERT,
-                        RawContactDeltaListTests.buildDataInsert(values, TEST_ID)),
-                RawContactDeltaListTests.buildUpdateAggregationDefault());
-
-        // Trim empty rows and try again, expecting delete of overall contact
-        RawContactModifier.trimEmpty(state, source);
-        RawContactDeltaListTests.assertDiffPattern(state,
-                RawContactDeltaListTests.buildAssertVersion(VER_FIRST),
-                RawContactDeltaListTests.buildDelete(RawContacts.CONTENT_URI));
-    }
-
-    public void testTrimLeaveValid() {
-        final AccountType source = getAccountType();
-        final DataKind kindPhone = source.getKindForMimetype(Phone.CONTENT_ITEM_TYPE);
-        final EditType typeHome = RawContactModifier.getType(kindPhone, Phone.TYPE_HOME);
-
-        // Test row that has type values with valid number
-        final RawContactDelta state = RawContactDeltaListTests.buildBeforeEntity(mContext, TEST_ID,
-                VER_FIRST);
-        final ValuesDelta values = RawContactModifier.insertChild(state, kindPhone, typeHome);
-        values.put(Phone.NUMBER, TEST_PHONE);
-
-        // Build diff, expecting insert for data row and update enforcement
-        RawContactDeltaListTests.assertDiffPattern(state,
-                RawContactDeltaListTests.buildAssertVersion(VER_FIRST),
-                RawContactDeltaListTests.buildUpdateAggregationSuspended(),
-                RawContactDeltaListTests.buildOper(Data.CONTENT_URI, TYPE_INSERT,
-                        RawContactDeltaListTests.buildDataInsert(values, TEST_ID)),
-                RawContactDeltaListTests.buildUpdateAggregationDefault());
-
-        // Trim empty rows and try again, expecting no differences
-        RawContactModifier.trimEmpty(state, source);
-        RawContactDeltaListTests.assertDiffPattern(state,
-                RawContactDeltaListTests.buildAssertVersion(VER_FIRST),
-                RawContactDeltaListTests.buildUpdateAggregationSuspended(),
-                RawContactDeltaListTests.buildOper(Data.CONTENT_URI, TYPE_INSERT,
-                        RawContactDeltaListTests.buildDataInsert(values, TEST_ID)),
-                RawContactDeltaListTests.buildUpdateAggregationDefault());
-    }
-
-    public void testTrimEmptyUntouched() {
-        final AccountType source = getAccountType();
-        final DataKind kindPhone = source.getKindForMimetype(Phone.CONTENT_ITEM_TYPE);
-        RawContactModifier.getType(kindPhone, Phone.TYPE_HOME);
-
-        // Build "before" that has empty row
-        final RawContactDelta state = getRawContact(TEST_ID);
-        final ContentValues before = new ContentValues();
-        before.put(Data._ID, TEST_ID);
-        before.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
-        state.addEntry(ValuesDelta.fromBefore(before));
-
-        // Build diff, expecting no changes
-        final ArrayList<ContentProviderOperation> diff = Lists.newArrayList();
-        state.buildDiff(diff);
-        assertEquals("Unexpected operations", 0, diff.size());
-
-        // Try trimming existing empty, which we shouldn't touch
-        RawContactModifier.trimEmpty(state, source);
-        diff.clear();
-        state.buildDiff(diff);
-        assertEquals("Unexpected operations", 0, diff.size());
-    }
-
-    public void testTrimEmptyAfterUpdate() {
-        final AccountType source = getAccountType();
-        final DataKind kindPhone = source.getKindForMimetype(Phone.CONTENT_ITEM_TYPE);
-        final EditType typeHome = RawContactModifier.getType(kindPhone, Phone.TYPE_HOME);
-
-        // Build "before" that has row with some phone number
-        final ContentValues before = new ContentValues();
-        before.put(Data._ID, TEST_ID);
-        before.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
-        before.put(kindPhone.typeColumn, typeHome.rawValue);
-        before.put(Phone.NUMBER, TEST_PHONE);
-        final RawContactDelta state = getRawContact(TEST_ID, before);
-
-        // Build diff, expecting no changes
-        final ArrayList<ContentProviderOperation> diff = Lists.newArrayList();
-        state.buildDiff(diff);
-        assertEquals("Unexpected operations", 0, diff.size());
-
-        // Now update row by changing number to empty string, expecting single update
-        final ValuesDelta child = state.getEntry(TEST_ID);
-        child.put(Phone.NUMBER, "");
-        diff.clear();
-        state.buildDiff(diff);
-        assertEquals("Unexpected operations", 3, diff.size());
-        {
-            final ContentProviderOperation oper = diff.get(0);
-            assertEquals("Expected aggregation mode change", TYPE_UPDATE, oper.getType());
-            assertEquals("Incorrect target", RawContacts.CONTENT_URI, oper.getUri());
-        }
-        {
-            final ContentProviderOperation oper = diff.get(1);
-            assertEquals("Incorrect type", TYPE_UPDATE, oper.getType());
-            assertEquals("Incorrect target", Data.CONTENT_URI, oper.getUri());
-        }
-        {
-            final ContentProviderOperation oper = diff.get(2);
-            assertEquals("Expected aggregation mode change", TYPE_UPDATE, oper.getType());
-            assertEquals("Incorrect target", RawContacts.CONTENT_URI, oper.getUri());
-        }
-
-        // Now run trim, which should turn that update into delete
-        RawContactModifier.trimEmpty(state, source);
-        diff.clear();
-        state.buildDiff(diff);
-        assertEquals("Unexpected operations", 1, diff.size());
-        {
-            final ContentProviderOperation oper = diff.get(0);
-            assertEquals("Incorrect type", TYPE_DELETE, oper.getType());
-            assertEquals("Incorrect target", RawContacts.CONTENT_URI, oper.getUri());
-        }
-    }
-
-    public void testTrimInsertEmpty() {
-        final AccountType accountType = getAccountType();
-        final AccountTypeManager accountTypes = getAccountTypes(accountType);
-        final DataKind kindPhone = accountType.getKindForMimetype(Phone.CONTENT_ITEM_TYPE);
-        RawContactModifier.getType(kindPhone, Phone.TYPE_HOME);
-
-        // Try creating a contact without any child entries
-        final RawContactDelta state = getRawContact(null);
-        final RawContactDeltaList set = new RawContactDeltaList();
-        set.add(state);
-
-
-        // Build diff, expecting single insert
-        final ArrayList<ContentProviderOperation> diff = Lists.newArrayList();
-        state.buildDiff(diff);
-        assertEquals("Unexpected operations", 2, diff.size());
-        {
-            final ContentProviderOperation oper = diff.get(0);
-            assertEquals("Incorrect type", TYPE_INSERT, oper.getType());
-            assertEquals("Incorrect target", RawContacts.CONTENT_URI, oper.getUri());
-        }
-
-        // Trim empty rows and try again, expecting no insert
-        RawContactModifier.trimEmpty(set, accountTypes);
-        diff.clear();
-        state.buildDiff(diff);
-        assertEquals("Unexpected operations", 0, diff.size());
-    }
-
-    public void testTrimInsertInsert() {
-        final AccountType accountType = getAccountType();
-        final AccountTypeManager accountTypes = getAccountTypes(accountType);
-        final DataKind kindPhone = accountType.getKindForMimetype(Phone.CONTENT_ITEM_TYPE);
-        final EditType typeHome = RawContactModifier.getType(kindPhone, Phone.TYPE_HOME);
-
-        // Try creating a contact with single empty entry
-        final RawContactDelta state = getRawContact(null);
-        RawContactModifier.insertChild(state, kindPhone, typeHome);
-        final RawContactDeltaList set = new RawContactDeltaList();
-        set.add(state);
-
-        // Build diff, expecting two insert operations
-        final ArrayList<ContentProviderOperation> diff = Lists.newArrayList();
-        state.buildDiff(diff);
-        assertEquals("Unexpected operations", 3, diff.size());
-        {
-            final ContentProviderOperation oper = diff.get(0);
-            assertEquals("Incorrect type", TYPE_INSERT, oper.getType());
-            assertEquals("Incorrect target", RawContacts.CONTENT_URI, oper.getUri());
-        }
-        {
-            final ContentProviderOperation oper = diff.get(1);
-            assertEquals("Incorrect type", TYPE_INSERT, oper.getType());
-            assertEquals("Incorrect target", Data.CONTENT_URI, oper.getUri());
-        }
-
-        // Trim empty rows and try again, expecting silence
-        RawContactModifier.trimEmpty(set, accountTypes);
-        diff.clear();
-        state.buildDiff(diff);
-        assertEquals("Unexpected operations", 0, diff.size());
-    }
-
-    public void testTrimUpdateRemain() {
-        final AccountType accountType = getAccountType();
-        final AccountTypeManager accountTypes = getAccountTypes(accountType);
-        final DataKind kindPhone = accountType.getKindForMimetype(Phone.CONTENT_ITEM_TYPE);
-        final EditType typeHome = RawContactModifier.getType(kindPhone, Phone.TYPE_HOME);
-
-        // Build "before" with two phone numbers
-        final ContentValues first = new ContentValues();
-        first.put(Data._ID, TEST_ID);
-        first.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
-        first.put(kindPhone.typeColumn, typeHome.rawValue);
-        first.put(Phone.NUMBER, TEST_PHONE);
-
-        final ContentValues second = new ContentValues();
-        second.put(Data._ID, TEST_ID);
-        second.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
-        second.put(kindPhone.typeColumn, typeHome.rawValue);
-        second.put(Phone.NUMBER, TEST_PHONE);
-
-        final RawContactDelta state = getRawContact(TEST_ID, first, second);
-        final RawContactDeltaList set = new RawContactDeltaList();
-        set.add(state);
-
-        // Build diff, expecting no changes
-        final ArrayList<ContentProviderOperation> diff = Lists.newArrayList();
-        state.buildDiff(diff);
-        assertEquals("Unexpected operations", 0, diff.size());
-
-        // Now update row by changing number to empty string, expecting single update
-        final ValuesDelta child = state.getEntry(TEST_ID);
-        child.put(Phone.NUMBER, "");
-        diff.clear();
-        state.buildDiff(diff);
-        assertEquals("Unexpected operations", 3, diff.size());
-        {
-            final ContentProviderOperation oper = diff.get(0);
-            assertEquals("Expected aggregation mode change", TYPE_UPDATE, oper.getType());
-            assertEquals("Incorrect target", RawContacts.CONTENT_URI, oper.getUri());
-        }
-        {
-            final ContentProviderOperation oper = diff.get(1);
-            assertEquals("Incorrect type", TYPE_UPDATE, oper.getType());
-            assertEquals("Incorrect target", Data.CONTENT_URI, oper.getUri());
-        }
-        {
-            final ContentProviderOperation oper = diff.get(2);
-            assertEquals("Expected aggregation mode change", TYPE_UPDATE, oper.getType());
-            assertEquals("Incorrect target", RawContacts.CONTENT_URI, oper.getUri());
-        }
-
-        // Now run trim, which should turn that update into delete
-        RawContactModifier.trimEmpty(set, accountTypes);
-        diff.clear();
-        state.buildDiff(diff);
-        assertEquals("Unexpected operations", 3, diff.size());
-        {
-            final ContentProviderOperation oper = diff.get(0);
-            assertEquals("Expected aggregation mode change", TYPE_UPDATE, oper.getType());
-            assertEquals("Incorrect target", RawContacts.CONTENT_URI, oper.getUri());
-        }
-        {
-            final ContentProviderOperation oper = diff.get(1);
-            assertEquals("Incorrect type", TYPE_DELETE, oper.getType());
-            assertEquals("Incorrect target", Data.CONTENT_URI, oper.getUri());
-        }
-        {
-            final ContentProviderOperation oper = diff.get(2);
-            assertEquals("Expected aggregation mode change", TYPE_UPDATE, oper.getType());
-            assertEquals("Incorrect target", RawContacts.CONTENT_URI, oper.getUri());
-        }
-    }
-
-    public void testTrimUpdateUpdate() {
-        final AccountType accountType = getAccountType();
-        final AccountTypeManager accountTypes = getAccountTypes(accountType);
-        final DataKind kindPhone = accountType.getKindForMimetype(Phone.CONTENT_ITEM_TYPE);
-        final EditType typeHome = RawContactModifier.getType(kindPhone, Phone.TYPE_HOME);
-
-        // Build "before" with two phone numbers
-        final ContentValues first = new ContentValues();
-        first.put(Data._ID, TEST_ID);
-        first.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
-        first.put(kindPhone.typeColumn, typeHome.rawValue);
-        first.put(Phone.NUMBER, TEST_PHONE);
-
-        final RawContactDelta state = getRawContact(TEST_ID, first);
-        final RawContactDeltaList set = new RawContactDeltaList();
-        set.add(state);
-
-        // Build diff, expecting no changes
-        final ArrayList<ContentProviderOperation> diff = Lists.newArrayList();
-        state.buildDiff(diff);
-        assertEquals("Unexpected operations", 0, diff.size());
-
-        // Now update row by changing number to empty string, expecting single update
-        final ValuesDelta child = state.getEntry(TEST_ID);
-        child.put(Phone.NUMBER, "");
-        diff.clear();
-        state.buildDiff(diff);
-        assertEquals("Unexpected operations", 3, diff.size());
-        {
-            final ContentProviderOperation oper = diff.get(0);
-            assertEquals("Expected aggregation mode change", TYPE_UPDATE, oper.getType());
-            assertEquals("Incorrect target", RawContacts.CONTENT_URI, oper.getUri());
-        }
-        {
-            final ContentProviderOperation oper = diff.get(1);
-            assertEquals("Incorrect type", TYPE_UPDATE, oper.getType());
-            assertEquals("Incorrect target", Data.CONTENT_URI, oper.getUri());
-        }
-        {
-            final ContentProviderOperation oper = diff.get(2);
-            assertEquals("Expected aggregation mode change", TYPE_UPDATE, oper.getType());
-            assertEquals("Incorrect target", RawContacts.CONTENT_URI, oper.getUri());
-        }
-
-        // Now run trim, which should turn into deleting the whole contact
-        RawContactModifier.trimEmpty(set, accountTypes);
-        diff.clear();
-        state.buildDiff(diff);
-        assertEquals("Unexpected operations", 1, diff.size());
-        {
-            final ContentProviderOperation oper = diff.get(0);
-            assertEquals("Incorrect type", TYPE_DELETE, oper.getType());
-            assertEquals("Incorrect target", RawContacts.CONTENT_URI, oper.getUri());
-        }
-    }
-
-    public void testParseExtrasExistingName() {
-        final AccountType accountType = getAccountType();
-
-        // Build "before" name
-        final ContentValues first = new ContentValues();
-        first.put(Data._ID, TEST_ID);
-        first.put(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE);
-        first.put(StructuredName.GIVEN_NAME, TEST_NAME);
-
-        // Parse extras, making sure we keep single name
-        final RawContactDelta state = getRawContact(TEST_ID, first);
-        final Bundle extras = new Bundle();
-        extras.putString(Insert.NAME, TEST_NAME2);
-        RawContactModifier.parseExtras(mContext, accountType, state, extras);
-
-        final int nameCount = state.getMimeEntriesCount(StructuredName.CONTENT_ITEM_TYPE, true);
-        assertEquals("Unexpected names", 1, nameCount);
-    }
-
-    public void testParseExtrasIgnoreLimit() {
-        final AccountType accountType = getAccountType();
-
-        // Build "before" IM
-        final ContentValues first = new ContentValues();
-        first.put(Data._ID, TEST_ID);
-        first.put(Data.MIMETYPE, Im.CONTENT_ITEM_TYPE);
-        first.put(Im.DATA, TEST_IM);
-
-        final RawContactDelta state = getRawContact(TEST_ID, first);
-        final int beforeCount = state.getMimeEntries(Im.CONTENT_ITEM_TYPE).size();
-
-        // We should ignore data that doesn't fit account type rules, since account type
-        // only allows single Im
-        final Bundle extras = new Bundle();
-        extras.putInt(Insert.IM_PROTOCOL, Im.PROTOCOL_GOOGLE_TALK);
-        extras.putString(Insert.IM_HANDLE, TEST_IM);
-        RawContactModifier.parseExtras(mContext, accountType, state, extras);
-
-        final int afterCount = state.getMimeEntries(Im.CONTENT_ITEM_TYPE).size();
-        assertEquals("Broke account type rules", beforeCount, afterCount);
-    }
-
-    public void testParseExtrasIgnoreUnhandled() {
-        final AccountType accountType = getAccountType();
-        final RawContactDelta state = getRawContact(TEST_ID);
-
-        // We should silently ignore types unsupported by account type
-        final Bundle extras = new Bundle();
-        extras.putString(Insert.POSTAL, TEST_POSTAL);
-        RawContactModifier.parseExtras(mContext, accountType, state, extras);
-
-        assertNull("Broke accoun type rules",
-                state.getMimeEntries(StructuredPostal.CONTENT_ITEM_TYPE));
-    }
-
-    public void testParseExtrasJobTitle() {
-        final AccountType accountType = getAccountType();
-        final RawContactDelta state = getRawContact(TEST_ID);
-
-        // Make sure that we create partial Organizations
-        final Bundle extras = new Bundle();
-        extras.putString(Insert.JOB_TITLE, TEST_NAME);
-        RawContactModifier.parseExtras(mContext, accountType, state, extras);
-
-        final int count = state.getMimeEntries(Organization.CONTENT_ITEM_TYPE).size();
-        assertEquals("Expected to create organization", 1, count);
-    }
-
-    public void testMigrateWithDisplayNameFromGoogleToExchange1() {
-        AccountType oldAccountType = new GoogleAccountType(getContext(), "");
-        AccountType newAccountType = new ExchangeAccountType(getContext(), "", EXCHANGE_ACCT_TYPE);
-        DataKind kind = newAccountType.getKindForMimetype(StructuredName.CONTENT_ITEM_TYPE);
-
-        ContactsMockContext context = new ContactsMockContext(getContext());
-
-        RawContactDelta oldState = new RawContactDelta();
-        ContentValues mockNameValues = new ContentValues();
-        mockNameValues.put(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE);
-        mockNameValues.put(StructuredName.PREFIX, "prefix");
-        mockNameValues.put(StructuredName.GIVEN_NAME, "given");
-        mockNameValues.put(StructuredName.MIDDLE_NAME, "middle");
-        mockNameValues.put(StructuredName.FAMILY_NAME, "family");
-        mockNameValues.put(StructuredName.SUFFIX, "suffix");
-        mockNameValues.put(StructuredName.PHONETIC_FAMILY_NAME, "PHONETIC_FAMILY");
-        mockNameValues.put(StructuredName.PHONETIC_MIDDLE_NAME, "PHONETIC_MIDDLE");
-        mockNameValues.put(StructuredName.PHONETIC_GIVEN_NAME, "PHONETIC_GIVEN");
-        oldState.addEntry(ValuesDelta.fromAfter(mockNameValues));
-
-        RawContactDelta newState = new RawContactDelta();
-        RawContactModifier.migrateStructuredName(context, oldState, newState, kind);
-        List<ValuesDelta> list = newState.getMimeEntries(StructuredName.CONTENT_ITEM_TYPE);
-        assertEquals(1, list.size());
-
-        ContentValues output = list.get(0).getAfter();
-        assertEquals("prefix", output.getAsString(StructuredName.PREFIX));
-        assertEquals("given", output.getAsString(StructuredName.GIVEN_NAME));
-        assertEquals("middle", output.getAsString(StructuredName.MIDDLE_NAME));
-        assertEquals("family", output.getAsString(StructuredName.FAMILY_NAME));
-        assertEquals("suffix", output.getAsString(StructuredName.SUFFIX));
-        // Phonetic middle name isn't supported by Exchange.
-        assertEquals("PHONETIC_FAMILY", output.getAsString(StructuredName.PHONETIC_FAMILY_NAME));
-        assertEquals("PHONETIC_GIVEN", output.getAsString(StructuredName.PHONETIC_GIVEN_NAME));
-    }
-
-    public void testMigrateWithDisplayNameFromGoogleToExchange2() {
-        AccountType oldAccountType = new GoogleAccountType(getContext(), "");
-        AccountType newAccountType = new ExchangeAccountType(getContext(), "", EXCHANGE_ACCT_TYPE);
-        DataKind kind = newAccountType.getKindForMimetype(StructuredName.CONTENT_ITEM_TYPE);
-
-        ContactsMockContext context = new ContactsMockContext(getContext());
-        MockContentProvider provider = context.getContactsProvider();
-
-        String inputDisplayName = "prefix given middle family suffix";
-        // The method will ask the provider to split/join StructuredName.
-        Uri uriForBuildDisplayName =
-                ContactsContract.AUTHORITY_URI
-                        .buildUpon()
-                        .appendPath("complete_name")
-                        .appendQueryParameter(StructuredName.DISPLAY_NAME, inputDisplayName)
-                        .build();
-        provider.expectQuery(uriForBuildDisplayName)
-                .returnRow("prefix", "given", "middle", "family", "suffix")
-                .withProjection(StructuredName.PREFIX, StructuredName.GIVEN_NAME,
-                        StructuredName.MIDDLE_NAME, StructuredName.FAMILY_NAME,
-                        StructuredName.SUFFIX);
-
-        RawContactDelta oldState = new RawContactDelta();
-        ContentValues mockNameValues = new ContentValues();
-        mockNameValues.put(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE);
-        mockNameValues.put(StructuredName.DISPLAY_NAME, inputDisplayName);
-        oldState.addEntry(ValuesDelta.fromAfter(mockNameValues));
-
-        RawContactDelta newState = new RawContactDelta();
-        RawContactModifier.migrateStructuredName(context, oldState, newState, kind);
-        List<ValuesDelta> list = newState.getMimeEntries(StructuredName.CONTENT_ITEM_TYPE);
-        assertEquals(1, list.size());
-
-        ContentValues outputValues = list.get(0).getAfter();
-        assertEquals("prefix", outputValues.getAsString(StructuredName.PREFIX));
-        assertEquals("given", outputValues.getAsString(StructuredName.GIVEN_NAME));
-        assertEquals("middle", outputValues.getAsString(StructuredName.MIDDLE_NAME));
-        assertEquals("family", outputValues.getAsString(StructuredName.FAMILY_NAME));
-        assertEquals("suffix", outputValues.getAsString(StructuredName.SUFFIX));
-    }
-
-    public void testMigrateWithStructuredNameFromExchangeToGoogle() {
-        AccountType oldAccountType = new ExchangeAccountType(getContext(), "", EXCHANGE_ACCT_TYPE);
-        AccountType newAccountType = new GoogleAccountType(getContext(), "");
-        DataKind kind = newAccountType.getKindForMimetype(StructuredName.CONTENT_ITEM_TYPE);
-
-        ContactsMockContext context = new ContactsMockContext(getContext());
-        MockContentProvider provider = context.getContactsProvider();
-
-        // The method will ask the provider to split/join StructuredName.
-        Uri uriForBuildDisplayName =
-                ContactsContract.AUTHORITY_URI
-                        .buildUpon()
-                        .appendPath("complete_name")
-                        .appendQueryParameter(StructuredName.PREFIX, "prefix")
-                        .appendQueryParameter(StructuredName.GIVEN_NAME, "given")
-                        .appendQueryParameter(StructuredName.MIDDLE_NAME, "middle")
-                        .appendQueryParameter(StructuredName.FAMILY_NAME, "family")
-                        .appendQueryParameter(StructuredName.SUFFIX, "suffix")
-                        .build();
-        provider.expectQuery(uriForBuildDisplayName)
-                .returnRow("prefix given middle family suffix")
-                .withProjection(StructuredName.DISPLAY_NAME);
-
-        RawContactDelta oldState = new RawContactDelta();
-        ContentValues mockNameValues = new ContentValues();
-        mockNameValues.put(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE);
-        mockNameValues.put(StructuredName.PREFIX, "prefix");
-        mockNameValues.put(StructuredName.GIVEN_NAME, "given");
-        mockNameValues.put(StructuredName.MIDDLE_NAME, "middle");
-        mockNameValues.put(StructuredName.FAMILY_NAME, "family");
-        mockNameValues.put(StructuredName.SUFFIX, "suffix");
-        oldState.addEntry(ValuesDelta.fromAfter(mockNameValues));
-
-        RawContactDelta newState = new RawContactDelta();
-        RawContactModifier.migrateStructuredName(context, oldState, newState, kind);
-
-        List<ValuesDelta> list = newState.getMimeEntries(StructuredName.CONTENT_ITEM_TYPE);
-        assertNotNull(list);
-        assertEquals(1, list.size());
-        ContentValues outputValues = list.get(0).getAfter();
-        assertEquals("prefix given middle family suffix",
-                outputValues.getAsString(StructuredName.DISPLAY_NAME));
-    }
-
-    public void testMigratePostalFromGoogleToExchange() {
-        AccountType oldAccountType = new GoogleAccountType(getContext(), "");
-        AccountType newAccountType = new ExchangeAccountType(getContext(), "", EXCHANGE_ACCT_TYPE);
-        DataKind kind = newAccountType.getKindForMimetype(StructuredPostal.CONTENT_ITEM_TYPE);
-
-        RawContactDelta oldState = new RawContactDelta();
-        ContentValues mockNameValues = new ContentValues();
-        mockNameValues.put(Data.MIMETYPE, StructuredPostal.CONTENT_ITEM_TYPE);
-        mockNameValues.put(StructuredPostal.FORMATTED_ADDRESS, "formatted_address");
-        oldState.addEntry(ValuesDelta.fromAfter(mockNameValues));
-
-        RawContactDelta newState = new RawContactDelta();
-        RawContactModifier.migratePostal(oldState, newState, kind);
-
-        List<ValuesDelta> list = newState.getMimeEntries(StructuredPostal.CONTENT_ITEM_TYPE);
-        assertNotNull(list);
-        assertEquals(1, list.size());
-        ContentValues outputValues = list.get(0).getAfter();
-        // FORMATTED_ADDRESS isn't supported by Exchange.
-        assertNull(outputValues.getAsString(StructuredPostal.FORMATTED_ADDRESS));
-        assertEquals("formatted_address", outputValues.getAsString(StructuredPostal.STREET));
-    }
-
-    public void testMigratePostalFromExchangeToGoogle() {
-        AccountType oldAccountType = new ExchangeAccountType(getContext(), "", EXCHANGE_ACCT_TYPE);
-        AccountType newAccountType = new GoogleAccountType(getContext(), "");
-        DataKind kind = newAccountType.getKindForMimetype(StructuredPostal.CONTENT_ITEM_TYPE);
-
-        RawContactDelta oldState = new RawContactDelta();
-        ContentValues mockNameValues = new ContentValues();
-        mockNameValues.put(Data.MIMETYPE, StructuredPostal.CONTENT_ITEM_TYPE);
-        mockNameValues.put(StructuredPostal.COUNTRY, "country");
-        mockNameValues.put(StructuredPostal.POSTCODE, "postcode");
-        mockNameValues.put(StructuredPostal.REGION, "region");
-        mockNameValues.put(StructuredPostal.CITY, "city");
-        mockNameValues.put(StructuredPostal.STREET, "street");
-        oldState.addEntry(ValuesDelta.fromAfter(mockNameValues));
-
-        RawContactDelta newState = new RawContactDelta();
-        RawContactModifier.migratePostal(oldState, newState, kind);
-
-        List<ValuesDelta> list = newState.getMimeEntries(StructuredPostal.CONTENT_ITEM_TYPE);
-        assertNotNull(list);
-        assertEquals(1, list.size());
-        ContentValues outputValues = list.get(0).getAfter();
-
-        // Check FORMATTED_ADDRESS contains all info.
-        String formattedAddress = outputValues.getAsString(StructuredPostal.FORMATTED_ADDRESS);
-        assertNotNull(formattedAddress);
-        assertTrue(formattedAddress.contains("country"));
-        assertTrue(formattedAddress.contains("postcode"));
-        assertTrue(formattedAddress.contains("region"));
-        assertTrue(formattedAddress.contains("postcode"));
-        assertTrue(formattedAddress.contains("city"));
-        assertTrue(formattedAddress.contains("street"));
-    }
-
-    public void testMigrateEventFromGoogleToExchange1() {
-        testMigrateEventCommon(new GoogleAccountType(getContext(), ""),
-                new ExchangeAccountType(getContext(), "", EXCHANGE_ACCT_TYPE));
-    }
-
-    public void testMigrateEventFromExchangeToGoogle() {
-        testMigrateEventCommon(new ExchangeAccountType(getContext(), "", EXCHANGE_ACCT_TYPE),
-                new GoogleAccountType(getContext(), ""));
-    }
-
-    private void testMigrateEventCommon(AccountType oldAccountType, AccountType newAccountType) {
-        DataKind kind = newAccountType.getKindForMimetype(Event.CONTENT_ITEM_TYPE);
-
-        RawContactDelta oldState = new RawContactDelta();
-        ContentValues mockNameValues = new ContentValues();
-        mockNameValues.put(Data.MIMETYPE, Event.CONTENT_ITEM_TYPE);
-        mockNameValues.put(Event.START_DATE, "1972-02-08");
-        mockNameValues.put(Event.TYPE, Event.TYPE_BIRTHDAY);
-        oldState.addEntry(ValuesDelta.fromAfter(mockNameValues));
-
-        RawContactDelta newState = new RawContactDelta();
-        RawContactModifier.migrateEvent(oldState, newState, kind, 1990);
-
-        List<ValuesDelta> list = newState.getMimeEntries(Event.CONTENT_ITEM_TYPE);
-        assertNotNull(list);
-        assertEquals(1, list.size());  // Anniversary should be dropped.
-        ContentValues outputValues = list.get(0).getAfter();
-
-        assertEquals("1972-02-08", outputValues.getAsString(Event.START_DATE));
-        assertEquals(Event.TYPE_BIRTHDAY, outputValues.getAsInteger(Event.TYPE).intValue());
-    }
-
-    public void testMigrateEventFromGoogleToExchange2() {
-        AccountType oldAccountType = new GoogleAccountType(getContext(), "");
-        AccountType newAccountType = new ExchangeAccountType(getContext(), "", EXCHANGE_ACCT_TYPE);
-        DataKind kind = newAccountType.getKindForMimetype(Event.CONTENT_ITEM_TYPE);
-
-        RawContactDelta oldState = new RawContactDelta();
-        ContentValues mockNameValues = new ContentValues();
-        mockNameValues.put(Data.MIMETYPE, Event.CONTENT_ITEM_TYPE);
-        // No year format is not supported by Exchange.
-        mockNameValues.put(Event.START_DATE, "--06-01");
-        mockNameValues.put(Event.TYPE, Event.TYPE_BIRTHDAY);
-        oldState.addEntry(ValuesDelta.fromAfter(mockNameValues));
-        mockNameValues = new ContentValues();
-        mockNameValues.put(Data.MIMETYPE, Event.CONTENT_ITEM_TYPE);
-        mockNameValues.put(Event.START_DATE, "1980-08-02");
-        // Anniversary is not supported by Exchange
-        mockNameValues.put(Event.TYPE, Event.TYPE_ANNIVERSARY);
-        oldState.addEntry(ValuesDelta.fromAfter(mockNameValues));
-
-        RawContactDelta newState = new RawContactDelta();
-        RawContactModifier.migrateEvent(oldState, newState, kind, 1990);
-
-        List<ValuesDelta> list = newState.getMimeEntries(Event.CONTENT_ITEM_TYPE);
-        assertNotNull(list);
-        assertEquals(1, list.size());  // Anniversary should be dropped.
-        ContentValues outputValues = list.get(0).getAfter();
-
-        // Default year should be used.
-        assertEquals("1990-06-01", outputValues.getAsString(Event.START_DATE));
-        assertEquals(Event.TYPE_BIRTHDAY, outputValues.getAsInteger(Event.TYPE).intValue());
-    }
-
-    public void testMigrateEmailFromGoogleToExchange() {
-        AccountType oldAccountType = new GoogleAccountType(getContext(), "");
-        AccountType newAccountType = new ExchangeAccountType(getContext(), "", EXCHANGE_ACCT_TYPE);
-        DataKind kind = newAccountType.getKindForMimetype(Email.CONTENT_ITEM_TYPE);
-
-        RawContactDelta oldState = new RawContactDelta();
-        ContentValues mockNameValues = new ContentValues();
-        mockNameValues.put(Data.MIMETYPE, Email.CONTENT_ITEM_TYPE);
-        mockNameValues.put(Email.TYPE, Email.TYPE_CUSTOM);
-        mockNameValues.put(Email.LABEL, "custom_type");
-        mockNameValues.put(Email.ADDRESS, "address1");
-        oldState.addEntry(ValuesDelta.fromAfter(mockNameValues));
-        mockNameValues = new ContentValues();
-        mockNameValues.put(Data.MIMETYPE, Email.CONTENT_ITEM_TYPE);
-        mockNameValues.put(Email.TYPE, Email.TYPE_HOME);
-        mockNameValues.put(Email.ADDRESS, "address2");
-        oldState.addEntry(ValuesDelta.fromAfter(mockNameValues));
-        mockNameValues = new ContentValues();
-        mockNameValues.put(Data.MIMETYPE, Email.CONTENT_ITEM_TYPE);
-        mockNameValues.put(Email.TYPE, Email.TYPE_WORK);
-        mockNameValues.put(Email.ADDRESS, "address3");
-        oldState.addEntry(ValuesDelta.fromAfter(mockNameValues));
-        // Exchange can have up to 3 email entries. This 4th entry should be dropped.
-        mockNameValues = new ContentValues();
-        mockNameValues.put(Data.MIMETYPE, Email.CONTENT_ITEM_TYPE);
-        mockNameValues.put(Email.TYPE, Email.TYPE_OTHER);
-        mockNameValues.put(Email.ADDRESS, "address4");
-        oldState.addEntry(ValuesDelta.fromAfter(mockNameValues));
-
-        RawContactDelta newState = new RawContactDelta();
-        RawContactModifier.migrateGenericWithTypeColumn(oldState, newState, kind);
-
-        List<ValuesDelta> list = newState.getMimeEntries(Email.CONTENT_ITEM_TYPE);
-        assertNotNull(list);
-        assertEquals(3, list.size());
-
-        ContentValues outputValues = list.get(0).getAfter();
-        assertEquals(Email.TYPE_CUSTOM, outputValues.getAsInteger(Email.TYPE).intValue());
-        assertEquals("custom_type", outputValues.getAsString(Email.LABEL));
-        assertEquals("address1", outputValues.getAsString(Email.ADDRESS));
-
-        outputValues = list.get(1).getAfter();
-        assertEquals(Email.TYPE_HOME, outputValues.getAsInteger(Email.TYPE).intValue());
-        assertEquals("address2", outputValues.getAsString(Email.ADDRESS));
-
-        outputValues = list.get(2).getAfter();
-        assertEquals(Email.TYPE_WORK, outputValues.getAsInteger(Email.TYPE).intValue());
-        assertEquals("address3", outputValues.getAsString(Email.ADDRESS));
-    }
-
-    public void testMigrateImFromGoogleToExchange() {
-        AccountType oldAccountType = new GoogleAccountType(getContext(), "");
-        AccountType newAccountType = new ExchangeAccountType(getContext(), "", EXCHANGE_ACCT_TYPE);
-        DataKind kind = newAccountType.getKindForMimetype(Im.CONTENT_ITEM_TYPE);
-
-        RawContactDelta oldState = new RawContactDelta();
-        ContentValues mockNameValues = new ContentValues();
-        mockNameValues.put(Data.MIMETYPE, Im.CONTENT_ITEM_TYPE);
-        // Exchange doesn't support TYPE_HOME
-        mockNameValues.put(Im.TYPE, Im.TYPE_HOME);
-        mockNameValues.put(Im.PROTOCOL, Im.PROTOCOL_JABBER);
-        mockNameValues.put(Im.DATA, "im1");
-        oldState.addEntry(ValuesDelta.fromAfter(mockNameValues));
-
-        mockNameValues = new ContentValues();
-        mockNameValues.put(Data.MIMETYPE, Im.CONTENT_ITEM_TYPE);
-        // Exchange doesn't support TYPE_WORK
-        mockNameValues.put(Im.TYPE, Im.TYPE_WORK);
-        mockNameValues.put(Im.PROTOCOL, Im.PROTOCOL_YAHOO);
-        mockNameValues.put(Im.DATA, "im2");
-        oldState.addEntry(ValuesDelta.fromAfter(mockNameValues));
-
-        mockNameValues = new ContentValues();
-        mockNameValues.put(Data.MIMETYPE, Im.CONTENT_ITEM_TYPE);
-        mockNameValues.put(Im.TYPE, Im.TYPE_OTHER);
-        mockNameValues.put(Im.PROTOCOL, Im.PROTOCOL_CUSTOM);
-        mockNameValues.put(Im.CUSTOM_PROTOCOL, "custom_protocol");
-        mockNameValues.put(Im.DATA, "im3");
-        oldState.addEntry(ValuesDelta.fromAfter(mockNameValues));
-
-        // Exchange can have up to 3 IM entries. This 4th entry should be dropped.
-        mockNameValues = new ContentValues();
-        mockNameValues.put(Data.MIMETYPE, Im.CONTENT_ITEM_TYPE);
-        mockNameValues.put(Im.TYPE, Im.TYPE_OTHER);
-        mockNameValues.put(Im.PROTOCOL, Im.PROTOCOL_GOOGLE_TALK);
-        mockNameValues.put(Im.DATA, "im4");
-        oldState.addEntry(ValuesDelta.fromAfter(mockNameValues));
-
-        RawContactDelta newState = new RawContactDelta();
-        RawContactModifier.migrateGenericWithTypeColumn(oldState, newState, kind);
-
-        List<ValuesDelta> list = newState.getMimeEntries(Im.CONTENT_ITEM_TYPE);
-        assertNotNull(list);
-        assertEquals(3, list.size());
-
-        assertNotNull(kind.defaultValues.getAsInteger(Im.TYPE));
-
-        int defaultType = kind.defaultValues.getAsInteger(Im.TYPE);
-
-        ContentValues outputValues = list.get(0).getAfter();
-        // HOME should become default type.
-        assertEquals(defaultType, outputValues.getAsInteger(Im.TYPE).intValue());
-        assertEquals(Im.PROTOCOL_JABBER, outputValues.getAsInteger(Im.PROTOCOL).intValue());
-        assertEquals("im1", outputValues.getAsString(Im.DATA));
-
-        outputValues = list.get(1).getAfter();
-        assertEquals(defaultType, outputValues.getAsInteger(Im.TYPE).intValue());
-        assertEquals(Im.PROTOCOL_YAHOO, outputValues.getAsInteger(Im.PROTOCOL).intValue());
-        assertEquals("im2", outputValues.getAsString(Im.DATA));
-
-        outputValues = list.get(2).getAfter();
-        assertEquals(defaultType, outputValues.getAsInteger(Im.TYPE).intValue());
-        assertEquals(Im.PROTOCOL_CUSTOM, outputValues.getAsInteger(Im.PROTOCOL).intValue());
-        assertEquals("custom_protocol", outputValues.getAsString(Im.CUSTOM_PROTOCOL));
-        assertEquals("im3", outputValues.getAsString(Im.DATA));
-    }
-
-    public void testMigratePhoneFromGoogleToExchange() {
-        AccountType oldAccountType = new GoogleAccountType(getContext(), "");
-        AccountType newAccountType = new ExchangeAccountType(getContext(), "", EXCHANGE_ACCT_TYPE);
-        DataKind kind = newAccountType.getKindForMimetype(Phone.CONTENT_ITEM_TYPE);
-
-        // Create 5 numbers.
-        // - "1" -- HOME
-        // - "2" -- WORK
-        // - "3" -- CUSTOM
-        // - "4" -- WORK
-        // - "5" -- WORK_MOBILE
-        // Then we convert it to Exchange account type.
-        // - "1" -- HOME
-        // - "2" -- WORK
-        // - "3" -- Because CUSTOM is not supported, it'll be changed to the default, MOBILE
-        // - "4" -- WORK
-        // - "5" -- WORK_MOBILE not suppoted again, so will be MOBILE.
-        // But then, Exchange doesn't support multiple MOBILE numbers, so "5" will be removed.
-        // i.e. the result will be:
-        // - "1" -- HOME
-        // - "2" -- WORK
-        // - "3" -- MOBILE
-        // - "4" -- WORK
-
-        RawContactDelta oldState = new RawContactDelta();
-        ContentValues mockNameValues = new ContentValues();
-        mockNameValues.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
-        mockNameValues.put(Phone.TYPE, Phone.TYPE_HOME);
-        mockNameValues.put(Phone.NUMBER, "1");
-        oldState.addEntry(ValuesDelta.fromAfter(mockNameValues));
-        mockNameValues = new ContentValues();
-        mockNameValues.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
-        mockNameValues.put(Phone.TYPE, Phone.TYPE_WORK);
-        mockNameValues.put(Phone.NUMBER, "2");
-        oldState.addEntry(ValuesDelta.fromAfter(mockNameValues));
-        mockNameValues = new ContentValues();
-        mockNameValues.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
-        // Exchange doesn't support this type. Default to MOBILE
-        mockNameValues.put(Phone.TYPE, Phone.TYPE_CUSTOM);
-        mockNameValues.put(Phone.LABEL, "custom_type");
-        mockNameValues.put(Phone.NUMBER, "3");
-        oldState.addEntry(ValuesDelta.fromAfter(mockNameValues));
-        mockNameValues = new ContentValues();
-        mockNameValues.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
-        mockNameValues.put(Phone.TYPE, Phone.TYPE_WORK);
-        mockNameValues.put(Phone.NUMBER, "4");
-        oldState.addEntry(ValuesDelta.fromAfter(mockNameValues));
-        mockNameValues = new ContentValues();
-
-        mockNameValues.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
-        mockNameValues.put(Phone.TYPE, Phone.TYPE_WORK_MOBILE);
-        mockNameValues.put(Phone.NUMBER, "5");
-        oldState.addEntry(ValuesDelta.fromAfter(mockNameValues));
-
-        RawContactDelta newState = new RawContactDelta();
-        RawContactModifier.migrateGenericWithTypeColumn(oldState, newState, kind);
-
-        List<ValuesDelta> list = newState.getMimeEntries(Phone.CONTENT_ITEM_TYPE);
-        assertNotNull(list);
-        assertEquals(4, list.size());
-
-        int defaultType = Phone.TYPE_MOBILE;
-
-        ContentValues outputValues = list.get(0).getAfter();
-        assertEquals(Phone.TYPE_HOME, outputValues.getAsInteger(Phone.TYPE).intValue());
-        assertEquals("1", outputValues.getAsString(Phone.NUMBER));
-        outputValues = list.get(1).getAfter();
-        assertEquals(Phone.TYPE_WORK, outputValues.getAsInteger(Phone.TYPE).intValue());
-        assertEquals("2", outputValues.getAsString(Phone.NUMBER));
-        outputValues = list.get(2).getAfter();
-        assertEquals(defaultType, outputValues.getAsInteger(Phone.TYPE).intValue());
-        assertNull(outputValues.getAsInteger(Phone.LABEL));
-        assertEquals("3", outputValues.getAsString(Phone.NUMBER));
-        outputValues = list.get(3).getAfter();
-        assertEquals(Phone.TYPE_WORK, outputValues.getAsInteger(Phone.TYPE).intValue());
-        assertEquals("4", outputValues.getAsString(Phone.NUMBER));
-    }
-
-    public void testMigrateOrganizationFromGoogleToExchange() {
-        AccountType oldAccountType = new GoogleAccountType(getContext(), "");
-        AccountType newAccountType = new ExchangeAccountType(getContext(), "", EXCHANGE_ACCT_TYPE);
-        DataKind kind = newAccountType.getKindForMimetype(Organization.CONTENT_ITEM_TYPE);
-
-        RawContactDelta oldState = new RawContactDelta();
-        ContentValues mockNameValues = new ContentValues();
-        mockNameValues.put(Data.MIMETYPE, Organization.CONTENT_ITEM_TYPE);
-        mockNameValues.put(Organization.COMPANY, "company1");
-        mockNameValues.put(Organization.DEPARTMENT, "department1");
-        oldState.addEntry(ValuesDelta.fromAfter(mockNameValues));
-
-        RawContactDelta newState = new RawContactDelta();
-        RawContactModifier.migrateGenericWithoutTypeColumn(oldState, newState, kind);
-
-        List<ValuesDelta> list = newState.getMimeEntries(Organization.CONTENT_ITEM_TYPE);
-        assertNotNull(list);
-        assertEquals(1, list.size());
-
-        ContentValues outputValues = list.get(0).getAfter();
-        assertEquals("company1", outputValues.getAsString(Organization.COMPANY));
-        assertEquals("department1", outputValues.getAsString(Organization.DEPARTMENT));
-    }
-}
diff --git a/tests/src/com/android/contacts/activities/PeopleActivityTest.java b/tests/src/com/android/contacts/activities/PeopleActivityTest.java
index 4ede006..d882da7 100644
--- a/tests/src/com/android/contacts/activities/PeopleActivityTest.java
+++ b/tests/src/com/android/contacts/activities/PeopleActivityTest.java
@@ -45,10 +45,10 @@
 import com.android.contacts.common.model.account.AccountType;
 import com.android.contacts.common.model.account.AccountWithDataSet;
 import com.android.contacts.common.model.account.BaseAccountType;
-import com.android.contacts.test.InjectedServices;
-import com.android.contacts.tests.mocks.MockAccountTypeManager;
-import com.android.contacts.tests.mocks.MockContactPhotoManager;
-import com.android.contacts.tests.mocks.MockSharedPreferences;
+import com.android.contacts.common.test.InjectedServices;
+import com.android.contacts.common.test.mocks.MockAccountTypeManager;
+import com.android.contacts.common.test.mocks.MockContactPhotoManager;
+import com.android.contacts.common.test.mocks.MockSharedPreferences;
 import com.android.contacts.util.PhoneCapabilityTester;
 
 /**
diff --git a/tests/src/com/android/contacts/detail/ContactDetailFragmentTests.java b/tests/src/com/android/contacts/detail/ContactDetailFragmentTests.java
index 1747add..9c52161 100644
--- a/tests/src/com/android/contacts/detail/ContactDetailFragmentTests.java
+++ b/tests/src/com/android/contacts/detail/ContactDetailFragmentTests.java
@@ -25,9 +25,9 @@
 import android.test.suitebuilder.annotation.SmallTest;
 
 import com.android.contacts.detail.ContactDetailFragment.DetailViewEntry;
-import com.android.contacts.model.dataitem.DataItem;
-import com.android.contacts.model.dataitem.EmailDataItem;
-import com.android.contacts.model.dataitem.ImDataItem;
+import com.android.contacts.common.model.dataitem.DataItem;
+import com.android.contacts.common.model.dataitem.EmailDataItem;
+import com.android.contacts.common.model.dataitem.ImDataItem;
 
 /**
  * Tests for {@link ContactDetailFragment}.
diff --git a/tests/src/com/android/contacts/detail/StreamItemAdapterTest.java b/tests/src/com/android/contacts/detail/StreamItemAdapterTest.java
index 7f1ee02..abd4680 100644
--- a/tests/src/com/android/contacts/detail/StreamItemAdapterTest.java
+++ b/tests/src/com/android/contacts/detail/StreamItemAdapterTest.java
@@ -22,6 +22,7 @@
 
 import com.android.contacts.util.StreamItemEntry;
 import com.android.contacts.util.StreamItemEntryBuilder;
+
 import com.google.common.collect.Lists;
 
 import java.util.ArrayList;
diff --git a/tests/src/com/android/contacts/editor/ContactEditorUtilsTest.java b/tests/src/com/android/contacts/editor/ContactEditorUtilsTest.java
index 0d38c95..c41c836 100644
--- a/tests/src/com/android/contacts/editor/ContactEditorUtilsTest.java
+++ b/tests/src/com/android/contacts/editor/ContactEditorUtilsTest.java
@@ -22,7 +22,7 @@
 
 import com.android.contacts.common.model.account.AccountType;
 import com.android.contacts.common.model.account.AccountWithDataSet;
-import com.android.contacts.tests.mocks.MockAccountTypeManager;
+import com.android.contacts.common.test.mocks.MockAccountTypeManager;
 import com.google.common.collect.Sets;
 
 import java.util.Collection;
diff --git a/tests/src/com/android/contacts/interactions/ContactDeletionInteractionTest.java b/tests/src/com/android/contacts/interactions/ContactDeletionInteractionTest.java
index 34f1e4b..bcaa398 100644
--- a/tests/src/com/android/contacts/interactions/ContactDeletionInteractionTest.java
+++ b/tests/src/com/android/contacts/interactions/ContactDeletionInteractionTest.java
@@ -34,8 +34,8 @@
 import com.android.contacts.common.model.AccountTypeManager;
 import com.android.contacts.common.model.account.AccountType;
 import com.android.contacts.common.model.account.BaseAccountType;
-import com.android.contacts.test.InjectedServices;
-import com.android.contacts.tests.mocks.MockAccountTypeManager;
+import com.android.contacts.common.test.InjectedServices;
+import com.android.contacts.common.test.mocks.MockAccountTypeManager;
 
 /**
  * Tests for {@link ContactDeletionInteraction}.
diff --git a/tests/src/com/android/contacts/model/ContactLoaderTest.java b/tests/src/com/android/contacts/model/ContactLoaderTest.java
deleted file mode 100644
index 60d6930..0000000
--- a/tests/src/com/android/contacts/model/ContactLoaderTest.java
+++ /dev/null
@@ -1,388 +0,0 @@
-/*
- * Copyright (C) 2010 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.contacts.model;
-
-import android.content.ContentUris;
-import android.net.Uri;
-import android.provider.ContactsContract.CommonDataKinds.GroupMembership;
-import android.provider.ContactsContract.CommonDataKinds.StructuredName;
-import android.provider.ContactsContract.Contacts;
-import android.provider.ContactsContract.Data;
-import android.provider.ContactsContract.DisplayNameSources;
-import android.provider.ContactsContract.RawContacts;
-import android.provider.ContactsContract.StatusUpdates;
-import android.test.LoaderTestCase;
-import android.test.suitebuilder.annotation.LargeTest;
-
-import com.android.contacts.common.model.AccountTypeManager;
-import com.android.contacts.common.test.mocks.ContactsMockContext;
-import com.android.contacts.common.test.mocks.MockContentProvider;
-import com.android.contacts.common.model.account.AccountType;
-import com.android.contacts.common.model.account.AccountWithDataSet;
-import com.android.contacts.common.model.account.BaseAccountType;
-import com.android.contacts.test.InjectedServices;
-import com.android.contacts.tests.mocks.MockAccountTypeManager;
-
-/**
- * Runs ContactLoader tests for the the contact-detail and editor view.
- */
-@LargeTest
-public class ContactLoaderTest extends LoaderTestCase {
-    private ContactsMockContext mMockContext;
-    private MockContentProvider mContactsProvider;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mMockContext = new ContactsMockContext(getContext());
-        mContactsProvider = mMockContext.getContactsProvider();
-
-        InjectedServices services = new InjectedServices();
-        AccountType accountType = new BaseAccountType() {
-            @Override
-            public boolean areContactsWritable() {
-                return false;
-            }
-        };
-        accountType.accountType = "mockAccountType";
-
-        AccountWithDataSet account =
-                new AccountWithDataSet("mockAccountName", "mockAccountType", null);
-
-        AccountTypeManager.setInstanceForTest(
-                new MockAccountTypeManager(
-                        new AccountType[]{accountType}, new AccountWithDataSet[]{account}));
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        mMockContext = null;
-        mContactsProvider = null;
-        super.tearDown();
-    }
-
-    private Contact assertLoadContact(Uri uri) {
-        final ContactLoader loader = new ContactLoader(mMockContext, uri, true);
-        return getLoaderResultSynchronously(loader);
-    }
-
-    public void testNullUri() {
-        Contact result = assertLoadContact(null);
-        assertTrue(result.isError());
-    }
-
-    public void testEmptyUri() {
-        Contact result = assertLoadContact(Uri.EMPTY);
-        assertTrue(result.isError());
-    }
-
-    public void testInvalidUri() {
-        Contact result = assertLoadContact(Uri.parse("content://wtf"));
-        assertTrue(result.isError());
-    }
-
-    public void testLoadContactWithContactIdUri() {
-        // Use content Uris that only contain the ID
-        final long contactId = 1;
-        final long rawContactId = 11;
-        final long dataId = 21;
-
-        final String lookupKey = "aa%12%@!";
-        final Uri baseUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
-        final Uri entityUri = Uri.withAppendedPath(baseUri, Contacts.Entity.CONTENT_DIRECTORY);
-        final Uri lookupUri = ContentUris.withAppendedId(
-                Uri.withAppendedPath(Contacts.CONTENT_LOOKUP_URI, lookupKey),
-                contactId);
-
-        ContactQueries queries = new ContactQueries();
-        mContactsProvider.expectTypeQuery(baseUri, Contacts.CONTENT_ITEM_TYPE);
-        queries.fetchAllData(entityUri, contactId, rawContactId, dataId, lookupKey);
-
-        Contact contact = assertLoadContact(baseUri);
-
-        assertEquals(contactId, contact.getId());
-        assertEquals(rawContactId, contact.getNameRawContactId());
-        assertEquals(DisplayNameSources.STRUCTURED_NAME, contact.getDisplayNameSource());
-        assertEquals(lookupKey, contact.getLookupKey());
-        assertEquals(lookupUri, contact.getLookupUri());
-        assertEquals(1, contact.getRawContacts().size());
-        assertEquals(1, contact.getStatuses().size());
-        mContactsProvider.verify();
-    }
-
-    public void testLoadContactWithOldStyleUri() {
-        // Use content Uris that only contain the ID but use the format used in Donut
-        final long contactId = 1;
-        final long rawContactId = 11;
-        final long dataId = 21;
-
-        final String lookupKey = "aa%12%@!";
-        final Uri legacyUri = ContentUris.withAppendedId(
-                Uri.parse("content://contacts"), rawContactId);
-        final Uri rawContactUri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId);
-        final Uri baseUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
-        final Uri lookupUri = ContentUris.withAppendedId(
-                Uri.withAppendedPath(Contacts.CONTENT_LOOKUP_URI, lookupKey),
-                contactId);
-        final Uri entityUri = Uri.withAppendedPath(lookupUri, Contacts.Entity.CONTENT_DIRECTORY);
-
-        ContactQueries queries = new ContactQueries();
-        queries.fetchContactIdAndLookupFromRawContactUri(rawContactUri, contactId, lookupKey);
-        queries.fetchAllData(entityUri, contactId, rawContactId, dataId, lookupKey);
-
-        Contact contact = assertLoadContact(legacyUri);
-
-        assertEquals(contactId, contact.getId());
-        assertEquals(rawContactId, contact.getNameRawContactId());
-        assertEquals(DisplayNameSources.STRUCTURED_NAME, contact.getDisplayNameSource());
-        assertEquals(lookupKey, contact.getLookupKey());
-        assertEquals(lookupUri, contact.getLookupUri());
-        assertEquals(1, contact.getRawContacts().size());
-        assertEquals(1, contact.getStatuses().size());
-        mContactsProvider.verify();
-    }
-
-    public void testLoadContactWithRawContactIdUri() {
-        // Use content Uris that only contain the ID but use the format used in Donut
-        final long contactId = 1;
-        final long rawContactId = 11;
-        final long dataId = 21;
-
-        final String lookupKey = "aa%12%@!";
-        final Uri rawContactUri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId);
-        final Uri baseUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
-        final Uri lookupUri = ContentUris.withAppendedId(
-                Uri.withAppendedPath(Contacts.CONTENT_LOOKUP_URI, lookupKey),
-                contactId);
-        final Uri entityUri = Uri.withAppendedPath(lookupUri, Contacts.Entity.CONTENT_DIRECTORY);
-
-        ContactQueries queries = new ContactQueries();
-        mContactsProvider.expectTypeQuery(rawContactUri, RawContacts.CONTENT_ITEM_TYPE);
-        queries.fetchContactIdAndLookupFromRawContactUri(rawContactUri, contactId, lookupKey);
-        queries.fetchAllData(entityUri, contactId, rawContactId, dataId, lookupKey);
-
-        Contact contact = assertLoadContact(rawContactUri);
-
-        assertEquals(contactId, contact.getId());
-        assertEquals(rawContactId, contact.getNameRawContactId());
-        assertEquals(DisplayNameSources.STRUCTURED_NAME, contact.getDisplayNameSource());
-        assertEquals(lookupKey, contact.getLookupKey());
-        assertEquals(lookupUri, contact.getLookupUri());
-        assertEquals(1, contact.getRawContacts().size());
-        assertEquals(1, contact.getStatuses().size());
-        mContactsProvider.verify();
-    }
-
-    public void testLoadContactWithContactLookupUri() {
-        // Use lookup-style Uris that do not contain the Contact-ID
-
-        final long contactId = 1;
-        final long rawContactId = 11;
-        final long dataId = 21;
-
-        final String lookupKey = "aa%12%@!";
-        final Uri baseUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
-        final Uri lookupNoIdUri = Uri.withAppendedPath(Contacts.CONTENT_LOOKUP_URI, lookupKey);
-        final Uri lookupUri = ContentUris.withAppendedId(lookupNoIdUri, contactId);
-        final Uri entityUri = Uri.withAppendedPath(lookupNoIdUri, Contacts.Entity.CONTENT_DIRECTORY);
-
-        ContactQueries queries = new ContactQueries();
-        mContactsProvider.expectTypeQuery(lookupNoIdUri, Contacts.CONTENT_ITEM_TYPE);
-        queries.fetchAllData(entityUri, contactId, rawContactId, dataId, lookupKey);
-
-        Contact contact = assertLoadContact(lookupNoIdUri);
-
-        assertEquals(contactId, contact.getId());
-        assertEquals(rawContactId, contact.getNameRawContactId());
-        assertEquals(DisplayNameSources.STRUCTURED_NAME, contact.getDisplayNameSource());
-        assertEquals(lookupKey, contact.getLookupKey());
-        assertEquals(lookupUri, contact.getLookupUri());
-        assertEquals(1, contact.getRawContacts().size());
-        assertEquals(1, contact.getStatuses().size());
-        mContactsProvider.verify();
-    }
-
-    public void testLoadContactWithContactLookupAndIdUri() {
-        // Use lookup-style Uris that also contain the Contact-ID
-        final long contactId = 1;
-        final long rawContactId = 11;
-        final long dataId = 21;
-
-        final String lookupKey = "aa%12%@!";
-        final Uri baseUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
-        final Uri lookupUri = ContentUris.withAppendedId(
-                Uri.withAppendedPath(Contacts.CONTENT_LOOKUP_URI, lookupKey),
-                contactId);
-        final Uri entityUri = Uri.withAppendedPath(lookupUri, Contacts.Entity.CONTENT_DIRECTORY);
-
-        ContactQueries queries = new ContactQueries();
-        mContactsProvider.expectTypeQuery(lookupUri, Contacts.CONTENT_ITEM_TYPE);
-        queries.fetchAllData(entityUri, contactId, rawContactId, dataId, lookupKey);
-
-        Contact contact = assertLoadContact(lookupUri);
-
-        assertEquals(contactId, contact.getId());
-        assertEquals(rawContactId, contact.getNameRawContactId());
-        assertEquals(DisplayNameSources.STRUCTURED_NAME, contact.getDisplayNameSource());
-        assertEquals(lookupKey, contact.getLookupKey());
-        assertEquals(lookupUri, contact.getLookupUri());
-        assertEquals(1, contact.getRawContacts().size());
-        assertEquals(1, contact.getStatuses().size());
-        mContactsProvider.verify();
-    }
-
-    public void testLoadContactWithContactLookupWithIncorrectIdUri() {
-        // Use lookup-style Uris that contain incorrect Contact-ID
-        // (we want to ensure that still the correct contact is chosen)
-
-        final long contactId = 1;
-        final long wrongContactId = 2;
-        final long rawContactId = 11;
-        final long wrongRawContactId = 12;
-        final long dataId = 21;
-
-        final String lookupKey = "aa%12%@!";
-        final String wrongLookupKey = "ab%12%@!";
-        final Uri baseUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
-        final Uri wrongBaseUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, wrongContactId);
-        final Uri lookupUri = ContentUris.withAppendedId(
-                Uri.withAppendedPath(Contacts.CONTENT_LOOKUP_URI, lookupKey),
-                contactId);
-        final Uri lookupWithWrongIdUri = ContentUris.withAppendedId(
-                Uri.withAppendedPath(Contacts.CONTENT_LOOKUP_URI, lookupKey),
-                wrongContactId);
-        final Uri entityUri = Uri.withAppendedPath(lookupWithWrongIdUri,
-                Contacts.Entity.CONTENT_DIRECTORY);
-
-        ContactQueries queries = new ContactQueries();
-        mContactsProvider.expectTypeQuery(lookupWithWrongIdUri, Contacts.CONTENT_ITEM_TYPE);
-        queries.fetchAllData(entityUri, contactId, rawContactId, dataId, lookupKey);
-
-        Contact contact = assertLoadContact(lookupWithWrongIdUri);
-
-        assertEquals(contactId, contact.getId());
-        assertEquals(rawContactId, contact.getNameRawContactId());
-        assertEquals(DisplayNameSources.STRUCTURED_NAME, contact.getDisplayNameSource());
-        assertEquals(lookupKey, contact.getLookupKey());
-        assertEquals(lookupUri, contact.getLookupUri());
-        assertEquals(1, contact.getRawContacts().size());
-        assertEquals(1, contact.getStatuses().size());
-
-        mContactsProvider.verify();
-    }
-
-    class ContactQueries {
-        public void fetchAllData(
-                Uri baseUri, long contactId, long rawContactId, long dataId, String encodedLookup) {
-            mContactsProvider.expectQuery(baseUri)
-                    .withProjection(new String[] {
-                        Contacts.NAME_RAW_CONTACT_ID, Contacts.DISPLAY_NAME_SOURCE,
-                        Contacts.LOOKUP_KEY, Contacts.DISPLAY_NAME,
-                        Contacts.DISPLAY_NAME_ALTERNATIVE, Contacts.PHONETIC_NAME,
-                        Contacts.PHOTO_ID, Contacts.STARRED, Contacts.CONTACT_PRESENCE,
-                        Contacts.CONTACT_STATUS, Contacts.CONTACT_STATUS_TIMESTAMP,
-                        Contacts.CONTACT_STATUS_RES_PACKAGE, Contacts.CONTACT_STATUS_LABEL,
-
-                        Contacts.Entity.CONTACT_ID,
-                        Contacts.Entity.RAW_CONTACT_ID,
-
-                        RawContacts.ACCOUNT_NAME, RawContacts.ACCOUNT_TYPE,
-                        RawContacts.DATA_SET, RawContacts.ACCOUNT_TYPE_AND_DATA_SET,
-                        RawContacts.DIRTY, RawContacts.VERSION, RawContacts.SOURCE_ID,
-                        RawContacts.SYNC1, RawContacts.SYNC2, RawContacts.SYNC3, RawContacts.SYNC4,
-                        RawContacts.DELETED, RawContacts.NAME_VERIFIED,
-
-                        Contacts.Entity.DATA_ID,
-
-                        Data.DATA1, Data.DATA2, Data.DATA3, Data.DATA4, Data.DATA5,
-                        Data.DATA6, Data.DATA7, Data.DATA8, Data.DATA9, Data.DATA10,
-                        Data.DATA11, Data.DATA12, Data.DATA13, Data.DATA14, Data.DATA15,
-                        Data.SYNC1, Data.SYNC2, Data.SYNC3, Data.SYNC4,
-                        Data.DATA_VERSION, Data.IS_PRIMARY,
-                        Data.IS_SUPER_PRIMARY, Data.MIMETYPE, Data.RES_PACKAGE,
-
-                        GroupMembership.GROUP_SOURCE_ID,
-
-                        Data.PRESENCE, Data.CHAT_CAPABILITY,
-                        Data.STATUS, Data.STATUS_RES_PACKAGE, Data.STATUS_ICON,
-                        Data.STATUS_LABEL, Data.STATUS_TIMESTAMP,
-
-                        Contacts.PHOTO_URI,
-
-                        Contacts.SEND_TO_VOICEMAIL,
-                        Contacts.CUSTOM_RINGTONE,
-                        Contacts.IS_USER_PROFILE,
-                    })
-                    .withSortOrder(Contacts.Entity.RAW_CONTACT_ID)
-                    .returnRow(
-                        rawContactId, 40,
-                        "aa%12%@!", "John Doe", "Doe, John", "jdo",
-                        0, 0, StatusUpdates.AVAILABLE,
-                        "Having lunch", 0,
-                        "mockPkg1", 10,
-
-                        contactId,
-                        rawContactId,
-
-                        "mockAccountName", "mockAccountType", null, "mockAccountType",
-                        0, 1, 0,
-                        "sync1", "sync2", "sync3", "sync4",
-                        0, 0,
-
-                        dataId,
-
-                        "dat1", "dat2", "dat3", "dat4", "dat5",
-                        "dat6", "dat7", "dat8", "dat9", "dat10",
-                        "dat11", "dat12", "dat13", "dat14", "dat15",
-                        "syn1", "syn2", "syn3", "syn4",
-
-                        0, 0,
-                        0, StructuredName.CONTENT_ITEM_TYPE, "mockPkg2",
-
-                        "groupId",
-
-                        StatusUpdates.INVISIBLE, null,
-                        "Having dinner", "mockPkg3", 0,
-                        20, 0,
-
-                        "content:some.photo.uri",
-
-                        0,
-                        null,
-                        0
-                    );
-        }
-
-        void fetchLookupAndId(final Uri sourceUri, final long expectedContactId,
-                final String expectedEncodedLookup) {
-            mContactsProvider.expectQuery(sourceUri)
-                    .withProjection(Contacts.LOOKUP_KEY, Contacts._ID)
-                    .returnRow(expectedEncodedLookup, expectedContactId);
-        }
-
-        void fetchContactIdAndLookupFromRawContactUri(final Uri rawContactUri,
-                final long expectedContactId, final String expectedEncodedLookup) {
-            // TODO: use a lighter query by joining rawcontacts with contacts in provider
-            // (See ContactContracts.java)
-            final Uri dataUri = Uri.withAppendedPath(rawContactUri,
-                    RawContacts.Data.CONTENT_DIRECTORY);
-            mContactsProvider.expectQuery(dataUri)
-                    .withProjection(RawContacts.CONTACT_ID, Contacts.LOOKUP_KEY)
-                    .returnRow(expectedContactId, expectedEncodedLookup);
-        }
-    }
-}
diff --git a/tests/src/com/android/contacts/model/RawContactTest.java b/tests/src/com/android/contacts/model/RawContactTest.java
deleted file mode 100644
index f09e64f..0000000
--- a/tests/src/com/android/contacts/model/RawContactTest.java
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Copyright (C) 2012 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.contacts.model;
-
-import android.content.ContentValues;
-import android.net.Uri;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import junit.framework.TestCase;
-
-/**
- * Unit test for {@link RawContact}.
- */
-public class RawContactTest extends TestCase {
-
-    private RawContact buildRawContact() {
-        final ContentValues values = new ContentValues();
-        values.put("key1", "value1");
-        values.put("key2", "value2");
-
-        final ContentValues dataItem = new ContentValues();
-        dataItem.put("key3", "value3");
-        dataItem.put("key4", "value4");
-
-        final RawContact contact = new RawContact(values);
-        contact.addDataItemValues(dataItem);
-
-        return contact;
-    }
-
-    private RawContact buildRawContact2() {
-        final ContentValues values = new ContentValues();
-        values.put("key11", "value11");
-        values.put("key22", "value22");
-
-        final ContentValues dataItem = new ContentValues();
-        dataItem.put("key33", "value33");
-        dataItem.put("key44", "value44");
-
-        final RawContact contact = new RawContact(values);
-        contact.addDataItemValues(dataItem);
-
-        return contact;
-    }
-
-    public void testNotEquals() {
-        final RawContact one = buildRawContact();
-        final RawContact two = buildRawContact2();
-        assertFalse(one.equals(two));
-    }
-
-    public void testEquals() {
-        assertEquals(buildRawContact(), buildRawContact());
-    }
-
-    public void testParcelable() {
-        assertParcelableEquals(buildRawContact());
-    }
-
-    private RawContact.NamedDataItem buildNamedDataItem() {
-        final ContentValues values = new ContentValues();
-        values.put("key1", "value1");
-        values.put("key2", "value2");
-        final Uri uri = Uri.fromParts("content:", "ssp", "fragment");
-
-        return new RawContact.NamedDataItem(uri, values);
-    }
-
-    private RawContact.NamedDataItem buildNamedDataItem2() {
-        final ContentValues values = new ContentValues();
-        values.put("key11", "value11");
-        values.put("key22", "value22");
-        final Uri uri = Uri.fromParts("content:", "blah", "blah");
-
-        return new RawContact.NamedDataItem(uri, values);
-    }
-
-    public void testNamedDataItemEquals() {
-        assertEquals(buildNamedDataItem(), buildNamedDataItem());
-    }
-
-    public void testNamedDataItemNotEquals() {
-        assertFalse(buildNamedDataItem().equals(buildNamedDataItem2()));
-    }
-
-    public void testNamedDataItemParcelable() {
-        assertParcelableEquals(buildNamedDataItem());
-    }
-
-    private void assertParcelableEquals(Parcelable parcelable) {
-        final Parcel parcel = Parcel.obtain();
-        try {
-            parcel.writeParcelable(parcelable, 0);
-            parcel.setDataPosition(0);
-
-            Parcelable out = parcel.readParcelable(parcelable.getClass().getClassLoader());
-            assertEquals(parcelable, out);
-        } finally {
-            parcel.recycle();
-        }
-    }
-}
diff --git a/tests/src/com/android/contacts/tests/mocks/MockAccountTypeManager.java b/tests/src/com/android/contacts/tests/mocks/MockAccountTypeManager.java
deleted file mode 100644
index 3357af3..0000000
--- a/tests/src/com/android/contacts/tests/mocks/MockAccountTypeManager.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (C) 2010 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.contacts.tests.mocks;
-
-import com.android.contacts.common.model.AccountTypeManager;
-import com.android.contacts.common.model.account.AccountType;
-import com.android.contacts.common.model.account.AccountTypeWithDataSet;
-import com.android.contacts.common.model.account.AccountWithDataSet;
-import com.google.common.base.Objects;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
-
-/**
- * A mock {@link AccountTypeManager} class.
- */
-public class MockAccountTypeManager extends AccountTypeManager {
-
-    public AccountType[] mTypes;
-    public AccountWithDataSet[] mAccounts;
-
-    public MockAccountTypeManager(AccountType[] types, AccountWithDataSet[] accounts) {
-        this.mTypes = types;
-        this.mAccounts = accounts;
-    }
-
-    @Override
-    public AccountType getAccountType(AccountTypeWithDataSet accountTypeWithDataSet) {
-        for (AccountType type : mTypes) {
-            if (Objects.equal(accountTypeWithDataSet.accountType, type.accountType)
-                    && Objects.equal(accountTypeWithDataSet.dataSet, type.dataSet)) {
-                return type;
-            }
-        }
-        return null;
-    }
-
-    @Override
-    public List<AccountWithDataSet> getAccounts(boolean writableOnly) {
-        return Arrays.asList(mAccounts);
-    }
-
-    @Override
-    public List<AccountWithDataSet> getGroupWritableAccounts() {
-        return Arrays.asList(mAccounts);
-    }
-
-    @Override
-    public Map<AccountTypeWithDataSet, AccountType> getUsableInvitableAccountTypes() {
-        return Maps.newHashMap(); // Always returns empty
-    }
-
-    @Override
-    public List<AccountType> getAccountTypes(boolean writableOnly) {
-        final List<AccountType> ret = Lists.newArrayList();
-        synchronized (this) {
-            for (AccountType type : mTypes) {
-                if (!writableOnly || type.areContactsWritable()) {
-                    ret.add(type);
-                }
-            }
-        }
-        return ret;
-    }
-}
diff --git a/tests/src/com/android/contacts/tests/mocks/MockContactPhotoManager.java b/tests/src/com/android/contacts/tests/mocks/MockContactPhotoManager.java
deleted file mode 100644
index f5f6084..0000000
--- a/tests/src/com/android/contacts/tests/mocks/MockContactPhotoManager.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (C) 2011 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.contacts.tests.mocks;
-
-import android.graphics.Bitmap;
-import android.net.Uri;
-import android.widget.ImageView;
-
-import com.android.contacts.common.ContactPhotoManager;
-
-/**
- * A photo preloader that always uses the "no contact" picture and never executes any real
- * db queries
- */
-public class MockContactPhotoManager extends ContactPhotoManager {
-    @Override
-    public void loadThumbnail(ImageView view, long photoId, boolean darkTheme,
-            DefaultImageProvider defaultProvider) {
-        defaultProvider.applyDefaultImage(view, -1, darkTheme);
-    }
-
-    @Override
-    public void loadPhoto(ImageView view, Uri photoUri, int requestedExtent, boolean darkTheme,
-            DefaultImageProvider defaultProvider) {
-        defaultProvider.applyDefaultImage(view, requestedExtent, darkTheme);
-    }
-
-    @Override
-    public void removePhoto(ImageView view) {
-        view.setImageDrawable(null);
-    }
-
-    @Override
-    public void pause() {
-    }
-
-    @Override
-    public void resume() {
-    }
-
-    @Override
-    public void refreshCache() {
-    }
-
-    @Override
-    public void cacheBitmap(Uri photoUri, Bitmap bitmap, byte[] photoBytes) {
-    }
-
-    @Override
-    public void preloadPhotosInBackground() {
-    }
-}
diff --git a/tests/src/com/android/contacts/tests/mocks/MockSharedPreferences.java b/tests/src/com/android/contacts/tests/mocks/MockSharedPreferences.java
deleted file mode 100644
index 536ba7f..0000000
--- a/tests/src/com/android/contacts/tests/mocks/MockSharedPreferences.java
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * Copyright (C) 2010 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.contacts.tests.mocks;
-
-import android.content.SharedPreferences;
-
-import com.google.common.collect.Maps;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
-
-
-/**
- * A programmable mock content provider.
- */
-public class MockSharedPreferences implements SharedPreferences, SharedPreferences.Editor {
-
-    private HashMap<String, Object> mValues = Maps.newHashMap();
-    private HashMap<String, Object> mTempValues = Maps.newHashMap();
-
-    public Editor edit() {
-        return this;
-    }
-
-    public boolean contains(String key) {
-        return mValues.containsKey(key);
-    }
-
-    public Map<String, ?> getAll() {
-        return new HashMap<String, Object>(mValues);
-    }
-
-    public boolean getBoolean(String key, boolean defValue) {
-        if (mValues.containsKey(key)) {
-            return ((Boolean)mValues.get(key)).booleanValue();
-        }
-        return defValue;
-    }
-
-    public float getFloat(String key, float defValue) {
-        if (mValues.containsKey(key)) {
-            return ((Float)mValues.get(key)).floatValue();
-        }
-        return defValue;
-    }
-
-    public int getInt(String key, int defValue) {
-        if (mValues.containsKey(key)) {
-            return ((Integer)mValues.get(key)).intValue();
-        }
-        return defValue;
-    }
-
-    public long getLong(String key, long defValue) {
-        if (mValues.containsKey(key)) {
-            return ((Long)mValues.get(key)).longValue();
-        }
-        return defValue;
-    }
-
-    public String getString(String key, String defValue) {
-        if (mValues.containsKey(key))
-            return (String)mValues.get(key);
-        return defValue;
-    }
-
-    @SuppressWarnings("unchecked")
-    public Set<String> getStringSet(String key, Set<String> defValues) {
-        if (mValues.containsKey(key)) {
-            return (Set<String>) mValues.get(key);
-        }
-        return defValues;
-    }
-
-    public void registerOnSharedPreferenceChangeListener(
-            OnSharedPreferenceChangeListener listener) {
-        throw new UnsupportedOperationException();
-    }
-
-    public void unregisterOnSharedPreferenceChangeListener(
-            OnSharedPreferenceChangeListener listener) {
-        throw new UnsupportedOperationException();
-    }
-
-    public Editor putBoolean(String key, boolean value) {
-        mTempValues.put(key, Boolean.valueOf(value));
-        return this;
-    }
-
-    public Editor putFloat(String key, float value) {
-        mTempValues.put(key, value);
-        return this;
-    }
-
-    public Editor putInt(String key, int value) {
-        mTempValues.put(key, value);
-        return this;
-    }
-
-    public Editor putLong(String key, long value) {
-        mTempValues.put(key, value);
-        return this;
-    }
-
-    public Editor putString(String key, String value) {
-        mTempValues.put(key, value);
-        return this;
-    }
-
-    public Editor putStringSet(String key, Set<String> values) {
-        mTempValues.put(key, values);
-        return this;
-    }
-
-    public Editor remove(String key) {
-        mTempValues.remove(key);
-        return this;
-    }
-
-    public Editor clear() {
-        mTempValues.clear();
-        return this;
-    }
-
-    @SuppressWarnings("unchecked")
-    public boolean commit() {
-        mValues = (HashMap<String, Object>)mTempValues.clone();
-        return true;
-    }
-
-    public void apply() {
-        commit();
-    }
-}
diff --git a/tests/src/com/android/contacts/util/NameConverterTests.java b/tests/src/com/android/contacts/util/NameConverterTests.java
deleted file mode 100644
index e1773a7..0000000
--- a/tests/src/com/android/contacts/util/NameConverterTests.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright (C) 2011 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.contacts.util;
-
-import android.provider.ContactsContract.CommonDataKinds.StructuredName;
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.SmallTest;
-import android.text.TextUtils;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Tests for {@link NameConverter}.
- */
-@SmallTest
-public class NameConverterTests extends AndroidTestCase {
-
-    public void testStructuredNameToDisplayName() {
-        Map<String, String> structuredName = new HashMap<String, String>();
-        structuredName.put(StructuredName.PREFIX, "Mr.");
-        structuredName.put(StructuredName.GIVEN_NAME, "John");
-        structuredName.put(StructuredName.MIDDLE_NAME, "Quincy");
-        structuredName.put(StructuredName.FAMILY_NAME, "Adams");
-        structuredName.put(StructuredName.SUFFIX, "Esquire");
-
-        assertEquals("Mr. John Quincy Adams, Esquire",
-                NameConverter.structuredNameToDisplayName(mContext, structuredName));
-
-        structuredName.remove(StructuredName.SUFFIX);
-        assertEquals("Mr. John Quincy Adams",
-                NameConverter.structuredNameToDisplayName(mContext, structuredName));
-
-        structuredName.remove(StructuredName.MIDDLE_NAME);
-        assertEquals("Mr. John Adams",
-                NameConverter.structuredNameToDisplayName(mContext, structuredName));
-    }
-
-    public void testDisplayNameToStructuredName() {
-        assertStructuredName("Mr. John Quincy Adams, Esquire",
-                "Mr.", "John", "Quincy", "Adams", "Esquire");
-        assertStructuredName("John Doe", null, "John", null, "Doe", null);
-        assertStructuredName("Ms. Jane Eyre", "Ms.", "Jane", null, "Eyre", null);
-        assertStructuredName("Dr Leo Spaceman, PhD", "Dr", "Leo", null, "Spaceman", "PhD");
-    }
-
-    /**
-     * Helper method to check whether a given display name parses out to the other parameters.
-     * @param displayName Display name to break into a structured name.
-     * @param prefix Expected prefix (null if not expected).
-     * @param givenName Expected given name (null if not expected).
-     * @param middleName Expected middle name (null if not expected).
-     * @param familyName Expected family name (null if not expected).
-     * @param suffix Expected suffix (null if not expected).
-     */
-    private void assertStructuredName(String displayName, String prefix,
-            String givenName, String middleName, String familyName, String suffix) {
-        Map<String, String> structuredName = NameConverter.displayNameToStructuredName(mContext,
-                displayName);
-        checkNameComponent(StructuredName.PREFIX, prefix, structuredName);
-        checkNameComponent(StructuredName.GIVEN_NAME, givenName, structuredName);
-        checkNameComponent(StructuredName.MIDDLE_NAME, middleName, structuredName);
-        checkNameComponent(StructuredName.FAMILY_NAME, familyName, structuredName);
-        checkNameComponent(StructuredName.SUFFIX, suffix, structuredName);
-        assertEquals(0, structuredName.size());
-    }
-
-    /**
-     * Checks that the given field and value are present in the structured name map (or not present
-     * if the given value is null).  If the value is present and matches, the key is removed from
-     * the map - once all components of the name are checked, the map should be empty.
-     * @param field Field to check.
-     * @param value Expected value for the field (null if it is not expected to be populated).
-     * @param structuredName The map of structured field names to values.
-     */
-    private void checkNameComponent(String field, String value,
-            Map<String, String> structuredName) {
-        if (TextUtils.isEmpty(value)) {
-            assertNull(structuredName.get(field));
-        } else {
-            assertEquals(value, structuredName.get(field));
-        }
-        structuredName.remove(field);
-    }
-}
