/*
 * 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 android.pim.vcard;

import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.content.Entity;
import android.content.EntityIterator;
import android.content.Entity.NamedContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteException;
import android.net.Uri;
import android.os.RemoteException;
import android.provider.CallLog;
import android.provider.CallLog.Calls;
import android.provider.ContactsContract.Contacts;
import android.provider.ContactsContract.Data;
import android.provider.ContactsContract.RawContacts;
import android.provider.ContactsContract.CommonDataKinds.Email;
import android.provider.ContactsContract.CommonDataKinds.Event;
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.StructuredName;
import android.provider.ContactsContract.CommonDataKinds.StructuredPostal;
import android.provider.ContactsContract.CommonDataKinds.Website;
import android.telephony.PhoneNumberUtils;
import android.text.SpannableStringBuilder;
import android.text.TextUtils;
import android.text.format.Time;
import android.util.CharsetUtils;
import android.util.Log;

import java.io.BufferedWriter;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * <p>
 * The class for composing VCard from Contacts information. Note that this is
 * completely differnt implementation from
 * android.syncml.pim.vcard.VCardComposer, which is not maintained anymore.
 * </p>
 *
 * <p>
 * Usually, this class should be used like this.
 * </p>
 *
 * <pre class="prettyprint"> VCardComposer composer = null; try { composer = new
 * VCardComposer(context); composer.addHandler(composer.new
 * HandlerForOutputStream(outputStream)); if (!composer.init()) { // Do
 * something handling the situation. return; } while (!composer.isAfterLast()) {
 * if (mCanceled) { // Assume a user may cancel this operation during the
 * export. return; } if (!composer.createOneEntry()) { // Do something handling
 * the error situation. return; } } } finally { if (composer != null) {
 * composer.terminate(); } } </pre>
 */
public class VCardComposer {
    private static final String LOG_TAG = "vcard.VCardComposer";

    private static final String DEFAULT_EMAIL_TYPE = Constants.ATTR_TYPE_INTERNET;

    public static final String FAILURE_REASON_FAILED_TO_GET_DATABASE_INFO =
        "Failed to get database information";

    public static final String FAILURE_REASON_NO_ENTRY =
        "There's no exportable in the database";

    public static final String FAILURE_REASON_NOT_INITIALIZED =
        "The vCard composer object is not correctly initialized";

    public static final String NO_ERROR = "No error";

    private static final Uri sDataRequestUri;

    static {
        Uri.Builder builder = RawContacts.CONTENT_URI.buildUpon();
        builder.appendQueryParameter(Data.FOR_EXPORT_ONLY, "1");
        sDataRequestUri = builder.build();
    }

    public static interface OneEntryHandler {
        public boolean onInit(Context context);

        public boolean onEntryCreated(String vcard);

        public void onTerminate();
    }

    /**
     * <p>
     * An useful example handler, which emits VCard String to outputstream one
     * by one.
     * </p>
     * <p>
     * The input OutputStream object is closed() on {{@link #onTerminate()}.
     * Must not close the stream outside.
     * </p>
     */
    public class HandlerForOutputStream implements OneEntryHandler {
        @SuppressWarnings("hiding")
        private static final String LOG_TAG = "vcard.VCardComposer.HandlerForOutputStream";

        final private OutputStream mOutputStream; // mWriter will close this.
        private Writer mWriter;

        private boolean mOnTerminateIsCalled = false;

        /**
         * Input stream will be closed on the detruction of this object.
         */
        public HandlerForOutputStream(OutputStream outputStream) {
            mOutputStream = outputStream;
        }

        public boolean onInit(Context context) {
            try {
                mWriter = new BufferedWriter(new OutputStreamWriter(
                        mOutputStream, mCharsetString));
            } catch (UnsupportedEncodingException e1) {
                Log.e(LOG_TAG, "Unsupported charset: " + mCharsetString);
                mErrorReason = "Encoding is not supported (usually this does not happen!): "
                        + mCharsetString;
                return false;
            }

            if (mIsDoCoMo) {
                try {
                    // Create one empty entry.
                    mWriter.write(createOneEntryInternal("-1"));
                } catch (IOException e) {
                    Log.e(LOG_TAG,
                            "IOException occurred during exportOneContactData: "
                                    + e.getMessage());
                    mErrorReason = "IOException occurred: " + e.getMessage();
                    return false;
                }
            }
            return true;
        }

        public boolean onEntryCreated(String vcard) {
            try {
                mWriter.write(vcard);
            } catch (IOException e) {
                Log.e(LOG_TAG,
                        "IOException occurred during exportOneContactData: "
                                + e.getMessage());
                mErrorReason = "IOException occurred: " + e.getMessage();
                return false;
            }
            return true;
        }

        public void onTerminate() {
            mOnTerminateIsCalled = true;
            if (mWriter != null) {
                try {
                    // Flush and sync the data so that a user is able to pull
                    // the SDCard just after
                    // the export.
                    mWriter.flush();
                    if (mOutputStream != null
                            && mOutputStream instanceof FileOutputStream) {
                            ((FileOutputStream) mOutputStream).getFD().sync();
                    }
                } catch (IOException e) {
                    Log.d(LOG_TAG,
                            "IOException during closing the output stream: "
                                    + e.getMessage());
                } finally {
                    try {
                        mWriter.close();
                    } catch (IOException e) {
                    }
                }
            }
        }

        @Override
        public void finalize() {
            if (!mOnTerminateIsCalled) {
                onTerminate();
            }
        }
    }

    public static final String VCARD_TYPE_STRING_DOCOMO = "docomo";

    private static final String VCARD_PROPERTY_ADR = "ADR";
    private static final String VCARD_PROPERTY_BEGIN = "BEGIN";
    private static final String VCARD_PROPERTY_EMAIL = "EMAIL";
    private static final String VCARD_PROPERTY_END = "END";
    private static final String VCARD_PROPERTY_NAME = "N";
    private static final String VCARD_PROPERTY_FULL_NAME = "FN";
    private static final String VCARD_PROPERTY_NOTE = "NOTE";
    private static final String VCARD_PROPERTY_ORG = "ORG";
    private static final String VCARD_PROPERTY_SOUND = "SOUND";
    private static final String VCARD_PROPERTY_SORT_STRING = "SORT-STRING";
    private static final String VCARD_PROPERTY_NICKNAME = "NICKNAME";
    private static final String VCARD_PROPERTY_TEL = "TEL";
    private static final String VCARD_PROPERTY_TITLE = "TITLE";
    private static final String VCARD_PROPERTY_PHOTO = "PHOTO";
    private static final String VCARD_PROPERTY_VERSION = "VERSION";
    private static final String VCARD_PROPERTY_URL = "URL";
    private static final String VCARD_PROPERTY_BIRTHDAY = "BDAY";

    private static final String VCARD_PROPERTY_X_PHONETIC_FIRST_NAME = "X-PHONETIC-FIRST-NAME";
    private static final String VCARD_PROPERTY_X_PHONETIC_MIDDLE_NAME = "X-PHONETIC-MIDDLE-NAME";
    private static final String VCARD_PROPERTY_X_PHONETIC_LAST_NAME = "X-PHONETIC-LAST-NAME";

    // Android specific properties
    // TODO: ues extra MIME-TYPE instead of adding this kind of inflexible fields
    private static final String VCARD_PROPERTY_X_NICKNAME = "X-NICKNAME";

    // Property for call log entry
    private static final String VCARD_PROPERTY_X_TIMESTAMP = "X-IRMC-CALL-DATETIME";
    private static final String VCARD_PROPERTY_CALLTYPE_INCOMING = "INCOMING";
    private static final String VCARD_PROPERTY_CALLTYPE_OUTGOING = "OUTGOING";
    private static final String VCARD_PROPERTY_CALLTYPE_MISSED = "MISSED";

    // Properties for DoCoMo vCard.
    private static final String VCARD_PROPERTY_X_CLASS = "X-CLASS";
    private static final String VCARD_PROPERTY_X_REDUCTION = "X-REDUCTION";
    private static final String VCARD_PROPERTY_X_NO = "X-NO";
    private static final String VCARD_PROPERTY_X_DCM_HMN_MODE = "X-DCM-HMN-MODE";

    private static final String VCARD_DATA_VCARD = "VCARD";
    private static final String VCARD_DATA_PUBLIC = "PUBLIC";

    private static final String VCARD_ATTR_SEPARATOR = ";";
    private static final String VCARD_COL_SEPARATOR = "\r\n";
    private static final String VCARD_DATA_SEPARATOR = ":";
    private static final String VCARD_ITEM_SEPARATOR = ";";
    private static final String VCARD_WS = " ";
    private static final String VCARD_ATTR_EQUAL = "=";

    // Type strings are now in VCardConstants.java.

    private static final String VCARD_ATTR_ENCODING_QP = "ENCODING=QUOTED-PRINTABLE";

    private static final String VCARD_ATTR_ENCODING_BASE64_V21 = "ENCODING=BASE64";
    private static final String VCARD_ATTR_ENCODING_BASE64_V30 = "ENCODING=b";

    private static final String SHIFT_JIS = "SHIFT_JIS";

    private final Context mContext;
    private final int mVCardType;
    private final boolean mCareHandlerErrors;
    private final ContentResolver mContentResolver;

    // Convenient member variables about the restriction of the vCard format.
    // Used for not calling the same methods returning same results.
    private final boolean mIsV30;
    private final boolean mIsJapaneseMobilePhone;
    private final boolean mOnlyOneNoteFieldIsAvailable;
    private final boolean mIsDoCoMo;
    private final boolean mUsesQuotedPrintable;
    private final boolean mUsesAndroidProperty;
    private final boolean mUsesDefactProperty;
    private final boolean mUsesUtf8;
    private final boolean mUsesShiftJis;
    private final boolean mUsesQPToPrimaryProperties;

    private Cursor mCursor;
    private int mIdColumn;

    private final String mCharsetString;
    private final String mVCardAttributeCharset;
    private boolean mTerminateIsCalled;
    final private List<OneEntryHandler> mHandlerList;

    private String mErrorReason = NO_ERROR;

    private static final Map<Integer, String> sImMap;

    static {
        sImMap = new HashMap<Integer, String>();
        sImMap.put(Im.PROTOCOL_AIM, Constants.PROPERTY_X_AIM);
        sImMap.put(Im.PROTOCOL_MSN, Constants.PROPERTY_X_MSN);
        sImMap.put(Im.PROTOCOL_YAHOO, Constants.PROPERTY_X_YAHOO);
        sImMap.put(Im.PROTOCOL_ICQ, Constants.PROPERTY_X_ICQ);
        sImMap.put(Im.PROTOCOL_JABBER, Constants.PROPERTY_X_JABBER);
        sImMap.put(Im.PROTOCOL_SKYPE, Constants.PROPERTY_X_SKYPE_USERNAME);
        // Google talk is a special case.
    }

    private boolean mIsCallLogComposer = false;

    private boolean mNeedPhotoForVCard = true;

    private static final String[] sContactsProjection = new String[] {
        Contacts._ID,
    };

    /** The projection to use when querying the call log table */
    private static final String[] sCallLogProjection = new String[] {
            Calls.NUMBER, Calls.DATE, Calls.TYPE, Calls.CACHED_NAME, Calls.CACHED_NUMBER_TYPE,
            Calls.CACHED_NUMBER_LABEL
    };
    private static final int NUMBER_COLUMN_INDEX = 0;
    private static final int DATE_COLUMN_INDEX = 1;
    private static final int CALL_TYPE_COLUMN_INDEX = 2;
    private static final int CALLER_NAME_COLUMN_INDEX = 3;
    private static final int CALLER_NUMBERTYPE_COLUMN_INDEX = 4;
    private static final int CALLER_NUMBERLABEL_COLUMN_INDEX = 5;

    private static final String FLAG_TIMEZONE_UTC = "Z";

    public VCardComposer(Context context) {
        this(context, VCardConfig.VCARD_TYPE_DEFAULT, true, false, true);
    }

    public VCardComposer(Context context, String vcardTypeStr,
            boolean careHandlerErrors) {
        this(context, VCardConfig.getVCardTypeFromString(vcardTypeStr),
                careHandlerErrors, false, true);
    }

    public VCardComposer(Context context, int vcardType, boolean careHandlerErrors) {
        this(context, vcardType, careHandlerErrors, false, true);
    }

    /**
     * Construct for supporting call log entry vCard composing.
     *
     * @param isCallLogComposer true if this composer is for creating Call Log vCard.
     */
    public VCardComposer(Context context, int vcardType, boolean careHandlerErrors,
            boolean isCallLogComposer, boolean needPhotoInVCard) {
        mContext = context;
        mVCardType = vcardType;
        mCareHandlerErrors = careHandlerErrors;
        mIsCallLogComposer = isCallLogComposer;
        mNeedPhotoForVCard = needPhotoInVCard;
        mContentResolver = context.getContentResolver();

        mIsV30 = VCardConfig.isV30(vcardType);
        mUsesQuotedPrintable = VCardConfig.usesQuotedPrintable(vcardType);
        mIsDoCoMo = VCardConfig.isDoCoMo(vcardType);
        mIsJapaneseMobilePhone = VCardConfig
                .needsToConvertPhoneticString(vcardType);
        mOnlyOneNoteFieldIsAvailable = VCardConfig
                .onlyOneNoteFieldIsAvailable(vcardType);
        mUsesAndroidProperty = VCardConfig
                .usesAndroidSpecificProperty(vcardType);
        mUsesDefactProperty = VCardConfig.usesDefactProperty(vcardType);
        mUsesUtf8 = VCardConfig.usesUtf8(vcardType);
        mUsesShiftJis = VCardConfig.usesShiftJis(vcardType);
        mUsesQPToPrimaryProperties = VCardConfig.usesQPToPrimaryProperties(vcardType);
        mHandlerList = new ArrayList<OneEntryHandler>();

        if (mIsDoCoMo) {
            mCharsetString = CharsetUtils.charsetForVendor(SHIFT_JIS, "docomo").name();
            // Do not use mCharsetString bellow since it is different from "SHIFT_JIS" but
            // may be "DOCOMO_SHIFT_JIS" or something like that (internal expression used in
            // Android, not shown to the public).
            mVCardAttributeCharset = "CHARSET=" + SHIFT_JIS;
        } else if (mUsesShiftJis) {
            mCharsetString = CharsetUtils.charsetForVendor(SHIFT_JIS).name();
            mVCardAttributeCharset = "CHARSET=" + SHIFT_JIS;
        } else {
            mCharsetString = "UTF-8";
            mVCardAttributeCharset = "CHARSET=UTF-8";
        }
    }

    /**
     * This static function is to compose vCard for phone own number
     */
    public String composeVCardForPhoneOwnNumber(int phonetype, String phoneName,
            String phoneNumber, boolean vcardVer21) {
        final StringBuilder builder = new StringBuilder();
        appendVCardLine(builder, VCARD_PROPERTY_BEGIN, VCARD_DATA_VCARD);
        if (!vcardVer21) {
            appendVCardLine(builder, VCARD_PROPERTY_VERSION, Constants.VERSION_V30);
        } else {
            appendVCardLine(builder, VCARD_PROPERTY_VERSION, Constants.VERSION_V21);
        }

        boolean needCharset = false;
        if (!(VCardUtils.containsOnlyPrintableAscii(phoneName))) {
            needCharset = true;
        }
        // TODO: QP should be used? Using mUsesQPToPrimaryProperties should help.
        appendVCardLine(builder, VCARD_PROPERTY_FULL_NAME, phoneName, needCharset, false);
        appendVCardLine(builder, VCARD_PROPERTY_NAME, phoneName, needCharset, false);

        if (!TextUtils.isEmpty(phoneNumber)) {
            String label = Integer.toString(phonetype);
            appendVCardTelephoneLine(builder, phonetype, label, phoneNumber);
        }

        appendVCardLine(builder, VCARD_PROPERTY_END, VCARD_DATA_VCARD);

        return builder.toString();
    }

    /**
     * Must call before {{@link #init()}.
     */
    public void addHandler(OneEntryHandler handler) {
        mHandlerList.add(handler);
    }

    public boolean init() {
        return init(null, null);
    }

    /**
     * @return Returns true when initialization is successful and all the other
     *          methods are available. Returns false otherwise.
     */
    public boolean init(final String selection, final String[] selectionArgs) {
        if (mCareHandlerErrors) {
            List<OneEntryHandler> finishedList = new ArrayList<OneEntryHandler>(
                    mHandlerList.size());
            for (OneEntryHandler handler : mHandlerList) {
                if (!handler.onInit(mContext)) {
                    for (OneEntryHandler finished : finishedList) {
                        finished.onTerminate();
                    }
                    return false;
                }
            }
        } else {
            // Just ignore the false returned from onInit().
            for (OneEntryHandler handler : mHandlerList) {
                handler.onInit(mContext);
            }
        }

        if (mIsCallLogComposer) {
            mCursor = mContentResolver.query(CallLog.Calls.CONTENT_URI, sCallLogProjection,
                    selection, selectionArgs, null);
        } else {
            mCursor = mContentResolver.query(Contacts.CONTENT_URI, sContactsProjection,
                    selection, selectionArgs, null);
        }

        if (mCursor == null) {
            mErrorReason = FAILURE_REASON_FAILED_TO_GET_DATABASE_INFO;
            return false;
        }

        if (getCount() == 0 || !mCursor.moveToFirst()) {
            try {
                mCursor.close();
            } catch (SQLiteException e) {
                Log.e(LOG_TAG, "SQLiteException on Cursor#close(): " + e.getMessage());
            } finally {
                mCursor = null;
                mErrorReason = FAILURE_REASON_NO_ENTRY;
            }
            return false;
        }

        if (mIsCallLogComposer) {
            mIdColumn = -1;
        } else {
            mIdColumn = mCursor.getColumnIndex(Contacts._ID);
        }

        return true;
    }

    public boolean createOneEntry() {
        if (mCursor == null || mCursor.isAfterLast()) {
            mErrorReason = FAILURE_REASON_NOT_INITIALIZED;
            return false;
        }
        String name = null;
        String vcard;
        try {
            if (mIsCallLogComposer) {
                vcard = createOneCallLogEntryInternal();
            } else {
                if (mIdColumn >= 0) {
                    vcard = createOneEntryInternal(mCursor.getString(mIdColumn));
                } else {
                    Log.e(LOG_TAG, "Incorrect mIdColumn: " + mIdColumn);
                    return true;
                }
            }
        } catch (OutOfMemoryError error) {
            // Maybe some data (e.g. photo) is too big to have in memory. But it
            // should be rare.
            Log.e(LOG_TAG, "OutOfMemoryError occured. Ignore the entry: "
                    + name);
            System.gc();
            // TODO: should tell users what happened?
            return true;
        } finally {
            mCursor.moveToNext();
        }

        // This function does not care the OutOfMemoryError on the handler side
        // :-P
        if (mCareHandlerErrors) {
            List<OneEntryHandler> finishedList = new ArrayList<OneEntryHandler>(
                    mHandlerList.size());
            for (OneEntryHandler handler : mHandlerList) {
                if (!handler.onEntryCreated(vcard)) {
                    return false;
                }
            }
        } else {
            for (OneEntryHandler handler : mHandlerList) {
                handler.onEntryCreated(vcard);
            }
        }

        return true;
    }

    /**
     * Format according to RFC 2445 DATETIME type.
     * The format is: ("%Y%m%dT%H%M%SZ").
     */
    private final String toRfc2455Format(final long millSecs) {
        Time startDate = new Time();
        startDate.set(millSecs);
        String date = startDate.format2445();
        return date + FLAG_TIMEZONE_UTC;
    }

    /**
     * Try to append the property line for a call history time stamp field if possible.
     * Do nothing if the call log type gotton from the database is invalid.
     */
    private void tryAppendCallHistoryTimeStampField(final StringBuilder builder) {
        // Extension for call history as defined in
        // in the Specification for Ic Mobile Communcation - ver 1.1,
        // Oct 2000. This is used to send the details of the call
        // history - missed, incoming, outgoing along with date and time
        // to the requesting device (For example, transferring phone book
        // when connected over bluetooth)
        //
        // e.g. "X-IRMC-CALL-DATETIME;MISSED:20050320T100000Z"
        final int callLogType = mCursor.getInt(CALL_TYPE_COLUMN_INDEX);
        final String callLogTypeStr;
        switch (callLogType) {
            case Calls.INCOMING_TYPE: {
                callLogTypeStr = VCARD_PROPERTY_CALLTYPE_INCOMING;
                break;
            }
            case Calls.OUTGOING_TYPE: {
                callLogTypeStr = VCARD_PROPERTY_CALLTYPE_OUTGOING;
                break;
            }
            case Calls.MISSED_TYPE: {
                callLogTypeStr = VCARD_PROPERTY_CALLTYPE_MISSED;
                break;
            }
            default: {
                Log.w(LOG_TAG, "Call log type not correct.");
                return;
            }
        }

        final long dateAsLong = mCursor.getLong(DATE_COLUMN_INDEX);
        builder.append(VCARD_PROPERTY_X_TIMESTAMP);
        builder.append(VCARD_ATTR_SEPARATOR);
        appendTypeAttribute(builder, callLogTypeStr);
        builder.append(VCARD_DATA_SEPARATOR);
        builder.append(toRfc2455Format(dateAsLong));
        builder.append(VCARD_COL_SEPARATOR);
    }

    private String createOneCallLogEntryInternal() {
        final StringBuilder builder = new StringBuilder();
        appendVCardLine(builder, VCARD_PROPERTY_BEGIN, VCARD_DATA_VCARD);
        if (mIsV30) {
            appendVCardLine(builder, VCARD_PROPERTY_VERSION, Constants.VERSION_V30);
        } else {
            appendVCardLine(builder, VCARD_PROPERTY_VERSION, Constants.VERSION_V21);
        }
        String name = mCursor.getString(CALLER_NAME_COLUMN_INDEX);
        if (TextUtils.isEmpty(name)) {
            name = mCursor.getString(NUMBER_COLUMN_INDEX);
        }
        final boolean needCharset = !(VCardUtils.containsOnlyPrintableAscii(name));
        // TODO: QP should be used? Using mUsesQPToPrimaryProperties should help.
        appendVCardLine(builder, VCARD_PROPERTY_FULL_NAME, name, needCharset, false);
        appendVCardLine(builder, VCARD_PROPERTY_NAME, name, needCharset, false);

        String number = mCursor.getString(NUMBER_COLUMN_INDEX);
        int type = mCursor.getInt(CALLER_NUMBERTYPE_COLUMN_INDEX);
        String label = mCursor.getString(CALLER_NUMBERLABEL_COLUMN_INDEX);
        if (TextUtils.isEmpty(label)) {
            label = Integer.toString(type);
        }
        appendVCardTelephoneLine(builder, type, label, number);
        tryAppendCallHistoryTimeStampField(builder);
        appendVCardLine(builder, VCARD_PROPERTY_END, VCARD_DATA_VCARD);
        return builder.toString();
    }

    private String createOneEntryInternal(final String contactId) {
        final Map<String, List<ContentValues>> contentValuesListMap =
                new HashMap<String, List<ContentValues>>();
        final String selection = Data.CONTACT_ID + "=?";
        final String[] selectionArgs = new String[] {contactId};
        // The resolver may return the entity iterator with no data. It is possiible.
        // e.g. If all the data in the contact of the given contact id are not exportable ones,
        //      they are hidden from the view of this method, though contact id itself exists.
        boolean dataExists = false;
        EntityIterator entityIterator = null;
        try {
            entityIterator = mContentResolver.queryEntities(
                    sDataRequestUri, selection, selectionArgs, null);
            dataExists = entityIterator.hasNext();
            while (entityIterator.hasNext()) {
                Entity entity = entityIterator.next();
                for (NamedContentValues namedContentValues : entity
                        .getSubValues()) {
                    ContentValues contentValues = namedContentValues.values;
                    String key = contentValues.getAsString(Data.MIMETYPE);
                    if (key != null) {
                        List<ContentValues> contentValuesList =
                                contentValuesListMap.get(key);
                        if (contentValuesList == null) {
                            contentValuesList = new ArrayList<ContentValues>();
                            contentValuesListMap.put(key, contentValuesList);
                        }
                        contentValuesList.add(contentValues);
                    }
                }
            }
        } catch (RemoteException e) {
            Log.e(LOG_TAG, String.format("RemoteException at id %s (%s)",
                    contactId, e.getMessage()));
            return "";
        } finally {
            if (entityIterator != null) {
                entityIterator.close();
            }
        }

        if (!dataExists) {
            return "";
        }

        final StringBuilder builder = new StringBuilder();
        appendVCardLine(builder, VCARD_PROPERTY_BEGIN, VCARD_DATA_VCARD);
        if (mIsV30) {
            appendVCardLine(builder, VCARD_PROPERTY_VERSION, Constants.VERSION_V30);
        } else {
            appendVCardLine(builder, VCARD_PROPERTY_VERSION, Constants.VERSION_V21);
        }

        appendStructuredNames(builder, contentValuesListMap);
        appendNickNames(builder, contentValuesListMap);
        appendPhones(builder, contentValuesListMap);
        appendEmails(builder, contentValuesListMap);
        appendPostals(builder, contentValuesListMap);
        appendIms(builder, contentValuesListMap);
        appendWebsites(builder, contentValuesListMap);
        appendBirthday(builder, contentValuesListMap);
        appendOrganizations(builder, contentValuesListMap);
        if (mNeedPhotoForVCard) {
            appendPhotos(builder, contentValuesListMap);
        }
        appendNotes(builder, contentValuesListMap);
        // TODO: GroupMembership

        if (mIsDoCoMo) {
            appendVCardLine(builder, VCARD_PROPERTY_X_CLASS, VCARD_DATA_PUBLIC);
            appendVCardLine(builder, VCARD_PROPERTY_X_REDUCTION, "");
            appendVCardLine(builder, VCARD_PROPERTY_X_NO, "");
            appendVCardLine(builder, VCARD_PROPERTY_X_DCM_HMN_MODE, "");
        }

        appendVCardLine(builder, VCARD_PROPERTY_END, VCARD_DATA_VCARD);

        return builder.toString();
    }

    public void terminate() {
        for (OneEntryHandler handler : mHandlerList) {
            handler.onTerminate();
        }

        if (mCursor != null) {
            try {
                mCursor.close();
            } catch (SQLiteException e) {
                Log.e(LOG_TAG, "SQLiteException on Cursor#close(): "
                        + e.getMessage());
            }
            mCursor = null;
        }

        mTerminateIsCalled = true;
    }

    @Override
    public void finalize() {
        if (!mTerminateIsCalled) {
            terminate();
        }
    }

    public int getCount() {
        if (mCursor == null) {
            return 0;
        }
        return mCursor.getCount();
    }

    public boolean isAfterLast() {
        if (mCursor == null) {
            return false;
        }
        return mCursor.isAfterLast();
    }

    /**
     * @return Return the error reason if possible.
     */
    public String getErrorReason() {
        return mErrorReason;
    }

    private void appendStructuredNames(final StringBuilder builder,
            final Map<String, List<ContentValues>> contentValuesListMap) {
        final List<ContentValues> contentValuesList = contentValuesListMap
                .get(StructuredName.CONTENT_ITEM_TYPE);
        if (contentValuesList != null && contentValuesList.size() > 0) {
            appendStructuredNamesInternal(builder, contentValuesList);
        } else if (mIsDoCoMo) {
            appendVCardLine(builder, VCARD_PROPERTY_NAME, "");
        } else if (mIsV30) {
            // vCard 3.0 requires "N" and "FN" properties.
            appendVCardLine(builder, VCARD_PROPERTY_NAME, "");
            appendVCardLine(builder, VCARD_PROPERTY_FULL_NAME, "");
        }
    }

    private boolean containsNonEmptyName(ContentValues contentValues) {
        final String familyName = contentValues.getAsString(StructuredName.FAMILY_NAME);
        final String middleName = contentValues.getAsString(StructuredName.MIDDLE_NAME);
        final String givenName = contentValues.getAsString(StructuredName.GIVEN_NAME);
        final String prefix = contentValues.getAsString(StructuredName.PREFIX);
        final String suffix = contentValues.getAsString(StructuredName.SUFFIX);
        final String displayName = contentValues.getAsString(StructuredName.DISPLAY_NAME);
        return !(TextUtils.isEmpty(familyName) && TextUtils.isEmpty(middleName) &&
                TextUtils.isEmpty(givenName) && TextUtils.isEmpty(prefix) &&
                TextUtils.isEmpty(suffix) && TextUtils.isEmpty(displayName));
    }

    private void appendStructuredNamesInternal(final StringBuilder builder,
            final List<ContentValues> contentValuesList) {
        // For safety, we'll emit just one value around StructuredName, as external importers
        // may get confused with multiple "N", "FN", etc. properties, though it is valid in
        // vCard spec.
        ContentValues primaryContentValues = null;
        ContentValues subprimaryContentValues = null;
        for (ContentValues contentValues : contentValuesList) {
            if (contentValues == null){
                continue;
            }
            Integer isSuperPrimary = contentValues.getAsInteger(StructuredName.IS_SUPER_PRIMARY);
            if (isSuperPrimary != null && isSuperPrimary > 0) {
                // We choose "super primary" ContentValues.
                primaryContentValues = contentValues;
                break;
            } else if (primaryContentValues == null) {
                // We choose the first "primary" ContentValues
                // if "super primary" ContentValues does not exist.
                Integer isPrimary = contentValues.getAsInteger(StructuredName.IS_PRIMARY);
                if (isPrimary != null && isPrimary > 0 &&
                        containsNonEmptyName(contentValues)) {
                    primaryContentValues = contentValues;
                    // Do not break, since there may be ContentValues with "super primary"
                    // afterword.
                } else if (subprimaryContentValues == null &&
                        containsNonEmptyName(contentValues)) {
                    subprimaryContentValues = contentValues;
                }
            }
        }

        if (primaryContentValues == null) {
            if (subprimaryContentValues != null) {
                // We choose the first ContentValues if any "primary" ContentValues does not exist.
                primaryContentValues = subprimaryContentValues;
            } else {
                Log.e(LOG_TAG, "All ContentValues given from database is empty.");
                primaryContentValues = new ContentValues();
            }
        }

        final String familyName = primaryContentValues
                .getAsString(StructuredName.FAMILY_NAME);
        final String middleName = primaryContentValues
                .getAsString(StructuredName.MIDDLE_NAME);
        final String givenName = primaryContentValues
                .getAsString(StructuredName.GIVEN_NAME);
        final String prefix = primaryContentValues
                .getAsString(StructuredName.PREFIX);
        final String suffix = primaryContentValues
                .getAsString(StructuredName.SUFFIX);
        final String displayName = primaryContentValues
                .getAsString(StructuredName.DISPLAY_NAME);

        if (!TextUtils.isEmpty(familyName) || !TextUtils.isEmpty(givenName)) {
            final String encodedFamily;
            final String encodedGiven;
            final String encodedMiddle;
            final String encodedPrefix;
            final String encodedSuffix;

            final boolean reallyUseQuotedPrintableToName =
                (mUsesQPToPrimaryProperties &&
                    !(VCardUtils.containsOnlyNonCrLfPrintableAscii(familyName) &&
                            VCardUtils.containsOnlyNonCrLfPrintableAscii(givenName) &&
                            VCardUtils.containsOnlyNonCrLfPrintableAscii(middleName) &&
                            VCardUtils.containsOnlyNonCrLfPrintableAscii(prefix) &&
                            VCardUtils.containsOnlyNonCrLfPrintableAscii(suffix)));

            if (reallyUseQuotedPrintableToName) {
                encodedFamily = encodeQuotedPrintable(familyName);
                encodedGiven = encodeQuotedPrintable(givenName);
                encodedMiddle = encodeQuotedPrintable(middleName);
                encodedPrefix = encodeQuotedPrintable(prefix);
                encodedSuffix = encodeQuotedPrintable(suffix);
            } else {
                encodedFamily = escapeCharacters(familyName);
                encodedGiven = escapeCharacters(givenName);
                encodedMiddle = escapeCharacters(middleName);
                encodedPrefix = escapeCharacters(prefix);
                encodedSuffix = escapeCharacters(suffix);
            }

            // N property. This order is specified by vCard spec and does not depend on countries.
            builder.append(VCARD_PROPERTY_NAME);
            if (shouldAppendCharsetAttribute(Arrays.asList(
                    familyName, givenName, middleName, prefix, suffix))) {
                builder.append(VCARD_ATTR_SEPARATOR);
                builder.append(mVCardAttributeCharset);
            }
            if (reallyUseQuotedPrintableToName) {
                builder.append(VCARD_ATTR_SEPARATOR);
                builder.append(VCARD_ATTR_ENCODING_QP);
            }

            builder.append(VCARD_DATA_SEPARATOR);
            builder.append(encodedFamily);
            builder.append(VCARD_ITEM_SEPARATOR);
            builder.append(encodedGiven);
            builder.append(VCARD_ITEM_SEPARATOR);
            builder.append(encodedMiddle);
            builder.append(VCARD_ITEM_SEPARATOR);
            builder.append(encodedPrefix);
            builder.append(VCARD_ITEM_SEPARATOR);
            builder.append(encodedSuffix);
            builder.append(VCARD_COL_SEPARATOR);

            final String fullname = VCardUtils.constructNameFromElements(
                    VCardConfig.getNameOrderType(mVCardType),
                    encodedFamily, encodedMiddle, encodedGiven, encodedPrefix, encodedSuffix);
            final boolean reallyUseQuotedPrintableToFullname =
                mUsesQPToPrimaryProperties &&
                !VCardUtils.containsOnlyNonCrLfPrintableAscii(fullname);

            final String encodedFullname =
                reallyUseQuotedPrintableToFullname ?
                        encodeQuotedPrintable(fullname) :
                            escapeCharacters(fullname);

            // FN property
            builder.append(VCARD_PROPERTY_FULL_NAME);
            if (shouldAppendCharsetAttribute(encodedFullname)) {
                builder.append(VCARD_ATTR_SEPARATOR);
                builder.append(mVCardAttributeCharset);
            }
            if (reallyUseQuotedPrintableToFullname) {
                builder.append(VCARD_ATTR_SEPARATOR);
                builder.append(VCARD_ATTR_ENCODING_QP);
            }
            builder.append(VCARD_DATA_SEPARATOR);
            builder.append(encodedFullname);
            builder.append(VCARD_COL_SEPARATOR);
        } else if (!TextUtils.isEmpty(displayName)) {
            final boolean reallyUseQuotedPrintableToDisplayName =
                (mUsesQPToPrimaryProperties &&
                        !VCardUtils.containsOnlyNonCrLfPrintableAscii(displayName));
            final String encodedDisplayName =
                    reallyUseQuotedPrintableToDisplayName ?
                            encodeQuotedPrintable(displayName) :
                                escapeCharacters(displayName);

            builder.append(VCARD_PROPERTY_NAME);
            if (shouldAppendCharsetAttribute(encodedDisplayName)) {
                builder.append(VCARD_ATTR_SEPARATOR);
                builder.append(mVCardAttributeCharset);
            }
            if (reallyUseQuotedPrintableToDisplayName) {
                builder.append(VCARD_ATTR_SEPARATOR);
                builder.append(VCARD_ATTR_ENCODING_QP);
            }
            builder.append(VCARD_DATA_SEPARATOR);
            builder.append(encodedDisplayName);
            builder.append(VCARD_ITEM_SEPARATOR);
            builder.append(VCARD_ITEM_SEPARATOR);
            builder.append(VCARD_ITEM_SEPARATOR);
            builder.append(VCARD_ITEM_SEPARATOR);
            builder.append(VCARD_COL_SEPARATOR);
        } else if (mIsDoCoMo) {
            appendVCardLine(builder, VCARD_PROPERTY_NAME, "");
        } else if (mIsV30) {
            appendVCardLine(builder, VCARD_PROPERTY_NAME, "");
            appendVCardLine(builder, VCARD_PROPERTY_FULL_NAME, "");
        }

        String phoneticFamilyName = primaryContentValues
                .getAsString(StructuredName.PHONETIC_FAMILY_NAME);
        String phoneticMiddleName = primaryContentValues
                .getAsString(StructuredName.PHONETIC_MIDDLE_NAME);
        String phoneticGivenName = primaryContentValues
                .getAsString(StructuredName.PHONETIC_GIVEN_NAME);
        if (!(TextUtils.isEmpty(phoneticFamilyName)
                && TextUtils.isEmpty(phoneticMiddleName) &&
                TextUtils.isEmpty(phoneticGivenName))) { // if not empty
            if (mIsJapaneseMobilePhone) {
                phoneticFamilyName = VCardUtils
                        .toHalfWidthString(phoneticFamilyName);
                phoneticMiddleName = VCardUtils
                        .toHalfWidthString(phoneticMiddleName);
                phoneticGivenName = VCardUtils
                        .toHalfWidthString(phoneticGivenName);
            }

            if (mIsV30) {
                final String sortString = VCardUtils
                        .constructNameFromElements(mVCardType,
                                phoneticFamilyName,
                                phoneticMiddleName,
                                phoneticGivenName);
                builder.append(VCARD_PROPERTY_SORT_STRING);

                // Do not need to care about QP, since vCard 3.0 does not allow it.
                final String encodedSortString = escapeCharacters(sortString);
                if (shouldAppendCharsetAttribute(encodedSortString)) {
                    builder.append(VCARD_ATTR_SEPARATOR);
                    builder.append(mVCardAttributeCharset);
                }
                builder.append(VCARD_DATA_SEPARATOR);
                builder.append(encodedSortString);
                builder.append(VCARD_COL_SEPARATOR);
            } else {
                // Note: There is no appropriate property for expressing
                //       phonetic name in vCard 2.1, while there is in
                //       vCard 3.0 (SORT-STRING).
                //       We chose to use DoCoMo's way since it is supported by
                //       a lot of Japanese mobile phones. This is "X-" property, so
                //       any parser hopefully would not get confused with this.
                builder.append(VCARD_PROPERTY_SOUND);
                builder.append(VCARD_ATTR_SEPARATOR);
                builder.append(Constants.ATTR_TYPE_X_IRMC_N);

                boolean reallyUseQuotedPrintable =
                    (mUsesQPToPrimaryProperties &&
                            !(VCardUtils.containsOnlyNonCrLfPrintableAscii(
                                    phoneticFamilyName) &&
                              VCardUtils.containsOnlyNonCrLfPrintableAscii(
                                    phoneticMiddleName) &&
                              VCardUtils.containsOnlyNonCrLfPrintableAscii(
                                    phoneticGivenName)));

                final String encodedPhoneticFamilyName;
                final String encodedPhoneticMiddleName;
                final String encodedPhoneticGivenName;
                if (reallyUseQuotedPrintable) {
                    encodedPhoneticFamilyName = encodeQuotedPrintable(phoneticFamilyName);
                    encodedPhoneticMiddleName = encodeQuotedPrintable(phoneticMiddleName);
                    encodedPhoneticGivenName = encodeQuotedPrintable(phoneticGivenName);
                } else {
                    encodedPhoneticFamilyName = escapeCharacters(phoneticFamilyName);
                    encodedPhoneticMiddleName = escapeCharacters(phoneticMiddleName);
                    encodedPhoneticGivenName = escapeCharacters(phoneticGivenName);
                }

                if (shouldAppendCharsetAttribute(Arrays.asList(
                        encodedPhoneticFamilyName, encodedPhoneticMiddleName,
                        encodedPhoneticGivenName))) {
                    builder.append(VCARD_ATTR_SEPARATOR);
                    builder.append(mVCardAttributeCharset);
                }
                builder.append(VCARD_DATA_SEPARATOR);
                builder.append(encodedPhoneticFamilyName);
                builder.append(VCARD_ITEM_SEPARATOR);
                builder.append(encodedPhoneticGivenName);
                builder.append(VCARD_ITEM_SEPARATOR);
                builder.append(encodedPhoneticMiddleName);
                builder.append(VCARD_ITEM_SEPARATOR);
                builder.append(VCARD_ITEM_SEPARATOR);
                builder.append(VCARD_COL_SEPARATOR);
            }
        } else if (mIsDoCoMo) {
            builder.append(VCARD_PROPERTY_SOUND);
            builder.append(VCARD_ATTR_SEPARATOR);
            builder.append(Constants.ATTR_TYPE_X_IRMC_N);
            builder.append(VCARD_DATA_SEPARATOR);
            builder.append(VCARD_ITEM_SEPARATOR);
            builder.append(VCARD_ITEM_SEPARATOR);
            builder.append(VCARD_ITEM_SEPARATOR);
            builder.append(VCARD_ITEM_SEPARATOR);
            builder.append(VCARD_COL_SEPARATOR);
        }

        if (mUsesDefactProperty) {
            if (!TextUtils.isEmpty(phoneticGivenName)) {
                final boolean reallyUseQuotedPrintable =
                    (mUsesQPToPrimaryProperties &&
                            !VCardUtils.containsOnlyNonCrLfPrintableAscii(phoneticGivenName));
                final String encodedPhoneticGivenName;
                if (reallyUseQuotedPrintable) {
                    encodedPhoneticGivenName = encodeQuotedPrintable(phoneticGivenName);
                } else {
                    encodedPhoneticGivenName = escapeCharacters(phoneticGivenName);
                }
                builder.append(VCARD_PROPERTY_X_PHONETIC_FIRST_NAME);
                if (shouldAppendCharsetAttribute(encodedPhoneticGivenName)) {
                    builder.append(VCARD_ATTR_SEPARATOR);
                    builder.append(mVCardAttributeCharset);
                }
                if (reallyUseQuotedPrintable) {
                    builder.append(VCARD_ATTR_SEPARATOR);
                    builder.append(VCARD_ATTR_ENCODING_QP);
                }
                builder.append(VCARD_DATA_SEPARATOR);
                builder.append(encodedPhoneticGivenName);
                builder.append(VCARD_COL_SEPARATOR);
            }
            if (!TextUtils.isEmpty(phoneticMiddleName)) {
                final boolean reallyUseQuotedPrintable =
                    (mUsesQPToPrimaryProperties &&
                            !VCardUtils.containsOnlyNonCrLfPrintableAscii(phoneticMiddleName));
                final String encodedPhoneticMiddleName;
                if (reallyUseQuotedPrintable) {
                    encodedPhoneticMiddleName = encodeQuotedPrintable(phoneticMiddleName);
                } else {
                    encodedPhoneticMiddleName = escapeCharacters(phoneticMiddleName);
                }
                builder.append(VCARD_PROPERTY_X_PHONETIC_MIDDLE_NAME);
                if (shouldAppendCharsetAttribute(encodedPhoneticMiddleName)) {
                    builder.append(VCARD_ATTR_SEPARATOR);
                    builder.append(mVCardAttributeCharset);
                }
                if (reallyUseQuotedPrintable) {
                    builder.append(VCARD_ATTR_SEPARATOR);
                    builder.append(VCARD_ATTR_ENCODING_QP);
                }
                builder.append(VCARD_DATA_SEPARATOR);
                builder.append(encodedPhoneticMiddleName);
                builder.append(VCARD_COL_SEPARATOR);
            }
            if (!TextUtils.isEmpty(phoneticFamilyName)) {
                final boolean reallyUseQuotedPrintable =
                    (mUsesQPToPrimaryProperties &&
                            !VCardUtils.containsOnlyNonCrLfPrintableAscii(phoneticFamilyName));
                final String encodedPhoneticFamilyName;
                if (reallyUseQuotedPrintable) {
                    encodedPhoneticFamilyName = encodeQuotedPrintable(phoneticFamilyName);
                } else {
                    encodedPhoneticFamilyName = escapeCharacters(phoneticFamilyName);
                }
                builder.append(VCARD_PROPERTY_X_PHONETIC_LAST_NAME);
                if (shouldAppendCharsetAttribute(encodedPhoneticFamilyName)) {
                    builder.append(VCARD_ATTR_SEPARATOR);
                    builder.append(mVCardAttributeCharset);
                }
                if (reallyUseQuotedPrintable) {
                    builder.append(VCARD_ATTR_SEPARATOR);
                    builder.append(VCARD_ATTR_ENCODING_QP);
                }
                builder.append(VCARD_DATA_SEPARATOR);
                builder.append(encodedPhoneticFamilyName);
                builder.append(VCARD_COL_SEPARATOR);
            }
        }
    }

    private void appendNickNames(final StringBuilder builder,
            final Map<String, List<ContentValues>> contentValuesListMap) {
        final List<ContentValues> contentValuesList = contentValuesListMap
                .get(Nickname.CONTENT_ITEM_TYPE);
        if (contentValuesList != null) {
            final String propertyNickname;
            if (mIsV30) {
                propertyNickname = VCARD_PROPERTY_NICKNAME;
            } else if (mUsesAndroidProperty) {
                propertyNickname = VCARD_PROPERTY_X_NICKNAME;
            } else {
                // There's no way to add this field.
                return;
            }

            for (ContentValues contentValues : contentValuesList) {
                final String nickname = contentValues.getAsString(Nickname.NAME);
                if (TextUtils.isEmpty(nickname)) {
                    continue;
                }

                final String encodedNickname;
                final boolean reallyUseQuotedPrintable =
                    (mUsesQuotedPrintable &&
                            !VCardUtils.containsOnlyNonCrLfPrintableAscii(nickname));
                if (reallyUseQuotedPrintable) {
                    encodedNickname = encodeQuotedPrintable(nickname);
                } else {
                    encodedNickname = escapeCharacters(nickname);
                }

                builder.append(propertyNickname);
                if (shouldAppendCharsetAttribute(propertyNickname)) {
                    builder.append(VCARD_ATTR_SEPARATOR);
                    builder.append(mVCardAttributeCharset);
                }
                if (reallyUseQuotedPrintable) {
                    builder.append(VCARD_ATTR_SEPARATOR);
                    builder.append(VCARD_ATTR_ENCODING_QP);
                }
                builder.append(VCARD_DATA_SEPARATOR);
                builder.append(encodedNickname);
                builder.append(VCARD_COL_SEPARATOR);
            }
        }
    }

    private void appendPhones(final StringBuilder builder,
            final Map<String, List<ContentValues>> contentValuesListMap) {
        final List<ContentValues> contentValuesList = contentValuesListMap
                .get(Phone.CONTENT_ITEM_TYPE);
        boolean phoneLineExists = false;
        if (contentValuesList != null) {
            Set<String> phoneSet = new HashSet<String>();
            for (ContentValues contentValues : contentValuesList) {
                final Integer typeAsObject = contentValues.getAsInteger(Phone.TYPE);
                final String label = contentValues.getAsString(Phone.LABEL);
                String phoneNumber = contentValues.getAsString(Phone.NUMBER);
                if (phoneNumber != null) {
                    phoneNumber = phoneNumber.trim();
                }
                if (TextUtils.isEmpty(phoneNumber)) {
                    continue;
                }
                int type = (typeAsObject != null ? typeAsObject : Phone.TYPE_HOME);

                phoneLineExists = true;
                if (type == Phone.TYPE_PAGER) {
                    phoneLineExists = true;
                    if (!phoneSet.contains(phoneNumber)) {
                        phoneSet.add(phoneNumber);
                        appendVCardTelephoneLine(builder, type, label, phoneNumber);
                    }
                } else {
                    // The entry "may" have several phone numbers when the contact entry is
                    // corrupted because of its original source.
                    //
                    // e.g. I encountered the entry like the following.
                    // "111-222-3333 (Miami)\n444-555-6666 (Broward; 305-653-6796 (Miami); ..."
                    // This kind of entry is not able to be inserted via Android devices, but
                    // possible if the source of the data is already corrupted.
                    List<String> phoneNumberList = splitIfSeveralPhoneNumbersExist(phoneNumber);
                    if (phoneNumberList.isEmpty()) {
                        continue;
                    }
                    phoneLineExists = true;
                    for (String actualPhoneNumber : phoneNumberList) {
                        if (!phoneSet.contains(actualPhoneNumber)) {
                            final int format = VCardUtils.getPhoneNumberFormat(mVCardType);
                            SpannableStringBuilder tmpBuilder =
                                new SpannableStringBuilder(actualPhoneNumber);
                            PhoneNumberUtils.formatNumber(tmpBuilder, format);
                            final String formattedPhoneNumber = tmpBuilder.toString();
                            phoneSet.add(actualPhoneNumber);
                            appendVCardTelephoneLine(builder, type, label, formattedPhoneNumber);
                        }
                    }
                }
            }
        }

        if (!phoneLineExists && mIsDoCoMo) {
            appendVCardTelephoneLine(builder, Phone.TYPE_HOME, "", "");
        }
    }

    private List<String> splitIfSeveralPhoneNumbersExist(final String phoneNumber) {
        List<String> phoneList = new ArrayList<String>();

        StringBuilder builder = new StringBuilder();
        final int length = phoneNumber.length();
        for (int i = 0; i < length; i++) {
            final char ch = phoneNumber.charAt(i);
            if (Character.isDigit(ch)) {
                builder.append(ch);
            } else if ((ch == ';' || ch == '\n') && builder.length() > 0) {
                phoneList.add(builder.toString());
                builder = new StringBuilder();
            }
        }
        if (builder.length() > 0) {
            phoneList.add(builder.toString());
        }

        return phoneList;
    }

    private void appendEmails(final StringBuilder builder,
            final Map<String, List<ContentValues>> contentValuesListMap) {
        final List<ContentValues> contentValuesList = contentValuesListMap
                .get(Email.CONTENT_ITEM_TYPE);
        boolean emailAddressExists = false;
        if (contentValuesList != null) {
            Set<String> addressSet = new HashSet<String>();
            for (ContentValues contentValues : contentValuesList) {
                Integer typeAsObject = contentValues.getAsInteger(Email.TYPE);
                final int type = (typeAsObject != null ?
                        typeAsObject : Email.TYPE_OTHER);
                final String label = contentValues.getAsString(Email.LABEL);
                String emailAddress = contentValues.getAsString(Email.DATA);
                if (emailAddress != null) {
                    emailAddress = emailAddress.trim();
                }
                if (TextUtils.isEmpty(emailAddress)) {
                    continue;
                }
                emailAddressExists = true;
                if (!addressSet.contains(emailAddress)) {
                    addressSet.add(emailAddress);
                    appendVCardEmailLine(builder, type, label, emailAddress);
                }
            }
        }

        if (!emailAddressExists && mIsDoCoMo) {
            appendVCardEmailLine(builder, Email.TYPE_HOME, "", "");
        }
    }

    private void appendPostals(final StringBuilder builder,
            final Map<String, List<ContentValues>> contentValuesListMap) {
        final List<ContentValues> contentValuesList = contentValuesListMap
                .get(StructuredPostal.CONTENT_ITEM_TYPE);
        if (contentValuesList != null) {
            if (mIsDoCoMo) {
                appendPostalsForDoCoMo(builder, contentValuesList);
            } else {
                appendPostalsForGeneric(builder, contentValuesList);
            }
        } else if (mIsDoCoMo) {
            builder.append(VCARD_PROPERTY_ADR);
            builder.append(VCARD_ATTR_SEPARATOR);
            builder.append(Constants.ATTR_TYPE_HOME);
            builder.append(VCARD_DATA_SEPARATOR);
            builder.append(VCARD_COL_SEPARATOR);
        }
    }

    /**
     * Tries to append just one line. If there's no appropriate address
     * information, append an empty line.
     */
    private void appendPostalsForDoCoMo(final StringBuilder builder,
            final List<ContentValues> contentValuesList) {
        // TODO: from old, inefficient code. fix this.
        if (appendPostalsForDoCoMoInternal(builder, contentValuesList,
                StructuredPostal.TYPE_HOME)) {
            return;
        }
        if (appendPostalsForDoCoMoInternal(builder, contentValuesList,
                StructuredPostal.TYPE_WORK)) {
            return;
        }
        if (appendPostalsForDoCoMoInternal(builder, contentValuesList,
                StructuredPostal.TYPE_OTHER)) {
            return;
        }
        if (appendPostalsForDoCoMoInternal(builder, contentValuesList,
                StructuredPostal.TYPE_CUSTOM)) {
            return;
        }

        Log.w(LOG_TAG,
                "Should not come here. Must have at least one postal data.");
    }

    private boolean appendPostalsForDoCoMoInternal(final StringBuilder builder,
            final List<ContentValues> contentValuesList, Integer preferedType) {
        for (ContentValues contentValues : contentValuesList) {
            final Integer type = contentValues.getAsInteger(StructuredPostal.TYPE);
            final String label = contentValues.getAsString(StructuredPostal.LABEL);
            if (type == preferedType) {
                appendVCardPostalLine(builder, type, label, contentValues);
                return true;
            }
        }
        return false;
    }

    private void appendPostalsForGeneric(final StringBuilder builder,
            final List<ContentValues> contentValuesList) {
        for (ContentValues contentValues : contentValuesList) {
            final Integer type = contentValues.getAsInteger(StructuredPostal.TYPE);
            final String label = contentValues.getAsString(StructuredPostal.LABEL);
            if (type != null) {
                appendVCardPostalLine(builder, type, label, contentValues);
            }
        }
    }

    private void appendIms(final StringBuilder builder,
            final Map<String, List<ContentValues>> contentValuesListMap) {
        final List<ContentValues> contentValuesList = contentValuesListMap
                .get(Im.CONTENT_ITEM_TYPE);
        if (contentValuesList != null) {
            for (ContentValues contentValues : contentValuesList) {
                Integer protocol = contentValues.getAsInteger(Im.PROTOCOL);
                String data = contentValues.getAsString(Im.DATA);
                if (data != null) {
                    data = data.trim();
                }
                if (TextUtils.isEmpty(data)) {
                    continue;
                }

                if (protocol != null && protocol == Im.PROTOCOL_GOOGLE_TALK) {
                    if (VCardConfig.usesAndroidSpecificProperty(mVCardType)) {
                        appendVCardLine(builder, Constants.PROPERTY_X_GOOGLE_TALK, data);
                    }
                    // TODO: add "X-GOOGLE TALK" case...
                }
            }
        }
    }

    private void appendWebsites(final StringBuilder builder,
            final Map<String, List<ContentValues>> contentValuesListMap) {
        final List<ContentValues> contentValuesList = contentValuesListMap
                .get(Website.CONTENT_ITEM_TYPE);
        if (contentValuesList != null) {
            for (ContentValues contentValues : contentValuesList) {
                String website = contentValues.getAsString(Website.URL);
                if (website != null) {
                    website = website.trim();
                }
                if (!TextUtils.isEmpty(website)) {
                    appendVCardLine(builder, VCARD_PROPERTY_URL, website);
                }
            }
        }
    }

    private void appendBirthday(final StringBuilder builder,
            final Map<String, List<ContentValues>> contentValuesListMap) {
        final List<ContentValues> contentValuesList = contentValuesListMap
                .get(Event.CONTENT_ITEM_TYPE);
        if (contentValuesList != null && contentValuesList.size() > 0) {
            Integer eventType = contentValuesList.get(0).getAsInteger(Event.TYPE);
            if (eventType == null || !eventType.equals(Event.TYPE_BIRTHDAY)) {
                return;
            }
            // Theoretically, there must be only one birthday for each vCard data and
            // we are afraid of some parse error occuring in some devices, so
            // we emit only one birthday entry for now.
            String birthday = contentValuesList.get(0).getAsString(Event.START_DATE);
            if (birthday != null) {
                birthday = birthday.trim();
            }
            if (!TextUtils.isEmpty(birthday)) {
                appendVCardLine(builder, VCARD_PROPERTY_BIRTHDAY, birthday);
            }
        }
    }

    private void appendOrganizations(final StringBuilder builder,
            final Map<String, List<ContentValues>> contentValuesListMap) {
        final List<ContentValues> contentValuesList = contentValuesListMap
                .get(Organization.CONTENT_ITEM_TYPE);
        if (contentValuesList != null) {
            for (ContentValues contentValues : contentValuesList) {
                String company = contentValues
                        .getAsString(Organization.COMPANY);
                if (company != null) {
                    company = company.trim();
                }
                String title = contentValues
                        .getAsString(Organization.TITLE);
                if (title != null) {
                    title = title.trim();
                }

                if (!TextUtils.isEmpty(company)) {
                    appendVCardLine(builder, VCARD_PROPERTY_ORG, company,
                            !VCardUtils.containsOnlyPrintableAscii(company),
                            (mUsesQuotedPrintable &&
                                    !VCardUtils.containsOnlyNonCrLfPrintableAscii(company)));
                }
                if (!TextUtils.isEmpty(title)) {
                    appendVCardLine(builder, VCARD_PROPERTY_TITLE, title,
                            !VCardUtils.containsOnlyPrintableAscii(title),
                            (mUsesQuotedPrintable &&
                                    !VCardUtils.containsOnlyNonCrLfPrintableAscii(title)));
                }
            }
        }
    }

    private void appendPhotos(final StringBuilder builder,
            final Map<String, List<ContentValues>> contentValuesListMap) {
        final List<ContentValues> contentValuesList = contentValuesListMap
                .get(Photo.CONTENT_ITEM_TYPE);
        if (contentValuesList != null) {
            for (ContentValues contentValues : contentValuesList) {
                byte[] data = contentValues.getAsByteArray(Photo.PHOTO);
                if (data == null) {
                    continue;
                }
                final String photoType;
                // Use some heuristics for guessing the format of the image.
                // TODO: there should be some general API for detecting the file format.
                if (data.length >= 3 && data[0] == 'G' && data[1] == 'I'
                        && data[2] == 'F') {
                    photoType = "GIF";
                } else if (data.length >= 4 && data[0] == (byte) 0x89
                        && data[1] == 'P' && data[2] == 'N' && data[3] == 'G') {
                    // Note: vCard 2.1 officially does not support PNG, but we
                    // may have it
                    // and using X- word like "X-PNG" may not let importers know
                    // it is
                    // PNG. So we use the String "PNG" as is...
                    photoType = "PNG";
                } else if (data.length >= 2 && data[0] == (byte) 0xff
                        && data[1] == (byte) 0xd8) {
                    photoType = "JPEG";
                } else {
                    Log.d(LOG_TAG, "Unknown photo type. Ignore.");
                    continue;
                }
                final String photoString = VCardUtils.encodeBase64(data);
                if (photoString.length() > 0) {
                    appendVCardPhotoLine(builder, photoString, photoType);
                }
            }
        }
    }

    private void appendNotes(final StringBuilder builder,
            final Map<String, List<ContentValues>> contentValuesListMap) {
        final List<ContentValues> contentValuesList =
            contentValuesListMap.get(Note.CONTENT_ITEM_TYPE);
        if (contentValuesList != null) {
            if (mOnlyOneNoteFieldIsAvailable) {
                StringBuilder noteBuilder = new StringBuilder();
                boolean first = true;
                for (ContentValues contentValues : contentValuesList) {
                    String note = contentValues.getAsString(Note.NOTE);
                    if (note == null) {
                        note = "";
                    }
                    if (note.length() > 0) {
                        if (first) {
                            first = false;
                        } else {
                            noteBuilder.append('\n');
                        }
                        noteBuilder.append(note);
                    }
                }
                final String noteStr = noteBuilder.toString();
                // This means we scan noteStr completely twice, which is redundant.
                // But for now, we assume this is not so time-consuming..
                final boolean shouldAppendCharsetInfo =
                    !VCardUtils.containsOnlyPrintableAscii(noteStr);
                final boolean reallyUseQuotedPrintable =
                        (mUsesQuotedPrintable &&
                            !VCardUtils.containsOnlyNonCrLfPrintableAscii(noteStr));
                appendVCardLine(builder, VCARD_PROPERTY_NOTE, noteStr,
                        shouldAppendCharsetInfo, reallyUseQuotedPrintable);
            } else {
                for (ContentValues contentValues : contentValuesList) {
                    final String noteStr = contentValues.getAsString(Note.NOTE);
                    if (!TextUtils.isEmpty(noteStr)) {
                        final boolean shouldAppendCharsetInfo =
                                !VCardUtils.containsOnlyPrintableAscii(noteStr);
                        final boolean reallyUseQuotedPrintable =
                                (mUsesQuotedPrintable &&
                                    !VCardUtils.containsOnlyNonCrLfPrintableAscii(noteStr));
                        appendVCardLine(builder, VCARD_PROPERTY_NOTE, noteStr,
                                shouldAppendCharsetInfo, reallyUseQuotedPrintable);
                    }
                }
            }
        }
    }

    /**
     * Append '\' to the characters which should be escaped. The character set is different
     * not only between vCard 2.1 and vCard 3.0 but also among each device.
     *
     * Note that Quoted-Printable string must not be input here.
     */
    @SuppressWarnings("fallthrough")
    private String escapeCharacters(final String unescaped) {
        if (TextUtils.isEmpty(unescaped)) {
            return "";
        }

        final StringBuilder tmpBuilder = new StringBuilder();
        final int length = unescaped.length();
        for (int i = 0; i < length; i++) {
            char ch = unescaped.charAt(i);
            switch (ch) {
                case ';': {
                    tmpBuilder.append('\\');
                    tmpBuilder.append(';');
                    break;
                }
                case '\r': {
                    if (i + 1 < length) {
                        char nextChar = unescaped.charAt(i);
                        if (nextChar == '\n') {
                            continue;
                        } else {
                            // fall through
                        }
                    } else {
                        // fall through
                    }
                }
                case '\n': {
                    // In vCard 2.1, there's no specification about this, while
                    // vCard 3.0 explicitly requires this should be encoded to "\n".
                    tmpBuilder.append("\\n");
                    break;
                }
                case '\\': {
                    if (mIsV30) {
                        tmpBuilder.append("\\\\");
                        break;
                    } else {
                        // fall through
                    }
                }
                case '<':
                case '>': {
                    if (mIsDoCoMo) {
                        tmpBuilder.append('\\');
                        tmpBuilder.append(ch);
                    } else {
                        tmpBuilder.append(ch);
                    }
                    break;
                }
                case ',': {
                    if (mIsV30) {
                        tmpBuilder.append("\\,");
                    } else {
                        tmpBuilder.append(ch);
                    }
                    break;
                }
                default: {
                    tmpBuilder.append(ch);
                    break;
                }
            }
        }
        return tmpBuilder.toString();
    }

    private void appendVCardPhotoLine(final StringBuilder builder,
            final String encodedData, final String photoType) {
        StringBuilder tmpBuilder = new StringBuilder();
        tmpBuilder.append(VCARD_PROPERTY_PHOTO);
        tmpBuilder.append(VCARD_ATTR_SEPARATOR);
        if (mIsV30) {
            tmpBuilder.append(VCARD_ATTR_ENCODING_BASE64_V30);
        } else {
            tmpBuilder.append(VCARD_ATTR_ENCODING_BASE64_V21);
        }
        tmpBuilder.append(VCARD_ATTR_SEPARATOR);
        appendTypeAttribute(tmpBuilder, photoType);
        tmpBuilder.append(VCARD_DATA_SEPARATOR);
        tmpBuilder.append(encodedData);

        final String tmpStr = tmpBuilder.toString();
        tmpBuilder = new StringBuilder();
        int lineCount = 0;
        int length = tmpStr.length();
        for (int i = 0; i < length; i++) {
            tmpBuilder.append(tmpStr.charAt(i));
            lineCount++;
            if (lineCount > 72) {
                tmpBuilder.append(VCARD_COL_SEPARATOR);
                tmpBuilder.append(VCARD_WS);
                lineCount = 0;
            }
        }
        builder.append(tmpBuilder.toString());
        builder.append(VCARD_COL_SEPARATOR);
        builder.append(VCARD_COL_SEPARATOR);
    }

    private void appendVCardPostalLine(final StringBuilder builder,
            final Integer typeAsObject, final String label,
            final ContentValues contentValues) {
        builder.append(VCARD_PROPERTY_ADR);
        builder.append(VCARD_ATTR_SEPARATOR);

        // Note: Not sure why we need to emit "empty" line even when actual data does not exist.
        // There may be some reason or may not be any. We keep safer side.
        // TODO: investigate this.
        boolean dataExists = false;
        String[] dataArray = VCardUtils.getVCardPostalElements(contentValues);
        boolean actuallyUseQuotedPrintable = false;
        boolean shouldAppendCharset = false;
        for (String data : dataArray) {
            if (!TextUtils.isEmpty(data)) {
                dataExists = true;
                if (!shouldAppendCharset && !VCardUtils.containsOnlyPrintableAscii(data)) {
                    shouldAppendCharset = true;
                }
                if (mUsesQuotedPrintable && !VCardUtils.containsOnlyNonCrLfPrintableAscii(data)) {
                    actuallyUseQuotedPrintable = true;
                    break;
                }
            }
        }

        int length = dataArray.length;
        for (int i = 0; i < length; i++) {
            String data = dataArray[i];
            if (!TextUtils.isEmpty(data)) {
                if (actuallyUseQuotedPrintable) {
                    dataArray[i] = encodeQuotedPrintable(data);
                } else {
                    dataArray[i] = escapeCharacters(data);
                }
            }
        }

        final int typeAsPrimitive;
        if (typeAsObject == null) {
            typeAsPrimitive = StructuredPostal.TYPE_OTHER;
        } else {
            typeAsPrimitive = typeAsObject;
        }

        String typeAsString = null;
        switch (typeAsPrimitive) {
            case StructuredPostal.TYPE_HOME: {
                typeAsString = Constants.ATTR_TYPE_HOME;
                break;
            }
            case StructuredPostal.TYPE_WORK: {
                typeAsString = Constants.ATTR_TYPE_WORK;
                break;
            }
            case StructuredPostal.TYPE_CUSTOM: {
                if (mUsesAndroidProperty && !TextUtils.isEmpty(label)
                        && VCardUtils.containsOnlyAlphaDigitHyphen(label)) {
                    // We're not sure whether the label is valid in the spec
                    // ("IANA-token" in the vCard 3.0 is unclear...)
                    // Just  for safety, we add "X-" at the beggining of each label.
                    // Also checks the label obeys with vCard 3.0 spec.
                    builder.append("X-");
                    builder.append(label);
                    builder.append(VCARD_DATA_SEPARATOR);
                }
                break;
            }
            case StructuredPostal.TYPE_OTHER: {
                break;
            }
            default: {
                Log.e(LOG_TAG, "Unknown StructuredPostal type: " + typeAsPrimitive);
                break;
            }
        }

        // Attribute(s).

        {
            boolean shouldAppendAttrSeparator = false;
            if (typeAsString != null) {
                appendTypeAttribute(builder, typeAsString);
                shouldAppendAttrSeparator = true;
            }

            if (dataExists) {
                if (shouldAppendCharset) {
                    // Strictly, vCard 3.0 does not allow exporters to emit charset information,
                    // but we will add it since the information should be useful for importers,
                    //
                    // Assume no parser does not emit error with this attribute in vCard 3.0.
                    if (shouldAppendAttrSeparator) {
                        builder.append(VCARD_ATTR_SEPARATOR);
                    }
                    builder.append(mVCardAttributeCharset);
                    shouldAppendAttrSeparator = true;
                }

                if (actuallyUseQuotedPrintable) {
                    if (shouldAppendAttrSeparator) {
                        builder.append(VCARD_ATTR_SEPARATOR);
                    }
                    builder.append(VCARD_ATTR_ENCODING_QP);
                    shouldAppendAttrSeparator = true;
                }
            }
        }

        // Property values.

        builder.append(VCARD_DATA_SEPARATOR);
        if (dataExists) {
            // The elements in dataArray are already encoded to quoted printable
            // if needed.
            // See above.
            //
            // TODO: in vCard 3.0, one line may become too huge. Fix this.
            builder.append(dataArray[0]);
            builder.append(VCARD_ITEM_SEPARATOR);
            builder.append(dataArray[1]);
            builder.append(VCARD_ITEM_SEPARATOR);
            builder.append(dataArray[2]);
            builder.append(VCARD_ITEM_SEPARATOR);
            builder.append(dataArray[3]);
            builder.append(VCARD_ITEM_SEPARATOR);
            builder.append(dataArray[4]);
            builder.append(VCARD_ITEM_SEPARATOR);
            builder.append(dataArray[5]);
            builder.append(VCARD_ITEM_SEPARATOR);
            builder.append(dataArray[6]);
        }
        builder.append(VCARD_COL_SEPARATOR);
    }

    private void appendVCardEmailLine(final StringBuilder builder,
            final Integer typeAsObject, final String label, final String data) {
        builder.append(VCARD_PROPERTY_EMAIL);

        final int typeAsPrimitive;
        if (typeAsObject == null) {
            typeAsPrimitive = Email.TYPE_OTHER;
        } else {
            typeAsPrimitive = typeAsObject;
        }

        final String typeAsString;
        switch (typeAsPrimitive) {
            case Email.TYPE_CUSTOM: {
                // For backward compatibility.
                // Detail: Until Donut, there isn't TYPE_MOBILE for email while there is now.
                //         To support mobile type at that time, this custom label had been used.
                if (android.provider.Contacts.ContactMethodsColumns.MOBILE_EMAIL_TYPE_NAME
                        .equals(label)) {
                    typeAsString = Constants.ATTR_TYPE_CELL;
                } else if (mUsesAndroidProperty && !TextUtils.isEmpty(label)
                        && VCardUtils.containsOnlyAlphaDigitHyphen(label)) {
                    typeAsString = "X-" + label;
                } else {
                    typeAsString = DEFAULT_EMAIL_TYPE;
                }
                break;
            }
            case Email.TYPE_HOME: {
                typeAsString = Constants.ATTR_TYPE_HOME;
                break;
            }
            case Email.TYPE_WORK: {
                typeAsString = Constants.ATTR_TYPE_WORK;
                break;
            }
            case Email.TYPE_OTHER: {
                typeAsString = DEFAULT_EMAIL_TYPE;
                break;
            }
            case Email.TYPE_MOBILE: {
                typeAsString = Constants.ATTR_TYPE_CELL;
                break;
            }
            default: {
                Log.e(LOG_TAG, "Unknown Email type: " + typeAsPrimitive);
                typeAsString = DEFAULT_EMAIL_TYPE;
                break;
            }
        }

        builder.append(VCARD_ATTR_SEPARATOR);
        appendTypeAttribute(builder, typeAsString);
        builder.append(VCARD_DATA_SEPARATOR);
        builder.append(data);
        builder.append(VCARD_COL_SEPARATOR);
    }

    private void appendVCardTelephoneLine(final StringBuilder builder,
            final Integer typeAsObject, final String label,
            String encodedData) {
        builder.append(VCARD_PROPERTY_TEL);
        builder.append(VCARD_ATTR_SEPARATOR);

        final int typeAsPrimitive;
        if (typeAsObject == null) {
            typeAsPrimitive = Phone.TYPE_OTHER;
        } else {
            typeAsPrimitive = typeAsObject;
        }

        switch (typeAsPrimitive) {
        case Phone.TYPE_HOME:
            appendTypeAttributes(builder, Arrays.asList(
                    Constants.ATTR_TYPE_HOME, Constants.ATTR_TYPE_VOICE));
            break;
        case Phone.TYPE_WORK:
            appendTypeAttributes(builder, Arrays.asList(
                    Constants.ATTR_TYPE_WORK, Constants.ATTR_TYPE_VOICE));
            break;
        case Phone.TYPE_FAX_HOME:
            appendTypeAttributes(builder, Arrays.asList(
                    Constants.ATTR_TYPE_HOME, Constants.ATTR_TYPE_FAX));
            break;
        case Phone.TYPE_FAX_WORK:
            appendTypeAttributes(builder, Arrays.asList(
                    Constants.ATTR_TYPE_WORK, Constants.ATTR_TYPE_FAX));
            break;
        case Phone.TYPE_MOBILE:
            builder.append(Constants.ATTR_TYPE_CELL);
            break;
        case Phone.TYPE_PAGER:
            if (mIsDoCoMo) {
                // Not sure about the reason, but previous implementation had
                // used "VOICE" instead of "PAGER"
                // Also, refrain from using appendType() so that "TYPE=" is never be appended.
                builder.append(Constants.ATTR_TYPE_VOICE);
            } else {
                appendTypeAttribute(builder, Constants.ATTR_TYPE_PAGER);
            }
            break;
        case Phone.TYPE_OTHER:
            appendTypeAttribute(builder, Constants.ATTR_TYPE_VOICE);
            break;
        case Phone.TYPE_CUSTOM:
            if (mUsesAndroidProperty && !TextUtils.isEmpty(label)
                        && VCardUtils.containsOnlyAlphaDigitHyphen(label)) {
                appendTypeAttribute(builder, "X-" + label);
            } else {
                // Just ignore the custom type.
                appendTypeAttribute(builder, Constants.ATTR_TYPE_VOICE);
            }
            break;
        default:
            appendUncommonPhoneType(builder, typeAsPrimitive);
            break;
        }

        builder.append(VCARD_DATA_SEPARATOR);
        builder.append(encodedData);
        builder.append(VCARD_COL_SEPARATOR);
    }

    /**
     * Appends phone type string which may not be available in some devices.
     */
    private void appendUncommonPhoneType(final StringBuilder builder, final Integer type) {
        if (mIsDoCoMo) {
            // The previous implementation for DoCoMo had been conservative
            // about miscellaneous types.
            builder.append(Constants.ATTR_TYPE_VOICE);
        } else {
            String phoneAttribute = VCardUtils.getPhoneAttributeString(type);
            if (phoneAttribute != null) {
                appendTypeAttribute(builder, phoneAttribute);
            } else {
                Log.e(LOG_TAG, "Unknown or unsupported (by vCard) Phone type: " + type);
            }
        }
    }

    private void appendVCardLine(final StringBuilder builder,
            final String propertyName, final String rawData) {
        appendVCardLine(builder, propertyName, rawData, false, false);
    }

    private void appendVCardLine(final StringBuilder builder,
            final String field, final String rawData, final boolean needCharset,
            boolean needQuotedPrintable) {
        builder.append(field);
        if (needCharset) {
            builder.append(VCARD_ATTR_SEPARATOR);
            builder.append(mVCardAttributeCharset);
        }

        final String encodedData;
        if (needQuotedPrintable) {
            builder.append(VCARD_ATTR_SEPARATOR);
            builder.append(VCARD_ATTR_ENCODING_QP);
            encodedData = encodeQuotedPrintable(rawData);
        } else {
            // TODO: one line may be too huge, which may be invalid in vCard spec, though
            //       several (even well-known) applications do not care this.
            encodedData = escapeCharacters(rawData);
        }

        builder.append(VCARD_DATA_SEPARATOR);
        builder.append(encodedData);
        builder.append(VCARD_COL_SEPARATOR);
    }

    private void appendTypeAttributes(final StringBuilder builder,
            final List<String> types) {
        // We may have to make this comma separated form like "TYPE=DOM,WORK" in the future,
        // which would be recommended way in vcard 3.0 though not valid in vCard 2.1.
        boolean first = true;
        for (String type : types) {
            if (first) {
                first = false;
            } else {
                builder.append(VCARD_ATTR_SEPARATOR);
            }
            appendTypeAttribute(builder, type);
        }
    }

    private void appendTypeAttribute(final StringBuilder builder, final String type) {
        // Note: In vCard 3.0, Type strings also can be like this: "TYPE=HOME,PREF"
        if (mIsV30) {
            builder.append(Constants.ATTR_TYPE).append(VCARD_ATTR_EQUAL);
        }
        builder.append(type);
    }

    /**
     * Returns true when the property line should contain charset attribute
     * information. This method may return true even when vCard version is 3.0.
     *
     * Strictly, adding charset information is invalid in VCard 3.0.
     * However we'll add the info only when used charset is not UTF-8
     * in vCard 3.0 format, since parser side may be able to use the charset
     * via this field, though we may encounter another problem by adding it...
     *
     * e.g. Japanese mobile phones use Shift_Jis while RFC 2426
     * recommends UTF-8. By adding this field, parsers may be able
     * to know this text is NOT UTF-8 but Shift_Jis.
     */
    private boolean shouldAppendCharsetAttribute(final String propertyValue) {
        return (!VCardUtils.containsOnlyPrintableAscii(propertyValue) &&
                        (!mIsV30 || !mUsesUtf8));
    }

    private boolean shouldAppendCharsetAttribute(final List<String> propertyValueList) {
        boolean shouldAppendBasically = false;
        for (String propertyValue : propertyValueList) {
            if (!VCardUtils.containsOnlyPrintableAscii(propertyValue)) {
                shouldAppendBasically = true;
                break;
            }
        }
        return shouldAppendBasically && (!mIsV30 || !mUsesUtf8);
    }

    private String encodeQuotedPrintable(String str) {
        if (TextUtils.isEmpty(str)) {
            return "";
        }
        {
            // Replace "\n" and "\r" with "\r\n".
            StringBuilder tmpBuilder = new StringBuilder();
            int length = str.length();
            for (int i = 0; i < length; i++) {
                char ch = str.charAt(i);
                if (ch == '\r') {
                    if (i + 1 < length && str.charAt(i + 1) == '\n') {
                        i++;
                    }
                    tmpBuilder.append("\r\n");
                } else if (ch == '\n') {
                    tmpBuilder.append("\r\n");
                } else {
                    tmpBuilder.append(ch);
                }
            }
            str = tmpBuilder.toString();
        }

        final StringBuilder tmpBuilder = new StringBuilder();
        int index = 0;
        int lineCount = 0;
        byte[] strArray = null;

        try {
            strArray = str.getBytes(mCharsetString);
        } catch (UnsupportedEncodingException e) {
            Log.e(LOG_TAG, "Charset " + mCharsetString + " cannot be used. "
                    + "Try default charset");
            strArray = str.getBytes();
        }
        while (index < strArray.length) {
            tmpBuilder.append(String.format("=%02X", strArray[index]));
            index += 1;
            lineCount += 3;

            if (lineCount >= 67) {
                // Specification requires CRLF must be inserted before the
                // length of the line
                // becomes more than 76.
                // Assuming that the next character is a multi-byte character,
                // it will become
                // 6 bytes.
                // 76 - 6 - 3 = 67
                tmpBuilder.append("=\r\n");
                lineCount = 0;
            }
        }

        return tmpBuilder.toString();
    }
}
