VCardEntry.java revision 48dd8e86a81d2ab40eb762975c8211c225002bf0
14199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa/*
24199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * Copyright (C) 2009 The Android Open Source Project
34199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa *
44199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * Licensed under the Apache License, Version 2.0 (the "License");
54199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * you may not use this file except in compliance with the License.
64199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * You may obtain a copy of the License at
74199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa *
84199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa *      http://www.apache.org/licenses/LICENSE-2.0
94199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa *
104199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * Unless required by applicable law or agreed to in writing, software
114199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * distributed under the License is distributed on an "AS IS" BASIS,
124199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
134199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * See the License for the specific language governing permissions and
144199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * limitations under the License.
154199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa */
164199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawapackage com.android.vcard;
174199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
189919ad2126c06dbf2eb54a11e6158f87f316bc22Daisuke Miyakawaimport com.android.vcard.VCardUtils.PhoneNumberUtilsPort;
199919ad2126c06dbf2eb54a11e6158f87f316bc22Daisuke Miyakawa
204199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport android.accounts.Account;
214199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport android.content.ContentProviderOperation;
224199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport android.content.ContentResolver;
234199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport android.net.Uri;
244199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport android.provider.ContactsContract.CommonDataKinds.Email;
254199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport android.provider.ContactsContract.CommonDataKinds.Event;
264199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport android.provider.ContactsContract.CommonDataKinds.GroupMembership;
274199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport android.provider.ContactsContract.CommonDataKinds.Im;
284199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport android.provider.ContactsContract.CommonDataKinds.Nickname;
294199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport android.provider.ContactsContract.CommonDataKinds.Note;
304199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport android.provider.ContactsContract.CommonDataKinds.Organization;
314199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport android.provider.ContactsContract.CommonDataKinds.Phone;
324199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport android.provider.ContactsContract.CommonDataKinds.Photo;
3388d0f1ef715f2e1209eba5d175b1b71c556fa8b0Daisuke Miyakawaimport android.provider.ContactsContract.CommonDataKinds.SipAddress;
344199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport android.provider.ContactsContract.CommonDataKinds.StructuredName;
354199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport android.provider.ContactsContract.CommonDataKinds.StructuredPostal;
364199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport android.provider.ContactsContract.CommonDataKinds.Website;
3788d0f1ef715f2e1209eba5d175b1b71c556fa8b0Daisuke Miyakawaimport android.provider.ContactsContract.Contacts;
3888d0f1ef715f2e1209eba5d175b1b71c556fa8b0Daisuke Miyakawaimport android.provider.ContactsContract.Data;
3988d0f1ef715f2e1209eba5d175b1b71c556fa8b0Daisuke Miyakawaimport android.provider.ContactsContract.RawContacts;
404199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport android.text.TextUtils;
414199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport android.util.Log;
424199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
434199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport java.util.ArrayList;
444199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport java.util.Arrays;
454199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport java.util.Collection;
464199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport java.util.Collections;
474199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport java.util.HashMap;
484199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport java.util.HashSet;
4937634a0179f74431317f50d2ce493e3fad36f5a9Daisuke Miyakawaimport java.util.LinkedHashSet;
504199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport java.util.List;
514199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport java.util.Map;
5237634a0179f74431317f50d2ce493e3fad36f5a9Daisuke Miyakawaimport java.util.Set;
534199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
544199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa/**
554199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * This class bridges between data structure of Contact app and VCard data.
564199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa */
574199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawapublic class VCardEntry {
5802117b3d19787ff65486b9f9db8abd338ae4c9f9Daisuke Miyakawa    private static final String LOG_TAG = VCardConstants.LOG_TAG;
594199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
6048dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa    private static final int DEFAULT_ORGANIZATION_TYPE = Organization.TYPE_WORK;
614199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
624199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private static final Map<String, Integer> sImMap = new HashMap<String, Integer>();
634199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
644199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    static {
654199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        sImMap.put(VCardConstants.PROPERTY_X_AIM, Im.PROTOCOL_AIM);
664199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        sImMap.put(VCardConstants.PROPERTY_X_MSN, Im.PROTOCOL_MSN);
674199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        sImMap.put(VCardConstants.PROPERTY_X_YAHOO, Im.PROTOCOL_YAHOO);
684199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        sImMap.put(VCardConstants.PROPERTY_X_ICQ, Im.PROTOCOL_ICQ);
694199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        sImMap.put(VCardConstants.PROPERTY_X_JABBER, Im.PROTOCOL_JABBER);
704199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        sImMap.put(VCardConstants.PROPERTY_X_SKYPE_USERNAME, Im.PROTOCOL_SKYPE);
714199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        sImMap.put(VCardConstants.PROPERTY_X_GOOGLE_TALK, Im.PROTOCOL_GOOGLE_TALK);
724199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        sImMap.put(VCardConstants.ImportOnly.PROPERTY_X_GOOGLE_TALK_WITH_SPACE,
734199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                Im.PROTOCOL_GOOGLE_TALK);
744199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
754199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
764199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public static class PhoneData {
774199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public final int type;
784199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public final String data;
794199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public final String label;
804199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        // isPrimary is (not final but) changable, only when there's no appropriate one existing
814199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        // in the original VCard.
824199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public boolean isPrimary;
834199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public PhoneData(int type, String data, String label, boolean isPrimary) {
844199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            this.type = type;
854199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            this.data = data;
864199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            this.label = label;
874199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            this.isPrimary = isPrimary;
884199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
894199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
904199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        @Override
914199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public boolean equals(Object obj) {
924199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            if (!(obj instanceof PhoneData)) {
934199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                return false;
944199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
954199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            PhoneData phoneData = (PhoneData)obj;
964199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            return (type == phoneData.type && data.equals(phoneData.data) &&
974199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    label.equals(phoneData.label) && isPrimary == phoneData.isPrimary);
984199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
994199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
1004199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        @Override
1014199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public String toString() {
1024199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            return String.format("type: %d, data: %s, label: %s, isPrimary: %s",
1034199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    type, data, label, isPrimary);
1044199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
1054199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
1064199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
1074199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public static class EmailData {
1084199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public final int type;
1094199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public final String data;
1104199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        // Used only when TYPE is TYPE_CUSTOM.
1114199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public final String label;
1124199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public boolean isPrimary;
1134199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public EmailData(int type, String data, String label, boolean isPrimary) {
1144199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            this.type = type;
1154199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            this.data = data;
1164199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            this.label = label;
1174199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            this.isPrimary = isPrimary;
1184199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
1194199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
1204199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        @Override
1214199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public boolean equals(Object obj) {
1224199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            if (!(obj instanceof EmailData)) {
1234199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                return false;
1244199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
1254199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            EmailData emailData = (EmailData)obj;
1264199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            return (type == emailData.type && data.equals(emailData.data) &&
1274199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    label.equals(emailData.label) && isPrimary == emailData.isPrimary);
1284199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
1294199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
1304199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        @Override
1314199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public String toString() {
1324199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            return String.format("type: %d, data: %s, label: %s, isPrimary: %s",
1334199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    type, data, label, isPrimary);
1344199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
1354199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
1364199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
1374199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public static class PostalData {
1384199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        // Determined by vCard specification.
1394199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        // - PO Box, Extended Addr, Street, Locality, Region, Postal Code, Country Name
1404199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public static final int ADDR_MAX_DATA_SIZE = 7;
1414199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        private final String[] dataArray;
1424199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public final String pobox;
1434199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public final String extendedAddress;
1444199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public final String street;
1454199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public final String localty;
1464199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public final String region;
1474199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public final String postalCode;
1484199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public final String country;
1494199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public final int type;
1504199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public final String label;
1514199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public boolean isPrimary;
1524199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
1534199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public PostalData(final int type, final List<String> propValueList,
1544199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                final String label, boolean isPrimary) {
1554199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            this.type = type;
1564199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            dataArray = new String[ADDR_MAX_DATA_SIZE];
1574199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
1584199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            int size = propValueList.size();
1594199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            if (size > ADDR_MAX_DATA_SIZE) {
1604199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                size = ADDR_MAX_DATA_SIZE;
1614199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
1624199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
1634199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            // adr-value = 0*6(text-value ";") text-value
1644199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            //           ; PO Box, Extended Address, Street, Locality, Region, Postal
1654199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            //           ; Code, Country Name
1664199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            //
1674199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            // Use Iterator assuming List may be LinkedList, though actually it is
1684199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            // always ArrayList in the current implementation.
1694199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            int i = 0;
1704199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            for (String addressElement : propValueList) {
1714199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                dataArray[i] = addressElement;
1724199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                if (++i >= size) {
1734199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    break;
1744199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                }
1754199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
1764199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            while (i < ADDR_MAX_DATA_SIZE) {
1774199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                dataArray[i++] = null;
1784199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
1794199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
1804199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            this.pobox = dataArray[0];
1814199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            this.extendedAddress = dataArray[1];
1824199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            this.street = dataArray[2];
1834199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            this.localty = dataArray[3];
1844199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            this.region = dataArray[4];
1854199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            this.postalCode = dataArray[5];
1864199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            this.country = dataArray[6];
1874199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            this.label = label;
1884199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            this.isPrimary = isPrimary;
1894199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
1904199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
1914199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        @Override
1924199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public boolean equals(Object obj) {
1934199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            if (!(obj instanceof PostalData)) {
1944199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                return false;
1954199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
1964199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            final PostalData postalData = (PostalData)obj;
1974199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            return (Arrays.equals(dataArray, postalData.dataArray) &&
1984199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    (type == postalData.type &&
1994199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                            (type == StructuredPostal.TYPE_CUSTOM ?
2004199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                                    (label == postalData.label) : true)) &&
2014199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    (isPrimary == postalData.isPrimary));
2024199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
2034199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
2044199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public String getFormattedAddress(final int vcardType) {
2054199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            StringBuilder builder = new StringBuilder();
2064199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            boolean empty = true;
2074199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            if (VCardConfig.isJapaneseDevice(vcardType)) {
2084199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                // In Japan, the order is reversed.
2094199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                for (int i = ADDR_MAX_DATA_SIZE - 1; i >= 0; i--) {
2104199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    String addressPart = dataArray[i];
2114199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    if (!TextUtils.isEmpty(addressPart)) {
2124199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        if (!empty) {
2134199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                            builder.append(' ');
2144199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        } else {
2154199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                            empty = false;
2164199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        }
2174199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        builder.append(addressPart);
2184199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    }
2194199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                }
2204199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            } else {
2214199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                for (int i = 0; i < ADDR_MAX_DATA_SIZE; i++) {
2224199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    String addressPart = dataArray[i];
2234199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    if (!TextUtils.isEmpty(addressPart)) {
2244199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        if (!empty) {
2254199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                            builder.append(' ');
2264199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        } else {
2274199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                            empty = false;
2284199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        }
2294199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        builder.append(addressPart);
2304199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    }
2314199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                }
2324199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
2334199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
2344199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            return builder.toString().trim();
2354199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
2364199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
2374199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        @Override
2384199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public String toString() {
2394199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            return String.format("type: %d, label: %s, isPrimary: %s",
2404199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    type, label, isPrimary);
2414199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
2424199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
2434199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
2444199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public static class OrganizationData {
2454199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public final int type;
2464199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        // non-final is Intentional: we may change the values since this info is separated into
2474199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        // two parts in vCard: "ORG" + "TITLE", and we have to cope with each field in
2484199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        // different timing.
2494199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public String companyName;
2504199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public String departmentName;
2514199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public String titleName;
2524560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa        public final String phoneticName;  // We won't have this in "TITLE" property.
2534199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public boolean isPrimary;
2544199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
2554199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public OrganizationData(int type,
2564560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa                final String companyName,
2574560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa                final String departmentName,
2584560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa                final String titleName,
2594560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa                final String phoneticName,
2604560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa                final boolean isPrimary) {
2614199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            this.type = type;
2624199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            this.companyName = companyName;
2634199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            this.departmentName = departmentName;
2644199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            this.titleName = titleName;
2654560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa            this.phoneticName = phoneticName;
2664199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            this.isPrimary = isPrimary;
2674199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
2684199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
2694199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        @Override
2704199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public boolean equals(Object obj) {
2714199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            if (!(obj instanceof OrganizationData)) {
2724199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                return false;
2734199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
2744199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            OrganizationData organization = (OrganizationData)obj;
2754199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            return (type == organization.type &&
2764199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    TextUtils.equals(companyName, organization.companyName) &&
2774199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    TextUtils.equals(departmentName, organization.departmentName) &&
2784199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    TextUtils.equals(titleName, organization.titleName) &&
2794199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    isPrimary == organization.isPrimary);
2804199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
2814199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
2824199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public String getFormattedString() {
2834199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            final StringBuilder builder = new StringBuilder();
2844199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            if (!TextUtils.isEmpty(companyName)) {
2854199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.append(companyName);
2864199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
2874199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
2884199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            if (!TextUtils.isEmpty(departmentName)) {
2894199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                if (builder.length() > 0) {
2904199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    builder.append(", ");
2914199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                }
2924199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.append(departmentName);
2934199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
2944199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
2954199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            if (!TextUtils.isEmpty(titleName)) {
2964199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                if (builder.length() > 0) {
2974199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    builder.append(", ");
2984199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                }
2994199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.append(titleName);
3004199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
3014199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
3024199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            return builder.toString();
3034199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
3044199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
3054199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        @Override
3064199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public String toString() {
3074199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            return String.format(
3084199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    "type: %d, company: %s, department: %s, title: %s, isPrimary: %s",
3094199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    type, companyName, departmentName, titleName, isPrimary);
3104199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
3114199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
3124199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
3134199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public static class ImData {
3144199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public final int protocol;
3154199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public final String customProtocol;
3164199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public final int type;
3174199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public final String data;
3184199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public final boolean isPrimary;
3194199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
3204199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public ImData(final int protocol, final String customProtocol, final int type,
3214199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                final String data, final boolean isPrimary) {
3224199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            this.protocol = protocol;
3234199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            this.customProtocol = customProtocol;
3244199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            this.type = type;
3254199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            this.data = data;
3264199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            this.isPrimary = isPrimary;
3274199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
3284199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
3294199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        @Override
3304199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public boolean equals(Object obj) {
3314199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            if (!(obj instanceof ImData)) {
3324199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                return false;
3334199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
3344199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            ImData imData = (ImData)obj;
3354199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            return (type == imData.type && protocol == imData.protocol
3364199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    && (customProtocol != null ? customProtocol.equals(imData.customProtocol) :
3374199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        (imData.customProtocol == null))
3384199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    && (data != null ? data.equals(imData.data) : (imData.data == null))
3394199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    && isPrimary == imData.isPrimary);
3404199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
3414199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
3424199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        @Override
3434199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public String toString() {
3444199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            return String.format(
3454199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    "type: %d, protocol: %d, custom_protcol: %s, data: %s, isPrimary: %s",
3464199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    type, protocol, customProtocol, data, isPrimary);
3474199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
3484199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
3494199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
3504199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public static class PhotoData {
3514199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public static final String FORMAT_FLASH = "SWF";
3524199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public final int type;
3534199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public final String formatName;  // used when type is not defined in ContactsContract.
3544199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public final byte[] photoBytes;
3554199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public final boolean isPrimary;
3564199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
3574199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public PhotoData(int type, String formatName, byte[] photoBytes, boolean isPrimary) {
3584199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            this.type = type;
3594199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            this.formatName = formatName;
3604199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            this.photoBytes = photoBytes;
3614199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            this.isPrimary = isPrimary;
3624199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
3634199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
3644199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        @Override
3654199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public boolean equals(Object obj) {
3664199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            if (!(obj instanceof PhotoData)) {
3674199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                return false;
3684199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
3694199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            PhotoData photoData = (PhotoData)obj;
3704199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            return (type == photoData.type &&
3714199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    (formatName == null ? (photoData.formatName == null) :
3724199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                            formatName.equals(photoData.formatName)) &&
3734199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    (Arrays.equals(photoBytes, photoData.photoBytes)) &&
3744199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    (isPrimary == photoData.isPrimary));
3754199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
3764199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
3774199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        @Override
3784199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public String toString() {
3794199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            return String.format("type: %d, format: %s: size: %d, isPrimary: %s",
3804199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    type, formatName, photoBytes.length, isPrimary);
3814199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
3824199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
3834199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
38448dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa    /**
38548dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa     * TODO: implement better structure for Property. We also have PropertyData in
38648dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa     * VCardParserImpl_V21 for storing intermidate Property data.
38748dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa     * @hide public just for testing.
38848dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa     */
38948dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa    public static class Property {
3904199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        private String mPropertyName;
3914199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        private Map<String, Collection<String>> mParameterMap =
3924199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            new HashMap<String, Collection<String>>();
3934199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        private List<String> mPropertyValueList = new ArrayList<String>();
3944199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        private byte[] mPropertyBytes;
3954199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
3964199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public void setPropertyName(final String propertyName) {
3974199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mPropertyName = propertyName;
3984199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
3994199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
4004199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public void addParameter(final String paramName, final String paramValue) {
4014199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            Collection<String> values;
4024199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            if (!mParameterMap.containsKey(paramName)) {
4034199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                if (paramName.equals("TYPE")) {
4044199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    values = new HashSet<String>();
4054199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                } else {
4064199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    values = new ArrayList<String>();
4074199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                }
4084199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                mParameterMap.put(paramName, values);
4094199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            } else {
4104199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                values = mParameterMap.get(paramName);
4114199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
4124199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            values.add(paramValue);
4134199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
4144199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
41548dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa        public void addPropertyValue(final String propertyValue) {
4164199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mPropertyValueList.add(propertyValue);
4174199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
4184199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
41948dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa        public void addPropertyValue(final String... propertyValueList) {
42048dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa            mPropertyValueList.addAll(Arrays.asList(propertyValueList));
42148dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa        }
42248dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa
4234199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public void setPropertyBytes(final byte[] propertyBytes) {
4244199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mPropertyBytes = propertyBytes;
4254199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
4264199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
4274199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public final Collection<String> getParameters(String type) {
4284199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            return mParameterMap.get(type);
4294199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
4304199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
4314199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public final List<String> getPropertyValueList() {
4324199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            return mPropertyValueList;
4334199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
4344199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
4354199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public void clear() {
4364199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mPropertyName = null;
4374199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mParameterMap.clear();
4384199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mPropertyValueList.clear();
4394199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mPropertyBytes = null;
4404199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
44148dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa
44248dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa        @Override
44348dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa        public String toString() {
44448dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa            return String.format("Name: %s, value: %s",
44548dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa                    mPropertyName, Arrays.toString(mPropertyValueList.toArray(new String[0])));
44648dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa        }
4474199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
4484199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
4494560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa    // TODO(dmiyakawa): vCard 4.0 logically has multiple formatted names and we need to
4504560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa    // select the most preferable one using PREF parameter.
4514560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa    //
4524560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa    // e.g. (based on rev.13)
4534560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa    // FN;PREF=1:John M. Doe
4544560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa    // FN;PREF=2:John Doe
4554560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa    // FN;PREF=3;John
4564560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa
4574199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private String mFamilyName;
4584199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private String mGivenName;
4594199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private String mMiddleName;
4604199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private String mPrefix;
4614199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private String mSuffix;
4624199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
4634199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    // Used only when no family nor given name is found.
4644199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private String mFormattedName;
4654199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
4664199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private String mPhoneticFamilyName;
4674199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private String mPhoneticGivenName;
4684199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private String mPhoneticMiddleName;
4694199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
4704199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private String mPhoneticFullName;
4714199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
4724199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private List<String> mNickNameList;
4734199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
4744199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private String mDisplayName;
4754199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
4764199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private String mBirthday;
477c13101ba38c929d91dcb68e21165c82c19af35d7Daisuke Miyakawa    private String mAnniversary;
4784199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
4794199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private List<String> mNoteList;
4804199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private List<PhoneData> mPhoneList;
4814199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private List<EmailData> mEmailList;
4824199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private List<PostalData> mPostalList;
4834199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private List<OrganizationData> mOrganizationList;
4844199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private List<ImData> mImList;
4854199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private List<PhotoData> mPhotoList;
4864199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private List<String> mWebsiteList;
48737634a0179f74431317f50d2ce493e3fad36f5a9Daisuke Miyakawa    private Set<String> mSipSet;
4884199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private List<List<String>> mAndroidCustomPropertyList;
4894199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
4904199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private final int mVCardType;
4914199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private final Account mAccount;
4924199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
49348dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa    private List<VCardEntry> mChildren;
49448dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa
49548dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa    public String getNameFieldDebugString() {
49648dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa        StringBuilder builder = new StringBuilder();
49748dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa        builder.append(String.format(
49848dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa                "Family: %s, Given: %s, Middle: %s, Prefix: %s, Suffix: %s\n",
49948dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa                        mFamilyName, mGivenName, mMiddleName, mPrefix, mSuffix));
50048dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa        builder.append(String.format(
50148dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa                "Phonetic Family: %s, Phonetyc Given: %s, Phonetic Middle: %s\n",
50248dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa                        mPhoneticFamilyName, mPhoneticGivenName, mPhoneticMiddleName));
50348dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa        builder.append(String.format("Phonetic Full: %s\n", mPhoneticFullName));
50448dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa        builder.append(String.format("Formatted: %s, Display Name: %s\n",
50548dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa                mFormattedName, mDisplayName));
50648dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa        if (mNickNameList != null) {
50748dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa            builder.append(String.format(
50848dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa                    "Nick names: %s\n", Arrays.toString(mNickNameList.toArray(new String[0]))));
50948dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa        }
51048dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa        return builder.toString();
51148dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa    }
51248dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa
51348dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa    private String getStringFromCollection(String name, Collection<?> collection) {
51448dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa        return collection != null ?
51548dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa                String.format("%s: %s\n", name, Arrays.toString(collection.toArray())) : "";
51648dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa    }
51748dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa
51848dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa    @Override
51948dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa    public String toString() {
52048dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa        StringBuilder builder = new StringBuilder();
52148dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa        builder.append("hash: " + hashCode() + "\n");
52248dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa        builder.append(getNameFieldDebugString());
52348dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa        builder.append(getStringFromCollection("phone", mPhoneList));
52448dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa        builder.append(getStringFromCollection("email", mEmailList));
52548dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa        builder.append(getStringFromCollection("postal", mPostalList));
52648dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa        builder.append(getStringFromCollection("note", mNoteList));
52748dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa        builder.append(getStringFromCollection("organization", mOrganizationList));
52848dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa        builder.append(getStringFromCollection("im", mImList));
52948dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa        builder.append(getStringFromCollection("photo", mPhotoList));
53048dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa        builder.append(getStringFromCollection("website", mWebsiteList));
53148dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa        builder.append(getStringFromCollection("sip", mSipSet));
53248dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa        if (mChildren != null) {
53348dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa            int size = mChildren.size();
53448dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa            int[] hashArray = new int[size];
53548dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa            for (int i = 0; i < size; i++) {
53648dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa                hashArray[i] = mChildren.get(i).hashCode();
53748dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa            }
53848dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa            builder.append("children: " + Arrays.toString(hashArray) + "\n");
53948dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa        }
54048dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa        return "[[" + builder.toString().trim() + "]]";
54148dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa    }
54248dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa
5434199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public VCardEntry() {
5444199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        this(VCardConfig.VCARD_TYPE_V21_GENERIC);
5454199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
5464199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
5474199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public VCardEntry(int vcardType) {
5484199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        this(vcardType, null);
5494199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
5504199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
5514199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public VCardEntry(int vcardType, Account account) {
5524199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        mVCardType = vcardType;
5534199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        mAccount = account;
5544199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
5554199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
5564199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private void addPhone(int type, String data, String label, boolean isPrimary) {
5574199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (mPhoneList == null) {
5584199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mPhoneList = new ArrayList<PhoneData>();
5594199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
5604199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        final StringBuilder builder = new StringBuilder();
5614199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        final String trimed = data.trim();
5624199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        final String formattedNumber;
5634199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (type == Phone.TYPE_PAGER || VCardConfig.refrainPhoneNumberFormatting(mVCardType)) {
5644199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            formattedNumber = trimed;
5654199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else {
5664199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            final int length = trimed.length();
5674199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            for (int i = 0; i < length; i++) {
5684199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                char ch = trimed.charAt(i);
5694199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                if (('0' <= ch && ch <= '9') || (i == 0 && ch == '+')) {
5704199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    builder.append(ch);
5714199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                }
5724199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
5734199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
5744199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            final int formattingType = VCardUtils.getPhoneNumberFormat(mVCardType);
5759919ad2126c06dbf2eb54a11e6158f87f316bc22Daisuke Miyakawa            formattedNumber = PhoneNumberUtilsPort.formatNumber(builder.toString(), formattingType);
5769919ad2126c06dbf2eb54a11e6158f87f316bc22Daisuke Miyakawa         }
5774199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        PhoneData phoneData = new PhoneData(type, formattedNumber, label, isPrimary);
5784199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        mPhoneList.add(phoneData);
5794199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
5804199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
5814199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private void addNickName(final String nickName) {
5824199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (mNickNameList == null) {
5834199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mNickNameList = new ArrayList<String>();
5844199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
5854199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        mNickNameList.add(nickName);
5864199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
5874199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
5884199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private void addEmail(int type, String data, String label, boolean isPrimary){
5894199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (mEmailList == null) {
5904199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mEmailList = new ArrayList<EmailData>();
5914199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
5924199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        mEmailList.add(new EmailData(type, data, label, isPrimary));
5934199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
5944199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
5954199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private void addPostal(int type, List<String> propValueList, String label, boolean isPrimary){
5964199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (mPostalList == null) {
5974199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mPostalList = new ArrayList<PostalData>(0);
5984199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
5994199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        mPostalList.add(new PostalData(type, propValueList, label, isPrimary));
6004199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
6014199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
6024199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    /**
60302117b3d19787ff65486b9f9db8abd338ae4c9f9Daisuke Miyakawa     * Should be called via {@link #handleOrgValue(int, List, Map, boolean)} or
6044199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa     * {@link #handleTitleValue(String)}.
6054199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa     */
6064199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private void addNewOrganization(int type, final String companyName,
6074199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            final String departmentName,
6084560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa            final String titleName,
6094560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa            final String phoneticName,
6104560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa            final boolean isPrimary) {
6114199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (mOrganizationList == null) {
6124199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mOrganizationList = new ArrayList<OrganizationData>();
6134199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
6144199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        mOrganizationList.add(new OrganizationData(type, companyName,
6154560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa                departmentName, titleName, phoneticName, isPrimary));
6164199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
6174199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
6184199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private static final List<String> sEmptyList =
6194199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            Collections.unmodifiableList(new ArrayList<String>(0));
6204199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
6214560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa    private String buildSinglePhoneticNameFromSortAsParam(Map<String, Collection<String>> paramMap) {
6224560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa        final Collection<String> sortAsCollection = paramMap.get(VCardConstants.PARAM_SORT_AS);
6234560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa        if (sortAsCollection != null && sortAsCollection.size() != 0) {
6244560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa            if (sortAsCollection.size() > 1) {
6254560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa                Log.w(LOG_TAG, "Incorrect multiple SORT_AS parameters detected: " +
6264560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa                        Arrays.toString(sortAsCollection.toArray()));
6274560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa            }
6284560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa            final List<String> sortNames =
6294560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa                    VCardUtils.constructListFromValue(sortAsCollection.iterator().next(),
6304560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa                            mVCardType);
6314560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa            final StringBuilder builder = new StringBuilder();
6324560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa            for (final String elem : sortNames) {
6334560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa                builder.append(elem);
6344560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa            }
6354560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa            return builder.toString();
6364560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa        } else {
6374560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa            return null;
6384560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa        }
6394560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa    }
6404560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa
6414199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    /**
6424199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa     * Set "ORG" related values to the appropriate data. If there's more than one
6434199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa     * {@link OrganizationData} objects, this input data are attached to the last one which
6444199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa     * does not have valid values (not including empty but only null). If there's no
6454199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa     * {@link OrganizationData} object, a new {@link OrganizationData} is created,
6464199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa     * whose title is set to null.
6474199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa     */
6484560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa    private void handleOrgValue(final int type, List<String> orgList,
6494560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa            Map<String, Collection<String>> paramMap, boolean isPrimary) {
6504560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa        final String phoneticName = buildSinglePhoneticNameFromSortAsParam(paramMap);
6514199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (orgList == null) {
6524199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            orgList = sEmptyList;
6534199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
6544199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        final String companyName;
6554199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        final String departmentName;
6564199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        final int size = orgList.size();
6574199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        switch (size) {
6584199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            case 0: {
6594199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                companyName = "";
6604199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                departmentName = null;
6614199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                break;
6624199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
6634199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            case 1: {
6644199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                companyName = orgList.get(0);
6654199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                departmentName = null;
6664199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                break;
6674199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
6684199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            default: {  // More than 1.
6694199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                companyName = orgList.get(0);
6704199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                // We're not sure which is the correct string for department.
6714199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                // In order to keep all the data, concatinate the rest of elements.
6724199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                StringBuilder builder = new StringBuilder();
6734199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                for (int i = 1; i < size; i++) {
6744199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    if (i > 1) {
6754199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        builder.append(' ');
6764199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    }
6774199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    builder.append(orgList.get(i));
6784199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                }
6794199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                departmentName = builder.toString();
6804199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
6814199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
6824199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (mOrganizationList == null) {
6834199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            // Create new first organization entry, with "null" title which may be
6844199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            // added via handleTitleValue().
6854560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa            addNewOrganization(type, companyName, departmentName, null, phoneticName, isPrimary);
6864199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            return;
6874199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
6884199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        for (OrganizationData organizationData : mOrganizationList) {
6894199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            // Not use TextUtils.isEmpty() since ORG was set but the elements might be empty.
6904199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            // e.g. "ORG;PREF:;" -> Both companyName and departmentName become empty but not null.
6914199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            if (organizationData.companyName == null &&
6924199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    organizationData.departmentName == null) {
6934199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                // Probably the "TITLE" property comes before the "ORG" property via
6944199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                // handleTitleLine().
6954199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                organizationData.companyName = companyName;
6964199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                organizationData.departmentName = departmentName;
6974199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                organizationData.isPrimary = isPrimary;
6984199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                return;
6994199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
7004199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
7014199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        // No OrganizatioData is available. Create another one, with "null" title, which may be
7024199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        // added via handleTitleValue().
7034560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa        addNewOrganization(type, companyName, departmentName, null, phoneticName, isPrimary);
7044199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
7054199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
7064199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    /**
7074199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa     * Set "title" value to the appropriate data. If there's more than one
7084199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa     * OrganizationData objects, this input is attached to the last one which does not
7094199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa     * have valid title value (not including empty but only null). If there's no
7104199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa     * OrganizationData object, a new OrganizationData is created, whose company name is
7114199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa     * set to null.
7124199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa     */
7134199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private void handleTitleValue(final String title) {
7144199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (mOrganizationList == null) {
7154199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            // Create new first organization entry, with "null" other info, which may be
7164199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            // added via handleOrgValue().
7174560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa            addNewOrganization(DEFAULT_ORGANIZATION_TYPE, null, null, title, null, false);
7184199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            return;
7194199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
7204199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        for (OrganizationData organizationData : mOrganizationList) {
7214199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            if (organizationData.titleName == null) {
7224199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                organizationData.titleName = title;
7234199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                return;
7244199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
7254199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
7264199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        // No Organization is available. Create another one, with "null" other info, which may be
7274199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        // added via handleOrgValue().
7284560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa        addNewOrganization(DEFAULT_ORGANIZATION_TYPE, null, null, title, null, false);
7294199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
7304199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
7314199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private void addIm(int protocol, String customProtocol, int type,
7324199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            String propValue, boolean isPrimary) {
7334199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (mImList == null) {
7344199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mImList = new ArrayList<ImData>();
7354199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
7364199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        mImList.add(new ImData(protocol, customProtocol, type, propValue, isPrimary));
7374199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
7384199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
7394199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private void addNote(final String note) {
7404199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (mNoteList == null) {
7414199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mNoteList = new ArrayList<String>(1);
7424199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
7434199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        mNoteList.add(note);
7444199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
7454199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
7464199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private void addPhotoBytes(String formatName, byte[] photoBytes, boolean isPrimary) {
7474199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (mPhotoList == null) {
7484199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mPhotoList = new ArrayList<PhotoData>(1);
7494199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
7504199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        final PhotoData photoData = new PhotoData(0, null, photoBytes, isPrimary);
7514199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        mPhotoList.add(photoData);
7524199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
7534199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
7544560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa    /**
7554560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa     * Tries to extract paramMap, constructs SORT-AS parameter values, and store them in
7564560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa     * appropriate phonetic name variables.
7574560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa     *
7584560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa     * This method does not care the vCard version. Even when we have SORT-AS parameters in
7594560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa     * invalid versions (i.e. 2.1 and 3.0), we scilently accept them so that we won't drop
7604560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa     * meaningful information. If we had this parameter in the N field of vCard 3.0, and
7614560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa     * the contact data also have SORT-STRING, we will prefer SORT-STRING, since it is
7624560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa     * regitimate property to be understood.
7634560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa     */
7644560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa    private void tryHandleSortAsName(final Map<String, Collection<String>> paramMap) {
7654560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa        if (VCardConfig.isVersion30(mVCardType) &&
7664560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa                !(TextUtils.isEmpty(mPhoneticFamilyName) &&
7674560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa                        TextUtils.isEmpty(mPhoneticMiddleName) &&
7684560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa                        TextUtils.isEmpty(mPhoneticGivenName))) {
7694560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa            return;
7704560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa        }
7714560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa
7724560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa        final Collection<String> sortAsCollection = paramMap.get(VCardConstants.PARAM_SORT_AS);
7734560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa        if (sortAsCollection != null && sortAsCollection.size() != 0) {
7744560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa            if (sortAsCollection.size() > 1) {
7754560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa                Log.w(LOG_TAG, "Incorrect multiple SORT_AS parameters detected: " +
7764560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa                        Arrays.toString(sortAsCollection.toArray()));
7774560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa            }
7784560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa            final List<String> sortNames =
7794560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa                    VCardUtils.constructListFromValue(sortAsCollection.iterator().next(),
7804560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa                            mVCardType);
7814560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa            int size = sortNames.size();
7824560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa            if (size > 3) {
7834560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa                size = 3;
7844560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa            }
7854560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa            switch (size) {
7864560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa            case 3: mPhoneticMiddleName = sortNames.get(2); //$FALL-THROUGH$
7874560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa            case 2: mPhoneticGivenName = sortNames.get(1); //$FALL-THROUGH$
7884560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa            default: mPhoneticFamilyName = sortNames.get(0); break;
7894560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa            }
7904560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa        }
7914560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa    }
7924560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa
7934199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    @SuppressWarnings("fallthrough")
7944560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa    private void handleNProperty(final List<String> paramValues,
7954560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa            Map<String, Collection<String>> paramMap) {
7964560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa        // in vCard 4.0, SORT-AS parameter is available.
7974560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa        tryHandleSortAsName(paramMap);
7984560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa
7994199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        // Family, Given, Middle, Prefix, Suffix. (1 - 5)
8004199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        int size;
8014560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa        if (paramValues == null || (size = paramValues.size()) < 1) {
8024199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            return;
8034199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
8044199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (size > 5) {
8054199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            size = 5;
8064199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
8074199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
8084199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        switch (size) {
8094560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa        // Fall-through.
8104560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa        case 5: mSuffix = paramValues.get(4);
8114560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa        case 4: mPrefix = paramValues.get(3);
8124560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa        case 3: mMiddleName = paramValues.get(2);
8134560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa        case 2: mGivenName = paramValues.get(1);
8144560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa        default: mFamilyName = paramValues.get(0);
8154199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
8164199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
8174199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
8184199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    /**
8194199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa     * Note: Some Japanese mobile phones use this field for phonetic name,
8204199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa     *       since vCard 2.1 does not have "SORT-STRING" type.
8214199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa     *       Also, in some cases, the field has some ';'s in it.
8224199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa     *       Assume the ';' means the same meaning in N property
8234199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa     */
8244199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    @SuppressWarnings("fallthrough")
8254199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private void handlePhoneticNameFromSound(List<String> elems) {
8264199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (!(TextUtils.isEmpty(mPhoneticFamilyName) &&
8274199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                TextUtils.isEmpty(mPhoneticMiddleName) &&
8284199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                TextUtils.isEmpty(mPhoneticGivenName))) {
8294199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            // This means the other properties like "X-PHONETIC-FIRST-NAME" was already found.
8304199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            // Ignore "SOUND;X-IRMC-N".
8314199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            return;
8324199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
8334199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
8344199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        int size;
8354199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (elems == null || (size = elems.size()) < 1) {
8364199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            return;
8374199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
8384199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
8394199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        // Assume that the order is "Family, Given, Middle".
8404199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        // This is not from specification but mere assumption. Some Japanese phones use this order.
8414199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (size > 3) {
8424199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            size = 3;
8434199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
8444199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
8454199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (elems.get(0).length() > 0) {
8464199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            boolean onlyFirstElemIsNonEmpty = true;
8474199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            for (int i = 1; i < size; i++) {
8484199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                if (elems.get(i).length() > 0) {
8494199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    onlyFirstElemIsNonEmpty = false;
8504199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    break;
8514199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                }
8524199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
8534199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            if (onlyFirstElemIsNonEmpty) {
8544199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                final String[] namesArray = elems.get(0).split(" ");
8554199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                final int nameArrayLength = namesArray.length;
8564199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                if (nameArrayLength == 3) {
8574199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    // Assume the string is "Family Middle Given".
8584199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    mPhoneticFamilyName = namesArray[0];
8594199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    mPhoneticMiddleName = namesArray[1];
8604199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    mPhoneticGivenName = namesArray[2];
8614199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                } else if (nameArrayLength == 2) {
8624199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    // Assume the string is "Family Given" based on the Japanese mobile
8634199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    // phones' preference.
8644199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    mPhoneticFamilyName = namesArray[0];
8654199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    mPhoneticGivenName = namesArray[1];
8664199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                } else {
8674199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    mPhoneticFullName = elems.get(0);
8684199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                }
8694199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                return;
8704199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
8714199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
8724199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
8734199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        switch (size) {
8744199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            // fallthrough
8754199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            case 3: mPhoneticMiddleName = elems.get(2);
8764199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            case 2: mPhoneticGivenName = elems.get(1);
8774199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            default: mPhoneticFamilyName = elems.get(0);
8784199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
8794199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
8804199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
8814199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public void addProperty(final Property property) {
8824199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        final String propName = property.mPropertyName;
8834199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        final Map<String, Collection<String>> paramMap = property.mParameterMap;
8844199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        final List<String> propValueList = property.mPropertyValueList;
8854199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        byte[] propBytes = property.mPropertyBytes;
8864199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
8874199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (propValueList.size() == 0) {
8884199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            return;
8894199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
8904199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        final String propValue = listToString(propValueList).trim();
8914199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
8924199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (propName.equals(VCardConstants.PROPERTY_VERSION)) {
8934199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            // vCard version. Ignore this.
8944199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else if (propName.equals(VCardConstants.PROPERTY_FN)) {
8954199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mFormattedName = propValue;
8964199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else if (propName.equals(VCardConstants.PROPERTY_NAME) && mFormattedName == null) {
8974199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            // Only in vCard 3.0. Use this if FN, which must exist in vCard 3.0 but may not
8984199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            // actually exist in the real vCard data, does not exist.
8994199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mFormattedName = propValue;
9004199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else if (propName.equals(VCardConstants.PROPERTY_N)) {
9014560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa            handleNProperty(propValueList, paramMap);
9024199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else if (propName.equals(VCardConstants.PROPERTY_SORT_STRING)) {
9034199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mPhoneticFullName = propValue;
9044199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else if (propName.equals(VCardConstants.PROPERTY_NICKNAME) ||
9054199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                propName.equals(VCardConstants.ImportOnly.PROPERTY_X_NICKNAME)) {
9064199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            addNickName(propValue);
9074199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else if (propName.equals(VCardConstants.PROPERTY_SOUND)) {
9084199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            Collection<String> typeCollection = paramMap.get(VCardConstants.PARAM_TYPE);
9094199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            if (typeCollection != null
9104199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    && typeCollection.contains(VCardConstants.PARAM_TYPE_X_IRMC_N)) {
9114199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                // As of 2009-10-08, Parser side does not split a property value into separated
9124199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                // values using ';' (in other words, propValueList.size() == 1),
9134199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                // which is correct behavior from the view of vCard 2.1.
9144199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                // But we want it to be separated, so do the separation here.
9154199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                final List<String> phoneticNameList =
9164560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa                        VCardUtils.constructListFromValue(propValue, mVCardType);
9174199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                handlePhoneticNameFromSound(phoneticNameList);
9184199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            } else {
9194199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                // Ignore this field since Android cannot understand what it is.
9204199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
9214199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else if (propName.equals(VCardConstants.PROPERTY_ADR)) {
9224199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            boolean valuesAreAllEmpty = true;
9234199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            for (String value : propValueList) {
9244199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                if (value.length() > 0) {
9254199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    valuesAreAllEmpty = false;
9264199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    break;
9274199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                }
9284199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
9294199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            if (valuesAreAllEmpty) {
9304199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                return;
9314199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
9324199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
9334199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            int type = -1;
9344199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            String label = "";
9354199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            boolean isPrimary = false;
93600b4b98ea94df7fa3f88ee9a623d60db0d4fc451Daisuke Miyakawa            final Collection<String> typeCollection = paramMap.get(VCardConstants.PARAM_TYPE);
9374199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            if (typeCollection != null) {
93800b4b98ea94df7fa3f88ee9a623d60db0d4fc451Daisuke Miyakawa                for (final String typeStringOrg : typeCollection) {
93900b4b98ea94df7fa3f88ee9a623d60db0d4fc451Daisuke Miyakawa                    final String typeStringUpperCase = typeStringOrg.toUpperCase();
94000b4b98ea94df7fa3f88ee9a623d60db0d4fc451Daisuke Miyakawa                    if (typeStringUpperCase.equals(VCardConstants.PARAM_TYPE_PREF)) {
9414199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        isPrimary = true;
94200b4b98ea94df7fa3f88ee9a623d60db0d4fc451Daisuke Miyakawa                    } else if (typeStringUpperCase.equals(VCardConstants.PARAM_TYPE_HOME)) {
9434199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        type = StructuredPostal.TYPE_HOME;
9444199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        label = "";
94500b4b98ea94df7fa3f88ee9a623d60db0d4fc451Daisuke Miyakawa                    } else if (typeStringUpperCase.equals(VCardConstants.PARAM_TYPE_WORK) ||
94600b4b98ea94df7fa3f88ee9a623d60db0d4fc451Daisuke Miyakawa                            typeStringUpperCase.equalsIgnoreCase(
94700b4b98ea94df7fa3f88ee9a623d60db0d4fc451Daisuke Miyakawa                                        VCardConstants.PARAM_EXTRA_TYPE_COMPANY)) {
9484199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        // "COMPANY" seems emitted by Windows Mobile, which is not
9494199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        // specifically supported by vCard 2.1. We assume this is same
9504199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        // as "WORK".
9514199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        type = StructuredPostal.TYPE_WORK;
9524199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        label = "";
95300b4b98ea94df7fa3f88ee9a623d60db0d4fc451Daisuke Miyakawa                    } else if (typeStringUpperCase.equals(VCardConstants.PARAM_ADR_TYPE_PARCEL) ||
95400b4b98ea94df7fa3f88ee9a623d60db0d4fc451Daisuke Miyakawa                            typeStringUpperCase.equals(VCardConstants.PARAM_ADR_TYPE_DOM) ||
95500b4b98ea94df7fa3f88ee9a623d60db0d4fc451Daisuke Miyakawa                            typeStringUpperCase.equals(VCardConstants.PARAM_ADR_TYPE_INTL)) {
9564199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        // We do not have any appropriate way to store this information.
95700b4b98ea94df7fa3f88ee9a623d60db0d4fc451Daisuke Miyakawa                    } else if (type < 0) {  // If no other type is specified before
9584199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        type = StructuredPostal.TYPE_CUSTOM;
95900b4b98ea94df7fa3f88ee9a623d60db0d4fc451Daisuke Miyakawa                        if (typeStringUpperCase.startsWith("X-")) {  // If X- or x-
96000b4b98ea94df7fa3f88ee9a623d60db0d4fc451Daisuke Miyakawa                            label = typeStringOrg.substring(2);
96100b4b98ea94df7fa3f88ee9a623d60db0d4fc451Daisuke Miyakawa                        } else {
96200b4b98ea94df7fa3f88ee9a623d60db0d4fc451Daisuke Miyakawa                            label = typeStringOrg;
96300b4b98ea94df7fa3f88ee9a623d60db0d4fc451Daisuke Miyakawa                        }
9644199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    }
9654199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                }
9664199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
9674199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            // We use "HOME" as default
9684199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            if (type < 0) {
9694199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                type = StructuredPostal.TYPE_HOME;
9704199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
9714199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
9724199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            addPostal(type, propValueList, label, isPrimary);
9734199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else if (propName.equals(VCardConstants.PROPERTY_EMAIL)) {
9744199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            int type = -1;
9754199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            String label = null;
9764199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            boolean isPrimary = false;
97700b4b98ea94df7fa3f88ee9a623d60db0d4fc451Daisuke Miyakawa            final Collection<String> typeCollection = paramMap.get(VCardConstants.PARAM_TYPE);
9784199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            if (typeCollection != null) {
97900b4b98ea94df7fa3f88ee9a623d60db0d4fc451Daisuke Miyakawa                for (final String typeStringOrg : typeCollection) {
98000b4b98ea94df7fa3f88ee9a623d60db0d4fc451Daisuke Miyakawa                    final String typeStringUpperCase = typeStringOrg.toUpperCase();
98100b4b98ea94df7fa3f88ee9a623d60db0d4fc451Daisuke Miyakawa                    if (typeStringUpperCase.equals(VCardConstants.PARAM_TYPE_PREF)) {
9824199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        isPrimary = true;
98300b4b98ea94df7fa3f88ee9a623d60db0d4fc451Daisuke Miyakawa                    } else if (typeStringUpperCase.equals(VCardConstants.PARAM_TYPE_HOME)) {
9844199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        type = Email.TYPE_HOME;
98500b4b98ea94df7fa3f88ee9a623d60db0d4fc451Daisuke Miyakawa                    } else if (typeStringUpperCase.equals(VCardConstants.PARAM_TYPE_WORK)) {
9864199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        type = Email.TYPE_WORK;
98700b4b98ea94df7fa3f88ee9a623d60db0d4fc451Daisuke Miyakawa                    } else if (typeStringUpperCase.equals(VCardConstants.PARAM_TYPE_CELL)) {
9884199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        type = Email.TYPE_MOBILE;
98900b4b98ea94df7fa3f88ee9a623d60db0d4fc451Daisuke Miyakawa                    } else if (type < 0) {  // If no other type is specified before
99000b4b98ea94df7fa3f88ee9a623d60db0d4fc451Daisuke Miyakawa                        if (typeStringUpperCase.startsWith("X-")) {  // If X- or x-
99100b4b98ea94df7fa3f88ee9a623d60db0d4fc451Daisuke Miyakawa                            label = typeStringOrg.substring(2);
99200b4b98ea94df7fa3f88ee9a623d60db0d4fc451Daisuke Miyakawa                        } else {
99300b4b98ea94df7fa3f88ee9a623d60db0d4fc451Daisuke Miyakawa                            label = typeStringOrg;
9944199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        }
9954199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        type = Email.TYPE_CUSTOM;
9964199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    }
9974199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                }
9984199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
9994199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            if (type < 0) {
10004199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                type = Email.TYPE_OTHER;
10014199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
10024199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            addEmail(type, propValue, label, isPrimary);
10034199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else if (propName.equals(VCardConstants.PROPERTY_ORG)) {
10044199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            // vCard specification does not specify other types.
10054199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            final int type = Organization.TYPE_WORK;
10064199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            boolean isPrimary = false;
10074199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            Collection<String> typeCollection = paramMap.get(VCardConstants.PARAM_TYPE);
10084199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            if (typeCollection != null) {
10094199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                for (String typeString : typeCollection) {
10104199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    if (typeString.equals(VCardConstants.PARAM_TYPE_PREF)) {
10114199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        isPrimary = true;
10124199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    }
10134199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                }
10144199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
10154560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa            handleOrgValue(type, propValueList, paramMap, isPrimary);
10164199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else if (propName.equals(VCardConstants.PROPERTY_TITLE)) {
10174199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            handleTitleValue(propValue);
10184199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else if (propName.equals(VCardConstants.PROPERTY_ROLE)) {
10194199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            // This conflicts with TITLE. Ignore for now...
10204199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            // handleTitleValue(propValue);
10214199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else if (propName.equals(VCardConstants.PROPERTY_PHOTO) ||
10224199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                propName.equals(VCardConstants.PROPERTY_LOGO)) {
10234199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            Collection<String> paramMapValue = paramMap.get("VALUE");
10244199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            if (paramMapValue != null && paramMapValue.contains("URL")) {
10254199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                // Currently we do not have appropriate example for testing this case.
10264199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            } else {
10274199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                final Collection<String> typeCollection = paramMap.get("TYPE");
10284199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                String formatName = null;
10294199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                boolean isPrimary = false;
10304199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                if (typeCollection != null) {
10314199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    for (String typeValue : typeCollection) {
10324199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        if (VCardConstants.PARAM_TYPE_PREF.equals(typeValue)) {
10334199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                            isPrimary = true;
10344199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        } else if (formatName == null){
10354199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                            formatName = typeValue;
10364199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        }
10374199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    }
10384199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                }
10394199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                addPhotoBytes(formatName, propBytes, isPrimary);
10404199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
10414199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else if (propName.equals(VCardConstants.PROPERTY_TEL)) {
104237634a0179f74431317f50d2ce493e3fad36f5a9Daisuke Miyakawa            final String phoneNumber;
104337634a0179f74431317f50d2ce493e3fad36f5a9Daisuke Miyakawa            if (VCardConfig.isVersion40(mVCardType)) {
104437634a0179f74431317f50d2ce493e3fad36f5a9Daisuke Miyakawa                // Given propValue is in URI format, not in phone number format used until
104537634a0179f74431317f50d2ce493e3fad36f5a9Daisuke Miyakawa                // vCard 3.0.
104637634a0179f74431317f50d2ce493e3fad36f5a9Daisuke Miyakawa                if (propValue.startsWith("sip:") ) {
104737634a0179f74431317f50d2ce493e3fad36f5a9Daisuke Miyakawa                    if (propValue.length() > 4) {
104837634a0179f74431317f50d2ce493e3fad36f5a9Daisuke Miyakawa                        if (mSipSet == null) {
104937634a0179f74431317f50d2ce493e3fad36f5a9Daisuke Miyakawa                            mSipSet = new LinkedHashSet<String>();
105037634a0179f74431317f50d2ce493e3fad36f5a9Daisuke Miyakawa                        }
105137634a0179f74431317f50d2ce493e3fad36f5a9Daisuke Miyakawa                        mSipSet.add(propValue.substring(4));
105237634a0179f74431317f50d2ce493e3fad36f5a9Daisuke Miyakawa                    }
105337634a0179f74431317f50d2ce493e3fad36f5a9Daisuke Miyakawa                    return;
105437634a0179f74431317f50d2ce493e3fad36f5a9Daisuke Miyakawa                } else if (propValue.startsWith("tel:")) {
105537634a0179f74431317f50d2ce493e3fad36f5a9Daisuke Miyakawa                    phoneNumber = propValue.substring(4);
105637634a0179f74431317f50d2ce493e3fad36f5a9Daisuke Miyakawa                } else {
105737634a0179f74431317f50d2ce493e3fad36f5a9Daisuke Miyakawa                    // We don't know appropriate way to handle the other schemas. Also,
105837634a0179f74431317f50d2ce493e3fad36f5a9Daisuke Miyakawa                    // we may still have non-URI phone number. To keep given data as much as
105937634a0179f74431317f50d2ce493e3fad36f5a9Daisuke Miyakawa                    // we can, just save original value here.
106037634a0179f74431317f50d2ce493e3fad36f5a9Daisuke Miyakawa                    phoneNumber = propValue;
106137634a0179f74431317f50d2ce493e3fad36f5a9Daisuke Miyakawa                }
106237634a0179f74431317f50d2ce493e3fad36f5a9Daisuke Miyakawa            } else {
106337634a0179f74431317f50d2ce493e3fad36f5a9Daisuke Miyakawa                phoneNumber = propValue;
106437634a0179f74431317f50d2ce493e3fad36f5a9Daisuke Miyakawa            }
106537634a0179f74431317f50d2ce493e3fad36f5a9Daisuke Miyakawa
106637634a0179f74431317f50d2ce493e3fad36f5a9Daisuke Miyakawa            if (propValue.length() == 0) {
106737634a0179f74431317f50d2ce493e3fad36f5a9Daisuke Miyakawa                return;
106837634a0179f74431317f50d2ce493e3fad36f5a9Daisuke Miyakawa            }
10694199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            final Collection<String> typeCollection = paramMap.get(VCardConstants.PARAM_TYPE);
10704199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            final Object typeObject =
107137634a0179f74431317f50d2ce493e3fad36f5a9Daisuke Miyakawa                    VCardUtils.getPhoneTypeFromStrings(typeCollection, phoneNumber);
10724199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            final int type;
10734199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            final String label;
10744199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            if (typeObject instanceof Integer) {
10754199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                type = (Integer)typeObject;
10764199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                label = null;
10774199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            } else {
10784199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                type = Phone.TYPE_CUSTOM;
10794199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                label = typeObject.toString();
10804199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
10814199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
10824199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            final boolean isPrimary;
108337634a0179f74431317f50d2ce493e3fad36f5a9Daisuke Miyakawa            if (typeCollection != null &&
108437634a0179f74431317f50d2ce493e3fad36f5a9Daisuke Miyakawa                    typeCollection.contains(VCardConstants.PARAM_TYPE_PREF)) {
10854199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                isPrimary = true;
10864199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            } else {
10874199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                isPrimary = false;
10884199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
108937634a0179f74431317f50d2ce493e3fad36f5a9Daisuke Miyakawa            addPhone(type, phoneNumber, label, isPrimary);
10904199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else if (propName.equals(VCardConstants.PROPERTY_X_SKYPE_PSTNNUMBER)) {
10914199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            // The phone number available via Skype.
10924199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            Collection<String> typeCollection = paramMap.get(VCardConstants.PARAM_TYPE);
10934199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            final int type = Phone.TYPE_OTHER;
10944199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            final boolean isPrimary;
109502117b3d19787ff65486b9f9db8abd338ae4c9f9Daisuke Miyakawa            if (typeCollection != null &&
109602117b3d19787ff65486b9f9db8abd338ae4c9f9Daisuke Miyakawa                    typeCollection.contains(VCardConstants.PARAM_TYPE_PREF)) {
10974199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                isPrimary = true;
10984199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            } else {
10994199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                isPrimary = false;
11004199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
11014199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            addPhone(type, propValue, null, isPrimary);
11024199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else if (sImMap.containsKey(propName)) {
11034199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            final int protocol = sImMap.get(propName);
11044199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            boolean isPrimary = false;
11054199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            int type = -1;
11064199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            final Collection<String> typeCollection = paramMap.get(VCardConstants.PARAM_TYPE);
11074199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            if (typeCollection != null) {
11084199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                for (String typeString : typeCollection) {
11094199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    if (typeString.equals(VCardConstants.PARAM_TYPE_PREF)) {
11104199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        isPrimary = true;
11114199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    } else if (type < 0) {
11124199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        if (typeString.equalsIgnoreCase(VCardConstants.PARAM_TYPE_HOME)) {
11134199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                            type = Im.TYPE_HOME;
11144199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        } else if (typeString.equalsIgnoreCase(VCardConstants.PARAM_TYPE_WORK)) {
11154199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                            type = Im.TYPE_WORK;
11164199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        }
11174199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    }
11184199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                }
11194199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
11204199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            if (type < 0) {
112106ae82316d0b5f7222a7a1d15b7d03df88fdea15Daisuke Miyakawa                type = Im.TYPE_HOME;
11224199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
11234199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            addIm(protocol, null, type, propValue, isPrimary);
11244199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else if (propName.equals(VCardConstants.PROPERTY_NOTE)) {
11254199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            addNote(propValue);
11264199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else if (propName.equals(VCardConstants.PROPERTY_URL)) {
11274199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            if (mWebsiteList == null) {
11284199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                mWebsiteList = new ArrayList<String>(1);
11294199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
11304199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mWebsiteList.add(propValue);
11314199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else if (propName.equals(VCardConstants.PROPERTY_BDAY)) {
11324199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mBirthday = propValue;
1133c13101ba38c929d91dcb68e21165c82c19af35d7Daisuke Miyakawa        } else if (propName.equals(VCardConstants.PROPERTY_ANNIVERSARY)) {
1134c13101ba38c929d91dcb68e21165c82c19af35d7Daisuke Miyakawa            mAnniversary = propValue;
11354199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else if (propName.equals(VCardConstants.PROPERTY_X_PHONETIC_FIRST_NAME)) {
11364199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mPhoneticGivenName = propValue;
11374199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else if (propName.equals(VCardConstants.PROPERTY_X_PHONETIC_MIDDLE_NAME)) {
11384199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mPhoneticMiddleName = propValue;
11394199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else if (propName.equals(VCardConstants.PROPERTY_X_PHONETIC_LAST_NAME)) {
11404199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mPhoneticFamilyName = propValue;
114188d0f1ef715f2e1209eba5d175b1b71c556fa8b0Daisuke Miyakawa        } else if (propName.equals(VCardConstants.PROPERTY_IMPP)) {
114288d0f1ef715f2e1209eba5d175b1b71c556fa8b0Daisuke Miyakawa            // See also RFC 4770 (for vCard 3.0)
114388d0f1ef715f2e1209eba5d175b1b71c556fa8b0Daisuke Miyakawa            if (propValue.startsWith("sip:") && propValue.length() > 4) {
114437634a0179f74431317f50d2ce493e3fad36f5a9Daisuke Miyakawa                if (mSipSet == null) {
114537634a0179f74431317f50d2ce493e3fad36f5a9Daisuke Miyakawa                    mSipSet = new LinkedHashSet<String>();
114688d0f1ef715f2e1209eba5d175b1b71c556fa8b0Daisuke Miyakawa                }
114737634a0179f74431317f50d2ce493e3fad36f5a9Daisuke Miyakawa                mSipSet.add(propValue.substring(4));
114888d0f1ef715f2e1209eba5d175b1b71c556fa8b0Daisuke Miyakawa            }
11495db8b7baeffb35191032789cb0b0d643b78f0120Daisuke Miyakawa        } else if (propName.equals(VCardConstants.PROPERTY_X_SIP)) {
11505db8b7baeffb35191032789cb0b0d643b78f0120Daisuke Miyakawa            if (!TextUtils.isEmpty(propValue)) {
115137634a0179f74431317f50d2ce493e3fad36f5a9Daisuke Miyakawa                if (mSipSet == null) {
115237634a0179f74431317f50d2ce493e3fad36f5a9Daisuke Miyakawa                    mSipSet = new LinkedHashSet<String>();
11535db8b7baeffb35191032789cb0b0d643b78f0120Daisuke Miyakawa                }
11540fc278de46840f89c01aa984de7565c1f97e3103Daisuke Miyakawa
115537634a0179f74431317f50d2ce493e3fad36f5a9Daisuke Miyakawa                if (propValue.startsWith("sip:")) {
115637634a0179f74431317f50d2ce493e3fad36f5a9Daisuke Miyakawa                    if (propValue.length() > 4) {
115737634a0179f74431317f50d2ce493e3fad36f5a9Daisuke Miyakawa                        mSipSet.add(propValue.substring(4));
115837634a0179f74431317f50d2ce493e3fad36f5a9Daisuke Miyakawa                    } else {
115937634a0179f74431317f50d2ce493e3fad36f5a9Daisuke Miyakawa                        // Empty sip value. Ignore.
116037634a0179f74431317f50d2ce493e3fad36f5a9Daisuke Miyakawa                    }
11610fc278de46840f89c01aa984de7565c1f97e3103Daisuke Miyakawa                } else {
116237634a0179f74431317f50d2ce493e3fad36f5a9Daisuke Miyakawa                    mSipSet.add(propValue);
11630fc278de46840f89c01aa984de7565c1f97e3103Daisuke Miyakawa                }
11645db8b7baeffb35191032789cb0b0d643b78f0120Daisuke Miyakawa            }
11654199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else if (propName.equals(VCardConstants.PROPERTY_X_ANDROID_CUSTOM)) {
11664199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            final List<String> customPropertyList =
11674560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa                VCardUtils.constructListFromValue(propValue, mVCardType);
11684199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            handleAndroidCustomProperty(customPropertyList);
11694199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else {
11704199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
117137634a0179f74431317f50d2ce493e3fad36f5a9Daisuke Miyakawa        // Be careful when adding some logic here, as some blocks above may use "return".
11724199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
11734199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
117448dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa    public void addChild(VCardEntry child) {
117548dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa        if (mChildren == null) {
117648dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa            mChildren = new ArrayList<VCardEntry>();
117748dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa        }
117848dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa        mChildren.add(child);
117948dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa    }
118048dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa
11814199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private void handleAndroidCustomProperty(final List<String> customPropertyList) {
11824199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (mAndroidCustomPropertyList == null) {
11834199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mAndroidCustomPropertyList = new ArrayList<List<String>>();
11844199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
11854199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        mAndroidCustomPropertyList.add(customPropertyList);
11864199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
11874199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
11884199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    /**
11894199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa     * Construct the display name. The constructed data must not be null.
11904199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa     */
11914199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private void constructDisplayName() {
11924199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        // FullName (created via "FN" or "NAME" field) is prefered.
11934199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (!TextUtils.isEmpty(mFormattedName)) {
11944199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mDisplayName = mFormattedName;
11954199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else if (!(TextUtils.isEmpty(mFamilyName) && TextUtils.isEmpty(mGivenName))) {
11964199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mDisplayName = VCardUtils.constructNameFromElements(mVCardType,
11974199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    mFamilyName, mMiddleName, mGivenName, mPrefix, mSuffix);
11984199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else if (!(TextUtils.isEmpty(mPhoneticFamilyName) &&
11994199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                TextUtils.isEmpty(mPhoneticGivenName))) {
12004199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mDisplayName = VCardUtils.constructNameFromElements(mVCardType,
12014199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    mPhoneticFamilyName, mPhoneticMiddleName, mPhoneticGivenName);
12024199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else if (mEmailList != null && mEmailList.size() > 0) {
12034199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mDisplayName = mEmailList.get(0).data;
12044199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else if (mPhoneList != null && mPhoneList.size() > 0) {
12054199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mDisplayName = mPhoneList.get(0).data;
12064199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else if (mPostalList != null && mPostalList.size() > 0) {
12074199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mDisplayName = mPostalList.get(0).getFormattedAddress(mVCardType);
12084199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else if (mOrganizationList != null && mOrganizationList.size() > 0) {
12094199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mDisplayName = mOrganizationList.get(0).getFormattedString();
12104199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
12114199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
12124199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (mDisplayName == null) {
12134199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mDisplayName = "";
12144199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
12154199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
12164199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
12174199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    /**
12184199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa     * Consolidate several fielsds (like mName) using name candidates,
12194199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa     */
12204199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public void consolidateFields() {
12214199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        constructDisplayName();
12224199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
12234199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (mPhoneticFullName != null) {
12244199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mPhoneticFullName = mPhoneticFullName.trim();
12254199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
12264199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
12274199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
122848dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa    private boolean isEmpty(Collection<?> collection) {
122948dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa        return (collection == null || collection.size() == 0);
123048dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa    }
123148dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa
123248dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa    public boolean isEmpty() {
123348dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa        // TODO: should implement iterator for all collections so that we can share iteration
123448dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa        // logic for isEmpty(), constructInsertOperations(), and toString()
123548dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa        // TODO: handle mAndroidCustomPropertyList appropriately. This logic is fragile.
123648dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa        return (nameFieldsAreEmpty() && isEmpty(mNickNameList) && isEmpty(mNoteList)
123748dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa                && isEmpty(mPhoneList) && isEmpty(mEmailList) && isEmpty(mPostalList)
123848dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa                && isEmpty(mOrganizationList) && isEmpty(mImList) && isEmpty(mPhotoList)
123948dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa                && isEmpty(mWebsiteList) && isEmpty(mSipSet)
124048dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa                && isEmpty(mAndroidCustomPropertyList)
124148dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa                && TextUtils.isEmpty(mBirthday) && TextUtils.isEmpty(mAnniversary));
124248dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa    }
124348dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa
1244f98084b727f30713a31ace82e63341a4fa2ae5d7Daisuke Miyakawa    /**
1245f98084b727f30713a31ace82e63341a4fa2ae5d7Daisuke Miyakawa     * Constructs the list of insert operation for this object.
1246f98084b727f30713a31ace82e63341a4fa2ae5d7Daisuke Miyakawa     *
1247f98084b727f30713a31ace82e63341a4fa2ae5d7Daisuke Miyakawa     * When the operationList argument is null, this method creates a new ArrayList and return it.
1248f98084b727f30713a31ace82e63341a4fa2ae5d7Daisuke Miyakawa     * The returned object is filled with new insert operations for this object. When operationList
1249f98084b727f30713a31ace82e63341a4fa2ae5d7Daisuke Miyakawa     * argument is not null, this method appends those new operations into the object instead
1250f98084b727f30713a31ace82e63341a4fa2ae5d7Daisuke Miyakawa     * of creating a new ArrayList.
1251f98084b727f30713a31ace82e63341a4fa2ae5d7Daisuke Miyakawa     *
1252f98084b727f30713a31ace82e63341a4fa2ae5d7Daisuke Miyakawa     * @param resolver {@link ContentResolver} object to be used in this method.
1253f98084b727f30713a31ace82e63341a4fa2ae5d7Daisuke Miyakawa     * @param operationList object to be filled. You can use this argument to concatinate
1254f98084b727f30713a31ace82e63341a4fa2ae5d7Daisuke Miyakawa     * operation lists. If null, this method creates a new array object.
1255f98084b727f30713a31ace82e63341a4fa2ae5d7Daisuke Miyakawa     * @return If operationList argument is null, new object with new insert operations.
1256f98084b727f30713a31ace82e63341a4fa2ae5d7Daisuke Miyakawa     * If it is not null, the operationList object with operations inserted by this method.
1257f98084b727f30713a31ace82e63341a4fa2ae5d7Daisuke Miyakawa     */
1258f98084b727f30713a31ace82e63341a4fa2ae5d7Daisuke Miyakawa    public ArrayList<ContentProviderOperation> constructInsertOperations(
1259f98084b727f30713a31ace82e63341a4fa2ae5d7Daisuke Miyakawa            ContentResolver resolver, ArrayList<ContentProviderOperation> operationList) {
1260f98084b727f30713a31ace82e63341a4fa2ae5d7Daisuke Miyakawa        if (operationList == null) {
1261f98084b727f30713a31ace82e63341a4fa2ae5d7Daisuke Miyakawa            operationList = new ArrayList<ContentProviderOperation>();
1262f98084b727f30713a31ace82e63341a4fa2ae5d7Daisuke Miyakawa        }
1263f98084b727f30713a31ace82e63341a4fa2ae5d7Daisuke Miyakawa
126448dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa        if (isEmpty()) {
126548dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa            return operationList;
126648dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa        }
126748dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa
1268f98084b727f30713a31ace82e63341a4fa2ae5d7Daisuke Miyakawa        final int backReferenceIndex = operationList.size();
1269f98084b727f30713a31ace82e63341a4fa2ae5d7Daisuke Miyakawa
12704199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        // After applying the batch the first result's Uri is returned so it is important that
1271f98084b727f30713a31ace82e63341a4fa2ae5d7Daisuke Miyakawa        // the RawContact is the first operation that gets inserted into the list.
12724199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        ContentProviderOperation.Builder builder =
1273f98084b727f30713a31ace82e63341a4fa2ae5d7Daisuke Miyakawa                ContentProviderOperation.newInsert(RawContacts.CONTENT_URI);
12744199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (mAccount != null) {
12754199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            builder.withValue(RawContacts.ACCOUNT_NAME, mAccount.name);
12764199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            builder.withValue(RawContacts.ACCOUNT_TYPE, mAccount.type);
12774199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else {
12784199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            builder.withValue(RawContacts.ACCOUNT_NAME, null);
12794199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            builder.withValue(RawContacts.ACCOUNT_TYPE, null);
12804199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
12814199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        operationList.add(builder.build());
12824199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
12834199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (!nameFieldsAreEmpty()) {
12844199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            builder = ContentProviderOperation.newInsert(Data.CONTENT_URI);
1285f98084b727f30713a31ace82e63341a4fa2ae5d7Daisuke Miyakawa            builder.withValueBackReference(StructuredName.RAW_CONTACT_ID, backReferenceIndex);
12864199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            builder.withValue(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE);
12874199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
12884199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            builder.withValue(StructuredName.GIVEN_NAME, mGivenName);
12894199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            builder.withValue(StructuredName.FAMILY_NAME, mFamilyName);
12904199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            builder.withValue(StructuredName.MIDDLE_NAME, mMiddleName);
12914199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            builder.withValue(StructuredName.PREFIX, mPrefix);
12924199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            builder.withValue(StructuredName.SUFFIX, mSuffix);
12934199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
12944199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            if (!(TextUtils.isEmpty(mPhoneticGivenName)
12954199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    && TextUtils.isEmpty(mPhoneticFamilyName)
12964199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    && TextUtils.isEmpty(mPhoneticMiddleName))) {
12974199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.withValue(StructuredName.PHONETIC_GIVEN_NAME, mPhoneticGivenName);
12984199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.withValue(StructuredName.PHONETIC_FAMILY_NAME, mPhoneticFamilyName);
12994199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.withValue(StructuredName.PHONETIC_MIDDLE_NAME, mPhoneticMiddleName);
13004199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            } else if (!TextUtils.isEmpty(mPhoneticFullName)) {
13014199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.withValue(StructuredName.PHONETIC_GIVEN_NAME, mPhoneticFullName);
13024199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
13034199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
13044199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            builder.withValue(StructuredName.DISPLAY_NAME, getDisplayName());
13054199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            operationList.add(builder.build());
13064199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
13074199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
13084199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (mNickNameList != null && mNickNameList.size() > 0) {
13094199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            for (String nickName : mNickNameList) {
13104199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder = ContentProviderOperation.newInsert(Data.CONTENT_URI);
1311f98084b727f30713a31ace82e63341a4fa2ae5d7Daisuke Miyakawa                builder.withValueBackReference(Nickname.RAW_CONTACT_ID, backReferenceIndex);
13124199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.withValue(Data.MIMETYPE, Nickname.CONTENT_ITEM_TYPE);
13134199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.withValue(Nickname.TYPE, Nickname.TYPE_DEFAULT);
13144199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.withValue(Nickname.NAME, nickName);
13154199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                operationList.add(builder.build());
13164199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
13174199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
13184199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
13194199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (mPhoneList != null) {
13204199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            for (PhoneData phoneData : mPhoneList) {
13214199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder = ContentProviderOperation.newInsert(Data.CONTENT_URI);
1322f98084b727f30713a31ace82e63341a4fa2ae5d7Daisuke Miyakawa                builder.withValueBackReference(Phone.RAW_CONTACT_ID, backReferenceIndex);
13234199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.withValue(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
13244199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
13254199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.withValue(Phone.TYPE, phoneData.type);
13264199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                if (phoneData.type == Phone.TYPE_CUSTOM) {
13274199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    builder.withValue(Phone.LABEL, phoneData.label);
13284199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                }
13294199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.withValue(Phone.NUMBER, phoneData.data);
13304199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                if (phoneData.isPrimary) {
13314199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    builder.withValue(Phone.IS_PRIMARY, 1);
13324199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                }
13334199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                operationList.add(builder.build());
13344199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
13354199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
13364199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
13374199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (mOrganizationList != null) {
13384199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            for (OrganizationData organizationData : mOrganizationList) {
13394199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder = ContentProviderOperation.newInsert(Data.CONTENT_URI);
1340f98084b727f30713a31ace82e63341a4fa2ae5d7Daisuke Miyakawa                builder.withValueBackReference(Organization.RAW_CONTACT_ID, backReferenceIndex);
13414199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.withValue(Data.MIMETYPE, Organization.CONTENT_ITEM_TYPE);
13424199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.withValue(Organization.TYPE, organizationData.type);
13434199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                if (organizationData.companyName != null) {
13444199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    builder.withValue(Organization.COMPANY, organizationData.companyName);
13454199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                }
13464199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                if (organizationData.departmentName != null) {
13474199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    builder.withValue(Organization.DEPARTMENT, organizationData.departmentName);
13484199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                }
13494199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                if (organizationData.titleName != null) {
13504199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    builder.withValue(Organization.TITLE, organizationData.titleName);
13514199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                }
13524560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa                if (organizationData.phoneticName != null) {
13534560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa                    builder.withValue(Organization.PHONETIC_NAME, organizationData.phoneticName);
13544560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa                }
13554199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                if (organizationData.isPrimary) {
13564199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    builder.withValue(Organization.IS_PRIMARY, 1);
13574199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                }
13584199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                operationList.add(builder.build());
13594199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
13604199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
13614199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
13624199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (mEmailList != null) {
13634199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            for (EmailData emailData : mEmailList) {
13644199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder = ContentProviderOperation.newInsert(Data.CONTENT_URI);
1365f98084b727f30713a31ace82e63341a4fa2ae5d7Daisuke Miyakawa                builder.withValueBackReference(Email.RAW_CONTACT_ID, backReferenceIndex);
13664199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.withValue(Data.MIMETYPE, Email.CONTENT_ITEM_TYPE);
13674199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
13684199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.withValue(Email.TYPE, emailData.type);
13694199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                if (emailData.type == Email.TYPE_CUSTOM) {
13704199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    builder.withValue(Email.LABEL, emailData.label);
13714199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                }
13724199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.withValue(Email.DATA, emailData.data);
13734199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                if (emailData.isPrimary) {
13744199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    builder.withValue(Data.IS_PRIMARY, 1);
13754199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                }
13764199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                operationList.add(builder.build());
13774199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
13784199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
13794199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
13804199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (mPostalList != null) {
13814199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            for (PostalData postalData : mPostalList) {
13824199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder = ContentProviderOperation.newInsert(Data.CONTENT_URI);
1383f98084b727f30713a31ace82e63341a4fa2ae5d7Daisuke Miyakawa                builder.withValueBackReference(Event.RAW_CONTACT_ID, backReferenceIndex);
13844199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                VCardUtils.insertStructuredPostalDataUsingContactsStruct(
13854199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        mVCardType, builder, postalData);
13864199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                operationList.add(builder.build());
13874199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
13884199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
13894199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
13904199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (mImList != null) {
13914199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            for (ImData imData : mImList) {
13924199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder = ContentProviderOperation.newInsert(Data.CONTENT_URI);
1393f98084b727f30713a31ace82e63341a4fa2ae5d7Daisuke Miyakawa                builder.withValueBackReference(Im.RAW_CONTACT_ID, backReferenceIndex);
13944199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.withValue(Data.MIMETYPE, Im.CONTENT_ITEM_TYPE);
13954199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.withValue(Im.TYPE, imData.type);
13964199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.withValue(Im.PROTOCOL, imData.protocol);
139706ae82316d0b5f7222a7a1d15b7d03df88fdea15Daisuke Miyakawa                builder.withValue(Im.DATA, imData.data);
13984199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                if (imData.protocol == Im.PROTOCOL_CUSTOM) {
13994199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    builder.withValue(Im.CUSTOM_PROTOCOL, imData.customProtocol);
14004199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                }
14014199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                if (imData.isPrimary) {
14024199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    builder.withValue(Data.IS_PRIMARY, 1);
14034199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                }
140406ae82316d0b5f7222a7a1d15b7d03df88fdea15Daisuke Miyakawa                operationList.add(builder.build());
14054199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
14064199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
14074199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
14084199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (mNoteList != null) {
14094199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            for (String note : mNoteList) {
14104199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder = ContentProviderOperation.newInsert(Data.CONTENT_URI);
1411f98084b727f30713a31ace82e63341a4fa2ae5d7Daisuke Miyakawa                builder.withValueBackReference(Note.RAW_CONTACT_ID, backReferenceIndex);
14124199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.withValue(Data.MIMETYPE, Note.CONTENT_ITEM_TYPE);
14134199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.withValue(Note.NOTE, note);
14144199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                operationList.add(builder.build());
14154199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
14164199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
14174199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
14184199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (mPhotoList != null) {
14194199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            for (PhotoData photoData : mPhotoList) {
14204199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder = ContentProviderOperation.newInsert(Data.CONTENT_URI);
1421f98084b727f30713a31ace82e63341a4fa2ae5d7Daisuke Miyakawa                builder.withValueBackReference(Photo.RAW_CONTACT_ID, backReferenceIndex);
14224199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.withValue(Data.MIMETYPE, Photo.CONTENT_ITEM_TYPE);
14234199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.withValue(Photo.PHOTO, photoData.photoBytes);
14244199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                if (photoData.isPrimary) {
14254199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    builder.withValue(Photo.IS_PRIMARY, 1);
14264199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                }
14274199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                operationList.add(builder.build());
14284199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
14294199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
14304199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
14314199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (mWebsiteList != null) {
14324199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            for (String website : mWebsiteList) {
14334199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder = ContentProviderOperation.newInsert(Data.CONTENT_URI);
1434f98084b727f30713a31ace82e63341a4fa2ae5d7Daisuke Miyakawa                builder.withValueBackReference(Website.RAW_CONTACT_ID, backReferenceIndex);
14354199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.withValue(Data.MIMETYPE, Website.CONTENT_ITEM_TYPE);
14364199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.withValue(Website.URL, website);
14374199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                // There's no information about the type of URL in vCard.
14384199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                // We use TYPE_HOMEPAGE for safety.
14394199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.withValue(Website.TYPE, Website.TYPE_HOMEPAGE);
14404199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                operationList.add(builder.build());
14414199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
14424199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
14434199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
14444199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (!TextUtils.isEmpty(mBirthday)) {
14454199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            builder = ContentProviderOperation.newInsert(Data.CONTENT_URI);
1446f98084b727f30713a31ace82e63341a4fa2ae5d7Daisuke Miyakawa            builder.withValueBackReference(Event.RAW_CONTACT_ID, backReferenceIndex);
14474199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            builder.withValue(Data.MIMETYPE, Event.CONTENT_ITEM_TYPE);
14484199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            builder.withValue(Event.START_DATE, mBirthday);
14494199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            builder.withValue(Event.TYPE, Event.TYPE_BIRTHDAY);
14504199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            operationList.add(builder.build());
14514199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
14524199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
1453c13101ba38c929d91dcb68e21165c82c19af35d7Daisuke Miyakawa        if (!TextUtils.isEmpty(mAnniversary)) {
1454c13101ba38c929d91dcb68e21165c82c19af35d7Daisuke Miyakawa            builder = ContentProviderOperation.newInsert(Data.CONTENT_URI);
1455f98084b727f30713a31ace82e63341a4fa2ae5d7Daisuke Miyakawa            builder.withValueBackReference(Event.RAW_CONTACT_ID, backReferenceIndex);
1456c13101ba38c929d91dcb68e21165c82c19af35d7Daisuke Miyakawa            builder.withValue(Data.MIMETYPE, Event.CONTENT_ITEM_TYPE);
145742f5f84d9d501893bc14702276f0300ca8230bb5Daisuke Miyakawa            builder.withValue(Event.START_DATE, mAnniversary);
1458c13101ba38c929d91dcb68e21165c82c19af35d7Daisuke Miyakawa            builder.withValue(Event.TYPE, Event.TYPE_ANNIVERSARY);
1459c13101ba38c929d91dcb68e21165c82c19af35d7Daisuke Miyakawa            operationList.add(builder.build());
1460c13101ba38c929d91dcb68e21165c82c19af35d7Daisuke Miyakawa        }
1461c13101ba38c929d91dcb68e21165c82c19af35d7Daisuke Miyakawa
146237634a0179f74431317f50d2ce493e3fad36f5a9Daisuke Miyakawa        if (mSipSet != null && !mSipSet.isEmpty()) {
146337634a0179f74431317f50d2ce493e3fad36f5a9Daisuke Miyakawa            for (String sipAddress : mSipSet) {
146488d0f1ef715f2e1209eba5d175b1b71c556fa8b0Daisuke Miyakawa                builder = ContentProviderOperation.newInsert(Data.CONTENT_URI);
1465f98084b727f30713a31ace82e63341a4fa2ae5d7Daisuke Miyakawa                builder.withValueBackReference(Event.RAW_CONTACT_ID, backReferenceIndex);
146688d0f1ef715f2e1209eba5d175b1b71c556fa8b0Daisuke Miyakawa                builder.withValue(Data.MIMETYPE, SipAddress.CONTENT_ITEM_TYPE);
146788d0f1ef715f2e1209eba5d175b1b71c556fa8b0Daisuke Miyakawa                builder.withValue(SipAddress.SIP_ADDRESS, sipAddress);
146888d0f1ef715f2e1209eba5d175b1b71c556fa8b0Daisuke Miyakawa                operationList.add(builder.build());
146988d0f1ef715f2e1209eba5d175b1b71c556fa8b0Daisuke Miyakawa            }
147088d0f1ef715f2e1209eba5d175b1b71c556fa8b0Daisuke Miyakawa        }
147188d0f1ef715f2e1209eba5d175b1b71c556fa8b0Daisuke Miyakawa
14724199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (mAndroidCustomPropertyList != null) {
14734199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            for (List<String> customPropertyList : mAndroidCustomPropertyList) {
14744199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                int size = customPropertyList.size();
14754199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                if (size < 2 || TextUtils.isEmpty(customPropertyList.get(0))) {
14764199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    continue;
14774199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                } else if (size > VCardConstants.MAX_DATA_COLUMN + 1) {
14784199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    size = VCardConstants.MAX_DATA_COLUMN + 1;
14794199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    customPropertyList =
1480f98084b727f30713a31ace82e63341a4fa2ae5d7Daisuke Miyakawa                            customPropertyList.subList(0, VCardConstants.MAX_DATA_COLUMN + 2);
14814199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                }
14824199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
14834199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                int i = 0;
14844199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                for (final String customPropertyValue : customPropertyList) {
14854199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    if (i == 0) {
14864199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        final String mimeType = customPropertyValue;
14874199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        builder = ContentProviderOperation.newInsert(Data.CONTENT_URI);
1488f98084b727f30713a31ace82e63341a4fa2ae5d7Daisuke Miyakawa                        builder.withValueBackReference(GroupMembership.RAW_CONTACT_ID,
1489f98084b727f30713a31ace82e63341a4fa2ae5d7Daisuke Miyakawa                                backReferenceIndex);
14904199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        builder.withValue(Data.MIMETYPE, mimeType);
14914199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    } else {  // 1 <= i && i <= MAX_DATA_COLUMNS
14924199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        if (!TextUtils.isEmpty(customPropertyValue)) {
14934199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                            builder.withValue("data" + i, customPropertyValue);
14944199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        }
14954199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    }
14964199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
14974199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    i++;
14984199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                }
14994199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                operationList.add(builder.build());
15004199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
15014199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
15024199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
1503f98084b727f30713a31ace82e63341a4fa2ae5d7Daisuke Miyakawa        return operationList;
15044199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
15054199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
15064199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public static VCardEntry buildFromResolver(ContentResolver resolver) {
15074199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        return buildFromResolver(resolver, Contacts.CONTENT_URI);
15084199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
15094199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
15104199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public static VCardEntry buildFromResolver(ContentResolver resolver, Uri uri) {
15114199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        return null;
15124199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
15134199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
15144199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private boolean nameFieldsAreEmpty() {
15154199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        return (TextUtils.isEmpty(mFamilyName)
15164199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                && TextUtils.isEmpty(mMiddleName)
15174199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                && TextUtils.isEmpty(mGivenName)
15184199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                && TextUtils.isEmpty(mPrefix)
15194199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                && TextUtils.isEmpty(mSuffix)
15204199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                && TextUtils.isEmpty(mFormattedName)
15214199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                && TextUtils.isEmpty(mPhoneticFamilyName)
15224199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                && TextUtils.isEmpty(mPhoneticMiddleName)
15234199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                && TextUtils.isEmpty(mPhoneticGivenName)
15244199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                && TextUtils.isEmpty(mPhoneticFullName));
15254199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
15264199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
15274199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public boolean isIgnorable() {
15284199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        return getDisplayName().length() == 0;
15294199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
15304199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
15314199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private String listToString(List<String> list){
15324199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        final int size = list.size();
15334199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (size > 1) {
15344199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            StringBuilder builder = new StringBuilder();
15354199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            int i = 0;
15364199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            for (String type : list) {
15374199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.append(type);
15384199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                if (i < size - 1) {
15394199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    builder.append(";");
15404199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                }
15414199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
15424199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            return builder.toString();
15434199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else if (size == 1) {
15444199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            return list.get(0);
15454199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else {
15464199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            return "";
15474199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
15484199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
15494199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
15504199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    // All getter methods should be used carefully, since they may change
15514199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    // in the future as of 2009-10-05, on which I cannot be sure this structure
15524199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    // is completely consolidated.
15534199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    //
15544199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    // Also note that these getter methods should be used only after
15554199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    // all properties being pushed into this object. If not, incorrect
15564199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    // value will "be stored in the local cache and" be returned to you.
15574199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
15584199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public String getFamilyName() {
15594199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        return mFamilyName;
15604199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
15614199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
15624199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public String getGivenName() {
15634199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        return mGivenName;
15644199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
15654199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
15664199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public String getMiddleName() {
15674199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        return mMiddleName;
15684199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
15694199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
15704199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public String getPrefix() {
15714199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        return mPrefix;
15724199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
15734199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
15744199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public String getSuffix() {
15754199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        return mSuffix;
15764199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
15774199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
15784199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public String getFullName() {
15794199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        return mFormattedName;
15804199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
15814199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
15824199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public String getPhoneticFamilyName() {
15834199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        return mPhoneticFamilyName;
15844199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
15854199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
15864199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public String getPhoneticGivenName() {
15874199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        return mPhoneticGivenName;
15884199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
15894199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
15904199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public String getPhoneticMiddleName() {
15914199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        return mPhoneticMiddleName;
15924199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
15934199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
15944199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public String getPhoneticFullName() {
15954199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        return mPhoneticFullName;
15964199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
15974199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
15984199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public final List<String> getNickNameList() {
15994199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        return mNickNameList;
16004199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
16014199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
16024199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public String getBirthday() {
16034199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        return mBirthday;
16044199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
16054199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
16064199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public final List<String> getNotes() {
16074199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        return mNoteList;
16084199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
16094199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
16104199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public final List<PhoneData> getPhoneList() {
16114199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        return mPhoneList;
16124199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
16134199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
16144199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public final List<EmailData> getEmailList() {
16154199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        return mEmailList;
16164199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
16174199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
16184199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public final List<PostalData> getPostalList() {
16194199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        return mPostalList;
16204199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
16214199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
16224199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public final List<OrganizationData> getOrganizationList() {
16234199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        return mOrganizationList;
16244199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
16254199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
16264199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public final List<ImData> getImList() {
16274199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        return mImList;
16284199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
16294199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
16304199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public final List<PhotoData> getPhotoList() {
16314199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        return mPhotoList;
16324199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
16334199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
16344199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public final List<String> getWebsiteList() {
16354199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        return mWebsiteList;
16364199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
16374199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
163848dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa    /**
163948dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa     * @hide this interface may be changed for better support of vCard 4.0 (UID)
164048dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa     */
164148dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa    public final List<VCardEntry> getChildlen() {
164248dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa        return mChildren;
164348dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa    }
164448dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa
16454199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public String getDisplayName() {
16464199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (mDisplayName == null) {
16474199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            constructDisplayName();
16484199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
16494199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        return mDisplayName;
16504199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
16514199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa}
1652