VCardEntry.java revision 103d53645c0b8ef532e8715da6c6cd33ad5f98e2
18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/*
28e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 2009 The Android Open Source Project
38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * you may not use this file except in compliance with the License.
6635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * You may obtain a copy of the License at
7643ca7872b450ea4efacab6188849e5aac2ba161Steve Block *
88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * See the License for the specific language governing permissions and
148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * limitations under the License.
158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */
168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectpackage android.pim.vcard;
178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectimport android.accounts.Account;
198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectimport android.content.ContentProviderOperation;
208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectimport android.content.ContentResolver;
218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectimport android.content.OperationApplicationException;
228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectimport android.database.Cursor;
238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectimport android.net.Uri;
248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectimport android.os.RemoteException;
258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectimport android.provider.ContactsContract;
268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectimport android.provider.ContactsContract.Contacts;
278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectimport android.provider.ContactsContract.Data;
288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectimport android.provider.ContactsContract.Groups;
298a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Blockimport android.provider.ContactsContract.RawContacts;
308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectimport android.provider.ContactsContract.CommonDataKinds.Email;
318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectimport android.provider.ContactsContract.CommonDataKinds.Event;
325f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianimport android.provider.ContactsContract.CommonDataKinds.GroupMembership;
335f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianimport android.provider.ContactsContract.CommonDataKinds.Im;
348f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianimport android.provider.ContactsContract.CommonDataKinds.Nickname;
358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectimport android.provider.ContactsContract.CommonDataKinds.Note;
368f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianimport android.provider.ContactsContract.CommonDataKinds.Organization;
378f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianimport android.provider.ContactsContract.CommonDataKinds.Phone;
388f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianimport android.provider.ContactsContract.CommonDataKinds.Photo;
398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectimport android.provider.ContactsContract.CommonDataKinds.StructuredName;
408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectimport android.provider.ContactsContract.CommonDataKinds.StructuredPostal;
418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectimport android.provider.ContactsContract.CommonDataKinds.Website;
428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectimport android.telephony.PhoneNumberUtils;
438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectimport android.text.TextUtils;
448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectimport android.util.Log;
458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
465f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianimport java.util.ArrayList;
478f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianimport java.util.Arrays;
488f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianimport java.util.Collection;
498f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianimport java.util.Collections;
508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectimport java.util.HashMap;
518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectimport java.util.HashSet;
528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectimport java.util.List;
530bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochimport java.util.Map;
548f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
55635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project/**
56d0825bca7fe65beaee391d30da42e937db621564Steve Block * This class bridges between data structure of Contact app and VCard data.
57d0825bca7fe65beaee391d30da42e937db621564Steve Block */
58d0825bca7fe65beaee391d30da42e937db621564Steve Blockpublic class VCardEntry {
598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    private static final String LOG_TAG = "VCardEntry";
608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    private final static int DEFAULT_ORGANIZATION_TYPE = Organization.TYPE_WORK;
628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    private static final String ACCOUNT_TYPE_GOOGLE = "com.google";
648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    private static final String GOOGLE_MY_CONTACTS_GROUP = "System Group: My Contacts";
658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    private static final Map<String, Integer> sImMap = new HashMap<String, Integer>();
678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    static {
698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        sImMap.put(VCardConstants.PROPERTY_X_AIM, Im.PROTOCOL_AIM);
708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        sImMap.put(VCardConstants.PROPERTY_X_MSN, Im.PROTOCOL_MSN);
718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        sImMap.put(VCardConstants.PROPERTY_X_YAHOO, Im.PROTOCOL_YAHOO);
728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        sImMap.put(VCardConstants.PROPERTY_X_ICQ, Im.PROTOCOL_ICQ);
738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        sImMap.put(VCardConstants.PROPERTY_X_JABBER, Im.PROTOCOL_JABBER);
748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        sImMap.put(VCardConstants.PROPERTY_X_SKYPE_USERNAME, Im.PROTOCOL_SKYPE);
758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        sImMap.put(VCardConstants.PROPERTY_X_GOOGLE_TALK, Im.PROTOCOL_GOOGLE_TALK);
768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        sImMap.put(VCardConstants.ImportOnly.PROPERTY_X_GOOGLE_TALK_WITH_SPACE,
778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                Im.PROTOCOL_GOOGLE_TALK);
788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    static public class PhoneData {
818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        public final int type;
828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        public final String data;
838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        public final String label;
84643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        // isPrimary is changable only when there's no appropriate one existing in
85643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        // the original VCard.
86643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        public boolean isPrimary;
87643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        public PhoneData(int type, String data, String label, boolean isPrimary) {
88643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            this.type = type;
898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            this.data = data;
90643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            this.label = label;
918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            this.isPrimary = isPrimary;
928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        @Override
958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        public boolean equals(Object obj) {
968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (!(obj instanceof PhoneData)) {
978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                return false;
988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            PhoneData phoneData = (PhoneData)obj;
1008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return (type == phoneData.type && data.equals(phoneData.data) &&
1018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    label.equals(phoneData.label) && isPrimary == phoneData.isPrimary);
1028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
1038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        @Override
1058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        public String toString() {
1068f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            return String.format("type: %d, data: %s, label: %s, isPrimary: %s",
1078f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                    type, data, label, isPrimary);
1088f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        }
1098f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
1108f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
1118f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    static public class EmailData {
1128f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        public final int type;
1138f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        public final String data;
1148f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        // Used only when TYPE is TYPE_CUSTOM.
1158f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        public final String label;
1168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // isPrimary is changable only when there's no appropriate one existing in
1178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // the original VCard.
1188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        public boolean isPrimary;
1198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        public EmailData(int type, String data, String label, boolean isPrimary) {
1208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            this.type = type;
1218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            this.data = data;
1228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            this.label = label;
1238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            this.isPrimary = isPrimary;
1248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
1258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        @Override
1278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        public boolean equals(Object obj) {
1288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (!(obj instanceof EmailData)) {
1298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                return false;
1308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
1318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            EmailData emailData = (EmailData)obj;
1328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return (type == emailData.type && data.equals(emailData.data) &&
1338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    label.equals(emailData.label) && isPrimary == emailData.isPrimary);
1348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
1358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        @Override
1378f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        public String toString() {
1388f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            return String.format("type: %d, data: %s, label: %s, isPrimary: %s",
1398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    type, data, label, isPrimary);
1408f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        }
141635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    }
1428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    static public class PostalData {
1448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Determined by vCard spec.
1458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // PO Box, Extended Addr, Street, Locality, Region, Postal Code, Country Name
1468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        public static final int ADDR_MAX_DATA_SIZE = 7;
1478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        private final String[] dataArray;
1480bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        public final String pobox;
1490bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        public final String extendedAddress;
1508f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        public final String street;
1518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        public final String localty;
1528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        public final String region;
1538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        public final String postalCode;
1548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        public final String country;
1558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        public final int type;
1568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        public final String label;
1578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        public boolean isPrimary;
1588f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
1598f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        public PostalData(final int type, final List<String> propValueList,
1608f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                final String label, boolean isPrimary) {
1618f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            this.type = type;
1628f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            dataArray = new String[ADDR_MAX_DATA_SIZE];
1638f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
1648f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            int size = propValueList.size();
1658f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            if (size > ADDR_MAX_DATA_SIZE) {
1668f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                size = ADDR_MAX_DATA_SIZE;
1678f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            }
1688f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
1698f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            // adr-value = 0*6(text-value ";") text-value
1708f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            //           ; PO Box, Extended Address, Street, Locality, Region, Postal
1718f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            //           ; Code, Country Name
1728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            //
1738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // Use Iterator assuming List may be LinkedList, though actually it is
1748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // always ArrayList in the current implementation.
1758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            int i = 0;
1768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            for (String addressElement : propValueList) {
1778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                dataArray[i] = addressElement;
1788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (++i >= size) {
1798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    break;
1808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
1818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
1828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            while (i < ADDR_MAX_DATA_SIZE) {
1838f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                dataArray[i++] = null;
184635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            }
185635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
1868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            this.pobox = dataArray[0];
1878f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            this.extendedAddress = dataArray[1];
1888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            this.street = dataArray[2];
1898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            this.localty = dataArray[3];
1908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            this.region = dataArray[4];
1918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            this.postalCode = dataArray[5];
1928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            this.country = dataArray[6];
193635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            this.label = label;
194635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            this.isPrimary = isPrimary;
195e3a33d1e0c60357ad9f36df6e16799ddb5942917Steve Block        }
196e3a33d1e0c60357ad9f36df6e16799ddb5942917Steve Block
1978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        @Override
1988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        public boolean equals(Object obj) {
1998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (!(obj instanceof PostalData)) {
2008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                return false;
2018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
202635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            final PostalData postalData = (PostalData)obj;
203635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            return (Arrays.equals(dataArray, postalData.dataArray) &&
2048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    (type == postalData.type &&
2058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            (type == StructuredPostal.TYPE_CUSTOM ?
2068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                    (label == postalData.label) : true)) &&
2078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    (isPrimary == postalData.isPrimary));
2088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
2098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        public String getFormattedAddress(final int vcardType) {
2118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            StringBuilder builder = new StringBuilder();
2128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            boolean empty = true;
2138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (VCardConfig.isJapaneseDevice(vcardType)) {
2148f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                // In Japan, the order is reversed.
2158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                for (int i = ADDR_MAX_DATA_SIZE - 1; i >= 0; i--) {
2168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    String addressPart = dataArray[i];
2178f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                    if (!TextUtils.isEmpty(addressPart)) {
2188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        if (!empty) {
2198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            builder.append(' ');
2208f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                        } else {
2218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            empty = false;
2228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        }
2238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        builder.append(addressPart);
2248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    }
2258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
2268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            } else {
2278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                for (int i = 0; i < ADDR_MAX_DATA_SIZE; i++) {
2288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    String addressPart = dataArray[i];
2298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    if (!TextUtils.isEmpty(addressPart)) {
2308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        if (!empty) {
2318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            builder.append(' ');
2328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        } else {
2338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            empty = false;
2348f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                        }
2358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        builder.append(addressPart);
2368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    }
2378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
2388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
239643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
240643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            return builder.toString().trim();
241643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        }
242643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
243643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        @Override
244643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        public String toString() {
2458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return String.format("type: %d, label: %s, isPrimary: %s",
2468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    type, label, isPrimary);
2478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
2488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
2498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    static public class OrganizationData {
2518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        public final int type;
2528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // non-final is Intentional: we may change the values since this info is separated into
2538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // two parts in vCard: "ORG" + "TITLE".
2548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        public String companyName;
2558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        public String departmentName;
2568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        public String titleName;
2578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        public boolean isPrimary;
2588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        public OrganizationData(int type,
2608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                String companyName,
2618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                String departmentName,
2628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                String titleName,
2638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                boolean isPrimary) {
2648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            this.type = type;
2658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            this.companyName = companyName;
2668f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            this.departmentName = departmentName;
2678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            this.titleName = titleName;
268d0825bca7fe65beaee391d30da42e937db621564Steve Block            this.isPrimary = isPrimary;
2698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
270643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
2718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        @Override
2728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        public boolean equals(Object obj) {
2738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (!(obj instanceof OrganizationData)) {
2748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                return false;
2758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
2768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            OrganizationData organization = (OrganizationData)obj;
2778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return (type == organization.type &&
2788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    TextUtils.equals(companyName, organization.companyName) &&
2798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    TextUtils.equals(departmentName, organization.departmentName) &&
2808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    TextUtils.equals(titleName, organization.titleName) &&
2818f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                    isPrimary == organization.isPrimary);
2828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
2838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        public String getFormattedString() {
2858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            final StringBuilder builder = new StringBuilder();
286d0825bca7fe65beaee391d30da42e937db621564Steve Block            if (!TextUtils.isEmpty(companyName)) {
2878a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block                builder.append(companyName);
288643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            }
289643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
290643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            if (!TextUtils.isEmpty(departmentName)) {
291643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                if (builder.length() > 0) {
2928a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block                    builder.append(", ");
2938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
2948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                builder.append(departmentName);
2958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
2968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (!TextUtils.isEmpty(titleName)) {
2988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (builder.length() > 0) {
2998f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                    builder.append(", ");
3008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
3018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                builder.append(titleName);
3020bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            }
3038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
304231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            return builder.toString();
3058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
3068f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
3078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        @Override
3088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        public String toString() {
3098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return String.format(
3108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    "type: %d, company: %s, department: %s, title: %s, isPrimary: %s",
3118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    type, companyName, departmentName, titleName, isPrimary);
312231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        }
313231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    }
314231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
3158f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    static public class ImData {
3168f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        public final int protocol;
3178f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        public final String customProtocol;
3188f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        public final int type;
3198f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        public final String data;
3208f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        public final boolean isPrimary;
3218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
322d0825bca7fe65beaee391d30da42e937db621564Steve Block        public ImData(final int protocol, final String customProtocol, final int type,
323d0825bca7fe65beaee391d30da42e937db621564Steve Block                final String data, final boolean isPrimary) {
324d0825bca7fe65beaee391d30da42e937db621564Steve Block            this.protocol = protocol;
325d0825bca7fe65beaee391d30da42e937db621564Steve Block            this.customProtocol = customProtocol;
3268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            this.type = type;
3275f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            this.data = data;
3285f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            this.isPrimary = isPrimary;
3298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
3308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        @Override
3328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        public boolean equals(Object obj) {
3338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (!(obj instanceof ImData)) {
3345f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                return false;
335231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            }
3365f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            ImData imData = (ImData)obj;
337d0825bca7fe65beaee391d30da42e937db621564Steve Block            return (type == imData.type && protocol == imData.protocol
338d0825bca7fe65beaee391d30da42e937db621564Steve Block                    && (customProtocol != null ? customProtocol.equals(imData.customProtocol) :
3395f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                        (imData.customProtocol == null))
3405f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                    && (data != null ? data.equals(imData.data) : (imData.data == null))
3415f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                    && isPrimary == imData.isPrimary);
3425f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        }
3435f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
3445f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        @Override
3455f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        public String toString() {
3465f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            return String.format(
3475f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                    "type: %d, protocol: %d, custom_protcol: %s, data: %s, isPrimary: %s",
3485f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                    type, protocol, customProtocol, data, isPrimary);
3495f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        }
3505f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
3515f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
3525f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    public static class PhotoData {
3535f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        public static final String FORMAT_FLASH = "SWF";
3548a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block        public final int type;
3558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        public final String formatName;  // used when type is not defined in ContactsContract.
3565f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        public final byte[] photoBytes;
3575f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        public final boolean isPrimary;
3588a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block
3595f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        public PhotoData(int type, String formatName, byte[] photoBytes, boolean isPrimary) {
3605f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            this.type = type;
3615f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            this.formatName = formatName;
3625f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            this.photoBytes = photoBytes;
3635f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            this.isPrimary = isPrimary;
3648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
3658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        @Override
3678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        public boolean equals(Object obj) {
3688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (!(obj instanceof PhotoData)) {
3698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                return false;
3708f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            }
3718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            PhotoData photoData = (PhotoData)obj;
3728f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            return (type == photoData.type &&
3738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    (formatName == null ? (photoData.formatName == null) :
3748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            formatName.equals(photoData.formatName)) &&
3758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    (Arrays.equals(photoBytes, photoData.photoBytes)) &&
3768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    (isPrimary == photoData.isPrimary));
377635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        }
3788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        @Override
3808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        public String toString() {
3818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return String.format("type: %d, format: %s: size: %d, isPrimary: %s",
3828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    type, formatName, photoBytes.length, isPrimary);
3838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
3848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
3858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    /* package */ static class Property {
3878f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        private String mPropertyName;
3888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        private Map<String, Collection<String>> mParameterMap =
3898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            new HashMap<String, Collection<String>>();
3908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        private List<String> mPropertyValueList = new ArrayList<String>();
3918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        private byte[] mPropertyBytes;
3928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        public void setPropertyName(final String propertyName) {
3948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            mPropertyName = propertyName;
3958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
3968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        public void addParameter(final String paramName, final String paramValue) {
3988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            Collection<String> values;
3998f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            if (!mParameterMap.containsKey(paramName)) {
4008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (paramName.equals("TYPE")) {
4018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    values = new HashSet<String>();
4028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                } else {
4038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    values = new ArrayList<String>();
4048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
4058f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                mParameterMap.put(paramName, values);
4068f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            } else {
4078f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                values = mParameterMap.get(paramName);
4088f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            }
4098f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            values.add(paramValue);
4108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
4118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        public void addToPropertyValueList(final String propertyValue) {
4138f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            mPropertyValueList.add(propertyValue);
4140bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
4158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4168f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        public void setPropertyBytes(final byte[] propertyBytes) {
4178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            mPropertyBytes = propertyBytes;
4188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
4198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4208f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        public final Collection<String> getParameters(String type) {
4218f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            return mParameterMap.get(type);
4228f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        }
4238f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
4248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        public final List<String> getPropertyValueList() {
4258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return mPropertyValueList;
4268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
4278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        public void clear() {
4298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            mPropertyName = null;
430231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            mParameterMap.clear();
431231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            mPropertyValueList.clear();
432231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            mPropertyBytes = null;
433231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        }
434231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    }
4358f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
4368f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    private String mFamilyName;
4378f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    private String mGivenName;
4388f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    private String mMiddleName;
4398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    private String mPrefix;
4408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    private String mSuffix;
4418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Used only when no family nor given name is found.
4438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    private String mFullName;
4448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    private String mPhoneticFamilyName;
4468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    private String mPhoneticGivenName;
4478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    private String mPhoneticMiddleName;
4488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    private String mPhoneticFullName;
4508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    private List<String> mNickNameList;
4528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    private String mDisplayName;
4548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    private String mBirthday;
4568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    private List<String> mNoteList;
458635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    private List<PhoneData> mPhoneList;
459635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    private List<EmailData> mEmailList;
4608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    private List<PostalData> mPostalList;
4618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    private List<OrganizationData> mOrganizationList;
4628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    private List<ImData> mImList;
4638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    private List<PhotoData> mPhotoList;
4648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    private List<String> mWebsiteList;
4658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    private List<List<String>> mAndroidCustomPropertyList;
4668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    private final int mVCardType;
4688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    private final Account mAccount;
4698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    public VCardEntry() {
4718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        this(VCardConfig.VCARD_TYPE_V21_GENERIC_UTF8);
4728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
4738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    public VCardEntry(int vcardType) {
4758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        this(vcardType, null);
4768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
4775f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
4785f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    public VCardEntry(int vcardType, Account account) {
4798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        mVCardType = vcardType;
4808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        mAccount = account;
4818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
4828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    private void addPhone(int type, String data, String label, boolean isPrimary) {
4848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (mPhoneList == null) {
4855f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            mPhoneList = new ArrayList<PhoneData>();
4865f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        }
4878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        final StringBuilder builder = new StringBuilder();
4888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        final String trimed = data.trim();
4898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        final String formattedNumber;
4908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (type == Phone.TYPE_PAGER) {
4918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            formattedNumber = trimed;
4928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        } else {
4935f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            final int length = trimed.length();
4948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            for (int i = 0; i < length; i++) {
4958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                char ch = trimed.charAt(i);
4968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (('0' <= ch && ch <= '9') || (i == 0 && ch == '+')) {
4978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    builder.append(ch);
4988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
4998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
5008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // Use NANP in default when there's no information about locale.
5028f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            final int formattingType = (VCardConfig.isJapaneseDevice(mVCardType) ?
5035f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                    PhoneNumberUtils.FORMAT_JAPAN : PhoneNumberUtils.FORMAT_NANP);
5048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            formattedNumber = PhoneNumberUtils.formatNumber(builder.toString(), formattingType);
5058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
5068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        PhoneData phoneData = new PhoneData(type, formattedNumber, label, isPrimary);
5078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        mPhoneList.add(phoneData);
5088f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
5098f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
5108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    private void addNickName(final String nickName) {
5118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (mNickNameList == null) {
5128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            mNickNameList = new ArrayList<String>();
5138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
5148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        mNickNameList.add(nickName);
5158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
5168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    private void addEmail(int type, String data, String label, boolean isPrimary){
5188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (mEmailList == null) {
5198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            mEmailList = new ArrayList<EmailData>();
5208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
5218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        mEmailList.add(new EmailData(type, data, label, isPrimary));
5228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
5238f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
5248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    private void addPostal(int type, List<String> propValueList, String label, boolean isPrimary){
5258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (mPostalList == null) {
5268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            mPostalList = new ArrayList<PostalData>(0);
5278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
5288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        mPostalList.add(new PostalData(type, propValueList, label, isPrimary));
5298f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
5308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5318f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    /**
5328f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian     * Should be called via {@link #handleOrgValue(int, List, boolean)} or
5338f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian     * {@link #handleTitleValue(String)}.
5348f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian     */
5358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    private void addNewOrganization(int type, final String companyName,
5368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            final String departmentName,
5378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            final String titleName, boolean isPrimary) {
5388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (mOrganizationList == null) {
5398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            mOrganizationList = new ArrayList<OrganizationData>();
5408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
5418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        mOrganizationList.add(new OrganizationData(type, companyName,
5428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                departmentName, titleName, isPrimary));
5438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
5448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    private static final List<String> sEmptyList =
5468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            Collections.unmodifiableList(new ArrayList<String>(0));
5478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    /**
5498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     * Set "ORG" related values to the appropriate data. If there's more than one
5508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     * {@link OrganizationData} objects, this input data are attached to the last one which
5518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     * does not have valid values (not including empty but only null). If there's no
5528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     * {@link OrganizationData} object, a new {@link OrganizationData} is created,
553635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project     * whose title is set to null.
554635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project     */
5558f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    private void handleOrgValue(final int type, List<String> orgList, boolean isPrimary) {
5568f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (orgList == null) {
5578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            orgList = sEmptyList;
558635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        }
559635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        final String companyName;
5608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        final String departmentName;
561635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        final int size = orgList.size();
5628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        switch (size) {
563635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            case 0: {
5648f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                companyName = "";
5658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                departmentName = null;
566635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                break;
567635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            }
568231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            case 1: {
569231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                companyName = orgList.get(0);
570635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                departmentName = null;
5715f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                break;
572635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            }
573635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            default: {  // More than 1.
5748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                companyName = orgList.get(0);
575635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                // We're not sure which is the correct string for department.
5765f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                // In order to keep all the data, concatinate the rest of elements.
5778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                StringBuilder builder = new StringBuilder();
578d0825bca7fe65beaee391d30da42e937db621564Steve Block                for (int i = 1; i < size; i++) {
579d0825bca7fe65beaee391d30da42e937db621564Steve Block                    if (i > 1) {
5808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        builder.append(' ');
5818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    }
5828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    builder.append(orgList.get(i));
5838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
5848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                departmentName = builder.toString();
5858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
5868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
5878f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (mOrganizationList == null) {
5888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // Create new first organization entry, with "null" title which may be
5890bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            // added via handleTitleValue().
5900bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            addNewOrganization(type, companyName, departmentName, null, isPrimary);
5910bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            return;
5920bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
5930bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        for (OrganizationData organizationData : mOrganizationList) {
5948f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            // Not use TextUtils.isEmpty() since ORG was set but the elements might be empty.
5958f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            // e.g. "ORG;PREF:;" -> Both companyName and departmentName become empty but not null.
5968f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            if (organizationData.companyName == null &&
5978f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                    organizationData.departmentName == null) {
5988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // Probably the "TITLE" property comes before the "ORG" property via
5998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // handleTitleLine().
6008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                organizationData.companyName = companyName;
601635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                organizationData.departmentName = departmentName;
602635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                organizationData.isPrimary = isPrimary;
603635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                return;
6048f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            }
6058f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        }
6068f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        // No OrganizatioData is available. Create another one, with "null" title, which may be
6078f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        // added via handleTitleValue().
608635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        addNewOrganization(type, companyName, departmentName, null, isPrimary);
6098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
6108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    /**
6128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     * Set "title" value to the appropriate data. If there's more than one
6138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     * OrganizationData objects, this input is attached to the last one which does not
6148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     * have valid title value (not including empty but only null). If there's no
6158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     * OrganizationData object, a new OrganizationData is created, whose company name is
6168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     * set to null.
6178f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian     */
6188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    private void handleTitleValue(final String title) {
6198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (mOrganizationList == null) {
6208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // Create new first organization entry, with "null" other info, which may be
6218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // added via handleOrgValue().
6228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            addNewOrganization(DEFAULT_ORGANIZATION_TYPE, null, null, title, false);
6238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return;
6248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
6258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        for (OrganizationData organizationData : mOrganizationList) {
6268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (organizationData.titleName == null) {
6278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                organizationData.titleName = title;
6288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                return;
629635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            }
630635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        }
631635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        // No Organization is available. Create another one, with "null" other info, which may be
632635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        // added via handleOrgValue().
6338f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        addNewOrganization(DEFAULT_ORGANIZATION_TYPE, null, null, title, false);
6348f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
6358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
636635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    private void addIm(int protocol, String customProtocol, int type,
637635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            String propValue, boolean isPrimary) {
638635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        if (mImList == null) {
639635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            mImList = new ArrayList<ImData>();
6408f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        }
641635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        mImList.add(new ImData(protocol, customProtocol, type, propValue, isPrimary));
642635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    }
643635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
6448f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    private void addNote(final String note) {
6458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (mNoteList == null) {
6468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            mNoteList = new ArrayList<String>(1);
6478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
6488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        mNoteList.add(note);
6498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
6508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    private void addPhotoBytes(String formatName, byte[] photoBytes, boolean isPrimary) {
6528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (mPhotoList == null) {
6538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            mPhotoList = new ArrayList<PhotoData>(1);
6548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
6558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        final PhotoData photoData = new PhotoData(0, null, photoBytes, isPrimary);
6568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        mPhotoList.add(photoData);
6578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
6588f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
6598f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    @SuppressWarnings("fallthrough")
6608f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    private void handleNProperty(List<String> elems) {
6618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Family, Given, Middle, Prefix, Suffix. (1 - 5)
6628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        int size;
6638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (elems == null || (size = elems.size()) < 1) {
6648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return;
6658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
6668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (size > 5) {
6678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            size = 5;
6688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
6698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        switch (size) {
6718f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            // fallthrough
6728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            case 5: mSuffix = elems.get(4);
6738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            case 4: mPrefix = elems.get(3);
6748f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            case 3: mMiddleName = elems.get(2);
6758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            case 2: mGivenName = elems.get(1);
6768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            default: mFamilyName = elems.get(0);
6778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
6788f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
6798f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
6808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    /**
6818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     * Note: Some Japanese mobile phones use this field for phonetic name,
6828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     *       since vCard 2.1 does not have "SORT-STRING" type.
6838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     *       Also, in some cases, the field has some ';'s in it.
6848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     *       Assume the ';' means the same meaning in N property
6858f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian     */
6868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    @SuppressWarnings("fallthrough")
6878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    private void handlePhoneticNameFromSound(List<String> elems) {
6888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (!(TextUtils.isEmpty(mPhoneticFamilyName) &&
6898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                TextUtils.isEmpty(mPhoneticMiddleName) &&
6908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                TextUtils.isEmpty(mPhoneticGivenName))) {
6918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // This means the other properties like "X-PHONETIC-FIRST-NAME" was already found.
6928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // Ignore "SOUND;X-IRMC-N".
6938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return;
694231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        }
6958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
696231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        int size;
6978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (elems == null || (size = elems.size()) < 1) {
6988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return;
699635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        }
700635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
7018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Assume that the order is "Family, Given, Middle".
7028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // This is not from specification but mere assumption. Some Japanese phones use this order.
7038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (size > 3) {
704635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            size = 3;
7058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
7068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7078f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (elems.get(0).length() > 0) {
7088f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            boolean onlyFirstElemIsNonEmpty = true;
7098f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            for (int i = 1; i < size; i++) {
7108f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                if (elems.get(i).length() > 0) {
7118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    onlyFirstElemIsNonEmpty = false;
7128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    break;
7138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
7148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
7158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (onlyFirstElemIsNonEmpty) {
7168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                final String[] namesArray = elems.get(0).split(" ");
7178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                final int nameArrayLength = namesArray.length;
7188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (nameArrayLength == 3) {
7198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    // Assume the string is "Family Middle Given".
7208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    mPhoneticFamilyName = namesArray[0];
7218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    mPhoneticMiddleName = namesArray[1];
7228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    mPhoneticGivenName = namesArray[2];
7238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                } else if (nameArrayLength == 2) {
7248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    // Assume the string is "Family Given" based on the Japanese mobile
7258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    // phones' preference.
7268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    mPhoneticFamilyName = namesArray[0];
7278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    mPhoneticGivenName = namesArray[1];
7288f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                } else {
7298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    mPhoneticFullName = elems.get(0);
7308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
731635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                return;
732635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            }
7338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
7348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7358f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        switch (size) {
7368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // fallthrough
7378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            case 3: mPhoneticMiddleName = elems.get(2);
7388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            case 2: mPhoneticGivenName = elems.get(1);
7398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            default: mPhoneticFamilyName = elems.get(0);
7408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
7418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
7428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    public void addProperty(final Property property) {
7448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        final String propName = property.mPropertyName;
7458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        final Map<String, Collection<String>> paramMap = property.mParameterMap;
7468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        final List<String> propValueList = property.mPropertyValueList;
7478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        byte[] propBytes = property.mPropertyBytes;
7488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (propValueList.size() == 0) {
7508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return;
7518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
7528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        final String propValue = listToString(propValueList).trim();
7538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (propName.equals(VCardConstants.PROPERTY_VERSION)) {
755635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            // vCard version. Ignore this.
7568f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        } else if (propName.equals(VCardConstants.PROPERTY_FN)) {
7578f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            mFullName = propValue;
7588f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        } else if (propName.equals(VCardConstants.PROPERTY_NAME) && mFullName == null) {
7598f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            // Only in vCard 3.0. Use this if FN, which must exist in vCard 3.0 but may not
7608f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            // actually exist in the real vCard data, does not exist.
7618f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            mFullName = propValue;
7625f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        } else if (propName.equals(VCardConstants.PROPERTY_N)) {
7635f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            handleNProperty(propValueList);
764635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        } else if (propName.equals(VCardConstants.PROPERTY_SORT_STRING)) {
765d0825bca7fe65beaee391d30da42e937db621564Steve Block            mPhoneticFullName = propValue;
766635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        } else if (propName.equals(VCardConstants.PROPERTY_NICKNAME) ||
767635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                propName.equals(VCardConstants.ImportOnly.PROPERTY_X_NICKNAME)) {
768635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            addNickName(propValue);
769635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        } else if (propName.equals(VCardConstants.PROPERTY_SOUND)) {
770635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            Collection<String> typeCollection = paramMap.get(VCardConstants.PARAM_TYPE);
771635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            if (typeCollection != null
7728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    && typeCollection.contains(VCardConstants.PARAM_TYPE_X_IRMC_N)) {
7738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // As of 2009-10-08, Parser side does not split a property value into separated
7748f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                // values using ';' (in other words, propValueList.size() == 1),
7758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // which is correct behavior from the view of vCard 2.1.
7768f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                // But we want it to be separated, so do the separation here.
7778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                final List<String> phoneticNameList =
778635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                        VCardUtils.constructListFromValue(propValue,
779635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                                VCardConfig.isV30(mVCardType));
780635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                handlePhoneticNameFromSound(phoneticNameList);
7818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            } else {
7828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                // Ignore this field since Android cannot understand what it is.
7838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
7848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        } else if (propName.equals(VCardConstants.PROPERTY_ADR)) {
7858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            boolean valuesAreAllEmpty = true;
7868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            for (String value : propValueList) {
7878f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                if (value.length() > 0) {
788635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                    valuesAreAllEmpty = false;
7898f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                    break;
7908f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                }
7918f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            }
7928f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            if (valuesAreAllEmpty) {
7938f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                return;
7948f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            }
7958f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
7968f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            int type = -1;
7978f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            String label = "";
7988f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            boolean isPrimary = false;
7998f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            Collection<String> typeCollection = paramMap.get(VCardConstants.PARAM_TYPE);
8008f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            if (typeCollection != null) {
8018f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                for (String typeString : typeCollection) {
8028f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                    typeString = typeString.toUpperCase();
8038f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                    if (typeString.equals(VCardConstants.PARAM_TYPE_PREF)) {
8048f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                        isPrimary = true;
8058f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                    } else if (typeString.equals(VCardConstants.PARAM_TYPE_HOME)) {
8068f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                        type = StructuredPostal.TYPE_HOME;
8078f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                        label = "";
8088f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                    } else if (typeString.equals(VCardConstants.PARAM_TYPE_WORK) ||
8098f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                            typeString.equalsIgnoreCase(VCardConstants.PARAM_EXTRA_TYPE_COMPANY)) {
8108f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                        // "COMPANY" seems emitted by Windows Mobile, which is not
8118f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                        // specifically supported by vCard 2.1. We assume this is same
8128f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                        // as "WORK".
8138f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                        type = StructuredPostal.TYPE_WORK;
8148f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                        label = "";
8158f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                    } else if (typeString.equals(VCardConstants.PARAM_ADR_TYPE_PARCEL) ||
8168f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                            typeString.equals(VCardConstants.PARAM_ADR_TYPE_DOM) ||
8178f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                            typeString.equals(VCardConstants.PARAM_ADR_TYPE_INTL)) {
8188f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                        // We do not have any appropriate way to store this information.
8198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    } else {
8208f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                        if (typeString.startsWith("X-") && type < 0) {
8218f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                            typeString = typeString.substring(2);
8228f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                        }
8238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        // vCard 3.0 allows iana-token. Also some vCard 2.1 exporters
8248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        // emit non-standard types. We do not handle their values now.
8258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        type = StructuredPostal.TYPE_CUSTOM;
8268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        label = typeString;
8278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    }
8288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
8298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
8308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // We use "HOME" as default
8318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (type < 0) {
8328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                type = StructuredPostal.TYPE_HOME;
833635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            }
8348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            addPostal(type, propValueList, label, isPrimary);
8368f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        } else if (propName.equals(VCardConstants.PROPERTY_EMAIL)) {
8378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            int type = -1;
8388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            String label = null;
8398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            boolean isPrimary = false;
8408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            Collection<String> typeCollection = paramMap.get(VCardConstants.PARAM_TYPE);
8418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (typeCollection != null) {
8428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                for (String typeString : typeCollection) {
8438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    typeString = typeString.toUpperCase();
8448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    if (typeString.equals(VCardConstants.PARAM_TYPE_PREF)) {
8458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        isPrimary = true;
8468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    } else if (typeString.equals(VCardConstants.PARAM_TYPE_HOME)) {
8478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        type = Email.TYPE_HOME;
8488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    } else if (typeString.equals(VCardConstants.PARAM_TYPE_WORK)) {
8498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        type = Email.TYPE_WORK;
8508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    } else if (typeString.equals(VCardConstants.PARAM_TYPE_CELL)) {
851635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                        type = Email.TYPE_MOBILE;
8528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    } else {
8538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        if (typeString.startsWith("X-") && type < 0) {
8548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                            typeString = typeString.substring(2);
8558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        }
8568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        // vCard 3.0 allows iana-token.
8578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        // We may have INTERNET (specified in vCard spec),
8588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        // SCHOOL, etc.
8598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        type = Email.TYPE_CUSTOM;
8608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                        label = typeString;
8618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    }
8628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
8638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
8648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (type < 0) {
8658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                type = Email.TYPE_OTHER;
8668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
8678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            addEmail(type, propValue, label, isPrimary);
8688f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        } else if (propName.equals(VCardConstants.PROPERTY_ORG)) {
8698f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            // vCard specification does not specify other types.
8708f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            final int type = Organization.TYPE_WORK;
8718f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            boolean isPrimary = false;
8728f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            Collection<String> typeCollection = paramMap.get(VCardConstants.PARAM_TYPE);
8738f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            if (typeCollection != null) {
8748f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                for (String typeString : typeCollection) {
8758f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                    if (typeString.equals(VCardConstants.PARAM_TYPE_PREF)) {
8768f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                        isPrimary = true;
8778f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                    }
8788f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                }
8798f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            }
8808f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            handleOrgValue(type, propValueList, isPrimary);
8818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        } else if (propName.equals(VCardConstants.PROPERTY_TITLE)) {
8828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            handleTitleValue(propValue);
8838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        } else if (propName.equals(VCardConstants.PROPERTY_ROLE)) {
8848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // This conflicts with TITLE. Ignore for now...
8858f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            // handleTitleValue(propValue);
8868f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        } else if (propName.equals(VCardConstants.PROPERTY_PHOTO) ||
8878f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                propName.equals(VCardConstants.PROPERTY_LOGO)) {
8888f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            Collection<String> paramMapValue = paramMap.get("VALUE");
8898f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            if (paramMapValue != null && paramMapValue.contains("URL")) {
890231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                // Currently we do not have appropriate example for testing this case.
891231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            } else {
892231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                final Collection<String> typeCollection = paramMap.get("TYPE");
893231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                String formatName = null;
894231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                boolean isPrimary = false;
895231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                if (typeCollection != null) {
896231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                    for (String typeValue : typeCollection) {
897231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                        if (VCardConstants.PARAM_TYPE_PREF.equals(typeValue)) {
898231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                            isPrimary = true;
899231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                        } else if (formatName == null){
9008f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                            formatName = typeValue;
9018f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                        }
9028f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                    }
9038f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                }
9048f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                addPhotoBytes(formatName, propBytes, isPrimary);
9058f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            }
9068f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        } else if (propName.equals(VCardConstants.PROPERTY_TEL)) {
9078f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            final Collection<String> typeCollection = paramMap.get(VCardConstants.PARAM_TYPE);
9088f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            final Object typeObject =
9098f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                VCardUtils.getPhoneTypeFromStrings(typeCollection, propValue);
9108f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            final int type;
9118f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            final String label;
9128f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            if (typeObject instanceof Integer) {
9138f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                type = (Integer)typeObject;
9148f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                label = null;
9158f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            } else {
9168f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                type = Phone.TYPE_CUSTOM;
9178f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                label = typeObject.toString();
9188f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            }
9198f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
9208f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            final boolean isPrimary;
9218f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            if (typeCollection != null && typeCollection.contains(VCardConstants.PARAM_TYPE_PREF)) {
9228f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                isPrimary = true;
9238f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            } else {
9248f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                isPrimary = false;
9258f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            }
9268f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            addPhone(type, propValue, label, isPrimary);
9278f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        } else if (propName.equals(VCardConstants.PROPERTY_X_SKYPE_PSTNNUMBER)) {
9288f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            // The phone number available via Skype.
9298f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            Collection<String> typeCollection = paramMap.get(VCardConstants.PARAM_TYPE);
9308f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            final int type = Phone.TYPE_OTHER;
9318f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            final boolean isPrimary;
9328f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            if (typeCollection != null && typeCollection.contains(VCardConstants.PARAM_TYPE_PREF)) {
9338f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                isPrimary = true;
9348f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            } else {
9358f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                isPrimary = false;
9368f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            }
9378f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            addPhone(type, propValue, null, isPrimary);
9388f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        } else if (sImMap.containsKey(propName)) {
9398f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            final int protocol = sImMap.get(propName);
9408f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            boolean isPrimary = false;
9418f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            int type = -1;
9428f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            final Collection<String> typeCollection = paramMap.get(VCardConstants.PARAM_TYPE);
9438f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            if (typeCollection != null) {
9448f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                for (String typeString : typeCollection) {
9458f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                    if (typeString.equals(VCardConstants.PARAM_TYPE_PREF)) {
9468f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                        isPrimary = true;
9478f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                    } else if (type < 0) {
9488f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                        if (typeString.equalsIgnoreCase(VCardConstants.PARAM_TYPE_HOME)) {
9498f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                            type = Im.TYPE_HOME;
9508f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                        } else if (typeString.equalsIgnoreCase(VCardConstants.PARAM_TYPE_WORK)) {
9518f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                            type = Im.TYPE_WORK;
9528f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                        }
9538f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                    }
9548f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                }
9558f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            }
9568f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            if (type < 0) {
9578f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                type = Phone.TYPE_HOME;
9588f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            }
9598f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            addIm(protocol, null, type, propValue, isPrimary);
9608f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        } else if (propName.equals(VCardConstants.PROPERTY_NOTE)) {
9618f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            addNote(propValue);
9628f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        } else if (propName.equals(VCardConstants.PROPERTY_URL)) {
9638f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            if (mWebsiteList == null) {
9648f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                mWebsiteList = new ArrayList<String>(1);
9658f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            }
9668f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            mWebsiteList.add(propValue);
9678f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        } else if (propName.equals(VCardConstants.PROPERTY_BDAY)) {
9688f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            mBirthday = propValue;
9698f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        } else if (propName.equals(VCardConstants.PROPERTY_X_PHONETIC_FIRST_NAME)) {
9708f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            mPhoneticGivenName = propValue;
9718f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        } else if (propName.equals(VCardConstants.PROPERTY_X_PHONETIC_MIDDLE_NAME)) {
9728f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            mPhoneticMiddleName = propValue;
9738f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        } else if (propName.equals(VCardConstants.PROPERTY_X_PHONETIC_LAST_NAME)) {
9748f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            mPhoneticFamilyName = propValue;
9758f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        } else if (propName.equals(VCardConstants.PROPERTY_X_ANDROID_CUSTOM)) {
9768f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            final List<String> customPropertyList =
9778f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                VCardUtils.constructListFromValue(propValue,
9788f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian                        VCardConfig.isV30(mVCardType));
9798f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            handleAndroidCustomProperty(customPropertyList);
9808f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        /*} else if (propName.equals("REV")) {
9818f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            // Revision of this VCard entry. I think we can ignore this.
9828f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        } else if (propName.equals("UID")) {
9838f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        } else if (propName.equals("KEY")) {
9848f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            // Type is X509 or PGP? I don't know how to handle this...
9858f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        } else if (propName.equals("MAILER")) {
9868f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        } else if (propName.equals("TZ")) {
9878f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        } else if (propName.equals("GEO")) {
9888f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        } else if (propName.equals("CLASS")) {
9898f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            // vCard 3.0 only.
9908f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            // e.g. CLASS:CONFIDENTIAL
9918f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        } else if (propName.equals("PROFILE")) {
9928f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            // VCard 3.0 only. Must be "VCARD". I think we can ignore this.
9938f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        } else if (propName.equals("CATEGORIES")) {
9948f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            // VCard 3.0 only.
9958f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            // e.g. CATEGORIES:INTERNET,IETF,INDUSTRY,INFORMATION TECHNOLOGY
9968f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        } else if (propName.equals("SOURCE")) {
9978f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            // VCard 3.0 only.
9988f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        } else if (propName.equals("PRODID")) {
9998f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            // VCard 3.0 only.
10008f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            // To specify the identifier for the product that created
10018f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            // the vCard object.*/
10028f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        } else {
10038f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            // Unknown X- words and IANA token.
10048f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        }
10050bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    }
10068f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
10078f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    private void handleAndroidCustomProperty(final List<String> customPropertyList) {
10080bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        if (mAndroidCustomPropertyList == null) {
10098f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            mAndroidCustomPropertyList = new ArrayList<List<String>>();
10108f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        }
10110bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        mAndroidCustomPropertyList.add(customPropertyList);
10120bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    }
10138f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
10148f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    /**
10158f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian     * Construct the display name. The constructed data must not be null.
1016231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block     */
1017231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    private void constructDisplayName() {
1018231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        // FullName (created via "FN" or "NAME" field) is prefered.
1019231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        if (!TextUtils.isEmpty(mFullName)) {
1020231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            mDisplayName = mFullName;
1021231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        } else if (!(TextUtils.isEmpty(mFamilyName) && TextUtils.isEmpty(mGivenName))) {
1022231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            mDisplayName = VCardUtils.constructNameFromElements(mVCardType,
1023231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                    mFamilyName, mMiddleName, mGivenName, mPrefix, mSuffix);
1024231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        } else if (!(TextUtils.isEmpty(mPhoneticFamilyName) &&
1025231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                TextUtils.isEmpty(mPhoneticGivenName))) {
1026231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            mDisplayName = VCardUtils.constructNameFromElements(mVCardType,
1027231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                    mPhoneticFamilyName, mPhoneticMiddleName, mPhoneticGivenName);
1028231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        } else if (mEmailList != null && mEmailList.size() > 0) {
1029231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            mDisplayName = mEmailList.get(0).data;
1030231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        } else if (mPhoneList != null && mPhoneList.size() > 0) {
1031231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            mDisplayName = mPhoneList.get(0).data;
1032231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        } else if (mPostalList != null && mPostalList.size() > 0) {
1033231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            mDisplayName = mPostalList.get(0).getFormattedAddress(mVCardType);
1034231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        } else if (mOrganizationList != null && mOrganizationList.size() > 0) {
1035231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            mDisplayName = mOrganizationList.get(0).getFormattedString();
1036231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        }
1037231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
1038231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        if (mDisplayName == null) {
1039231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            mDisplayName = "";
1040231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        }
1041231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    }
1042231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
1043231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    /**
1044231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block     * Consolidate several fielsds (like mName) using name candidates,
1045231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block     */
1046231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    public void consolidateFields() {
1047231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        constructDisplayName();
1048231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
1049231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        if (mPhoneticFullName != null) {
1050231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            mPhoneticFullName = mPhoneticFullName.trim();
1051231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        }
10528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
10538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    public void pushIntoContentResolver(ContentResolver resolver) {
10558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ArrayList<ContentProviderOperation> operationList =
10568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            new ArrayList<ContentProviderOperation>();
1057643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        ContentProviderOperation.Builder builder =
1058643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            ContentProviderOperation.newInsert(RawContacts.CONTENT_URI);
1059643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        String myGroupsId = null;
1060643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        if (mAccount != null) {
10618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            builder.withValue(RawContacts.ACCOUNT_NAME, mAccount.name);
10628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            builder.withValue(RawContacts.ACCOUNT_TYPE, mAccount.type);
10638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1064            // Assume that caller side creates this group if it does not exist.
1065            if (ACCOUNT_TYPE_GOOGLE.equals(mAccount.type)) {
1066                final Cursor cursor = resolver.query(Groups.CONTENT_URI, new String[] {
1067                        Groups.SOURCE_ID },
1068                        Groups.TITLE + "=?", new String[] {
1069                        GOOGLE_MY_CONTACTS_GROUP }, null);
1070                try {
1071                    if (cursor != null && cursor.moveToFirst()) {
1072                        myGroupsId = cursor.getString(0);
1073                    }
1074                } finally {
1075                    if (cursor != null) {
1076                        cursor.close();
1077                    }
1078                }
1079            }
1080        } else {
1081            builder.withValue(RawContacts.ACCOUNT_NAME, null);
1082            builder.withValue(RawContacts.ACCOUNT_TYPE, null);
1083        }
1084        operationList.add(builder.build());
1085
1086        if (!nameFieldsAreEmpty()) {
1087            builder = ContentProviderOperation.newInsert(Data.CONTENT_URI);
1088            builder.withValueBackReference(StructuredName.RAW_CONTACT_ID, 0);
1089            builder.withValue(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE);
1090
1091            builder.withValue(StructuredName.GIVEN_NAME, mGivenName);
1092            builder.withValue(StructuredName.FAMILY_NAME, mFamilyName);
1093            builder.withValue(StructuredName.MIDDLE_NAME, mMiddleName);
1094            builder.withValue(StructuredName.PREFIX, mPrefix);
1095            builder.withValue(StructuredName.SUFFIX, mSuffix);
1096
1097            if (!(TextUtils.isEmpty(mPhoneticGivenName)
1098                    && TextUtils.isEmpty(mPhoneticFamilyName)
1099                    && TextUtils.isEmpty(mPhoneticMiddleName))) {
1100                builder.withValue(StructuredName.PHONETIC_GIVEN_NAME, mPhoneticGivenName);
1101                builder.withValue(StructuredName.PHONETIC_FAMILY_NAME, mPhoneticFamilyName);
1102                builder.withValue(StructuredName.PHONETIC_MIDDLE_NAME, mPhoneticMiddleName);
1103            } else if (!TextUtils.isEmpty(mPhoneticFullName)) {
1104                builder.withValue(StructuredName.PHONETIC_GIVEN_NAME, mPhoneticFullName);
1105            }
1106
1107            builder.withValue(StructuredName.DISPLAY_NAME, getDisplayName());
1108            operationList.add(builder.build());
1109        }
1110
1111        if (mNickNameList != null && mNickNameList.size() > 0) {
1112            for (String nickName : mNickNameList) {
1113                builder = ContentProviderOperation.newInsert(Data.CONTENT_URI);
1114                builder.withValueBackReference(Nickname.RAW_CONTACT_ID, 0);
1115                builder.withValue(Data.MIMETYPE, Nickname.CONTENT_ITEM_TYPE);
1116                builder.withValue(Nickname.TYPE, Nickname.TYPE_DEFAULT);
1117                builder.withValue(Nickname.NAME, nickName);
1118                operationList.add(builder.build());
1119            }
1120        }
1121
1122        if (mPhoneList != null) {
1123            for (PhoneData phoneData : mPhoneList) {
1124                builder = ContentProviderOperation.newInsert(Data.CONTENT_URI);
1125                builder.withValueBackReference(Phone.RAW_CONTACT_ID, 0);
1126                builder.withValue(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
1127
1128                builder.withValue(Phone.TYPE, phoneData.type);
1129                if (phoneData.type == Phone.TYPE_CUSTOM) {
1130                    builder.withValue(Phone.LABEL, phoneData.label);
1131                }
1132                builder.withValue(Phone.NUMBER, phoneData.data);
1133                if (phoneData.isPrimary) {
1134                    builder.withValue(Phone.IS_PRIMARY, 1);
1135                }
1136                operationList.add(builder.build());
1137            }
1138        }
1139
1140        if (mOrganizationList != null) {
1141            for (OrganizationData organizationData : mOrganizationList) {
1142                builder = ContentProviderOperation.newInsert(Data.CONTENT_URI);
1143                builder.withValueBackReference(Organization.RAW_CONTACT_ID, 0);
1144                builder.withValue(Data.MIMETYPE, Organization.CONTENT_ITEM_TYPE);
1145                builder.withValue(Organization.TYPE, organizationData.type);
1146                if (organizationData.companyName != null) {
1147                    builder.withValue(Organization.COMPANY, organizationData.companyName);
1148                }
1149                if (organizationData.departmentName != null) {
1150                    builder.withValue(Organization.DEPARTMENT, organizationData.departmentName);
1151                }
1152                if (organizationData.titleName != null) {
1153                    builder.withValue(Organization.TITLE, organizationData.titleName);
1154                }
1155                if (organizationData.isPrimary) {
1156                    builder.withValue(Organization.IS_PRIMARY, 1);
1157                }
1158                operationList.add(builder.build());
1159            }
1160        }
1161
1162        if (mEmailList != null) {
1163            for (EmailData emailData : mEmailList) {
1164                builder = ContentProviderOperation.newInsert(Data.CONTENT_URI);
1165                builder.withValueBackReference(Email.RAW_CONTACT_ID, 0);
1166                builder.withValue(Data.MIMETYPE, Email.CONTENT_ITEM_TYPE);
1167
1168                builder.withValue(Email.TYPE, emailData.type);
1169                if (emailData.type == Email.TYPE_CUSTOM) {
1170                    builder.withValue(Email.LABEL, emailData.label);
1171                }
1172                builder.withValue(Email.DATA, emailData.data);
1173                if (emailData.isPrimary) {
1174                    builder.withValue(Data.IS_PRIMARY, 1);
1175                }
1176                operationList.add(builder.build());
1177            }
1178        }
1179
1180        if (mPostalList != null) {
1181            for (PostalData postalData : mPostalList) {
1182                builder = ContentProviderOperation.newInsert(Data.CONTENT_URI);
1183                VCardUtils.insertStructuredPostalDataUsingContactsStruct(
1184                        mVCardType, builder, postalData);
1185                operationList.add(builder.build());
1186            }
1187        }
1188
1189        if (mImList != null) {
1190            for (ImData imData : mImList) {
1191                builder = ContentProviderOperation.newInsert(Data.CONTENT_URI);
1192                builder.withValueBackReference(Im.RAW_CONTACT_ID, 0);
1193                builder.withValue(Data.MIMETYPE, Im.CONTENT_ITEM_TYPE);
1194                builder.withValue(Im.TYPE, imData.type);
1195                builder.withValue(Im.PROTOCOL, imData.protocol);
1196                if (imData.protocol == Im.PROTOCOL_CUSTOM) {
1197                    builder.withValue(Im.CUSTOM_PROTOCOL, imData.customProtocol);
1198                }
1199                if (imData.isPrimary) {
1200                    builder.withValue(Data.IS_PRIMARY, 1);
1201                }
1202            }
1203        }
1204
1205        if (mNoteList != null) {
1206            for (String note : mNoteList) {
1207                builder = ContentProviderOperation.newInsert(Data.CONTENT_URI);
1208                builder.withValueBackReference(Note.RAW_CONTACT_ID, 0);
1209                builder.withValue(Data.MIMETYPE, Note.CONTENT_ITEM_TYPE);
1210                builder.withValue(Note.NOTE, note);
1211                operationList.add(builder.build());
1212            }
1213        }
1214
1215        if (mPhotoList != null) {
1216            for (PhotoData photoData : mPhotoList) {
1217                builder = ContentProviderOperation.newInsert(Data.CONTENT_URI);
1218                builder.withValueBackReference(Photo.RAW_CONTACT_ID, 0);
1219                builder.withValue(Data.MIMETYPE, Photo.CONTENT_ITEM_TYPE);
1220                builder.withValue(Photo.PHOTO, photoData.photoBytes);
1221                if (photoData.isPrimary) {
1222                    builder.withValue(Photo.IS_PRIMARY, 1);
1223                }
1224                operationList.add(builder.build());
1225            }
1226        }
1227
1228        if (mWebsiteList != null) {
1229            for (String website : mWebsiteList) {
1230                builder = ContentProviderOperation.newInsert(Data.CONTENT_URI);
1231                builder.withValueBackReference(Website.RAW_CONTACT_ID, 0);
1232                builder.withValue(Data.MIMETYPE, Website.CONTENT_ITEM_TYPE);
1233                builder.withValue(Website.URL, website);
1234                // There's no information about the type of URL in vCard.
1235                // We use TYPE_HOMEPAGE for safety.
1236                builder.withValue(Website.TYPE, Website.TYPE_HOMEPAGE);
1237                operationList.add(builder.build());
1238            }
1239        }
1240
1241        if (!TextUtils.isEmpty(mBirthday)) {
1242            builder = ContentProviderOperation.newInsert(Data.CONTENT_URI);
1243            builder.withValueBackReference(Event.RAW_CONTACT_ID, 0);
1244            builder.withValue(Data.MIMETYPE, Event.CONTENT_ITEM_TYPE);
1245            builder.withValue(Event.START_DATE, mBirthday);
1246            builder.withValue(Event.TYPE, Event.TYPE_BIRTHDAY);
1247            operationList.add(builder.build());
1248        }
1249
1250        if (mAndroidCustomPropertyList != null) {
1251            for (List<String> customPropertyList : mAndroidCustomPropertyList) {
1252                int size = customPropertyList.size();
1253                if (size < 2 || TextUtils.isEmpty(customPropertyList.get(0))) {
1254                    continue;
1255                } else if (size > VCardConstants.MAX_DATA_COLUMN + 1) {
1256                    size = VCardConstants.MAX_DATA_COLUMN + 1;
1257                    customPropertyList =
1258                        customPropertyList.subList(0, VCardConstants.MAX_DATA_COLUMN + 2);
1259                }
1260
1261                int i = 0;
1262                for (final String customPropertyValue : customPropertyList) {
1263                    if (i == 0) {
1264                        final String mimeType = customPropertyValue;
1265                        builder = ContentProviderOperation.newInsert(Data.CONTENT_URI);
1266                        builder.withValueBackReference(GroupMembership.RAW_CONTACT_ID, 0);
1267                        builder.withValue(Data.MIMETYPE, mimeType);
1268                    } else {  // 1 <= i && i <= MAX_DATA_COLUMNS
1269                        if (!TextUtils.isEmpty(customPropertyValue)) {
1270                            builder.withValue("data" + i, customPropertyValue);
1271                        }
1272                    }
1273
1274                    i++;
1275                }
1276                operationList.add(builder.build());
1277            }
1278        }
1279
1280        if (myGroupsId != null) {
1281            builder = ContentProviderOperation.newInsert(Data.CONTENT_URI);
1282            builder.withValueBackReference(GroupMembership.RAW_CONTACT_ID, 0);
1283            builder.withValue(Data.MIMETYPE, GroupMembership.CONTENT_ITEM_TYPE);
1284            builder.withValue(GroupMembership.GROUP_SOURCE_ID, myGroupsId);
1285            operationList.add(builder.build());
1286        }
1287
1288        try {
1289            resolver.applyBatch(ContactsContract.AUTHORITY, operationList);
1290        } catch (RemoteException e) {
1291            Log.e(LOG_TAG, String.format("%s: %s", e.toString(), e.getMessage()));
1292        } catch (OperationApplicationException e) {
1293            Log.e(LOG_TAG, String.format("%s: %s", e.toString(), e.getMessage()));
1294        }
1295    }
1296
1297    public static VCardEntry buildFromResolver(ContentResolver resolver) {
1298        return buildFromResolver(resolver, Contacts.CONTENT_URI);
1299    }
1300
1301    public static VCardEntry buildFromResolver(ContentResolver resolver, Uri uri) {
1302
1303        return null;
1304    }
1305
1306    private boolean nameFieldsAreEmpty() {
1307        return (TextUtils.isEmpty(mFamilyName)
1308                && TextUtils.isEmpty(mMiddleName)
1309                && TextUtils.isEmpty(mGivenName)
1310                && TextUtils.isEmpty(mPrefix)
1311                && TextUtils.isEmpty(mSuffix)
1312                && TextUtils.isEmpty(mFullName)
1313                && TextUtils.isEmpty(mPhoneticFamilyName)
1314                && TextUtils.isEmpty(mPhoneticMiddleName)
1315                && TextUtils.isEmpty(mPhoneticGivenName)
1316                && TextUtils.isEmpty(mPhoneticFullName));
1317    }
1318
1319    public boolean isIgnorable() {
1320        return getDisplayName().length() == 0;
1321    }
1322
1323    private String listToString(List<String> list){
1324        final int size = list.size();
1325        if (size > 1) {
1326            StringBuilder builder = new StringBuilder();
1327            int i = 0;
1328            for (String type : list) {
1329                builder.append(type);
1330                if (i < size - 1) {
1331                    builder.append(";");
1332                }
1333            }
1334            return builder.toString();
1335        } else if (size == 1) {
1336            return list.get(0);
1337        } else {
1338            return "";
1339        }
1340    }
1341
1342    // All getter methods should be used carefully, since they may change
1343    // in the future as of 2009-10-05, on which I cannot be sure this structure
1344    // is completely consolidated.
1345    //
1346    // Also note that these getter methods should be used only after
1347    // all properties being pushed into this object. If not, incorrect
1348    // value will "be stored in the local cache and" be returned to you.
1349
1350    public String getFamilyName() {
1351        return mFamilyName;
1352    }
1353
1354    public String getGivenName() {
1355        return mGivenName;
1356    }
1357
1358    public String getMiddleName() {
1359        return mMiddleName;
1360    }
1361
1362    public String getPrefix() {
1363        return mPrefix;
1364    }
1365
1366    public String getSuffix() {
1367        return mSuffix;
1368    }
1369
1370    public String getFullName() {
1371        return mFullName;
1372    }
1373
1374    public String getPhoneticFamilyName() {
1375        return mPhoneticFamilyName;
1376    }
1377
1378    public String getPhoneticGivenName() {
1379        return mPhoneticGivenName;
1380    }
1381
1382    public String getPhoneticMiddleName() {
1383        return mPhoneticMiddleName;
1384    }
1385
1386    public String getPhoneticFullName() {
1387        return mPhoneticFullName;
1388    }
1389
1390    public final List<String> getNickNameList() {
1391        return mNickNameList;
1392    }
1393
1394    public String getBirthday() {
1395        return mBirthday;
1396    }
1397
1398    public final List<String> getNotes() {
1399        return mNoteList;
1400    }
1401
1402    public final List<PhoneData> getPhoneList() {
1403        return mPhoneList;
1404    }
1405
1406    public final List<EmailData> getEmailList() {
1407        return mEmailList;
1408    }
1409
1410    public final List<PostalData> getPostalList() {
1411        return mPostalList;
1412    }
1413
1414    public final List<OrganizationData> getOrganizationList() {
1415        return mOrganizationList;
1416    }
1417
1418    public final List<ImData> getImList() {
1419        return mImList;
1420    }
1421
1422    public final List<PhotoData> getPhotoList() {
1423        return mPhotoList;
1424    }
1425
1426    public final List<String> getWebsiteList() {
1427        return mWebsiteList;
1428    }
1429
1430    public String getDisplayName() {
1431        if (mDisplayName == null) {
1432            constructDisplayName();
1433        }
1434        return mDisplayName;
1435    }
1436}
1437