/*
 * 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.model.account.AccountType;
import com.android.contacts.model.account.AccountType.EditField;
import com.android.contacts.model.account.AccountType.EditType;
import com.android.contacts.model.account.AccountType.EventEditType;
import com.android.contacts.model.account.GoogleAccountType;
import com.android.contacts.model.dataitem.DataKind;
import com.android.contacts.model.dataitem.PhoneDataItem;
import com.android.contacts.model.dataitem.StructuredNameDataItem;
import com.android.contacts.util.CommonDateUtils;
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, null, true, null, true).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}.
     *
     * @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)}.
     * @param checkOverall If true, check if the overall number of types is under limit.
     */
    public static ArrayList<EditType> getValidTypes(RawContactDelta state, DataKind kind,
            EditType forceInclude, boolean includeSecondary, SparseIntArray typeCount,
            boolean checkOverall) {
        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
        boolean validOverall = true;
        if (checkOverall) {
            final int overallCount = typeCount.get(FREQUENCY_TOTAL);
            validOverall = (kind.typeOverallMax == -1 ? true
                    : overallCount < kind.typeOverallMax);
        }

        for (EditType type : kind.typeList) {
            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 != null && 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 == null || 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, /*checkOverall=*/ true);
        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) {
        // Bail early if invalid kind
        if (kind == null) return null;
        // 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) {
        return hasChanges(set, accountTypes, /* excludedMimeTypes =*/ null);
    }

    public static boolean hasChanges(RawContactDeltaList set, AccountTypeManager accountTypes,
            Set<String> excludedMimeTypes) {
        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, excludedMimeTypes)) {
                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,
            Set<String> excludedMimeTypes) {
        for (DataKind kind : accountType.getSortedDataKinds()) {
            final String mimeType = kind.mimeType;
            if (excludedMimeTypes != null && excludedMimeTypes.contains(mimeType)) continue;
            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);

                if (cursor != 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)) {
            StructuredNameDataItem dataItem = NameConverter.parsePhoneticName(phoneticName, null);
            child.put(StructuredName.PHONETIC_FAMILY_NAME, dataItem.getPhoneticFamilyName());
            child.put(StructuredName.PHONETIC_MIDDLE_NAME, dataItem.getPhoneticMiddleName());
            child.put(StructuredName.PHONETIC_GIVEN_NAME, dataItem.getPhoneticGivenName());
        }
    }

    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_PHONETIC_NAME.equals(mimeType) ||
                        DataKind.PSEUDO_MIME_TYPE_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 supportPhoneticFullName = false;
        boolean supportPhoneticFamilyName = false;
        boolean supportPhoneticMiddleName = false;
        boolean supportPhoneticGivenName = false;
        for (EditField editField : newDataKind.fieldList) {
            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;
            }
        }


        // 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 =
                        NameConverter.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,
                        NameConverter.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,
                                CommonDateUtils.DEFAULT_HOUR, 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++;
        }
    }
}
