diff --git a/core/java/android/syncml/package.html b/core/java/android/syncml/package.html
deleted file mode 100644
index cb4ca46..0000000
--- a/core/java/android/syncml/package.html
+++ /dev/null
@@ -1,6 +0,0 @@
-<HTML>
-<BODY>
-Support classes for SyncML.
-{@hide}
-</BODY>
-</HTML>
\ No newline at end of file
diff --git a/core/java/android/syncml/pim/PropertyNode.java b/core/java/android/syncml/pim/PropertyNode.java
deleted file mode 100644
index 3a5c994..0000000
--- a/core/java/android/syncml/pim/PropertyNode.java
+++ /dev/null
@@ -1,324 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.syncml.pim;
-
-import android.content.ContentValues;
-
-import org.apache.commons.codec.binary.Base64;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import java.util.Map.Entry;
-import java.util.regex.Pattern;
-
-@Deprecated
-public class PropertyNode {
-
-    public String propName;
-
-    public String propValue;
-
-    public List<String> propValue_vector;
-
-    /** Store value as byte[],after decode.
-     * Used when propValue is encoded by something like BASE64, QUOTED-PRINTABLE, etc.
-     */
-    public byte[] propValue_bytes;
-
-    /** param store: key=paramType, value=paramValue
-     * Note that currently PropertyNode class does not support multiple param-values
-     * defined in vCard 3.0 (See also RFC 2426). multiple-values are stored as
-     * one String value like "A,B", not ["A", "B"]...
-     * TODO: fix this. 
-     */
-    public ContentValues paramMap;
-
-    /** Only for TYPE=??? param store. */
-    public Set<String> paramMap_TYPE;
-
-    /** Store group values. Used only in VCard. */
-    public Set<String> propGroupSet;
-    
-    public PropertyNode() {
-        propName = "";
-        propValue = "";
-        propValue_vector = new ArrayList<String>();
-        paramMap = new ContentValues();
-        paramMap_TYPE = new HashSet<String>();
-        propGroupSet = new HashSet<String>();
-    }
-    
-    public PropertyNode(
-            String propName, String propValue, List<String> propValue_vector,
-            byte[] propValue_bytes, ContentValues paramMap, Set<String> paramMap_TYPE,
-            Set<String> propGroupSet) {
-        if (propName != null) {
-            this.propName = propName;
-        } else {
-            this.propName = "";
-        }
-        if (propValue != null) {
-            this.propValue = propValue;
-        } else {
-            this.propValue = "";
-        }
-        if (propValue_vector != null) {
-            this.propValue_vector = propValue_vector;
-        } else {
-            this.propValue_vector = new ArrayList<String>();
-        }
-        this.propValue_bytes = propValue_bytes;
-        if (paramMap != null) {
-            this.paramMap = paramMap;
-        } else {
-            this.paramMap = new ContentValues();
-        }
-        if (paramMap_TYPE != null) {
-            this.paramMap_TYPE = paramMap_TYPE;
-        } else {
-            this.paramMap_TYPE = new HashSet<String>();
-        }
-        if (propGroupSet != null) {
-            this.propGroupSet = propGroupSet;
-        } else {
-            this.propGroupSet = new HashSet<String>();
-        }
-    }
-    
-    @Override
-    public boolean equals(Object obj) {
-        if (!(obj instanceof PropertyNode)) {
-            return false;
-        }
-        
-        PropertyNode node = (PropertyNode)obj;
-        
-        if (propName == null || !propName.equals(node.propName)) {
-            return false;
-        } else if (!paramMap.equals(node.paramMap)) {
-            return false;
-        } else if (!paramMap_TYPE.equals(node.paramMap_TYPE)) {
-            return false;
-        } else if (!propGroupSet.equals(node.propGroupSet)) {
-            return false;
-        }
-        
-        if (propValue_bytes != null && Arrays.equals(propValue_bytes, node.propValue_bytes)) {
-            return true;
-        } else {
-            // Log.d("@@@", propValue + ", " + node.propValue);
-            if (!propValue.equals(node.propValue)) {
-                return false;
-            }
-
-            // The value in propValue_vector is not decoded even if it should be
-            // decoded by BASE64 or QUOTED-PRINTABLE. When the size of propValue_vector
-            // is 1, the encoded value is stored in propValue, so we do not have to
-            // check it.
-            return (propValue_vector.equals(node.propValue_vector) ||
-                    propValue_vector.size() == 1 ||
-                    node.propValue_vector.size() == 1);
-        }
-    }
-    
-    @Override
-    public String toString() {
-        StringBuilder builder = new StringBuilder();
-        builder.append("propName: ");
-        builder.append(propName);
-        builder.append(", paramMap: ");
-        builder.append(paramMap.toString());
-        builder.append(", propmMap_TYPE: ");
-        builder.append(paramMap_TYPE.toString());
-        builder.append(", propGroupSet: ");
-        builder.append(propGroupSet.toString());
-        if (propValue_vector != null && propValue_vector.size() > 1) {
-            builder.append(", propValue_vector size: ");
-            builder.append(propValue_vector.size());
-        }
-        if (propValue_bytes != null) {
-            builder.append(", propValue_bytes size: ");
-            builder.append(propValue_bytes.length);
-        }
-        builder.append(", propValue: ");
-        builder.append(propValue);
-        return builder.toString();
-    }
-    
-    /**
-     * Encode this object into a string which can be decoded. 
-     */
-    public String encode() {
-        // PropertyNode#toString() is for reading, not for parsing in the future.
-        // We construct appropriate String here.
-        StringBuilder builder = new StringBuilder();
-        if (propName.length() > 0) {
-            builder.append("propName:[");
-            builder.append(propName);
-            builder.append("],");
-        }
-        int size = propGroupSet.size();
-        if (size > 0) {
-            Set<String> set = propGroupSet;
-            builder.append("propGroup:[");
-            int i = 0;
-            for (String group : set) {
-                // We do not need to double quote groups.
-                // group        = 1*(ALPHA / DIGIT / "-")
-                builder.append(group);
-                if (i < size - 1) {
-                    builder.append(",");
-                }
-                i++;
-            }
-            builder.append("],");
-        }
-
-        if (paramMap.size() > 0 || paramMap_TYPE.size() > 0) {
-            ContentValues values = paramMap;
-            builder.append("paramMap:[");
-            size = paramMap.size(); 
-            int i = 0;
-            for (Entry<String, Object> entry : values.valueSet()) {
-                // Assuming param-key does not contain NON-ASCII nor symbols.
-                //
-                // According to vCard 3.0:
-                // param-name   = iana-token / x-name
-                builder.append(entry.getKey());
-
-                // param-value may contain any value including NON-ASCIIs.
-                // We use the following replacing rule.
-                // \ -> \\
-                // , -> \,
-                // In String#replaceAll(), "\\\\" means a single backslash.
-                builder.append("=");
-                builder.append(entry.getValue().toString()
-                        .replaceAll("\\\\", "\\\\\\\\")
-                        .replaceAll(",", "\\\\,"));
-                if (i < size -1) {
-                    builder.append(",");
-                }
-                i++;
-            }
-
-            Set<String> set = paramMap_TYPE;
-            size = paramMap_TYPE.size();
-            if (i > 0 && size > 0) {
-                builder.append(",");
-            }
-            i = 0;
-            for (String type : set) {
-                builder.append("TYPE=");
-                builder.append(type
-                        .replaceAll("\\\\", "\\\\\\\\")
-                        .replaceAll(",", "\\\\,"));
-                if (i < size - 1) {
-                    builder.append(",");
-                }
-                i++;
-            }
-            builder.append("],");
-        }
-
-        size = propValue_vector.size();
-        if (size > 0) {
-            builder.append("propValue:[");
-            List<String> list = propValue_vector;
-            for (int i = 0; i < size; i++) {
-                builder.append(list.get(i)
-                        .replaceAll("\\\\", "\\\\\\\\")
-                        .replaceAll(",", "\\\\,"));
-                if (i < size -1) {
-                    builder.append(",");
-                }
-            }
-            builder.append("],");
-        }
-
-        return builder.toString();
-    }
-
-    public static PropertyNode decode(String encodedString) {
-        PropertyNode propertyNode = new PropertyNode();
-        String trimed = encodedString.trim();
-        if (trimed.length() == 0) {
-            return propertyNode;
-        }
-        String[] elems = trimed.split("],");
-        
-        for (String elem : elems) {
-            int index = elem.indexOf('[');
-            String name = elem.substring(0, index - 1);
-            Pattern pattern = Pattern.compile("(?<!\\\\),");
-            String[] values = pattern.split(elem.substring(index + 1), -1);
-            if (name.equals("propName")) {
-                propertyNode.propName = values[0];
-            } else if (name.equals("propGroupSet")) {
-                for (String value : values) {
-                    propertyNode.propGroupSet.add(value);
-                }
-            } else if (name.equals("paramMap")) {
-                ContentValues paramMap = propertyNode.paramMap;
-                Set<String> paramMap_TYPE = propertyNode.paramMap_TYPE;
-                for (String value : values) {
-                    String[] tmp = value.split("=", 2);
-                    String mapKey = tmp[0];
-                    // \, -> ,
-                    // \\ -> \
-                    // In String#replaceAll(), "\\\\" means a single backslash.
-                    String mapValue =
-                        tmp[1].replaceAll("\\\\,", ",").replaceAll("\\\\\\\\", "\\\\");
-                    if (mapKey.equalsIgnoreCase("TYPE")) {
-                        paramMap_TYPE.add(mapValue);
-                    } else {
-                        paramMap.put(mapKey, mapValue);
-                    }
-                }
-            } else if (name.equals("propValue")) {
-                StringBuilder builder = new StringBuilder();
-                List<String> list = propertyNode.propValue_vector;
-                int length = values.length;
-                for (int i = 0; i < length; i++) {
-                    String normValue = values[i]
-                                              .replaceAll("\\\\,", ",")
-                                              .replaceAll("\\\\\\\\", "\\\\");
-                    list.add(normValue);
-                    builder.append(normValue);
-                    if (i < length - 1) {
-                        builder.append(";");
-                    }
-                }
-                propertyNode.propValue = builder.toString();
-            }
-        }
-        
-        // At this time, QUOTED-PRINTABLE is already decoded to Java String.
-        // We just need to decode BASE64 String to binary.
-        String encoding = propertyNode.paramMap.getAsString("ENCODING");
-        if (encoding != null &&
-                (encoding.equalsIgnoreCase("BASE64") ||
-                        encoding.equalsIgnoreCase("B"))) {
-            propertyNode.propValue_bytes =
-                Base64.decodeBase64(propertyNode.propValue_vector.get(0).getBytes());
-        }
-        
-        return propertyNode;
-    }
-}
diff --git a/core/java/android/syncml/pim/VBuilder.java b/core/java/android/syncml/pim/VBuilder.java
deleted file mode 100644
index b6cb674..0000000
--- a/core/java/android/syncml/pim/VBuilder.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.syncml.pim;
-
-import java.util.List;
-
-@Deprecated
-public interface VBuilder {
-    void start();
-
-    void end();
-
-    /**
-     * @param type
-     *            VXX <br>
-     *            BEGIN:VXX
-     */
-    void startRecord(String type);
-
-    /** END:VXX */
-    void endRecord();
-
-    void startProperty();
-
-    void endProperty();
-
-    /**
-     * @param group 
-     */
-    void propertyGroup(String group);
-    
-    /**
-     * @param name
-     *            N <br>
-     *            N
-     */
-    void propertyName(String name);
-
-    /**
-     * @param type
-     *            LANGUAGE \ ENCODING <br>
-     *            ;LANGUage= \ ;ENCODING=
-     */
-    void propertyParamType(String type);
-
-    /**
-     * @param value
-     *            FR-EN \ GBK <br>
-     *            FR-EN \ GBK
-     */
-    void propertyParamValue(String value);
-
-    void propertyValues(List<String> values);
-}
diff --git a/core/java/android/syncml/pim/VBuilderCollection.java b/core/java/android/syncml/pim/VBuilderCollection.java
deleted file mode 100644
index 06e3100..0000000
--- a/core/java/android/syncml/pim/VBuilderCollection.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.syncml.pim;
-
-import java.util.Collection;
-import java.util.List;
-
-@Deprecated
-public class VBuilderCollection implements VBuilder {
-
-    private final Collection<VBuilder> mVBuilderCollection;
-    
-    public VBuilderCollection(Collection<VBuilder> vBuilderCollection) {
-        mVBuilderCollection = vBuilderCollection; 
-    }
-    
-    public Collection<VBuilder> getVBuilderCollection() {
-        return mVBuilderCollection;
-    }
-    
-    public void start() {
-        for (VBuilder builder : mVBuilderCollection) {
-            builder.start();
-        }
-    }
-    
-    public void end() {
-        for (VBuilder builder : mVBuilderCollection) {
-            builder.end();
-        }
-    }
-
-    public void startRecord(String type) {
-        for (VBuilder builder : mVBuilderCollection) {
-            builder.startRecord(type);
-        }
-    }
-    
-    public void endRecord() {
-        for (VBuilder builder : mVBuilderCollection) {
-            builder.endRecord();
-        }
-    }
-
-    public void startProperty() {
-        for (VBuilder builder : mVBuilderCollection) {
-            builder.startProperty();
-        }
-    }
-
-    
-    public void endProperty() {
-        for (VBuilder builder : mVBuilderCollection) {
-            builder.endProperty();
-        }
-    }
-
-    public void propertyGroup(String group) {
-        for (VBuilder builder : mVBuilderCollection) {
-            builder.propertyGroup(group);
-        }
-    }
-
-    public void propertyName(String name) {
-        for (VBuilder builder : mVBuilderCollection) {
-            builder.propertyName(name);
-        }
-    }
-
-    public void propertyParamType(String type) {
-        for (VBuilder builder : mVBuilderCollection) {
-            builder.propertyParamType(type);
-        }
-    }
-
-    public void propertyParamValue(String value) {
-        for (VBuilder builder : mVBuilderCollection) {
-            builder.propertyParamValue(value);
-        }
-    }
-
-    public void propertyValues(List<String> values) {
-        for (VBuilder builder : mVBuilderCollection) {
-            builder.propertyValues(values);
-        }
-    }
-}
diff --git a/core/java/android/syncml/pim/VDataBuilder.java b/core/java/android/syncml/pim/VDataBuilder.java
deleted file mode 100644
index db8a299..0000000
--- a/core/java/android/syncml/pim/VDataBuilder.java
+++ /dev/null
@@ -1,312 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.syncml.pim;
-
-import android.content.ContentValues;
-import android.util.CharsetUtils;
-import android.util.Log;
-
-import org.apache.commons.codec.DecoderException;
-import org.apache.commons.codec.binary.Base64;
-import org.apache.commons.codec.net.QuotedPrintableCodec;
-
-import java.io.UnsupportedEncodingException;
-import java.nio.ByteBuffer;
-import java.nio.charset.Charset;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Store the parse result to custom datastruct: VNode, PropertyNode
- * Maybe several vcard instance, so use vNodeList to store.
- * VNode: standy by a vcard instance.
- * PropertyNode: standy by a property line of a card.
- */
-@Deprecated
-public class VDataBuilder implements VBuilder {
-    static private String LOG_TAG = "VDATABuilder"; 
-    
-    /**
-     * If there's no other information available, this class uses this charset for encoding
-     * byte arrays.
-     */
-    static public String DEFAULT_CHARSET = "UTF-8"; 
-    
-    /** type=VNode */
-    public List<VNode> vNodeList = new ArrayList<VNode>();
-    private int mNodeListPos = 0;
-    private VNode mCurrentVNode;
-    private PropertyNode mCurrentPropNode;
-    private String mCurrentParamType;
-    
-    /**
-     * The charset using which VParser parses the text.
-     */
-    private String mSourceCharset;
-    
-    /**
-     * The charset with which byte array is encoded to String.
-     */
-    private String mTargetCharset;
-    
-    private boolean mStrictLineBreakParsing;
-    
-    public VDataBuilder() {
-        this(VParser.DEFAULT_CHARSET, DEFAULT_CHARSET, false);
-    }
-
-    public VDataBuilder(String charset, boolean strictLineBreakParsing) {
-        this(null, charset, strictLineBreakParsing);
-    }
-    
-    /**
-     * @hide sourceCharset is temporal. 
-     */
-    public VDataBuilder(String sourceCharset, String targetCharset,
-            boolean strictLineBreakParsing) {
-        if (sourceCharset != null) {
-            mSourceCharset = sourceCharset;
-        } else {
-            mSourceCharset = VParser.DEFAULT_CHARSET;
-        }
-        if (targetCharset != null) {
-            mTargetCharset = targetCharset;
-        } else {
-            mTargetCharset = DEFAULT_CHARSET;
-        }
-        mStrictLineBreakParsing = strictLineBreakParsing;
-    }
-
-    public void start() {
-    }
-
-    public void end() {
-    }
-
-    // Note: I guess that this code assumes the Record may nest like this:
-    // START:VPOS
-    // ...
-    // START:VPOS2
-    // ...
-    // END:VPOS2
-    // ...
-    // END:VPOS
-    //
-    // However the following code has a bug.
-    // When error occurs after calling startRecord(), the entry which is probably
-    // the cause of the error remains to be in vNodeList, while endRecord() is not called.
-    //
-    // I leave this code as is since I'm not familiar with vcalendar specification.
-    // But I believe we should refactor this code in the future.
-    // Until this, the last entry has to be removed when some error occurs.
-    public void startRecord(String type) {
-        
-        VNode vnode = new VNode();
-        vnode.parseStatus = 1;
-        vnode.VName = type;
-        // I feel this should be done in endRecord(), but it cannot be done because of
-        // the reason above.
-        vNodeList.add(vnode);
-        mNodeListPos = vNodeList.size() - 1;
-        mCurrentVNode = vNodeList.get(mNodeListPos);
-    }
-
-    public void endRecord() {
-        VNode endNode = vNodeList.get(mNodeListPos);
-        endNode.parseStatus = 0;
-        while(mNodeListPos > 0){
-            mNodeListPos--;
-            if((vNodeList.get(mNodeListPos)).parseStatus == 1)
-                break;
-        }
-        mCurrentVNode = vNodeList.get(mNodeListPos);
-    }
-
-    public void startProperty() {
-        mCurrentPropNode = new PropertyNode();
-    }
-
-    public void endProperty() {
-        mCurrentVNode.propList.add(mCurrentPropNode);
-    }
-    
-    public void propertyName(String name) {
-        mCurrentPropNode.propName = name;
-    }
-
-    // Used only in VCard.
-    public void propertyGroup(String group) {
-        mCurrentPropNode.propGroupSet.add(group);
-    }
-    
-    public void propertyParamType(String type) {
-        mCurrentParamType = type;
-    }
-
-    public void propertyParamValue(String value) {
-        if (mCurrentParamType == null ||
-                mCurrentParamType.equalsIgnoreCase("TYPE")) {
-            mCurrentPropNode.paramMap_TYPE.add(value);
-        } else {
-            mCurrentPropNode.paramMap.put(mCurrentParamType, value);
-        }
-
-        mCurrentParamType = null;
-    }
-
-    private String encodeString(String originalString, String targetCharset) {
-        if (mSourceCharset.equalsIgnoreCase(targetCharset)) {
-            return originalString;
-        }
-        Charset charset = Charset.forName(mSourceCharset);
-        ByteBuffer byteBuffer = charset.encode(originalString);
-        // byteBuffer.array() "may" return byte array which is larger than
-        // byteBuffer.remaining(). Here, we keep on the safe side.
-        byte[] bytes = new byte[byteBuffer.remaining()];
-        byteBuffer.get(bytes);
-        try {
-            return new String(bytes, targetCharset);
-        } catch (UnsupportedEncodingException e) {
-            Log.e(LOG_TAG, "Failed to encode: charset=" + targetCharset);
-            return new String(bytes);
-        }
-    }
-    
-    private String handleOneValue(String value, String targetCharset, String encoding) {
-        if (encoding != null) {
-            if (encoding.equals("BASE64") || encoding.equals("B")) {
-                // Assume BASE64 is used only when the number of values is 1.
-                mCurrentPropNode.propValue_bytes =
-                    Base64.decodeBase64(value.getBytes());
-                return value;
-            } else if (encoding.equals("QUOTED-PRINTABLE")) {
-                String quotedPrintable = value
-                .replaceAll("= ", " ").replaceAll("=\t", "\t");
-                String[] lines;
-                if (mStrictLineBreakParsing) {
-                    lines = quotedPrintable.split("\r\n");
-                } else {
-                    StringBuilder builder = new StringBuilder();
-                    int length = quotedPrintable.length();
-                    ArrayList<String> list = new ArrayList<String>();
-                    for (int i = 0; i < length; i++) {
-                        char ch = quotedPrintable.charAt(i);
-                        if (ch == '\n') {
-                            list.add(builder.toString());
-                            builder = new StringBuilder();
-                        } else if (ch == '\r') {
-                            list.add(builder.toString());
-                            builder = new StringBuilder();
-                            if (i < length - 1) {
-                                char nextCh = quotedPrintable.charAt(i + 1);
-                                if (nextCh == '\n') {
-                                    i++;
-                                }
-                            }
-                        } else {
-                            builder.append(ch);
-                        }
-                    }
-                    String finalLine = builder.toString();
-                    if (finalLine.length() > 0) {
-                        list.add(finalLine);
-                    }
-                    lines = list.toArray(new String[0]);
-                }
-                StringBuilder builder = new StringBuilder();
-                for (String line : lines) {
-                    if (line.endsWith("=")) {
-                        line = line.substring(0, line.length() - 1);
-                    }
-                    builder.append(line);
-                }
-                byte[] bytes;
-                try {
-                    bytes = builder.toString().getBytes(mSourceCharset);
-                } catch (UnsupportedEncodingException e1) {
-                    Log.e(LOG_TAG, "Failed to encode: charset=" + mSourceCharset);
-                    bytes = builder.toString().getBytes();
-                }
-                
-                try {
-                    bytes = QuotedPrintableCodec.decodeQuotedPrintable(bytes);
-                } catch (DecoderException e) {
-                    Log.e(LOG_TAG, "Failed to decode quoted-printable: " + e);
-                    return "";
-                }
-
-                try {
-                    return new String(bytes, targetCharset);
-                } catch (UnsupportedEncodingException e) {
-                    Log.e(LOG_TAG, "Failed to encode: charset=" + targetCharset);
-                    return new String(bytes);
-                }
-            }
-            // Unknown encoding. Fall back to default.
-        }
-        return encodeString(value, targetCharset);
-    }
-    
-    public void propertyValues(List<String> values) {
-        if (values == null || values.size() == 0) {
-            mCurrentPropNode.propValue_bytes = null;
-            mCurrentPropNode.propValue_vector.clear();
-            mCurrentPropNode.propValue_vector.add("");
-            mCurrentPropNode.propValue = "";
-            return;
-        }
-        
-        ContentValues paramMap = mCurrentPropNode.paramMap;
-        
-        String targetCharset = CharsetUtils.nameForDefaultVendor(paramMap.getAsString("CHARSET")); 
-        String encoding = paramMap.getAsString("ENCODING"); 
-        
-        if (targetCharset == null || targetCharset.length() == 0) {
-            targetCharset = mTargetCharset;
-        }
-        
-        for (String value : values) {
-            mCurrentPropNode.propValue_vector.add(
-                    handleOneValue(value, targetCharset, encoding));
-        }
-
-        mCurrentPropNode.propValue = listToString(mCurrentPropNode.propValue_vector);
-    }
-
-    private String listToString(List<String> list){
-        int size = list.size();
-        if (size > 1) {
-            StringBuilder typeListB = new StringBuilder();
-            for (String type : list) {
-                typeListB.append(type).append(";");
-            }
-            int len = typeListB.length();
-            if (len > 0 && typeListB.charAt(len - 1) == ';') {
-                return typeListB.substring(0, len - 1);
-            }
-            return typeListB.toString();
-        } else if (size == 1) {
-            return list.get(0);
-        } else {
-            return "";
-        }
-    }
-    
-    public String getResult(){
-        return null;
-    }
-}
diff --git a/core/java/android/syncml/pim/VNode.java b/core/java/android/syncml/pim/VNode.java
deleted file mode 100644
index 378a9d1..0000000
--- a/core/java/android/syncml/pim/VNode.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.syncml.pim;
-
-import java.util.ArrayList;
-
-@Deprecated
-public class VNode {
-
-    public String VName;
-
-    public ArrayList<PropertyNode> propList = new ArrayList<PropertyNode>();
-
-    /** 0:parse over. 1:parsing. */
-    public int parseStatus = 1;
-}
diff --git a/core/java/android/syncml/pim/VParser.java b/core/java/android/syncml/pim/VParser.java
deleted file mode 100644
index fc302f1..0000000
--- a/core/java/android/syncml/pim/VParser.java
+++ /dev/null
@@ -1,740 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.syncml.pim;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.UnsupportedEncodingException;
-
-/**
- * This interface is used to parse the V format files, such as VCard & VCal
- */
-@Deprecated
-abstract public class VParser {
-    // Assume that "iso-8859-1" is able to map "all" 8bit characters to some unicode and
-    // decode the unicode to the original charset. If not, this setting will cause some bug. 
-    public static String DEFAULT_CHARSET = "iso-8859-1";
-
-    /**
-     * The buffer used to store input stream
-     */
-    protected String mBuffer = null;
-
-    /** The builder to build parsed data */
-    protected VBuilder mBuilder = null;
-
-    /** The encoding type */
-    protected String mEncoding = null;
-
-    protected final int PARSE_ERROR = -1;
-
-    protected final String mDefaultEncoding = "8BIT";
-
-    /**
-     * If offset reach '\r\n' return 2. Else return PARSE_ERROR.
-     */
-    protected int parseCrlf(int offset) {
-        if (offset >= mBuffer.length())
-            return PARSE_ERROR;
-        char ch = mBuffer.charAt(offset);
-        if (ch == '\r') {
-            offset++;
-            ch = mBuffer.charAt(offset);
-            if (ch == '\n') {
-                return 2;
-            }
-        }
-        return PARSE_ERROR;
-    }
-
-    /**
-     * Parse the given stream
-     *
-     * @param is
-     *            The source to parse.
-     * @param encoding
-     *            The encoding type.
-     * @param builder
-     *            The v builder which used to construct data.
-     * @return Return true for success, otherwise false.
-     * @throws IOException
-     */
-    public boolean parse(InputStream is, String encoding, VBuilder builder)
-            throws IOException {
-        setInputStream(is, encoding);
-        mBuilder = builder;
-        int ret = 0, offset = 0, sum = 0;
-
-        if (mBuilder != null) {
-            mBuilder.start();
-        }
-        for (;;) {
-            ret = parseVFile(offset); // for next property length
-            if (PARSE_ERROR == ret) {
-                break;
-            } else {
-                offset += ret;
-                sum += ret;
-            }
-        }
-        if (mBuilder != null) {
-            mBuilder.end();
-        }
-        return (mBuffer.length() == sum);
-    }
-
-    /**
-     * Parse the given stream with the default encoding.
-     * 
-     * @param is
-     *            The source to parse.
-     * @param builder
-     *            The v builder which used to construct data.
-     * @return Return true for success, otherwise false.
-     * @throws IOException
-     */
-    public boolean parse(InputStream is, VBuilder builder) throws IOException {
-        return parse(is, DEFAULT_CHARSET, builder);
-    }
-    
-    /**
-     * Copy the content of input stream and filter the "folding"
-     */
-    protected void setInputStream(InputStream is, String encoding)
-            throws UnsupportedEncodingException {
-        InputStreamReader reader = new InputStreamReader(is, encoding);
-        StringBuilder b = new StringBuilder();
-
-        int ch;
-        try {
-            while ((ch = reader.read()) != -1) {
-                if (ch == '\r') {
-                    ch = reader.read();
-                    if (ch == '\n') {
-                        ch = reader.read();
-                        if (ch == ' ' || ch == '\t') {
-                            b.append((char) ch);
-                            continue;
-                        }
-                        b.append("\r\n");
-                        if (ch == -1) {
-                            break;
-                        }
-                    } else {
-                        b.append("\r");
-                    }
-                }
-                b.append((char) ch);
-            }
-            mBuffer = b.toString();
-        } catch (Exception e) {
-            return;
-        }
-        return;
-    }
-
-    /**
-     * abstract function, waiting implement.<br>
-     * analyse from offset, return the length of consumed property.
-     */
-    abstract protected int parseVFile(int offset);
-
-    /**
-     * From offset, jump ' ', '\t', '\r\n' sequence, return the length of jump.<br>
-     * 1 * (SPACE / HTAB / CRLF)
-     */
-    protected int parseWsls(int offset) {
-        int ret = 0, sum = 0;
-
-        try {
-            char ch = mBuffer.charAt(offset);
-            if (ch == ' ' || ch == '\t') {
-                sum++;
-                offset++;
-            } else if ((ret = parseCrlf(offset)) != PARSE_ERROR) {
-                offset += ret;
-                sum += ret;
-            } else {
-                return PARSE_ERROR;
-            }
-            for (;;) {
-                ch = mBuffer.charAt(offset);
-                if (ch == ' ' || ch == '\t') {
-                    sum++;
-                    offset++;
-                } else if ((ret = parseCrlf(offset)) != PARSE_ERROR) {
-                    offset += ret;
-                    sum += ret;
-                } else {
-                    break;
-                }
-            }
-        } catch (IndexOutOfBoundsException e) {
-            ;
-        }
-        if (sum > 0)
-            return sum;
-        return PARSE_ERROR;
-    }
-
-    /**
-     * To determine if the given string equals to the start of the current
-     * string.
-     *
-     * @param offset
-     *            The offset in buffer of current string
-     * @param tar
-     *            The given string.
-     * @param ignoreCase
-     *            To determine case sensitive or not.
-     * @return The consumed characters, otherwise return PARSE_ERROR.
-     */
-    protected int parseString(int offset, final String tar, boolean ignoreCase) {
-        int sum = 0;
-        if (tar == null) {
-            return PARSE_ERROR;
-        }
-
-        if (ignoreCase) {
-            int len = tar.length();
-            try {
-                if (mBuffer.substring(offset, offset + len).equalsIgnoreCase(
-                        tar)) {
-                    sum = len;
-                } else {
-                    return PARSE_ERROR;
-                }
-            } catch (IndexOutOfBoundsException e) {
-                return PARSE_ERROR;
-            }
-
-        } else { /* case sensitive */
-            if (mBuffer.startsWith(tar, offset)) {
-                sum = tar.length();
-            } else {
-                return PARSE_ERROR;
-            }
-        }
-        return sum;
-    }
-
-    /**
-     * Skip the white space in string.
-     */
-    protected int removeWs(int offset) {
-        if (offset >= mBuffer.length())
-            return PARSE_ERROR;
-        int sum = 0;
-        char ch;
-        while ((ch = mBuffer.charAt(offset)) == ' ' || ch == '\t') {
-            offset++;
-            sum++;
-        }
-        return sum;
-    }
-
-    /**
-     * "X-" word, and its value. Return consumed length.
-     */
-    protected int parseXWord(int offset) {
-        int ret = 0, sum = 0;
-        ret = parseString(offset, "X-", true);
-        if (PARSE_ERROR == ret)
-            return PARSE_ERROR;
-        offset += ret;
-        sum += ret;
-
-        ret = parseWord(offset);
-        if (PARSE_ERROR == ret) {
-            return PARSE_ERROR;
-        }
-        sum += ret;
-        return sum;
-    }
-
-    /**
-     * From offset, parse as :mEncoding ?= 7bit / 8bit / quoted-printable /
-     * base64
-     */
-    protected int parseValue(int offset) {
-        int ret = 0;
-
-        if (mEncoding == null || mEncoding.equalsIgnoreCase("7BIT")
-                || mEncoding.equalsIgnoreCase("8BIT")
-                || mEncoding.toUpperCase().startsWith("X-")) {
-            ret = parse8bit(offset);
-            if (ret != PARSE_ERROR) {
-                return ret;
-            }
-            return PARSE_ERROR;
-        }
-
-        if (mEncoding.equalsIgnoreCase("QUOTED-PRINTABLE")) {
-            ret = parseQuotedPrintable(offset);
-            if (ret != PARSE_ERROR) {
-                return ret;
-            }
-            return PARSE_ERROR;
-        }
-
-        if (mEncoding.equalsIgnoreCase("BASE64")) {
-            ret = parseBase64(offset);
-            if (ret != PARSE_ERROR) {
-                return ret;
-            }
-            return PARSE_ERROR;
-        }
-        return PARSE_ERROR;
-    }
-
-    /**
-     * Refer to RFC 1521, 8bit text
-     */
-    protected int parse8bit(int offset) {
-        int index = 0;
-
-        index = mBuffer.substring(offset).indexOf("\r\n");
-
-        if (index == -1)
-            return PARSE_ERROR;
-        else
-            return index;
-
-    }
-
-    /**
-     * Refer to RFC 1521, quoted printable text ([*(ptext / SPACE / TAB) ptext]
-     * ["="] CRLF)
-     */
-    protected int parseQuotedPrintable(int offset) {
-        int ret = 0, sum = 0;
-
-        ret = removeWs(offset);
-        offset += ret;
-        sum += ret;
-
-        for (;;) {
-            ret = parsePtext(offset);
-            if (PARSE_ERROR == ret)
-                break;
-            offset += ret;
-            sum += ret;
-
-            ret = removeWs(offset);
-            offset += ret;
-            sum += ret;
-        }
-
-        ret = parseString(offset, "=", false);
-        if (ret != PARSE_ERROR) {
-            // offset += ret;
-            sum += ret;
-        }
-
-        return sum;
-    }
-
-    /**
-     * return 1 or 3 <any ASCII character except "=", SPACE, or TAB>
-     */
-    protected int parsePtext(int offset) {
-        int ret = 0;
-
-        try {
-            char ch = mBuffer.charAt(offset);
-            if (isPrintable(ch) && ch != '=' && ch != ' ' && ch != '\t') {
-                return 1;
-            }
-        } catch (IndexOutOfBoundsException e) {
-            return PARSE_ERROR;
-        }
-
-        ret = parseOctet(offset);
-        if (ret != PARSE_ERROR) {
-            return ret;
-        }
-        return PARSE_ERROR;
-    }
-
-    /**
-     * start with "=" two of (DIGIT / "A" / "B" / "C" / "D" / "E" / "F") <br>
-     * So maybe return 3.
-     */
-    protected int parseOctet(int offset) {
-        int ret = 0, sum = 0;
-
-        ret = parseString(offset, "=", false);
-        if (PARSE_ERROR == ret)
-            return PARSE_ERROR;
-        offset += ret;
-        sum += ret;
-
-        try {
-            int ch = mBuffer.charAt(offset);
-            if (ch == ' ' || ch == '\t')
-                return ++sum;
-            if ((ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'F')) {
-                offset++;
-                sum++;
-                ch = mBuffer.charAt(offset);
-                if ((ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'F')) {
-                    sum++;
-                    return sum;
-                }
-            }
-        } catch (IndexOutOfBoundsException e) {
-            ;
-        }
-        return PARSE_ERROR;
-    }
-
-    /**
-     * Refer to RFC 1521, base64 text The end of the text is marked with two
-     * CRLF sequences
-     */
-    protected int parseBase64(int offset) {
-        int sum = 0;
-        try {
-            for (;;) {
-                char ch;
-                ch = mBuffer.charAt(offset);
-
-                if (ch == '\r') {
-                    int ret = parseString(offset, "\r\n\r\n", false);
-                    sum += ret;
-                    break;
-                } else {
-                    /* ignore none base64 character */
-                    sum++;
-                    offset++;
-                }
-            }
-        } catch (IndexOutOfBoundsException e) {
-            return PARSE_ERROR;
-        }
-        sum -= 2;/* leave one CRLF to parse the end of this property */
-        return sum;
-    }
-
-    /**
-     * Any printable ASCII sequence except [ ]=:.,;
-     */
-    protected int parseWord(int offset) {
-        int sum = 0;
-        try {
-            for (;;) {
-                char ch = mBuffer.charAt(offset);
-                if (!isPrintable(ch))
-                    break;
-                if (ch == ' ' || ch == '=' || ch == ':' || ch == '.'
-                        || ch == ',' || ch == ';')
-                    break;
-                if (ch == '\\') {
-                    ch = mBuffer.charAt(offset + 1);
-                    if (ch == ';') {
-                        offset++;
-                        sum++;
-                    }
-                }
-                offset++;
-                sum++;
-            }
-        } catch (IndexOutOfBoundsException e) {
-            ;
-        }
-        if (sum == 0)
-            return PARSE_ERROR;
-        return sum;
-    }
-
-    /**
-     * If it is a letter or digit.
-     */
-    protected boolean isLetterOrDigit(char ch) {
-        if (ch >= '0' && ch <= '9')
-            return true;
-        if (ch >= 'a' && ch <= 'z')
-            return true;
-        if (ch >= 'A' && ch <= 'Z')
-            return true;
-        return false;
-    }
-
-    /**
-     * If it is printable in ASCII
-     */
-    protected boolean isPrintable(char ch) {
-        if (ch >= ' ' && ch <= '~')
-            return true;
-        return false;
-    }
-
-    /**
-     * If it is a letter.
-     */
-    protected boolean isLetter(char ch) {
-        if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')) {
-            return true;
-        }
-        return false;
-    }
-
-    /**
-     * Get a word from current position.
-     */
-    protected String getWord(int offset) {
-        StringBuilder word = new StringBuilder();
-        try {
-            for (;;) {
-                char ch = mBuffer.charAt(offset);
-                if (isLetterOrDigit(ch) || ch == '-') {
-                    word.append(ch);
-                    offset++;
-                } else {
-                    break;
-                }
-            }
-        } catch (IndexOutOfBoundsException e) {
-            ;
-        }
-        return word.toString();
-    }
-
-    /**
-     * If is: "INLINE" / "URL" / "CONTENT-ID" / "CID" / "X-" word
-     */
-    protected int parsePValueVal(int offset) {
-        int ret = 0, sum = 0;
-
-        ret = parseString(offset, "INLINE", true);
-        if (ret != PARSE_ERROR) {
-            sum += ret;
-            return sum;
-        }
-
-        ret = parseString(offset, "URL", true);
-        if (ret != PARSE_ERROR) {
-            sum += ret;
-            return sum;
-        }
-
-        ret = parseString(offset, "CONTENT-ID", true);
-        if (ret != PARSE_ERROR) {
-            sum += ret;
-            return sum;
-        }
-
-        ret = parseString(offset, "CID", true);
-        if (ret != PARSE_ERROR) {
-            sum += ret;
-            return sum;
-        }
-
-        ret = parseString(offset, "INLINE", true);
-        if (ret != PARSE_ERROR) {
-            sum += ret;
-            return sum;
-        }
-
-        ret = parseXWord(offset);
-        if (ret != PARSE_ERROR) {
-            sum += ret;
-            return sum;
-        }
-
-        return PARSE_ERROR;
-    }
-
-    /**
-     * If is: "7BIT" / "8BIT" / "QUOTED-PRINTABLE" / "BASE64" / "X-" word and
-     * set mEncoding.
-     */
-    protected int parsePEncodingVal(int offset) {
-        int ret = 0, sum = 0;
-
-        ret = parseString(offset, "7BIT", true);
-        if (ret != PARSE_ERROR) {
-            mEncoding = "7BIT";
-            sum += ret;
-            return sum;
-        }
-
-        ret = parseString(offset, "8BIT", true);
-        if (ret != PARSE_ERROR) {
-            mEncoding = "8BIT";
-            sum += ret;
-            return sum;
-        }
-
-        ret = parseString(offset, "QUOTED-PRINTABLE", true);
-        if (ret != PARSE_ERROR) {
-            mEncoding = "QUOTED-PRINTABLE";
-            sum += ret;
-            return sum;
-        }
-
-        ret = parseString(offset, "BASE64", true);
-        if (ret != PARSE_ERROR) {
-            mEncoding = "BASE64";
-            sum += ret;
-            return sum;
-        }
-
-        ret = parseXWord(offset);
-        if (ret != PARSE_ERROR) {
-            mEncoding = mBuffer.substring(offset).substring(0, ret);
-            sum += ret;
-            return sum;
-        }
-
-        return PARSE_ERROR;
-    }
-
-    /**
-     * Refer to RFC1521, section 7.1<br>
-     * If is: "us-ascii" / "iso-8859-xxx" / "X-" word
-     */
-    protected int parseCharsetVal(int offset) {
-        int ret = 0, sum = 0;
-
-        ret = parseString(offset, "us-ascii", true);
-        if (ret != PARSE_ERROR) {
-            sum += ret;
-            return sum;
-        }
-
-        ret = parseString(offset, "iso-8859-1", true);
-        if (ret != PARSE_ERROR) {
-            sum += ret;
-            return sum;
-        }
-
-        ret = parseString(offset, "iso-8859-2", true);
-        if (ret != PARSE_ERROR) {
-            sum += ret;
-            return sum;
-        }
-
-        ret = parseString(offset, "iso-8859-3", true);
-        if (ret != PARSE_ERROR) {
-            sum += ret;
-            return sum;
-        }
-
-        ret = parseString(offset, "iso-8859-4", true);
-        if (ret != PARSE_ERROR) {
-            sum += ret;
-            return sum;
-        }
-
-        ret = parseString(offset, "iso-8859-5", true);
-        if (ret != PARSE_ERROR) {
-            sum += ret;
-            return sum;
-        }
-
-        ret = parseString(offset, "iso-8859-6", true);
-        if (ret != PARSE_ERROR) {
-            sum += ret;
-            return sum;
-        }
-
-        ret = parseString(offset, "iso-8859-7", true);
-        if (ret != PARSE_ERROR) {
-            sum += ret;
-            return sum;
-        }
-
-        ret = parseString(offset, "iso-8859-8", true);
-        if (ret != PARSE_ERROR) {
-            sum += ret;
-            return sum;
-        }
-
-        ret = parseString(offset, "iso-8859-9", true);
-        if (ret != PARSE_ERROR) {
-            sum += ret;
-            return sum;
-        }
-
-        ret = parseXWord(offset);
-        if (ret != PARSE_ERROR) {
-            sum += ret;
-            return sum;
-        }
-
-        return PARSE_ERROR;
-    }
-
-    /**
-     * Refer to RFC 1766<br>
-     * like: XXX(sequence letters)-XXX(sequence letters)
-     */
-    protected int parseLangVal(int offset) {
-        int ret = 0, sum = 0;
-
-        ret = parseTag(offset);
-        if (PARSE_ERROR == ret) {
-            return PARSE_ERROR;
-        }
-        offset += ret;
-        sum += ret;
-
-        for (;;) {
-            ret = parseString(offset, "-", false);
-            if (PARSE_ERROR == ret) {
-                break;
-            }
-            offset += ret;
-            sum += ret;
-
-            ret = parseTag(offset);
-            if (PARSE_ERROR == ret) {
-                break;
-            }
-            offset += ret;
-            sum += ret;
-        }
-        return sum;
-    }
-
-    /**
-     * From first 8 position, is sequence LETTER.
-     */
-    protected int parseTag(int offset) {
-        int sum = 0, i = 0;
-
-        try {
-            for (i = 0; i < 8; i++) {
-                char ch = mBuffer.charAt(offset);
-                if (!isLetter(ch)) {
-                    break;
-                }
-                sum++;
-                offset++;
-            }
-        } catch (IndexOutOfBoundsException e) {
-            ;
-        }
-        if (i == 0) {
-            return PARSE_ERROR;
-        }
-        return sum;
-    }
-
-}
diff --git a/core/java/android/syncml/pim/package.html b/core/java/android/syncml/pim/package.html
deleted file mode 100644
index cb4ca46..0000000
--- a/core/java/android/syncml/pim/package.html
+++ /dev/null
@@ -1,6 +0,0 @@
-<HTML>
-<BODY>
-Support classes for SyncML.
-{@hide}
-</BODY>
-</HTML>
\ No newline at end of file
diff --git a/core/java/android/syncml/pim/vcard/ContactStruct.java b/core/java/android/syncml/pim/vcard/ContactStruct.java
deleted file mode 100644
index e212c3f..0000000
--- a/core/java/android/syncml/pim/vcard/ContactStruct.java
+++ /dev/null
@@ -1,1006 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.syncml.pim.vcard;
-
-import android.content.AbstractSyncableContentProvider;
-import android.content.ContentResolver;
-import android.content.ContentUris;
-import android.content.ContentValues;
-import android.net.Uri;
-import android.provider.Contacts;
-import android.provider.CallLog.Calls;
-import android.provider.Contacts.ContactMethods;
-import android.provider.Contacts.Extensions;
-import android.provider.Contacts.GroupMembership;
-import android.provider.Contacts.Organizations;
-import android.provider.Contacts.People;
-import android.provider.Contacts.Phones;
-import android.provider.Contacts.Photos;
-import android.syncml.pim.PropertyNode;
-import android.syncml.pim.VNode;
-import android.telephony.PhoneNumberUtils;
-import android.text.TextUtils;
-import android.util.Log;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Map.Entry;
-
-/**
- * The parameter class of VCardComposer.
- * This class standy by the person-contact in
- * Android system, we must use this class instance as parameter to transmit to
- * VCardComposer so that create vCard string.
- * 
- * @deprecated Please use the new code in android.pim.vcard
- */
-// TODO: rename the class name, next step
-@Deprecated
-public class ContactStruct {
-    private static final String LOG_TAG = "ContactStruct";
-    
-    // Note: phonetic name probably should be "LAST FIRST MIDDLE" for European languages, and
-    //       space should be added between each element while it should not be in Japanese.
-    //       But unfortunately, we currently do not have the data and are not sure whether we should
-    //       support European version of name ordering.
-    //
-    // TODO: Implement the logic described above if we really need European version of
-    //        phonetic name handling. Also, adding the appropriate test case of vCard would be
-    //        highly appreciated.
-    public static final int NAME_ORDER_TYPE_ENGLISH = 0;
-    public static final int NAME_ORDER_TYPE_JAPANESE = 1;
-
-    /** MUST exist */
-    public String name;
-    public String phoneticName;
-    /** maybe folding */
-    public List<String> notes = new ArrayList<String>();
-    /** maybe folding */
-    public String title;
-    /** binary bytes of pic. */
-    public byte[] photoBytes;
-    /** The type of Photo (e.g. JPEG, BMP, etc.) */
-    public String photoType;
-    /** Only for GET. Use addPhoneList() to PUT. */
-    public List<PhoneData> phoneList;
-    /** Only for GET. Use addContactmethodList() to PUT. */
-    public List<ContactMethod> contactmethodList;
-    /** Only for GET. Use addOrgList() to PUT. */
-    public List<OrganizationData> organizationList;
-    /** Only for GET. Use addExtension() to PUT */
-    public Map<String, List<String>> extensionMap;
-
-    public String timeStamp;
-
-    // Use organizationList instead when handling ORG.
-    @Deprecated
-    public String company;
-    
-    public static class PhoneData {
-        public int type;
-        /** maybe folding */
-        public String data;
-        public String label;
-        public boolean isPrimary; 
-    }
-
-    public static class ContactMethod {
-        // Contacts.KIND_EMAIL, Contacts.KIND_POSTAL
-        public int kind;
-        // e.g. Contacts.ContactMethods.TYPE_HOME, Contacts.PhoneColumns.TYPE_HOME
-        // If type == Contacts.PhoneColumns.TYPE_CUSTOM, label is used.
-        public int type;
-        public String data;
-        // Used only when TYPE is TYPE_CUSTOM.
-        public String label;
-        public boolean isPrimary;
-    }
-    
-    public static class OrganizationData {
-        public int type;
-        public String companyName;
-        public String positionName;
-        public boolean isPrimary;
-    }
-
-    /**
-     * Add a phone info to phoneList.
-     * @param data phone number
-     * @param type type col of content://contacts/phones
-     * @param label lable col of content://contacts/phones
-     */
-    public void addPhone(int type, String data, String label, boolean isPrimary){
-        if (phoneList == null) {
-            phoneList = new ArrayList<PhoneData>();
-        }
-        PhoneData phoneData = new PhoneData();
-        phoneData.type = type;
-        
-        StringBuilder builder = new StringBuilder();
-        String trimed = data.trim();
-        int length = trimed.length();
-        for (int i = 0; i < length; i++) {
-            char ch = trimed.charAt(i);
-            if (('0' <= ch && ch <= '9') || (i == 0 && ch == '+')) {
-                builder.append(ch);
-            }
-        }
-        phoneData.data = PhoneNumberUtils.formatNumber(builder.toString());
-        phoneData.label = label;
-        phoneData.isPrimary = isPrimary;
-        phoneList.add(phoneData);
-    }
-
-    /**
-     * Add call history time stamp and call type.
-     * @param type call type
-     * @param timeStamp timeStamp
-     */
-    public void addCallHistoryTimeStamp(int type, String date) {
-        // Extension for call history as defined in
-        // in the Specification for Ic Mobile Communcation - ver 1.1,
-        // Oct 2000. This is used to send the details of the call
-        // history - missed, incoming, outgoing along with date and time
-        // to the requesting device (For example, transferring phone book
-        // when connected over bluetooth)
-        // X-IRMC-CALL-DATETIME;MISSED:20050320T100000
-        String strCallType;
-        if (type == Calls.INCOMING_TYPE) {
-            strCallType = "INCOMING";
-        } else if (type == Calls.OUTGOING_TYPE) {
-            strCallType = "OUTGOING";
-        } else if (type == Calls.MISSED_TYPE) {
-            strCallType = "MISSED";
-        } else {
-            strCallType = "";
-        }
-        timeStamp = "X-IRMC-CALL-DATETIME;" + strCallType + ":" + date;
-    }
-
-    /**
-     * Add a contactmethod info to contactmethodList.
-     * @param kind integer value defined in Contacts.java
-     * (e.g. Contacts.KIND_EMAIL)
-     * @param type type col of content://contacts/contact_methods
-     * @param data contact data
-     * @param label extra string used only when kind is Contacts.KIND_CUSTOM.
-     */
-    public void addContactmethod(int kind, int type, String data,
-            String label, boolean isPrimary){
-        if (contactmethodList == null) {
-            contactmethodList = new ArrayList<ContactMethod>();
-        }
-        ContactMethod contactMethod = new ContactMethod();
-        contactMethod.kind = kind;
-        contactMethod.type = type;
-        contactMethod.data = data;
-        contactMethod.label = label;
-        contactMethod.isPrimary = isPrimary;
-        contactmethodList.add(contactMethod);
-    }
-    
-    /**
-     * Add a Organization info to organizationList.
-     */
-    public void addOrganization(int type, String companyName, String positionName,
-            boolean isPrimary) {
-        if (organizationList == null) {
-            organizationList = new ArrayList<OrganizationData>();
-        }
-        OrganizationData organizationData = new OrganizationData();
-        organizationData.type = type;
-        organizationData.companyName = companyName;
-        organizationData.positionName = positionName;
-        organizationData.isPrimary = isPrimary;
-        organizationList.add(organizationData);
-    }
-
-    /**
-     * Set "position" value to the appropriate data. If there's more than one
-     * OrganizationData objects, the value is set to the last one. If there's no
-     * OrganizationData object, a new OrganizationData is created, whose company name is
-     * empty.  
-     * 
-     * TODO: incomplete logic. fix this:
-     * 
-     * e.g. This assumes ORG comes earlier, but TITLE may come earlier like this, though we do not
-     * know how to handle it in general cases...
-     * ----
-     * TITLE:Software Engineer
-     * ORG:Google
-     * ----
-     */
-    public void setPosition(String positionValue) {
-        if (organizationList == null) {
-            organizationList = new ArrayList<OrganizationData>();
-        }
-        int size = organizationList.size();
-        if (size == 0) {
-            addOrganization(Contacts.OrganizationColumns.TYPE_OTHER, "", null, false);
-            size = 1;
-        }
-        OrganizationData lastData = organizationList.get(size - 1);
-        lastData.positionName = positionValue;
-    }
-    
-    public void addExtension(PropertyNode propertyNode) {
-        if (propertyNode.propValue.length() == 0) {
-            return;
-        }
-        // Now store the string into extensionMap.
-        List<String> list;
-        String name = propertyNode.propName;
-        if (extensionMap == null) {
-            extensionMap = new HashMap<String, List<String>>();
-        }
-        if (!extensionMap.containsKey(name)){
-            list = new ArrayList<String>();
-            extensionMap.put(name, list);
-        } else {
-            list = extensionMap.get(name);
-        }        
-        
-        list.add(propertyNode.encode());
-    }
-    
-    private static String getNameFromNProperty(List<String> elems, int nameOrderType) {
-        // Family, Given, Middle, Prefix, Suffix. (1 - 5)
-        int size = elems.size();
-        if (size > 1) {
-            StringBuilder builder = new StringBuilder();
-            boolean builderIsEmpty = true;
-            // Prefix
-            if (size > 3 && elems.get(3).length() > 0) {
-                builder.append(elems.get(3));
-                builderIsEmpty = false;
-            }
-            String first, second;
-            if (nameOrderType == NAME_ORDER_TYPE_JAPANESE) {
-                first = elems.get(0);
-                second = elems.get(1);
-            } else {
-                first = elems.get(1);
-                second = elems.get(0);
-            }
-            if (first.length() > 0) {
-                if (!builderIsEmpty) {
-                    builder.append(' ');
-                }
-                builder.append(first);
-                builderIsEmpty = false;
-            }
-            // Middle name
-            if (size > 2 && elems.get(2).length() > 0) {
-                if (!builderIsEmpty) {
-                    builder.append(' ');
-                }
-                builder.append(elems.get(2));
-                builderIsEmpty = false;
-            }
-            if (second.length() > 0) {
-                if (!builderIsEmpty) {
-                    builder.append(' ');
-                }
-                builder.append(second);
-                builderIsEmpty = false;
-            }
-            // Suffix
-            if (size > 4 && elems.get(4).length() > 0) {
-                if (!builderIsEmpty) {
-                    builder.append(' ');
-                }
-                builder.append(elems.get(4));
-                builderIsEmpty = false;
-            }
-            return builder.toString();
-        } else if (size == 1) {
-            return elems.get(0);
-        } else {
-            return "";
-        }
-    }
-    
-    public static ContactStruct constructContactFromVNode(VNode node,
-            int nameOrderType) {
-        if (!node.VName.equals("VCARD")) {
-            // Impossible in current implementation. Just for safety.
-            Log.e(LOG_TAG, "Non VCARD data is inserted.");
-            return null;
-        }
-
-        // For name, there are three fields in vCard: FN, N, NAME.
-        // We prefer FN, which is a required field in vCard 3.0 , but not in vCard 2.1.
-        // Next, we prefer NAME, which is defined only in vCard 3.0.
-        // Finally, we use N, which is a little difficult to parse.
-        String fullName = null;
-        String nameFromNProperty = null;
-
-        // Some vCard has "X-PHONETIC-FIRST-NAME", "X-PHONETIC-MIDDLE-NAME", and
-        // "X-PHONETIC-LAST-NAME"
-        String xPhoneticFirstName = null;
-        String xPhoneticMiddleName = null;
-        String xPhoneticLastName = null;
-        
-        ContactStruct contact = new ContactStruct();
-
-        // Each Column of four properties has ISPRIMARY field
-        // (See android.provider.Contacts)
-        // If false even after the following loop, we choose the first
-        // entry as a "primary" entry.
-        boolean prefIsSetAddress = false;
-        boolean prefIsSetPhone = false;
-        boolean prefIsSetEmail = false;
-        boolean prefIsSetOrganization = false;
-        
-        for (PropertyNode propertyNode: node.propList) {
-            String name = propertyNode.propName;
-
-            if (TextUtils.isEmpty(propertyNode.propValue)) {
-                continue;
-            }
-            
-            if (name.equals("VERSION")) {
-                // vCard version. Ignore this.
-            } else if (name.equals("FN")) {
-                fullName = propertyNode.propValue;
-            } else if (name.equals("NAME") && fullName == null) {
-                // Only in vCard 3.0. Use this if FN does not exist.
-                // Though, note that vCard 3.0 requires FN.
-                fullName = propertyNode.propValue;
-            } else if (name.equals("N")) {
-                nameFromNProperty = getNameFromNProperty(propertyNode.propValue_vector,
-                        nameOrderType);
-            } else if (name.equals("SORT-STRING")) {
-                contact.phoneticName = propertyNode.propValue;
-            } else if (name.equals("SOUND")) {
-                if (propertyNode.paramMap_TYPE.contains("X-IRMC-N") &&
-                        contact.phoneticName == null) {
-                    // Some Japanese mobile phones use this field for phonetic name,
-                    // since vCard 2.1 does not have "SORT-STRING" type.
-                    // Also, in some cases, the field has some ';' in it.
-                    // We remove them.
-                    StringBuilder builder = new StringBuilder();
-                    String value = propertyNode.propValue;
-                    int length = value.length();
-                    for (int i = 0; i < length; i++) {
-                        char ch = value.charAt(i);
-                        if (ch != ';') {
-                            builder.append(ch);
-                        }
-                    }
-                    contact.phoneticName = builder.toString();
-                } else {
-                    contact.addExtension(propertyNode);
-                }
-            } else if (name.equals("ADR")) {
-                List<String> values = propertyNode.propValue_vector;
-                boolean valuesAreAllEmpty = true;
-                for (String value : values) {
-                    if (value.length() > 0) {
-                        valuesAreAllEmpty = false;
-                        break;
-                    }
-                }
-                if (valuesAreAllEmpty) {
-                    continue;
-                }
-
-                int kind = Contacts.KIND_POSTAL;
-                int type = -1;
-                String label = "";
-                boolean isPrimary = false;
-                for (String typeString : propertyNode.paramMap_TYPE) {
-                    if (typeString.equals("PREF") && !prefIsSetAddress) {
-                        // Only first "PREF" is considered.
-                        prefIsSetAddress = true;
-                        isPrimary = true;
-                    } else if (typeString.equalsIgnoreCase("HOME")) {
-                        type = Contacts.ContactMethodsColumns.TYPE_HOME;
-                        label = "";
-                    } else if (typeString.equalsIgnoreCase("WORK") || 
-                            typeString.equalsIgnoreCase("COMPANY")) {
-                        // "COMPANY" seems emitted by Windows Mobile, which is not
-                        // specifically supported by vCard 2.1. We assume this is same
-                        // as "WORK".
-                        type = Contacts.ContactMethodsColumns.TYPE_WORK;
-                        label = "";
-                    } else if (typeString.equalsIgnoreCase("POSTAL")) {
-                        kind = Contacts.KIND_POSTAL;
-                    } else if (typeString.equalsIgnoreCase("PARCEL") || 
-                            typeString.equalsIgnoreCase("DOM") ||
-                            typeString.equalsIgnoreCase("INTL")) {
-                        // We do not have a kind or type matching these.
-                        // TODO: fix this. We may need to split entries into two.
-                        // (e.g. entries for KIND_POSTAL and KIND_PERCEL)
-                    } else if (typeString.toUpperCase().startsWith("X-") &&
-                            type < 0) {
-                        type = Contacts.ContactMethodsColumns.TYPE_CUSTOM;
-                        label = typeString.substring(2);
-                    } else if (type < 0) {
-                        // vCard 3.0 allows iana-token. Also some vCard 2.1 exporters
-                        // emit non-standard types. We do not handle their values now.
-                        type = Contacts.ContactMethodsColumns.TYPE_CUSTOM;
-                        label = typeString;
-                    }
-                }
-                // We use "HOME" as default
-                if (type < 0) {
-                    type = Contacts.ContactMethodsColumns.TYPE_HOME;
-                }
-                                
-                // adr-value    = 0*6(text-value ";") text-value
-                //              ; PO Box, Extended Address, Street, Locality, Region, Postal
-                //              ; Code, Country Name
-                String address;
-                List<String> list = propertyNode.propValue_vector;
-                int size = list.size();
-                if (size > 1) {
-                    StringBuilder builder = new StringBuilder();
-                    boolean builderIsEmpty = true;
-                    if (Locale.getDefault().getCountry().equals(Locale.JAPAN.getCountry())) {
-                        // In Japan, the order is reversed.
-                        for (int i = size - 1; i >= 0; i--) {
-                            String addressPart = list.get(i);
-                            if (addressPart.length() > 0) {
-                                if (!builderIsEmpty) {
-                                    builder.append(' ');
-                                }
-                                builder.append(addressPart);
-                                builderIsEmpty = false;
-                            }
-                        }
-                    } else {
-                        for (int i = 0; i < size; i++) {
-                            String addressPart = list.get(i);
-                            if (addressPart.length() > 0) {
-                                if (!builderIsEmpty) {
-                                    builder.append(' ');
-                                }
-                                builder.append(addressPart);
-                                builderIsEmpty = false;
-                            }
-                        }
-                    }
-                    address = builder.toString().trim();
-                } else {
-                    address = propertyNode.propValue; 
-                }
-                contact.addContactmethod(kind, type, address, label, isPrimary);
-            } else if (name.equals("ORG")) {
-                // vCard specification does not specify other types.
-                int type = Contacts.OrganizationColumns.TYPE_WORK;
-                boolean isPrimary = false;
-                
-                for (String typeString : propertyNode.paramMap_TYPE) {
-                    if (typeString.equals("PREF") && !prefIsSetOrganization) {
-                        // vCard specification officially does not have PREF in ORG.
-                        // This is just for safety.
-                        prefIsSetOrganization = true;
-                        isPrimary = true;
-                    }
-                    // XXX: Should we cope with X- words?
-                }
-
-                List<String> list = propertyNode.propValue_vector; 
-                int size = list.size();
-                StringBuilder builder = new StringBuilder();
-                for (Iterator<String> iter = list.iterator(); iter.hasNext();) {
-                    builder.append(iter.next());
-                    if (iter.hasNext()) {
-                        builder.append(' ');
-                    }
-                }
-
-                contact.addOrganization(type, builder.toString(), "", isPrimary);
-            } else if (name.equals("TITLE")) {
-                contact.setPosition(propertyNode.propValue);
-            } else if (name.equals("ROLE")) {
-                contact.setPosition(propertyNode.propValue);
-            } else if (name.equals("PHOTO")) {
-                // We prefer PHOTO to LOGO.
-                String valueType = propertyNode.paramMap.getAsString("VALUE");
-                if (valueType != null && valueType.equals("URL")) {
-                    // TODO: do something.
-                } else {
-                    // Assume PHOTO is stored in BASE64. In that case,
-                    // data is already stored in propValue_bytes in binary form.
-                    // It should be automatically done by VBuilder (VDataBuilder/VCardDatabuilder) 
-                    contact.photoBytes = propertyNode.propValue_bytes;
-                    String type = propertyNode.paramMap.getAsString("TYPE");
-                    if (type != null) {
-                        contact.photoType = type;
-                    }
-                }
-            } else if (name.equals("LOGO")) {
-                // When PHOTO is not available this is not URL,
-                // we use this instead of PHOTO.
-                String valueType = propertyNode.paramMap.getAsString("VALUE");
-                if (valueType != null && valueType.equals("URL")) {
-                    // TODO: do something.
-                } else if (contact.photoBytes == null) {
-                    contact.photoBytes = propertyNode.propValue_bytes;
-                    String type = propertyNode.paramMap.getAsString("TYPE");
-                    if (type != null) {
-                        contact.photoType = type;
-                    }
-                }
-            } else if (name.equals("EMAIL")) {
-                int type = -1;
-                String label = null;
-                boolean isPrimary = false;
-                for (String typeString : propertyNode.paramMap_TYPE) {
-                    if (typeString.equals("PREF") && !prefIsSetEmail) {
-                        // Only first "PREF" is considered.
-                        prefIsSetEmail = true;
-                        isPrimary = true;
-                    } else if (typeString.equalsIgnoreCase("HOME")) {
-                        type = Contacts.ContactMethodsColumns.TYPE_HOME;
-                    } else if (typeString.equalsIgnoreCase("WORK")) {
-                        type = Contacts.ContactMethodsColumns.TYPE_WORK;
-                    } else if (typeString.equalsIgnoreCase("CELL")) {
-                        // We do not have Contacts.ContactMethodsColumns.TYPE_MOBILE yet.
-                        type = Contacts.ContactMethodsColumns.TYPE_CUSTOM;
-                        label = Contacts.ContactMethodsColumns.MOBILE_EMAIL_TYPE_NAME;
-                    } else if (typeString.toUpperCase().startsWith("X-") &&
-                            type < 0) {
-                        type = Contacts.ContactMethodsColumns.TYPE_CUSTOM;
-                        label = typeString.substring(2);
-                    } else if (type < 0) {
-                        // vCard 3.0 allows iana-token.
-                        // We may have INTERNET (specified in vCard spec),
-                        // SCHOOL, etc.
-                        type = Contacts.ContactMethodsColumns.TYPE_CUSTOM;
-                        label = typeString;
-                    }
-                }
-                // We use "OTHER" as default.
-                if (type < 0) {
-                    type = Contacts.ContactMethodsColumns.TYPE_OTHER;
-                }
-                contact.addContactmethod(Contacts.KIND_EMAIL,
-                        type, propertyNode.propValue,label, isPrimary);
-            } else if (name.equals("TEL")) {
-                int type = -1;
-                String label = null;
-                boolean isPrimary = false;
-                boolean isFax = false;
-                for (String typeString : propertyNode.paramMap_TYPE) {
-                    if (typeString.equals("PREF") && !prefIsSetPhone) {
-                        // Only first "PREF" is considered.
-                        prefIsSetPhone = true;
-                        isPrimary = true;
-                    } else if (typeString.equalsIgnoreCase("HOME")) {
-                        type = Contacts.PhonesColumns.TYPE_HOME;
-                    } else if (typeString.equalsIgnoreCase("WORK")) {
-                        type = Contacts.PhonesColumns.TYPE_WORK;
-                    } else if (typeString.equalsIgnoreCase("CELL")) {
-                        type = Contacts.PhonesColumns.TYPE_MOBILE;
-                    } else if (typeString.equalsIgnoreCase("PAGER")) {
-                        type = Contacts.PhonesColumns.TYPE_PAGER;
-                    } else if (typeString.equalsIgnoreCase("FAX")) {
-                        isFax = true;
-                    } else if (typeString.equalsIgnoreCase("VOICE") ||
-                            typeString.equalsIgnoreCase("MSG")) {
-                        // Defined in vCard 3.0. Ignore these because they
-                        // conflict with "HOME", "WORK", etc.
-                        // XXX: do something?
-                    } else if (typeString.toUpperCase().startsWith("X-") &&
-                            type < 0) {
-                        type = Contacts.PhonesColumns.TYPE_CUSTOM;
-                        label = typeString.substring(2);
-                    } else if (type < 0){
-                        // We may have MODEM, CAR, ISDN, etc...
-                        type = Contacts.PhonesColumns.TYPE_CUSTOM;
-                        label = typeString;
-                    }
-                }
-                // We use "HOME" as default
-                if (type < 0) {
-                    type = Contacts.PhonesColumns.TYPE_HOME;
-                }
-                if (isFax) {
-                    if (type == Contacts.PhonesColumns.TYPE_HOME) {
-                        type = Contacts.PhonesColumns.TYPE_FAX_HOME; 
-                    } else if (type == Contacts.PhonesColumns.TYPE_WORK) {
-                        type = Contacts.PhonesColumns.TYPE_FAX_WORK; 
-                    }
-                }
-
-                contact.addPhone(type, propertyNode.propValue, label, isPrimary);
-            } else if (name.equals("NOTE")) {
-                contact.notes.add(propertyNode.propValue);
-            } else if (name.equals("BDAY")) {
-                contact.addExtension(propertyNode);
-            } else if (name.equals("URL")) {
-                contact.addExtension(propertyNode);
-            } else if (name.equals("REV")) {                
-                // Revision of this VCard entry. I think we can ignore this.
-                contact.addExtension(propertyNode);
-            } else if (name.equals("UID")) {
-                contact.addExtension(propertyNode);
-            } else if (name.equals("KEY")) {
-                // Type is X509 or PGP? I don't know how to handle this...
-                contact.addExtension(propertyNode);
-            } else if (name.equals("MAILER")) {
-                contact.addExtension(propertyNode);
-            } else if (name.equals("TZ")) {
-                contact.addExtension(propertyNode);
-            } else if (name.equals("GEO")) {
-                contact.addExtension(propertyNode);
-            } else if (name.equals("NICKNAME")) {
-                // vCard 3.0 only.
-                contact.addExtension(propertyNode);
-            } else if (name.equals("CLASS")) {
-                // vCard 3.0 only.
-                // e.g. CLASS:CONFIDENTIAL
-                contact.addExtension(propertyNode);
-            } else if (name.equals("PROFILE")) {
-                // VCard 3.0 only. Must be "VCARD". I think we can ignore this.
-                contact.addExtension(propertyNode);
-            } else if (name.equals("CATEGORIES")) {
-                // VCard 3.0 only.
-                // e.g. CATEGORIES:INTERNET,IETF,INDUSTRY,INFORMATION TECHNOLOGY
-                contact.addExtension(propertyNode);
-            } else if (name.equals("SOURCE")) {
-                // VCard 3.0 only.
-                contact.addExtension(propertyNode);
-            } else if (name.equals("PRODID")) {
-                // VCard 3.0 only.
-                // To specify the identifier for the product that created
-                // the vCard object.
-                contact.addExtension(propertyNode);
-            } else if (name.equals("X-PHONETIC-FIRST-NAME")) {
-                xPhoneticFirstName = propertyNode.propValue;
-            } else if (name.equals("X-PHONETIC-MIDDLE-NAME")) {
-                xPhoneticMiddleName = propertyNode.propValue;
-            } else if (name.equals("X-PHONETIC-LAST-NAME")) {
-                xPhoneticLastName = propertyNode.propValue;
-            } else {
-                // Unknown X- words and IANA token.
-                contact.addExtension(propertyNode);
-            }
-        }
-
-        if (fullName != null) {
-            contact.name = fullName;
-        } else if(nameFromNProperty != null) {
-            contact.name = nameFromNProperty;
-        } else {
-            contact.name = "";
-        }
-
-        if (contact.phoneticName == null &&
-                (xPhoneticFirstName != null || xPhoneticMiddleName != null ||
-                        xPhoneticLastName != null)) {
-            // Note: In Europe, this order should be "LAST FIRST MIDDLE". See the comment around
-            //       NAME_ORDER_TYPE_* for more detail.
-            String first;
-            String second;
-            if (nameOrderType == NAME_ORDER_TYPE_JAPANESE) {
-                first = xPhoneticLastName;
-                second = xPhoneticFirstName;
-            } else {
-                first = xPhoneticFirstName;
-                second = xPhoneticLastName;
-            }
-            StringBuilder builder = new StringBuilder();
-            if (first != null) {
-                builder.append(first);
-            }
-            if (xPhoneticMiddleName != null) {
-                builder.append(xPhoneticMiddleName);
-            }
-            if (second != null) {
-                builder.append(second);
-            }
-            contact.phoneticName = builder.toString();
-        }
-        
-        // Remove unnecessary white spaces.
-        // It is found that some mobile phone emits  phonetic name with just one white space
-        // when a user does not specify one.
-        // This logic is effective toward such kind of weird data.
-        if (contact.phoneticName != null) {
-            contact.phoneticName = contact.phoneticName.trim();
-        }
-
-        // If there is no "PREF", we choose the first entries as primary.
-        if (!prefIsSetPhone &&
-                contact.phoneList != null && 
-                contact.phoneList.size() > 0) {
-            contact.phoneList.get(0).isPrimary = true;
-        }
-
-        if (!prefIsSetAddress && contact.contactmethodList != null) {
-            for (ContactMethod contactMethod : contact.contactmethodList) {
-                if (contactMethod.kind == Contacts.KIND_POSTAL) {
-                    contactMethod.isPrimary = true;
-                    break;
-                }
-            }
-        }
-        if (!prefIsSetEmail && contact.contactmethodList != null) {
-            for (ContactMethod contactMethod : contact.contactmethodList) {
-                if (contactMethod.kind == Contacts.KIND_EMAIL) {
-                    contactMethod.isPrimary = true;
-                    break;
-                }
-            }
-        }
-        if (!prefIsSetOrganization &&
-                contact.organizationList != null &&
-                contact.organizationList.size() > 0) {
-            contact.organizationList.get(0).isPrimary = true;
-        }
-        
-        return contact;
-    }
-    
-    public String displayString() {
-        if (name.length() > 0) {
-            return name;
-        }
-        if (contactmethodList != null && contactmethodList.size() > 0) {
-            for (ContactMethod contactMethod : contactmethodList) {
-                if (contactMethod.kind == Contacts.KIND_EMAIL && contactMethod.isPrimary) {
-                    return contactMethod.data;
-                }
-            }
-        }
-        if (phoneList != null && phoneList.size() > 0) {
-            for (PhoneData phoneData : phoneList) {
-                if (phoneData.isPrimary) {
-                    return phoneData.data;
-                }
-            }
-        }
-        return "";
-    }
-    
-    private void pushIntoContentProviderOrResolver(Object contentSomething,
-            long myContactsGroupId) {
-        ContentResolver resolver = null;
-        AbstractSyncableContentProvider provider = null;
-        if (contentSomething instanceof ContentResolver) {
-            resolver = (ContentResolver)contentSomething;
-        } else if (contentSomething instanceof AbstractSyncableContentProvider) {
-            provider = (AbstractSyncableContentProvider)contentSomething;
-        } else {
-            Log.e(LOG_TAG, "Unsupported object came.");
-            return;
-        }
-        
-        ContentValues contentValues = new ContentValues();
-        contentValues.put(People.NAME, name);
-        contentValues.put(People.PHONETIC_NAME, phoneticName);
-        
-        if (notes.size() > 1) {
-            StringBuilder builder = new StringBuilder();
-            for (String note : notes) {
-                builder.append(note);
-                builder.append("\n");
-            }
-            contentValues.put(People.NOTES, builder.toString());
-        } else if (notes.size() == 1){
-            contentValues.put(People.NOTES, notes.get(0));
-        }
-        
-        Uri personUri;
-        long personId = 0;
-        if (resolver != null) {
-            personUri = Contacts.People.createPersonInMyContactsGroup(
-                    resolver, contentValues);
-            if (personUri != null) {
-                personId = ContentUris.parseId(personUri);
-            }
-        } else {
-            personUri = provider.insert(People.CONTENT_URI, contentValues);
-            if (personUri != null) {
-                personId = ContentUris.parseId(personUri);
-                ContentValues values = new ContentValues();
-                values.put(GroupMembership.PERSON_ID, personId);
-                values.put(GroupMembership.GROUP_ID, myContactsGroupId);
-                Uri resultUri = provider.insert(GroupMembership.CONTENT_URI, values);
-                if (resultUri == null) {
-                    Log.e(LOG_TAG, "Faild to insert the person to MyContact.");
-                    provider.delete(personUri, null, null);
-                    personUri = null;
-                }
-            }
-        }
-
-        if (personUri == null) {
-            Log.e(LOG_TAG, "Failed to create the contact.");
-            return;
-        }
-        
-        if (photoBytes != null) {
-            if (resolver != null) {
-                People.setPhotoData(resolver, personUri, photoBytes);
-            } else {
-                Uri photoUri = Uri.withAppendedPath(personUri, Contacts.Photos.CONTENT_DIRECTORY);
-                ContentValues values = new ContentValues();
-                values.put(Photos.DATA, photoBytes);
-                provider.update(photoUri, values, null, null);
-            }
-        }
-        
-        long primaryPhoneId = -1;
-        if (phoneList != null && phoneList.size() > 0) {
-            for (PhoneData phoneData : phoneList) {
-                ContentValues values = new ContentValues();
-                values.put(Contacts.PhonesColumns.TYPE, phoneData.type);
-                if (phoneData.type == Contacts.PhonesColumns.TYPE_CUSTOM) {
-                    values.put(Contacts.PhonesColumns.LABEL, phoneData.label);
-                }
-                // Already formatted.
-                values.put(Contacts.PhonesColumns.NUMBER, phoneData.data);
-                
-                // Not sure about Contacts.PhonesColumns.NUMBER_KEY ...
-                values.put(Contacts.PhonesColumns.ISPRIMARY, 1);
-                values.put(Contacts.Phones.PERSON_ID, personId);
-                Uri phoneUri;
-                if (resolver != null) {
-                    phoneUri = resolver.insert(Phones.CONTENT_URI, values);
-                } else {
-                    phoneUri = provider.insert(Phones.CONTENT_URI, values);
-                }
-                if (phoneData.isPrimary) {
-                    primaryPhoneId = Long.parseLong(phoneUri.getLastPathSegment());
-                }
-            }
-        }
-        
-        long primaryOrganizationId = -1;
-        if (organizationList != null && organizationList.size() > 0) {
-            for (OrganizationData organizationData : organizationList) {
-                ContentValues values = new ContentValues();
-                // Currently, we do not use TYPE_CUSTOM.
-                values.put(Contacts.OrganizationColumns.TYPE,
-                        organizationData.type);
-                values.put(Contacts.OrganizationColumns.COMPANY,
-                        organizationData.companyName);
-                values.put(Contacts.OrganizationColumns.TITLE,
-                        organizationData.positionName);
-                values.put(Contacts.OrganizationColumns.ISPRIMARY, 1);
-                values.put(Contacts.OrganizationColumns.PERSON_ID, personId);
-                
-                Uri organizationUri;
-                if (resolver != null) {
-                    organizationUri = resolver.insert(Organizations.CONTENT_URI, values);
-                } else {
-                    organizationUri = provider.insert(Organizations.CONTENT_URI, values);
-                }
-                if (organizationData.isPrimary) {
-                    primaryOrganizationId = Long.parseLong(organizationUri.getLastPathSegment());
-                }
-            }
-        }
-        
-        long primaryEmailId = -1;
-        if (contactmethodList != null && contactmethodList.size() > 0) {
-            for (ContactMethod contactMethod : contactmethodList) {
-                ContentValues values = new ContentValues();
-                values.put(Contacts.ContactMethodsColumns.KIND, contactMethod.kind);
-                values.put(Contacts.ContactMethodsColumns.TYPE, contactMethod.type);
-                if (contactMethod.type == Contacts.ContactMethodsColumns.TYPE_CUSTOM) {
-                    values.put(Contacts.ContactMethodsColumns.LABEL, contactMethod.label);
-                }
-                values.put(Contacts.ContactMethodsColumns.DATA, contactMethod.data);
-                values.put(Contacts.ContactMethodsColumns.ISPRIMARY, 1);
-                values.put(Contacts.ContactMethods.PERSON_ID, personId);
-                
-                if (contactMethod.kind == Contacts.KIND_EMAIL) {
-                    Uri emailUri;
-                    if (resolver != null) {
-                        emailUri = resolver.insert(ContactMethods.CONTENT_URI, values);
-                    } else {
-                        emailUri = provider.insert(ContactMethods.CONTENT_URI, values);
-                    }
-                    if (contactMethod.isPrimary) {
-                        primaryEmailId = Long.parseLong(emailUri.getLastPathSegment());
-                    }
-                } else {  // probably KIND_POSTAL
-                    if (resolver != null) {
-                        resolver.insert(ContactMethods.CONTENT_URI, values);
-                    } else {
-                        provider.insert(ContactMethods.CONTENT_URI, values);
-                    }
-                }
-            }
-        }
-        
-        if (extensionMap != null && extensionMap.size() > 0) {
-            ArrayList<ContentValues> contentValuesArray;
-            if (resolver != null) {
-                contentValuesArray = new ArrayList<ContentValues>();
-            } else {
-                contentValuesArray = null;
-            }
-            for (Entry<String, List<String>> entry : extensionMap.entrySet()) {
-                String key = entry.getKey();
-                List<String> list = entry.getValue();
-                for (String value : list) {
-                    ContentValues values = new ContentValues();
-                    values.put(Extensions.NAME, key);
-                    values.put(Extensions.VALUE, value);
-                    values.put(Extensions.PERSON_ID, personId);
-                    if (resolver != null) {
-                        contentValuesArray.add(values);
-                    } else {
-                        provider.insert(Extensions.CONTENT_URI, values);
-                    }
-                }
-            }
-            if (resolver != null) {
-                resolver.bulkInsert(Extensions.CONTENT_URI,
-                        contentValuesArray.toArray(new ContentValues[0]));
-            }
-        }
-        
-        if (primaryPhoneId >= 0 || primaryOrganizationId >= 0 || primaryEmailId >= 0) {
-            ContentValues values = new ContentValues();
-            if (primaryPhoneId >= 0) {
-                values.put(People.PRIMARY_PHONE_ID, primaryPhoneId);
-            }
-            if (primaryOrganizationId >= 0) {
-                values.put(People.PRIMARY_ORGANIZATION_ID, primaryOrganizationId);
-            }
-            if (primaryEmailId >= 0) {
-                values.put(People.PRIMARY_EMAIL_ID, primaryEmailId);
-            }
-            if (resolver != null) {
-                resolver.update(personUri, values, null, null);
-            } else {
-                provider.update(personUri, values, null, null);
-            }
-        }
-    }
-
-    /**
-     * Push this object into database in the resolver.
-     */
-    public void pushIntoContentResolver(ContentResolver resolver) {
-        pushIntoContentProviderOrResolver(resolver, 0);
-    }
-    
-    /**
-     * Push this object into AbstractSyncableContentProvider object.
-     */
-    public void pushIntoAbstractSyncableContentProvider(
-            AbstractSyncableContentProvider provider, long myContactsGroupId) {
-        boolean successful = false;
-        provider.beginBatch();
-        try {
-            pushIntoContentProviderOrResolver(provider, myContactsGroupId);
-            successful = true;
-        } finally {
-            provider.endBatch(successful);
-        }
-    }
-    
-    public boolean isIgnorable() {
-        return TextUtils.isEmpty(name) &&
-                TextUtils.isEmpty(phoneticName) &&
-                (phoneList == null || phoneList.size() == 0) &&
-                (contactmethodList == null || contactmethodList.size() == 0);
-    }
-}
diff --git a/core/java/android/syncml/pim/vcard/VCardComposer.java b/core/java/android/syncml/pim/vcard/VCardComposer.java
deleted file mode 100644
index a75ccf7..0000000
--- a/core/java/android/syncml/pim/vcard/VCardComposer.java
+++ /dev/null
@@ -1,358 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.syncml.pim.vcard;
-
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.commons.codec.binary.Base64;
-
-import android.provider.Contacts;
-import android.syncml.pim.vcard.ContactStruct.PhoneData;
-
-/**
- * Compose VCard string
- */
-@Deprecated
-public class VCardComposer {
-    final public static int VERSION_VCARD21_INT = 1;
-
-    final public static int VERSION_VCARD30_INT = 2;
-
-    /**
-     * A new line
-     */
-    private String mNewline;
-
-    /**
-     * The composed string
-     */
-    private StringBuilder mResult;
-
-    /**
-     * The email's type
-     */
-    static final private HashSet<String> emailTypes = new HashSet<String>(
-            Arrays.asList("CELL", "AOL", "APPLELINK", "ATTMAIL", "CIS",
-                    "EWORLD", "INTERNET", "IBMMAIL", "MCIMAIL", "POWERSHARE",
-                    "PRODIGY", "TLX", "X400"));
-
-    static final private HashSet<String> phoneTypes = new HashSet<String>(
-            Arrays.asList("PREF", "WORK", "HOME", "VOICE", "FAX", "MSG",
-                    "CELL", "PAGER", "BBS", "MODEM", "CAR", "ISDN", "VIDEO"));
-
-    static final private String TAG = "VCardComposer";
-
-    public VCardComposer() {
-    }
-
-    private static final HashMap<Integer, String> phoneTypeMap = new HashMap<Integer, String>();
-
-    private static final HashMap<Integer, String> emailTypeMap = new HashMap<Integer, String>();
-
-    static {
-        phoneTypeMap.put(Contacts.Phones.TYPE_HOME, "HOME");
-        phoneTypeMap.put(Contacts.Phones.TYPE_MOBILE, "CELL");
-        phoneTypeMap.put(Contacts.Phones.TYPE_WORK, "WORK");
-        // FAX_WORK not exist in vcard spec. The approximate is the combine of
-        // WORK and FAX, here only map to FAX
-        phoneTypeMap.put(Contacts.Phones.TYPE_FAX_WORK, "WORK;FAX");
-        phoneTypeMap.put(Contacts.Phones.TYPE_FAX_HOME, "HOME;FAX");
-        phoneTypeMap.put(Contacts.Phones.TYPE_PAGER, "PAGER");
-        phoneTypeMap.put(Contacts.Phones.TYPE_OTHER, "X-OTHER");
-        emailTypeMap.put(Contacts.ContactMethods.TYPE_HOME, "HOME");
-        emailTypeMap.put(Contacts.ContactMethods.TYPE_WORK, "WORK");
-    }
-
-    /**
-     * Create a vCard String.
-     *
-     * @param struct
-     *            see more from ContactStruct class
-     * @param vcardversion
-     *            MUST be VERSION_VCARD21 /VERSION_VCARD30
-     * @return vCard string
-     * @throws VCardException
-     *             struct.name is null /vcardversion not match
-     */
-    public String createVCard(ContactStruct struct, int vcardversion)
-            throws VCardException {
-
-        mResult = new StringBuilder();
-        // check exception:
-        if (struct.name == null || struct.name.trim().equals("")) {
-            throw new VCardException(" struct.name MUST have value.");
-        }
-        if (vcardversion == VERSION_VCARD21_INT) {
-            mNewline = "\r\n";
-        } else if (vcardversion == VERSION_VCARD30_INT) {
-            mNewline = "\n";
-        } else {
-            throw new VCardException(
-                    " version not match VERSION_VCARD21 or VERSION_VCARD30.");
-        }
-        // build vcard:
-        mResult.append("BEGIN:VCARD").append(mNewline);
-
-        if (vcardversion == VERSION_VCARD21_INT) {
-            mResult.append("VERSION:2.1").append(mNewline);
-        } else {
-            mResult.append("VERSION:3.0").append(mNewline);
-        }
-
-        if (!isNull(struct.name)) {
-            appendNameStr(struct.name);
-        }
-
-        if (!isNull(struct.company)) {
-            mResult.append("ORG:").append(struct.company).append(mNewline);
-        }
-
-        if (struct.notes.size() > 0 && !isNull(struct.notes.get(0))) {
-            mResult.append("NOTE:").append(
-                    foldingString(struct.notes.get(0), vcardversion)).append(mNewline);
-        }
-
-        if (!isNull(struct.title)) {
-            mResult.append("TITLE:").append(
-                    foldingString(struct.title, vcardversion)).append(mNewline);
-        }
-
-        if (struct.photoBytes != null) {
-            appendPhotoStr(struct.photoBytes, struct.photoType, vcardversion);
-        }
-
-        if (struct.phoneList != null) {
-            appendPhoneStr(struct.phoneList, vcardversion);
-        }
-
-        if (struct.contactmethodList != null) {
-            appendContactMethodStr(struct.contactmethodList, vcardversion);
-        }
-
-        if (!isNull(struct.timeStamp)) {
-            mResult.append(struct.timeStamp).append(mNewline);
-        }
-
-        mResult.append("END:VCARD").append(mNewline);
-        return mResult.toString();
-    }
-
-    /**
-     * Alter str to folding supported format.
-     *
-     * @param str
-     *            the string to be folded
-     * @param version
-     *            the vcard version
-     * @return the folded string
-     */
-    private String foldingString(String str, int version) {
-        if (str.endsWith("\r\n")) {
-            str = str.substring(0, str.length() - 2);
-        } else if (str.endsWith("\n")) {
-            str = str.substring(0, str.length() - 1);
-        } else {
-            return null;
-        }
-
-        str = str.replaceAll("\r\n", "\n");
-        if (version == VERSION_VCARD21_INT) {
-            return str.replaceAll("\n", "\r\n ");
-        } else if (version == VERSION_VCARD30_INT) {
-            return str.replaceAll("\n", "\n ");
-        } else {
-            return null;
-        }
-    }
-
-    /**
-     * Build LOGO property. format LOGO's param and encode value as base64.
-     *
-     * @param bytes
-     *            the binary string to be converted
-     * @param type
-     *            the type of the content
-     * @param version
-     *            the version of vcard
-     */
-    private void appendPhotoStr(byte[] bytes, String type, int version)
-            throws VCardException {
-        String value, encodingStr;
-        try {
-            value = foldingString(new String(Base64.encodeBase64(bytes, true)),
-                    version);
-        } catch (Exception e) {
-            throw new VCardException(e.getMessage());
-        }
-
-        if (isNull(type) || type.toUpperCase().indexOf("JPEG") >= 0) {
-            type = "JPEG";
-        } else if (type.toUpperCase().indexOf("GIF") >= 0) {
-            type = "GIF";
-        } else if (type.toUpperCase().indexOf("BMP") >= 0) {
-            type = "BMP";
-        } else {
-            // Handle the string like "image/tiff".
-            int indexOfSlash = type.indexOf("/");
-            if (indexOfSlash >= 0) {
-                type = type.substring(indexOfSlash + 1).toUpperCase();
-            } else {
-                type = type.toUpperCase();
-            }
-        }
-
-        mResult.append("LOGO;TYPE=").append(type);
-        if (version == VERSION_VCARD21_INT) {
-            encodingStr = ";ENCODING=BASE64:";
-            value = value + mNewline;
-        } else if (version == VERSION_VCARD30_INT) {
-            encodingStr = ";ENCODING=b:";
-        } else {
-            return;
-        }
-        mResult.append(encodingStr).append(value).append(mNewline);
-    }
-
-    private boolean isNull(String str) {
-        if (str == null || str.trim().equals("")) {
-            return true;
-        }
-        return false;
-    }
-
-    /**
-     * Build FN and N property. format N's value.
-     *
-     * @param name
-     *            the name of the contact
-     */
-    private void appendNameStr(String name) {
-        mResult.append("FN:").append(name).append(mNewline);
-        mResult.append("N:").append(name).append(mNewline);
-        /*
-         * if(name.indexOf(";") > 0)
-         * mResult.append("N:").append(name).append(mNewline); else
-         * if(name.indexOf(" ") > 0) mResult.append("N:").append(name.replace(' ',
-         * ';')). append(mNewline); else
-         * mResult.append("N:").append(name).append("; ").append(mNewline);
-         */
-    }
-
-    /** Loop append TEL property. */
-    private void appendPhoneStr(List<ContactStruct.PhoneData> phoneList,
-            int version) {
-        HashMap<String, String> numMap = new HashMap<String, String>();
-        String joinMark = version == VERSION_VCARD21_INT ? ";" : ",";
-
-        for (ContactStruct.PhoneData phone : phoneList) {
-            String type;
-            if (!isNull(phone.data)) {
-                type = getPhoneTypeStr(phone);
-                if (version == VERSION_VCARD30_INT && type.indexOf(";") != -1) {
-                    type = type.replace(";", ",");
-                }
-                if (numMap.containsKey(phone.data)) {
-                    type = numMap.get(phone.data) + joinMark + type;
-                }
-                numMap.put(phone.data, type);
-            }
-        }
-
-        for (Map.Entry<String, String> num : numMap.entrySet()) {
-            if (version == VERSION_VCARD21_INT) {
-                mResult.append("TEL;");
-            } else { // vcard3.0
-                mResult.append("TEL;TYPE=");
-            }
-            mResult.append(num.getValue()).append(":").append(num.getKey())
-                    .append(mNewline);
-        }
-    }
-
-    private String getPhoneTypeStr(PhoneData phone) {
-
-        int phoneType = phone.type;
-        String typeStr, label;
-
-        if (phoneTypeMap.containsKey(phoneType)) {
-            typeStr = phoneTypeMap.get(phoneType);
-        } else if (phoneType == Contacts.Phones.TYPE_CUSTOM) {
-            label = phone.label.toUpperCase();
-            if (phoneTypes.contains(label) || label.startsWith("X-")) {
-                typeStr = label;
-            } else {
-                typeStr = "X-CUSTOM-" + label;
-            }
-        } else {
-            // TODO: need be updated with the provider's future changes
-            typeStr = "VOICE"; // the default type is VOICE in spec.
-        }
-        return typeStr;
-    }
-
-    /** Loop append ADR / EMAIL property. */
-    private void appendContactMethodStr(
-            List<ContactStruct.ContactMethod> contactMList, int version) {
-
-        HashMap<String, String> emailMap = new HashMap<String, String>();
-        String joinMark = version == VERSION_VCARD21_INT ? ";" : ",";
-        for (ContactStruct.ContactMethod contactMethod : contactMList) {
-            // same with v2.1 and v3.0
-            switch (contactMethod.kind) {
-            case Contacts.KIND_EMAIL:
-                String mailType = "INTERNET";
-                if (!isNull(contactMethod.data)) {
-                    int methodType = new Integer(contactMethod.type).intValue();
-                    if (emailTypeMap.containsKey(methodType)) {
-                        mailType = emailTypeMap.get(methodType);
-                    } else if (emailTypes.contains(contactMethod.label
-                            .toUpperCase())) {
-                        mailType = contactMethod.label.toUpperCase();
-                    }
-                    if (emailMap.containsKey(contactMethod.data)) {
-                        mailType = emailMap.get(contactMethod.data) + joinMark
-                                + mailType;
-                    }
-                    emailMap.put(contactMethod.data, mailType);
-                }
-                break;
-            case Contacts.KIND_POSTAL:
-                if (!isNull(contactMethod.data)) {
-                    mResult.append("ADR;TYPE=POSTAL:").append(
-                            foldingString(contactMethod.data, version)).append(
-                            mNewline);
-                }
-                break;
-            default:
-                break;
-            }
-        }
-        for (Map.Entry<String, String> email : emailMap.entrySet()) {
-            if (version == VERSION_VCARD21_INT) {
-                mResult.append("EMAIL;");
-            } else {
-                mResult.append("EMAIL;TYPE=");
-            }
-            mResult.append(email.getValue()).append(":").append(email.getKey())
-                    .append(mNewline);
-        }
-    }
-}
diff --git a/core/java/android/syncml/pim/vcard/VCardDataBuilder.java b/core/java/android/syncml/pim/vcard/VCardDataBuilder.java
deleted file mode 100644
index 7158a76..0000000
--- a/core/java/android/syncml/pim/vcard/VCardDataBuilder.java
+++ /dev/null
@@ -1,447 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.syncml.pim.vcard;
-
-import android.app.ProgressDialog;
-import android.content.AbstractSyncableContentProvider;
-import android.content.ContentProvider;
-import android.content.ContentResolver;
-import android.content.ContentValues;
-import android.content.IContentProvider;
-import android.os.Handler;
-import android.provider.Contacts;
-import android.syncml.pim.PropertyNode;
-import android.syncml.pim.VBuilder;
-import android.syncml.pim.VNode;
-import android.syncml.pim.VParser;
-import android.text.TextUtils;
-import android.util.CharsetUtils;
-import android.util.Log;
-
-import org.apache.commons.codec.DecoderException;
-import org.apache.commons.codec.binary.Base64;
-import org.apache.commons.codec.net.QuotedPrintableCodec;
-
-import java.io.UnsupportedEncodingException;
-import java.nio.ByteBuffer;
-import java.nio.charset.Charset;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * VBuilder for VCard. VCard may contain big photo images encoded by BASE64,
- * If we store all VNode entries in memory like VDataBuilder.java,
- * OutOfMemoryError may be thrown. Thus, this class push each VCard entry into
- * ContentResolver immediately.
- */
-@Deprecated
-public class VCardDataBuilder implements VBuilder {
-    static private String LOG_TAG = "VCardDataBuilder"; 
-    
-    /**
-     * If there's no other information available, this class uses this charset for encoding
-     * byte arrays.
-     */
-    static public String DEFAULT_CHARSET = "UTF-8"; 
-    
-    private class ProgressShower implements Runnable {
-        private ContactStruct mContact;
-        
-        public ProgressShower(ContactStruct contact) {
-            mContact = contact;
-        }
-        
-        public void run () {
-            mProgressDialog.setMessage(mProgressMessage + "\n" + 
-                    mContact.displayString());
-        }
-    }
-    
-    /** type=VNode */
-    private VNode mCurrentVNode;
-    private PropertyNode mCurrentPropNode;
-    private String mCurrentParamType;
-    
-    /**
-     * The charset using which VParser parses the text.
-     */
-    private String mSourceCharset;
-    
-    /**
-     * The charset with which byte array is encoded to String.
-     */
-    private String mTargetCharset;
-    private boolean mStrictLineBreakParsing;
-    private ContentResolver mContentResolver;
-    
-    // For letting VCardDataBuilder show the display name of VCard while handling it.
-    private Handler mHandler;
-    private ProgressDialog mProgressDialog;
-    private String mProgressMessage;
-    private Runnable mOnProgressRunnable;
-    private boolean mLastNameComesBeforeFirstName;
-    
-    // Just for testing.
-    private long mTimeCreateContactStruct;
-    private long mTimePushIntoContentResolver;
-    
-    // Ideally, this should be ContactsProvider but it seems Class loader cannot find it,
-    // even when it is subclass of ContactsProvider...
-    private AbstractSyncableContentProvider mProvider;
-    private long mMyContactsGroupId;
-    
-    public VCardDataBuilder(ContentResolver resolver) {
-        mTargetCharset = DEFAULT_CHARSET;
-        mContentResolver = resolver;
-    }
-    
-    /**
-     * Constructor which requires minimum requiredvariables.
-     * 
-     * @param resolver insert each data into this ContentResolver
-     * @param progressDialog 
-     * @param progressMessage
-     * @param handler if this importer works on the different thread than main one,
-     * set appropriate handler object. If not, it is ok to set this null.
-     */
-    public VCardDataBuilder(ContentResolver resolver,
-            ProgressDialog progressDialog,
-            String progressMessage,
-            Handler handler) {
-        this(resolver, progressDialog, progressMessage, handler,
-                null, null, false, false);
-    }
-
-    public VCardDataBuilder(ContentResolver resolver,
-            ProgressDialog progressDialog,
-            String progressMessage,
-            Handler handler,
-            String charset,
-            boolean strictLineBreakParsing,
-            boolean lastNameComesBeforeFirstName) {
-        this(resolver, progressDialog, progressMessage, handler,
-                null, charset, strictLineBreakParsing,
-                lastNameComesBeforeFirstName);
-    }
-    
-    /**
-     * @hide
-     */
-    public VCardDataBuilder(ContentResolver resolver,
-            ProgressDialog progressDialog,
-            String progressMessage,
-            Handler handler,
-            String sourceCharset,
-            String targetCharset,
-            boolean strictLineBreakParsing,
-            boolean lastNameComesBeforeFirstName) {
-        if (sourceCharset != null) {
-            mSourceCharset = sourceCharset;
-        } else {
-            mSourceCharset = VParser.DEFAULT_CHARSET;
-        }
-        if (targetCharset != null) {
-            mTargetCharset = targetCharset;
-        } else {
-            mTargetCharset = DEFAULT_CHARSET;
-        }
-        mContentResolver = resolver;
-        mStrictLineBreakParsing = strictLineBreakParsing;
-        mHandler = handler;
-        mProgressDialog = progressDialog;
-        mProgressMessage = progressMessage;
-        mLastNameComesBeforeFirstName = lastNameComesBeforeFirstName;
-        
-        tryGetOriginalProvider();
-    }
-    
-    private void tryGetOriginalProvider() {
-        final ContentResolver resolver = mContentResolver;
-        
-        if ((mMyContactsGroupId = Contacts.People.tryGetMyContactsGroupId(resolver)) == 0) {
-            Log.e(LOG_TAG, "Could not get group id of MyContact");
-            return;
-        }
-
-        IContentProvider iProviderForName = resolver.acquireProvider(Contacts.CONTENT_URI);
-        ContentProvider contentProvider =
-            ContentProvider.coerceToLocalContentProvider(iProviderForName);
-        if (contentProvider == null) {
-            Log.e(LOG_TAG, "Fail to get ContentProvider object.");
-            return;
-        }
-        
-        if (!(contentProvider instanceof AbstractSyncableContentProvider)) {
-            Log.e(LOG_TAG,
-                    "Acquired ContentProvider object is not AbstractSyncableContentProvider.");
-            return;
-        }
-        
-        mProvider = (AbstractSyncableContentProvider)contentProvider; 
-    }
-    
-    public void setOnProgressRunnable(Runnable runnable) {
-        mOnProgressRunnable = runnable;
-    }
-    
-    public void start() {
-    }
-
-    public void end() {
-    }
-
-    /**
-     * Assume that VCard is not nested. In other words, this code does not accept 
-     */
-    public void startRecord(String type) {
-        if (mCurrentVNode != null) {
-            // This means startRecord() is called inside startRecord() - endRecord() block.
-            // TODO: should throw some Exception
-            Log.e(LOG_TAG, "Nested VCard code is not supported now.");
-        }
-        mCurrentVNode = new VNode();
-        mCurrentVNode.parseStatus = 1;
-        mCurrentVNode.VName = type;
-    }
-
-    public void endRecord() {
-        mCurrentVNode.parseStatus = 0;
-        long start = System.currentTimeMillis();
-        ContactStruct contact = ContactStruct.constructContactFromVNode(mCurrentVNode,
-                mLastNameComesBeforeFirstName ? ContactStruct.NAME_ORDER_TYPE_JAPANESE :
-                    ContactStruct.NAME_ORDER_TYPE_ENGLISH);
-        mTimeCreateContactStruct += System.currentTimeMillis() - start;
-        if (!contact.isIgnorable()) {
-            if (mProgressDialog != null && mProgressMessage != null) {
-                if (mHandler != null) {
-                    mHandler.post(new ProgressShower(contact));
-                } else {
-                    mProgressDialog.setMessage(mProgressMessage + "\n" + 
-                            contact.displayString());
-                }
-            }
-            start = System.currentTimeMillis();
-            if (mProvider != null) {
-                contact.pushIntoAbstractSyncableContentProvider(
-                        mProvider, mMyContactsGroupId);
-            } else {
-                contact.pushIntoContentResolver(mContentResolver);
-            }
-            mTimePushIntoContentResolver += System.currentTimeMillis() - start;
-        }
-        if (mOnProgressRunnable != null) {
-            mOnProgressRunnable.run();
-        }
-        mCurrentVNode = null;
-    }
-
-    public void startProperty() {
-        mCurrentPropNode = new PropertyNode();
-    }
-
-    public void endProperty() {
-        mCurrentVNode.propList.add(mCurrentPropNode);
-        mCurrentPropNode = null;
-    }
-    
-    public void propertyName(String name) {
-        mCurrentPropNode.propName = name;
-    }
-
-    public void propertyGroup(String group) {
-        mCurrentPropNode.propGroupSet.add(group);
-    }
-    
-    public void propertyParamType(String type) {
-        mCurrentParamType = type;
-    }
-
-    public void propertyParamValue(String value) {
-        if (mCurrentParamType == null ||
-                mCurrentParamType.equalsIgnoreCase("TYPE")) {
-            mCurrentPropNode.paramMap_TYPE.add(value);
-        } else {
-            mCurrentPropNode.paramMap.put(mCurrentParamType, value);
-        }
-
-        mCurrentParamType = null;
-    }
-    
-    private String encodeString(String originalString, String targetCharset) {
-        if (mSourceCharset.equalsIgnoreCase(targetCharset)) {
-            return originalString;
-        }
-        Charset charset = Charset.forName(mSourceCharset);
-        ByteBuffer byteBuffer = charset.encode(originalString);
-        // byteBuffer.array() "may" return byte array which is larger than
-        // byteBuffer.remaining(). Here, we keep on the safe side.
-        byte[] bytes = new byte[byteBuffer.remaining()];
-        byteBuffer.get(bytes);
-        try {
-            return new String(bytes, targetCharset);
-        } catch (UnsupportedEncodingException e) {
-            Log.e(LOG_TAG, "Failed to encode: charset=" + targetCharset);
-            return new String(bytes);
-        }
-    }
-    
-    private String handleOneValue(String value, String targetCharset, String encoding) {
-        if (encoding != null) {
-            if (encoding.equals("BASE64") || encoding.equals("B")) {
-                mCurrentPropNode.propValue_bytes =
-                    Base64.decodeBase64(value.getBytes());
-                return value;
-            } else if (encoding.equals("QUOTED-PRINTABLE")) {
-                // "= " -> " ", "=\t" -> "\t".
-                // Previous code had done this replacement. Keep on the safe side.
-                StringBuilder builder = new StringBuilder();
-                int length = value.length();
-                for (int i = 0; i < length; i++) {
-                    char ch = value.charAt(i);
-                    if (ch == '=' && i < length - 1) {
-                        char nextCh = value.charAt(i + 1);
-                        if (nextCh == ' ' || nextCh == '\t') {
-
-                            builder.append(nextCh);
-                            i++;
-                            continue;
-                        }
-                    }
-                    builder.append(ch);
-                }
-                String quotedPrintable = builder.toString();
-                
-                String[] lines;
-                if (mStrictLineBreakParsing) {
-                    lines = quotedPrintable.split("\r\n");
-                } else {
-                    builder = new StringBuilder();
-                    length = quotedPrintable.length();
-                    ArrayList<String> list = new ArrayList<String>();
-                    for (int i = 0; i < length; i++) {
-                        char ch = quotedPrintable.charAt(i);
-                        if (ch == '\n') {
-                            list.add(builder.toString());
-                            builder = new StringBuilder();
-                        } else if (ch == '\r') {
-                            list.add(builder.toString());
-                            builder = new StringBuilder();
-                            if (i < length - 1) {
-                                char nextCh = quotedPrintable.charAt(i + 1);
-                                if (nextCh == '\n') {
-                                    i++;
-                                }
-                            }
-                        } else {
-                            builder.append(ch);
-                        }
-                    }
-                    String finalLine = builder.toString();
-                    if (finalLine.length() > 0) {
-                        list.add(finalLine);
-                    }
-                    lines = list.toArray(new String[0]);
-                }
-                
-                builder = new StringBuilder();
-                for (String line : lines) {
-                    if (line.endsWith("=")) {
-                        line = line.substring(0, line.length() - 1);
-                    }
-                    builder.append(line);
-                }
-                byte[] bytes;
-                try {
-                    bytes = builder.toString().getBytes(mSourceCharset);
-                } catch (UnsupportedEncodingException e1) {
-                    Log.e(LOG_TAG, "Failed to encode: charset=" + mSourceCharset);
-                    bytes = builder.toString().getBytes();
-                }
-                
-                try {
-                    bytes = QuotedPrintableCodec.decodeQuotedPrintable(bytes);
-                } catch (DecoderException e) {
-                    Log.e(LOG_TAG, "Failed to decode quoted-printable: " + e);
-                    return "";
-                }
-
-                try {
-                    return new String(bytes, targetCharset);
-                } catch (UnsupportedEncodingException e) {
-                    Log.e(LOG_TAG, "Failed to encode: charset=" + targetCharset);
-                    return new String(bytes);
-                }
-            }
-            // Unknown encoding. Fall back to default.
-        }
-        return encodeString(value, targetCharset);
-    }
-    
-    public void propertyValues(List<String> values) {
-        if (values == null || values.size() == 0) {
-            mCurrentPropNode.propValue_bytes = null;
-            mCurrentPropNode.propValue_vector.clear();
-            mCurrentPropNode.propValue_vector.add("");
-            mCurrentPropNode.propValue = "";
-            return;
-        }
-        
-        ContentValues paramMap = mCurrentPropNode.paramMap;
-        
-        String targetCharset = CharsetUtils.nameForDefaultVendor(paramMap.getAsString("CHARSET")); 
-        String encoding = paramMap.getAsString("ENCODING"); 
-        
-        Log.d("@@@", String.format("targetCharset: \"%s\", encoding: \"%s\"",
-                targetCharset, encoding));
-
-        if (TextUtils.isEmpty(targetCharset)) {
-            targetCharset = mTargetCharset;
-        }
-        
-        for (String value : values) {
-            mCurrentPropNode.propValue_vector.add(
-                    handleOneValue(value, targetCharset, encoding));
-        }
-
-        mCurrentPropNode.propValue = listToString(mCurrentPropNode.propValue_vector);
-    }
-
-    public void showDebugInfo() {
-        Log.d(LOG_TAG, "time for creating ContactStruct: " + mTimeCreateContactStruct + " ms");
-        Log.d(LOG_TAG, "time for insert ContactStruct to database: " + 
-                mTimePushIntoContentResolver + " ms");
-    }
-    
-    private String listToString(List<String> list){
-        int size = list.size();
-        if (size > 1) {
-            StringBuilder builder = new StringBuilder();
-            int i = 0;
-            for (String type : list) {
-                builder.append(type);
-                if (i < size - 1) {
-                    builder.append(";");
-                }
-            }
-            return builder.toString();
-        } else if (size == 1) {
-            return list.get(0);
-        } else {
-            return "";
-        }
-    }
-}
diff --git a/core/java/android/syncml/pim/vcard/VCardEntryCounter.java b/core/java/android/syncml/pim/vcard/VCardEntryCounter.java
deleted file mode 100644
index 0658290..0000000
--- a/core/java/android/syncml/pim/vcard/VCardEntryCounter.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.syncml.pim.vcard;
-
-import java.util.List;
-
-import android.syncml.pim.VBuilder;
-
-@Deprecated
-public class VCardEntryCounter implements VBuilder {
-    private int mCount;
-    
-    public int getCount() {
-        return mCount;
-    }
-    
-    public void start() {
-    }
-    
-    public void end() {
-    }
-
-    public void startRecord(String type) {
-    }
-
-    public void endRecord() {
-        mCount++;
-    }
-    
-    public void startProperty() {
-    }
-    
-    public void endProperty() {
-    }
-
-    public void propertyGroup(String group) {
-    }
-
-    public void propertyName(String name) {
-    }
-
-    public void propertyParamType(String type) {
-    }
-
-    public void propertyParamValue(String value) {
-    }
-
-    public void propertyValues(List<String> values) {
-    }    
-}
\ No newline at end of file
diff --git a/core/java/android/syncml/pim/vcard/VCardException.java b/core/java/android/syncml/pim/vcard/VCardException.java
deleted file mode 100644
index 92ca0de..0000000
--- a/core/java/android/syncml/pim/vcard/VCardException.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.syncml.pim.vcard;
-
-@Deprecated
-public class VCardException extends java.lang.Exception{
-    // constructors
-
-    /**
-     * Constructs a VCardException object
-     */
-
-    public VCardException()
-    {
-    }
-
-    /**
-     * Constructs a VCardException object
-     *
-     * @param message the error message
-     */
-
-    public VCardException( String message )
-    {
-        super( message );
-    }
-
-}
diff --git a/core/java/android/syncml/pim/vcard/VCardNestedException.java b/core/java/android/syncml/pim/vcard/VCardNestedException.java
deleted file mode 100644
index aa064fd..0000000
--- a/core/java/android/syncml/pim/vcard/VCardNestedException.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.syncml.pim.vcard;
-
-/**
- * VCardException thrown when VCard is nested without VCardParser's being notified.
- */
-@Deprecated
-public class VCardNestedException extends VCardException {
-    public VCardNestedException() {}
-    public VCardNestedException(String message) {
-        super(message);
-    }
-}
diff --git a/core/java/android/syncml/pim/vcard/VCardParser.java b/core/java/android/syncml/pim/vcard/VCardParser.java
deleted file mode 100644
index 4fe8c73..0000000
--- a/core/java/android/syncml/pim/vcard/VCardParser.java
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.syncml.pim.vcard;
-
-import android.syncml.pim.VDataBuilder;
-import android.util.Config;
-import android.util.Log;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-
-@Deprecated
-public class VCardParser {
-
-    // TODO: fix this.
-    VCardParser_V21 mParser = null;
-
-    public final static String VERSION_VCARD21 = "vcard2.1";
-
-    public final static String VERSION_VCARD30 = "vcard3.0";
-
-    final public static int VERSION_VCARD21_INT = 1;
-
-    final public static int VERSION_VCARD30_INT = 2;
-
-    String mVersion = null;
-
-    static final private String TAG = "VCardParser";
-
-    public VCardParser() {
-    }
-
-    /**
-     * If version not given. Search from vcard string of the VERSION property.
-     * Then instance mParser to appropriate parser.
-     *
-     * @param vcardStr
-     *            the content of vcard data
-     */
-    private void judgeVersion(String vcardStr) {
-        if (mVersion == null) {// auto judge
-            int verIdx = vcardStr.indexOf("\nVERSION:");
-            if (verIdx == -1) // if not have VERSION, v2.1 default
-                mVersion = VERSION_VCARD21;
-            else {
-                String verStr = vcardStr.substring(verIdx, vcardStr.indexOf(
-                        "\n", verIdx + 1));
-                if (verStr.indexOf("2.1") > 0)
-                    mVersion = VERSION_VCARD21;
-                else if (verStr.indexOf("3.0") > 0)
-                    mVersion = VERSION_VCARD30;
-                else
-                    mVersion = VERSION_VCARD21;
-            }
-        }
-        if (mVersion.equals(VERSION_VCARD21))
-            mParser = new VCardParser_V21();
-        if (mVersion.equals(VERSION_VCARD30))
-            mParser = new VCardParser_V30();
-    }
-
-    /**
-     * To make sure the vcard string has proper wrap character
-     *
-     * @param vcardStr
-     *            the string to be checked
-     * @return string after verified
-     */
-    private String verifyVCard(String vcardStr) {
-        this.judgeVersion(vcardStr);
-        // -- indent line:
-        vcardStr = vcardStr.replaceAll("\r\n", "\n");
-        String[] strlist = vcardStr.split("\n");
-        StringBuilder v21str = new StringBuilder("");
-        for (int i = 0; i < strlist.length; i++) {
-            if (strlist[i].indexOf(":") < 0) {
-                if (strlist[i].length() == 0 && strlist[i + 1].indexOf(":") > 0)
-                    v21str.append(strlist[i]).append("\r\n");
-                else
-                    v21str.append(" ").append(strlist[i]).append("\r\n");
-            } else
-                v21str.append(strlist[i]).append("\r\n");
-        }
-        return v21str.toString();
-    }
-
-    /**
-     * Set current version
-     *
-     * @param version
-     *            the new version
-     */
-    private void setVersion(String version) {
-        this.mVersion = version;
-    }
-
-    /**
-     * Parse the given vcard string
-     *
-     * @param vcardStr
-     *            to content to be parsed
-     * @param builder
-     *            the data builder to hold data
-     * @return true if the string is successfully parsed, else return false
-     * @throws VCardException
-     * @throws IOException
-     */
-    public boolean parse(String vcardStr, VDataBuilder builder)
-            throws VCardException, IOException {
-
-        vcardStr = this.verifyVCard(vcardStr);
-
-        boolean isSuccess = mParser.parse(new ByteArrayInputStream(vcardStr
-                .getBytes()), "US-ASCII", builder);
-        if (!isSuccess) {
-            if (mVersion.equals(VERSION_VCARD21)) {
-                if (Config.LOGD)
-                    Log.d(TAG, "Parse failed for vCard 2.1 parser."
-                            + " Try to use 3.0 parser.");
-
-                this.setVersion(VERSION_VCARD30);
-
-                return this.parse(vcardStr, builder);
-            }
-            throw new VCardException("parse failed.(even use 3.0 parser)");
-        }
-        return true;
-    }
-}
diff --git a/core/java/android/syncml/pim/vcard/VCardParser_V21.java b/core/java/android/syncml/pim/vcard/VCardParser_V21.java
deleted file mode 100644
index e6379a9..0000000
--- a/core/java/android/syncml/pim/vcard/VCardParser_V21.java
+++ /dev/null
@@ -1,976 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.syncml.pim.vcard;
-
-import android.syncml.pim.VBuilder;
-import android.syncml.pim.VParser;
-import android.util.Log;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.Reader;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashSet;
-
-/**
- * This class is used to parse vcard. Please refer to vCard Specification 2.1.
- */
-@Deprecated
-public class VCardParser_V21 {
-    private static final String LOG_TAG = "VCardParser_V21";
-    
-    public static final String DEFAULT_CHARSET = VParser.DEFAULT_CHARSET;
-    
-    /** Store the known-type */
-    private static final HashSet<String> sKnownTypeSet = new HashSet<String>(
-            Arrays.asList("DOM", "INTL", "POSTAL", "PARCEL", "HOME", "WORK",
-                    "PREF", "VOICE", "FAX", "MSG", "CELL", "PAGER", "BBS",
-                    "MODEM", "CAR", "ISDN", "VIDEO", "AOL", "APPLELINK",
-                    "ATTMAIL", "CIS", "EWORLD", "INTERNET", "IBMMAIL",
-                    "MCIMAIL", "POWERSHARE", "PRODIGY", "TLX", "X400", "GIF",
-                    "CGM", "WMF", "BMP", "MET", "PMB", "DIB", "PICT", "TIFF",
-                    "PDF", "PS", "JPEG", "QTIME", "MPEG", "MPEG2", "AVI",
-                    "WAVE", "AIFF", "PCM", "X509", "PGP"));
-
-    /** Store the known-value */
-    private static final HashSet<String> sKnownValueSet = new HashSet<String>(
-            Arrays.asList("INLINE", "URL", "CONTENT-ID", "CID"));
-        
-    /** Store the property names available in vCard 2.1 */
-    private static final HashSet<String> sAvailablePropertyNameV21 =
-        new HashSet<String>(Arrays.asList(
-                "BEGIN", "LOGO", "PHOTO", "LABEL", "FN", "TITLE", "SOUND",
-                "VERSION", "TEL", "EMAIL", "TZ", "GEO", "NOTE", "URL",
-                "BDAY", "ROLE", "REV", "UID", "KEY", "MAILER"));
-
-    // Though vCard 2.1 specification does not allow "B" encoding, some data may have it.
-    // We allow it for safety...
-    private static final HashSet<String> sAvailableEncodingV21 =
-        new HashSet<String>(Arrays.asList(
-                "7BIT", "8BIT", "QUOTED-PRINTABLE", "BASE64", "B"));
-    
-    // Used only for parsing END:VCARD.
-    private String mPreviousLine;
-    
-    /** The builder to build parsed data */
-    protected VBuilder mBuilder = null;
-
-    /** The encoding type */
-    protected String mEncoding = null;
-    
-    protected final String sDefaultEncoding = "8BIT";
-    
-    // Should not directly read a line from this. Use getLine() instead.
-    protected BufferedReader mReader;
-    
-    private boolean mCanceled;
-    
-    // In some cases, vCard is nested. Currently, we only consider the most interior vCard data.
-    // See v21_foma_1.vcf in test directory for more information.
-    private int mNestCount;
-    
-    // In order to reduce warning message as much as possible, we hold the value which made Logger
-    // emit a warning message.
-    protected HashSet<String> mWarningValueMap = new HashSet<String>();
-    
-    // Just for debugging
-    private long mTimeTotal;
-    private long mTimeStartRecord;
-    private long mTimeEndRecord;
-    private long mTimeStartProperty;
-    private long mTimeEndProperty;
-    private long mTimeParseItems;
-    private long mTimeParseItem1;
-    private long mTimeParseItem2;
-    private long mTimeParseItem3;
-    private long mTimeHandlePropertyValue1;
-    private long mTimeHandlePropertyValue2;
-    private long mTimeHandlePropertyValue3;
-    
-    /**
-     * Create a new VCard parser.
-     */
-    public VCardParser_V21() {
-        super();
-    }
-
-    public VCardParser_V21(VCardSourceDetector detector) {
-        super();
-        if (detector != null && detector.getType() == VCardSourceDetector.TYPE_FOMA) {
-            mNestCount = 1;
-        }
-    }
-    
-    /**
-     * Parse the file at the given position
-     * vcard_file   = [wsls] vcard [wsls]
-     */
-    protected void parseVCardFile() throws IOException, VCardException {
-        boolean firstReading = true;
-        while (true) {
-            if (mCanceled) {
-                break;
-            }
-            if (!parseOneVCard(firstReading)) {
-                break;
-            }
-            firstReading = false;
-        }
-
-        if (mNestCount > 0) {
-            boolean useCache = true;
-            for (int i = 0; i < mNestCount; i++) {
-                readEndVCard(useCache, true);
-                useCache = false;
-            }
-        }
-    }
-
-    protected String getVersion() {
-        return "2.1";
-    }
-    
-    /**
-     * @return true when the propertyName is a valid property name.
-     */
-    protected boolean isValidPropertyName(String propertyName) {
-        if (!(sAvailablePropertyNameV21.contains(propertyName.toUpperCase()) ||
-                propertyName.startsWith("X-")) && 
-                !mWarningValueMap.contains(propertyName)) {
-            mWarningValueMap.add(propertyName);
-            Log.w(LOG_TAG, "Property name unsupported by vCard 2.1: " + propertyName);
-        }
-        return true;
-    }
-
-    /**
-     * @return true when the encoding is a valid encoding.
-     */
-    protected boolean isValidEncoding(String encoding) {
-        return sAvailableEncodingV21.contains(encoding.toUpperCase());
-    }
-    
-    /**
-     * @return String. It may be null, or its length may be 0
-     * @throws IOException
-     */
-    protected String getLine() throws IOException {
-        return mReader.readLine();
-    }
-    
-    /**
-     * @return String with it's length > 0
-     * @throws IOException
-     * @throws VCardException when the stream reached end of line
-     */
-    protected String getNonEmptyLine() throws IOException, VCardException {
-        String line;
-        while (true) {
-            line = getLine();
-            if (line == null) {
-                throw new VCardException("Reached end of buffer.");
-            } else if (line.trim().length() > 0) {                
-                return line;
-            }
-        }
-    }
-    
-    /**
-     *  vcard        = "BEGIN" [ws] ":" [ws] "VCARD" [ws] 1*CRLF
-     *                 items *CRLF
-     *                 "END" [ws] ":" [ws] "VCARD"
-     */
-    private boolean parseOneVCard(boolean firstReading) throws IOException, VCardException {
-        boolean allowGarbage = false;
-        if (firstReading) {
-            if (mNestCount > 0) {
-                for (int i = 0; i < mNestCount; i++) {
-                    if (!readBeginVCard(allowGarbage)) {
-                        return false;
-                    }
-                    allowGarbage = true;
-                }
-            }
-        }
-
-        if (!readBeginVCard(allowGarbage)) {
-            return false;
-        }
-        long start;
-        if (mBuilder != null) {
-            start = System.currentTimeMillis();
-            mBuilder.startRecord("VCARD");
-            mTimeStartRecord += System.currentTimeMillis() - start;
-        }
-        start = System.currentTimeMillis();
-        parseItems();
-        mTimeParseItems += System.currentTimeMillis() - start;
-        readEndVCard(true, false);
-        if (mBuilder != null) {
-            start = System.currentTimeMillis();
-            mBuilder.endRecord();
-            mTimeEndRecord += System.currentTimeMillis() - start;
-        }
-        return true;
-    }
-    
-    /**
-     * @return True when successful. False when reaching the end of line  
-     * @throws IOException
-     * @throws VCardException
-     */
-    protected boolean readBeginVCard(boolean allowGarbage)
-            throws IOException, VCardException {
-        String line;
-        do {
-            while (true) {
-                line = getLine();
-                if (line == null) {
-                    return false;
-                } else if (line.trim().length() > 0) {
-                    break;
-                }
-            }
-            String[] strArray = line.split(":", 2);
-            int length = strArray.length;
-
-            // Though vCard 2.1/3.0 specification does not allow lower cases,
-            // some data may have them, so we allow it (Actually, previous code
-            // had explicitly allowed "BEGIN:vCard" though there's no example).
-            //
-            // TODO: ignore non vCard entry (e.g. vcalendar).
-            // XXX: Not sure, but according to VDataBuilder.java, vcalendar
-            // entry
-            // may be nested. Just seeking "END:SOMETHING" may not be enough.
-            // e.g.
-            // BEGIN:VCARD
-            // ... (Valid. Must parse this)
-            // END:VCARD
-            // BEGIN:VSOMETHING
-            // ... (Must ignore this)
-            // BEGIN:VSOMETHING2
-            // ... (Must ignore this)
-            // END:VSOMETHING2
-            // ... (Must ignore this!)
-            // END:VSOMETHING
-            // BEGIN:VCARD
-            // ... (Valid. Must parse this)
-            // END:VCARD
-            // INVALID_STRING (VCardException should be thrown)
-            if (length == 2 &&
-                    strArray[0].trim().equalsIgnoreCase("BEGIN") &&
-                    strArray[1].trim().equalsIgnoreCase("VCARD")) {
-                return true;
-            } else if (!allowGarbage) {
-                if (mNestCount > 0) {
-                    mPreviousLine = line;
-                    return false;
-                } else {
-                    throw new VCardException(
-                            "Expected String \"BEGIN:VCARD\" did not come "
-                            + "(Instead, \"" + line + "\" came)");
-                }
-            }
-        } while(allowGarbage);
-
-        throw new VCardException("Reached where must not be reached.");
-    }
-
-    /**
-     * The arguments useCache and allowGarbase are usually true and false accordingly when
-     * this function is called outside this function itself. 
-     * 
-     * @param useCache When true, line is obtained from mPreviousline. Otherwise, getLine()
-     * is used.
-     * @param allowGarbage When true, ignore non "END:VCARD" line.
-     * @throws IOException
-     * @throws VCardException
-     */
-    protected void readEndVCard(boolean useCache, boolean allowGarbage)
-            throws IOException, VCardException {
-        String line;
-        do {
-            if (useCache) {
-                // Though vCard specification does not allow lower cases,
-                // some data may have them, so we allow it.
-                line = mPreviousLine;
-            } else {
-                while (true) {
-                    line = getLine();
-                    if (line == null) {
-                        throw new VCardException("Expected END:VCARD was not found.");
-                    } else if (line.trim().length() > 0) {
-                        break;
-                    }
-                }
-            }
-
-            String[] strArray = line.split(":", 2);
-            if (strArray.length == 2 &&
-                    strArray[0].trim().equalsIgnoreCase("END") &&
-                    strArray[1].trim().equalsIgnoreCase("VCARD")) {
-                return;
-            } else if (!allowGarbage) {
-                throw new VCardException("END:VCARD != \"" + mPreviousLine + "\"");
-            }
-            useCache = false;
-        } while (allowGarbage);
-    }
-    
-    /**
-     * items = *CRLF item 
-     *       / item
-     */
-    protected void parseItems() throws IOException, VCardException {
-        /* items *CRLF item / item */
-        boolean ended = false;
-        
-        if (mBuilder != null) {
-            long start = System.currentTimeMillis();
-            mBuilder.startProperty();
-            mTimeStartProperty += System.currentTimeMillis() - start;
-        }
-        ended = parseItem();
-        if (mBuilder != null && !ended) {
-            long start = System.currentTimeMillis();
-            mBuilder.endProperty();
-            mTimeEndProperty += System.currentTimeMillis() - start;
-        }
-
-        while (!ended) {
-            // follow VCARD ,it wont reach endProperty
-            if (mBuilder != null) {
-                long start = System.currentTimeMillis();
-                mBuilder.startProperty();
-                mTimeStartProperty += System.currentTimeMillis() - start;
-            }
-            ended = parseItem();
-            if (mBuilder != null && !ended) {
-                long start = System.currentTimeMillis();
-                mBuilder.endProperty();
-                mTimeEndProperty += System.currentTimeMillis() - start;
-            }
-        }
-    }
-    
-    /**
-     * item      = [groups "."] name    [params] ":" value CRLF
-     *           / [groups "."] "ADR"   [params] ":" addressparts CRLF
-     *           / [groups "."] "ORG"   [params] ":" orgparts CRLF
-     *           / [groups "."] "N"     [params] ":" nameparts CRLF
-     *           / [groups "."] "AGENT" [params] ":" vcard CRLF 
-     */
-    protected boolean parseItem() throws IOException, VCardException {
-        mEncoding = sDefaultEncoding;
-
-        String line = getNonEmptyLine();
-        long start = System.currentTimeMillis();
-
-        String[] propertyNameAndValue = separateLineAndHandleGroup(line);
-        if (propertyNameAndValue == null) {
-            return true;
-        }
-        if (propertyNameAndValue.length != 2) {
-            throw new VCardException("Invalid line \"" + line + "\""); 
-        }
-        String propertyName = propertyNameAndValue[0].toUpperCase();
-        String propertyValue = propertyNameAndValue[1];
-
-        mTimeParseItem1 += System.currentTimeMillis() - start;
-
-        if (propertyName.equals("ADR") ||
-                propertyName.equals("ORG") ||
-                propertyName.equals("N")) {
-            start = System.currentTimeMillis();
-            handleMultiplePropertyValue(propertyName, propertyValue);
-            mTimeParseItem3 += System.currentTimeMillis() - start;
-            return false;
-        } else if (propertyName.equals("AGENT")) {
-            handleAgent(propertyValue);
-            return false;
-        } else if (isValidPropertyName(propertyName)) {
-            if (propertyName.equals("BEGIN")) {
-                if (propertyValue.equals("VCARD")) {
-                    throw new VCardNestedException("This vCard has nested vCard data in it.");
-                } else {
-                    throw new VCardException("Unknown BEGIN type: " + propertyValue);
-                }
-            } else if (propertyName.equals("VERSION") &&
-                    !propertyValue.equals(getVersion())) {
-                throw new VCardVersionException("Incompatible version: " + 
-                        propertyValue + " != " + getVersion());
-            }
-            start = System.currentTimeMillis();
-            handlePropertyValue(propertyName, propertyValue);
-            mTimeParseItem2 += System.currentTimeMillis() - start;
-            return false;
-        }
-        
-        throw new VCardException("Unknown property name: \"" + 
-                propertyName + "\"");
-    }
-
-    static private final int STATE_GROUP_OR_PROPNAME = 0;
-    static private final int STATE_PARAMS = 1;
-    // vCard 3.1 specification allows double-quoted param-value, while vCard 2.1 does not.
-    // This is just for safety.
-    static private final int STATE_PARAMS_IN_DQUOTE = 2;
-    
-    protected String[] separateLineAndHandleGroup(String line) throws VCardException {
-        int length = line.length();
-        int state = STATE_GROUP_OR_PROPNAME;
-        int nameIndex = 0;
-
-        String[] propertyNameAndValue = new String[2];
-        
-        for (int i = 0; i < length; i++) {
-            char ch = line.charAt(i); 
-            switch (state) {
-            case STATE_GROUP_OR_PROPNAME:
-                if (ch == ':') { 
-                    String propertyName = line.substring(nameIndex, i);
-                    if (propertyName.equalsIgnoreCase("END")) {
-                        mPreviousLine = line;
-                        return null;
-                    }
-                    if (mBuilder != null) {
-                        mBuilder.propertyName(propertyName);
-                    }
-                    propertyNameAndValue[0] = propertyName; 
-                    if (i < length - 1) {
-                        propertyNameAndValue[1] = line.substring(i + 1); 
-                    } else {
-                        propertyNameAndValue[1] = "";
-                    }
-                    return propertyNameAndValue;
-                } else if (ch == '.') {
-                    String groupName = line.substring(nameIndex, i);
-                    if (mBuilder != null) {
-                        mBuilder.propertyGroup(groupName);
-                    }
-                    nameIndex = i + 1;
-                } else if (ch == ';') {
-                    String propertyName = line.substring(nameIndex, i);
-                    if (propertyName.equalsIgnoreCase("END")) {
-                        mPreviousLine = line;
-                        return null;
-                    }
-                    if (mBuilder != null) {
-                        mBuilder.propertyName(propertyName);
-                    }
-                    propertyNameAndValue[0] = propertyName;
-                    nameIndex = i + 1;
-                    state = STATE_PARAMS;
-                }
-                break;
-            case STATE_PARAMS:
-                if (ch == '"') {
-                    state = STATE_PARAMS_IN_DQUOTE;
-                } else if (ch == ';') { 
-                    handleParams(line.substring(nameIndex, i));
-                    nameIndex = i + 1;
-                } else if (ch == ':') {
-                    handleParams(line.substring(nameIndex, i));
-                    if (i < length - 1) {
-                        propertyNameAndValue[1] = line.substring(i + 1);
-                    } else {
-                        propertyNameAndValue[1] = "";
-                    }
-                    return propertyNameAndValue;
-                }
-                break;
-            case STATE_PARAMS_IN_DQUOTE:
-                if (ch == '"') {
-                    state = STATE_PARAMS;
-                }
-                break;
-            }
-        }
-        
-        throw new VCardException("Invalid line: \"" + line + "\"");
-    }
-    
-    
-    /**
-     * params      = ";" [ws] paramlist
-     * paramlist   = paramlist [ws] ";" [ws] param
-     *             / param
-     * param       = "TYPE" [ws] "=" [ws] ptypeval
-     *             / "VALUE" [ws] "=" [ws] pvalueval
-     *             / "ENCODING" [ws] "=" [ws] pencodingval
-     *             / "CHARSET" [ws] "=" [ws] charsetval
-     *             / "LANGUAGE" [ws] "=" [ws] langval
-     *             / "X-" word [ws] "=" [ws] word
-     *             / knowntype
-     */
-    protected void handleParams(String params) throws VCardException {
-        String[] strArray = params.split("=", 2);
-        if (strArray.length == 2) {
-            String paramName = strArray[0].trim();
-            String paramValue = strArray[1].trim();
-            if (paramName.equals("TYPE")) {
-                handleType(paramValue);
-            } else if (paramName.equals("VALUE")) {
-                handleValue(paramValue);
-            } else if (paramName.equals("ENCODING")) {
-                handleEncoding(paramValue);
-            } else if (paramName.equals("CHARSET")) {
-                handleCharset(paramValue);
-            } else if (paramName.equals("LANGUAGE")) {
-                handleLanguage(paramValue);
-            } else if (paramName.startsWith("X-")) {
-                handleAnyParam(paramName, paramValue);
-            } else {
-                throw new VCardException("Unknown type \"" + paramName + "\"");
-            }
-        } else {
-            handleType(strArray[0]);
-        }
-    }
-    
-    /**
-     * ptypeval  = knowntype / "X-" word
-     */
-    protected void handleType(String ptypeval) {
-        String upperTypeValue = ptypeval;
-        if (!(sKnownTypeSet.contains(upperTypeValue) || upperTypeValue.startsWith("X-")) && 
-                !mWarningValueMap.contains(ptypeval)) {
-            mWarningValueMap.add(ptypeval);
-            Log.w(LOG_TAG, "Type unsupported by vCard 2.1: " + ptypeval);
-        }
-        if (mBuilder != null) {
-            mBuilder.propertyParamType("TYPE");
-            mBuilder.propertyParamValue(upperTypeValue);
-        }
-    }
-    
-    /**
-     * pvalueval = "INLINE" / "URL" / "CONTENT-ID" / "CID" / "X-" word
-     */
-    protected void handleValue(String pvalueval) throws VCardException {
-        if (sKnownValueSet.contains(pvalueval.toUpperCase()) ||
-                pvalueval.startsWith("X-")) {
-            if (mBuilder != null) {
-                mBuilder.propertyParamType("VALUE");
-                mBuilder.propertyParamValue(pvalueval);
-            }
-        } else {
-            throw new VCardException("Unknown value \"" + pvalueval + "\"");
-        }
-    }
-    
-    /**
-     * pencodingval = "7BIT" / "8BIT" / "QUOTED-PRINTABLE" / "BASE64" / "X-" word
-     */
-    protected void handleEncoding(String pencodingval) throws VCardException {
-        if (isValidEncoding(pencodingval) ||
-                pencodingval.startsWith("X-")) {
-            if (mBuilder != null) {
-                mBuilder.propertyParamType("ENCODING");
-                mBuilder.propertyParamValue(pencodingval);
-            }
-            mEncoding = pencodingval;
-        } else {
-            throw new VCardException("Unknown encoding \"" + pencodingval + "\"");
-        }
-    }
-    
-    /**
-     * vCard specification only allows us-ascii and iso-8859-xxx (See RFC 1521),
-     * but some vCard contains other charset, so we allow them. 
-     */
-    protected void handleCharset(String charsetval) {
-        if (mBuilder != null) {
-            mBuilder.propertyParamType("CHARSET");
-            mBuilder.propertyParamValue(charsetval);
-        }
-    }
-    
-    /**
-     * See also Section 7.1 of RFC 1521
-     */
-    protected void handleLanguage(String langval) throws VCardException {
-        String[] strArray = langval.split("-");
-        if (strArray.length != 2) {
-            throw new VCardException("Invalid Language: \"" + langval + "\"");
-        }
-        String tmp = strArray[0];
-        int length = tmp.length();
-        for (int i = 0; i < length; i++) {
-            if (!isLetter(tmp.charAt(i))) {
-                throw new VCardException("Invalid Language: \"" + langval + "\"");
-            }
-        }
-        tmp = strArray[1];
-        length = tmp.length();
-        for (int i = 0; i < length; i++) {
-            if (!isLetter(tmp.charAt(i))) {
-                throw new VCardException("Invalid Language: \"" + langval + "\"");
-            }
-        }
-        if (mBuilder != null) {
-            mBuilder.propertyParamType("LANGUAGE");
-            mBuilder.propertyParamValue(langval);
-        }
-    }
-
-    /**
-     * Mainly for "X-" type. This accepts any kind of type without check.
-     */
-    protected void handleAnyParam(String paramName, String paramValue) {
-        if (mBuilder != null) {
-            mBuilder.propertyParamType(paramName);
-            mBuilder.propertyParamValue(paramValue);
-        }
-    }
-    
-    protected void handlePropertyValue(
-            String propertyName, String propertyValue) throws
-            IOException, VCardException {
-        if (mEncoding.equalsIgnoreCase("QUOTED-PRINTABLE")) {
-            long start = System.currentTimeMillis();
-            String result = getQuotedPrintable(propertyValue);
-            if (mBuilder != null) {
-                ArrayList<String> v = new ArrayList<String>();
-                v.add(result);
-                mBuilder.propertyValues(v);
-            }
-            mTimeHandlePropertyValue2 += System.currentTimeMillis() - start;
-        } else if (mEncoding.equalsIgnoreCase("BASE64") ||
-                mEncoding.equalsIgnoreCase("B")) {
-            long start = System.currentTimeMillis();
-            // It is very rare, but some BASE64 data may be so big that
-            // OutOfMemoryError occurs. To ignore such cases, use try-catch.
-            try {
-                String result = getBase64(propertyValue);
-                if (mBuilder != null) {
-                    ArrayList<String> v = new ArrayList<String>();
-                    v.add(result);
-                    mBuilder.propertyValues(v);
-                }
-            } catch (OutOfMemoryError error) {
-                Log.e(LOG_TAG, "OutOfMemoryError happened during parsing BASE64 data!");
-                if (mBuilder != null) {
-                    mBuilder.propertyValues(null);
-                }
-            }
-            mTimeHandlePropertyValue3 += System.currentTimeMillis() - start;
-        } else {
-            if (!(mEncoding == null || mEncoding.equalsIgnoreCase("7BIT")
-                    || mEncoding.equalsIgnoreCase("8BIT")
-                    || mEncoding.toUpperCase().startsWith("X-"))) {
-                Log.w(LOG_TAG, "The encoding unsupported by vCard spec: \"" + mEncoding + "\".");
-            }
-
-            long start = System.currentTimeMillis();
-            if (mBuilder != null) {
-                ArrayList<String> v = new ArrayList<String>();
-                v.add(maybeUnescapeText(propertyValue));
-                mBuilder.propertyValues(v);
-            }
-            mTimeHandlePropertyValue1 += System.currentTimeMillis() - start;
-        }
-    }
-    
-    protected String getQuotedPrintable(String firstString) throws IOException, VCardException {
-        // Specifically, there may be some padding between = and CRLF.
-        // See the following:
-        //
-        // qp-line := *(qp-segment transport-padding CRLF)
-        //            qp-part transport-padding
-        // qp-segment := qp-section *(SPACE / TAB) "="
-        //             ; Maximum length of 76 characters
-        //
-        // e.g. (from RFC 2045)
-        // Now's the time =
-        // for all folk to come=
-        //  to the aid of their country.
-        if (firstString.trim().endsWith("=")) {
-            // remove "transport-padding"
-            int pos = firstString.length() - 1;
-            while(firstString.charAt(pos) != '=') {
-            }
-            StringBuilder builder = new StringBuilder();
-            builder.append(firstString.substring(0, pos + 1));
-            builder.append("\r\n");
-            String line;
-            while (true) {
-                line = getLine();
-                if (line == null) {
-                    throw new VCardException(
-                            "File ended during parsing quoted-printable String");
-                }
-                if (line.trim().endsWith("=")) {
-                    // remove "transport-padding"
-                    pos = line.length() - 1;
-                    while(line.charAt(pos) != '=') {
-                    }
-                    builder.append(line.substring(0, pos + 1));
-                    builder.append("\r\n");
-                } else {
-                    builder.append(line);
-                    break;
-                }
-            }
-            return builder.toString(); 
-        } else {
-            return firstString;
-        }
-    }
-    
-    protected String getBase64(String firstString) throws IOException, VCardException {
-        StringBuilder builder = new StringBuilder();
-        builder.append(firstString);
-        
-        while (true) {
-            String line = getLine();
-            if (line == null) {
-                throw new VCardException(
-                        "File ended during parsing BASE64 binary");
-            }
-            if (line.length() == 0) {
-                break;
-            }
-            builder.append(line);
-        }
-        
-        return builder.toString();
-    }
-    
-    /**
-     * Mainly for "ADR", "ORG", and "N"
-     * We do not care the number of strnosemi here.
-     * 
-     * addressparts = 0*6(strnosemi ";") strnosemi
-     *              ; PO Box, Extended Addr, Street, Locality, Region,
-     *                Postal Code, Country Name
-     * orgparts     = *(strnosemi ";") strnosemi
-     *              ; First is Organization Name,
-     *                remainder are Organization Units.
-     * nameparts    = 0*4(strnosemi ";") strnosemi
-     *              ; Family, Given, Middle, Prefix, Suffix.
-     *              ; Example:Public;John;Q.;Reverend Dr.;III, Esq.
-     * strnosemi    = *(*nonsemi ("\;" / "\" CRLF)) *nonsemi
-     *              ; To include a semicolon in this string, it must be escaped
-     *              ; with a "\" character.
-     *              
-     * We are not sure whether we should add "\" CRLF to each value.
-     * For now, we exclude them.               
-     */
-    protected void handleMultiplePropertyValue(
-            String propertyName, String propertyValue) throws IOException, VCardException {
-        // vCard 2.1 does not allow QUOTED-PRINTABLE here, but some data have it.
-        if (mEncoding.equalsIgnoreCase("QUOTED-PRINTABLE")) {
-            propertyValue = getQuotedPrintable(propertyValue);
-        }
-
-        if (mBuilder != null) {
-            // TODO: limit should be set in accordance with propertyName?
-            StringBuilder builder = new StringBuilder();
-            ArrayList<String> list = new ArrayList<String>();
-            int length = propertyValue.length();
-            for (int i = 0; i < length; i++) {
-                char ch = propertyValue.charAt(i);
-                if (ch == '\\' && i < length - 1) {
-                    char nextCh = propertyValue.charAt(i + 1);
-                    String unescapedString = maybeUnescape(nextCh); 
-                    if (unescapedString != null) {
-                        builder.append(unescapedString);
-                        i++;
-                    } else {
-                        builder.append(ch);
-                    }
-                } else if (ch == ';') {
-                    list.add(builder.toString());
-                    builder = new StringBuilder();
-                } else {
-                    builder.append(ch);
-                }
-            }
-            list.add(builder.toString());
-            mBuilder.propertyValues(list);
-        }
-    }
-    
-    /**
-     * vCard 2.1 specifies AGENT allows one vcard entry. It is not encoded at all.
-     * 
-     * item     = ...
-     *          / [groups "."] "AGENT"
-     *            [params] ":" vcard CRLF
-     * vcard    = "BEGIN" [ws] ":" [ws] "VCARD" [ws] 1*CRLF
-     *            items *CRLF "END" [ws] ":" [ws] "VCARD"
-     * 
-     */
-    protected void handleAgent(String propertyValue) throws VCardException {
-        throw new VCardException("AGENT Property is not supported.");
-        /* This is insufficient support. Also, AGENT Property is very rare.
-           Ignore it for now.
-           TODO: fix this.
-
-        String[] strArray = propertyValue.split(":", 2);
-        if (!(strArray.length == 2 ||
-                strArray[0].trim().equalsIgnoreCase("BEGIN") && 
-                strArray[1].trim().equalsIgnoreCase("VCARD"))) {
-            throw new VCardException("BEGIN:VCARD != \"" + propertyValue + "\"");
-        }
-        parseItems();
-        readEndVCard();
-        */
-    }
-    
-    /**
-     * For vCard 3.0.
-     */
-    protected String maybeUnescapeText(String text) {
-        return text;
-    }
-    
-    /**
-     * Returns unescaped String if the character should be unescaped. Return null otherwise.
-     * e.g. In vCard 2.1, "\;" should be unescaped into ";" while "\x" should not be.
-     */
-    protected String maybeUnescape(char ch) {
-        // Original vCard 2.1 specification does not allow transformation
-        // "\:" -> ":", "\," -> ",", and "\\" -> "\", but previous implementation of
-        // this class allowed them, so keep it as is.
-        if (ch == '\\' || ch == ';' || ch == ':' || ch == ',') {
-            return String.valueOf(ch);
-        } else {
-            return null;
-        }
-    }
-    
-    /**
-     * Parse the given stream and constructs VCardDataBuilder object.
-     * Note that vCard 2.1 specification allows "CHARSET" parameter, and some career sets
-     * local encoding to it. For example, Japanese phone career uses Shift_JIS, which
-     * is not formally allowed in vCard specification.
-     * As a result, there is a case where the encoding given here does not do well with
-     * the "CHARSET".
-     * 
-     * In order to avoid such cases, It may be fine to use "ISO-8859-1" as an encoding,
-     * and to encode each localized String afterward.
-     * 
-     * RFC 2426 "recommends" (not forces) to use UTF-8, so it may be OK to use
-     * UTF-8 as an encoding when parsing vCard 3.0. But note that some Japanese
-     * phone uses Shift_JIS as a charset (e.g. W61SH), and another uses
-     * "CHARSET=SHIFT_JIS", which is explicitly prohibited in vCard 3.0 specification
-     * (e.g. W53K). 
-     *      
-     * @param is
-     *            The source to parse.
-     * @param charset
-     *            The charset.
-     * @param builder
-     *            The v builder which used to construct data.
-     * @return Return true for success, otherwise false.
-     * @throws IOException
-     */
-    public boolean parse(InputStream is, String charset, VBuilder builder)
-            throws IOException, VCardException {
-        // TODO: make this count error entries instead of just throwing VCardException.
-        
-        // TODO: If we really need to allow only CRLF as line break,
-        // we will have to develop our own BufferedReader().
-        mReader = new CustomBufferedReader(new InputStreamReader(is, charset));
-        
-        mBuilder = builder;
-
-        long start = System.currentTimeMillis();
-        if (mBuilder != null) {
-            mBuilder.start();
-        }
-        parseVCardFile();
-        if (mBuilder != null) {
-            mBuilder.end();
-        }
-        mTimeTotal += System.currentTimeMillis() - start;
-                
-        return true;
-    }
-    
-    public boolean parse(InputStream is, VBuilder builder) throws IOException, VCardException {
-        return parse(is, DEFAULT_CHARSET, builder);
-    }
-    
-    /**
-     * Cancel parsing.
-     * Actual cancel is done after the end of the current one vcard entry parsing.
-     */
-    public void cancel() {
-        mCanceled = true;
-    }
-    
-    /**
-     * It is very, very rare case, but there is a case where
-     * canceled may be already true outside this object.
-     * @hide
-     */
-    public void parse(InputStream is, String charset, VBuilder builder, boolean canceled)
-            throws IOException, VCardException {
-        mCanceled = canceled;
-        parse(is, charset, builder);
-    }
-    
-    public void showDebugInfo() {
-        Log.d(LOG_TAG, "total parsing time:  " + mTimeTotal + " ms");
-        if (mReader instanceof CustomBufferedReader) {
-            Log.d(LOG_TAG, "total readLine time: " +
-                    ((CustomBufferedReader)mReader).getTotalmillisecond() + " ms");
-        }
-        Log.d(LOG_TAG, "mTimeStartRecord: " + mTimeStartRecord + " ms");
-        Log.d(LOG_TAG, "mTimeEndRecord: " + mTimeEndRecord + " ms");
-        Log.d(LOG_TAG, "mTimeParseItem1: " + mTimeParseItem1 + " ms");
-        Log.d(LOG_TAG, "mTimeParseItem2: " + mTimeParseItem2 + " ms");
-        Log.d(LOG_TAG, "mTimeParseItem3: " + mTimeParseItem3 + " ms");
-        Log.d(LOG_TAG, "mTimeHandlePropertyValue1: " + mTimeHandlePropertyValue1 + " ms");
-        Log.d(LOG_TAG, "mTimeHandlePropertyValue2: " + mTimeHandlePropertyValue2 + " ms");
-        Log.d(LOG_TAG, "mTimeHandlePropertyValue3: " + mTimeHandlePropertyValue3 + " ms");
-    }
-    
-    private boolean isLetter(char ch) {
-        if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')) {
-            return true;
-        }
-        return false;
-    }
-}
-
-class CustomBufferedReader extends BufferedReader {
-    private long mTime;
-    
-    public CustomBufferedReader(Reader in) {
-        super(in);
-    }
-    
-    @Override
-    public String readLine() throws IOException {
-        long start = System.currentTimeMillis();
-        String ret = super.readLine();
-        long end = System.currentTimeMillis();
-        mTime += end - start;
-        return ret;
-    }
-    
-    public long getTotalmillisecond() {
-        return mTime;
-    }
-}
diff --git a/core/java/android/syncml/pim/vcard/VCardParser_V30.java b/core/java/android/syncml/pim/vcard/VCardParser_V30.java
deleted file mode 100644
index 10da408..0000000
--- a/core/java/android/syncml/pim/vcard/VCardParser_V30.java
+++ /dev/null
@@ -1,307 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.syncml.pim.vcard;
-
-import android.util.Log;
-
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.HashSet;
-
-/**
- * This class is used to parse vcard3.0. <br>
- * Please refer to vCard Specification 3.0 (http://tools.ietf.org/html/rfc2426)
- */
-@Deprecated
-public class VCardParser_V30 extends VCardParser_V21 {
-    private static final String LOG_TAG = "VCardParser_V30";
-    
-    private static final HashSet<String> acceptablePropsWithParam = new HashSet<String>(
-            Arrays.asList(
-                    "BEGIN", "LOGO", "PHOTO", "LABEL", "FN", "TITLE", "SOUND", 
-                    "VERSION", "TEL", "EMAIL", "TZ", "GEO", "NOTE", "URL",
-                    "BDAY", "ROLE", "REV", "UID", "KEY", "MAILER", // 2.1
-                    "NAME", "PROFILE", "SOURCE", "NICKNAME", "CLASS",
-                    "SORT-STRING", "CATEGORIES", "PRODID")); // 3.0
-    
-    // Although "7bit" and "BASE64" is not allowed in vCard 3.0, we allow it for safety.
-    private static final HashSet<String> sAcceptableEncodingV30 = new HashSet<String>(
-            Arrays.asList("7BIT", "8BIT", "BASE64", "B"));
-    
-    // Although RFC 2426 specifies some property must not have parameters, we allow it, 
-    // since there may be some careers which violates the RFC...
-    private static final HashSet<String> acceptablePropsWithoutParam = new HashSet<String>();
-
-    private String mPreviousLine;
-    
-    @Override
-    protected String getVersion() {
-        return "3.0";
-    }
-    
-    @Override
-    protected boolean isValidPropertyName(String propertyName) {
-        if (!(acceptablePropsWithParam.contains(propertyName) ||
-                acceptablePropsWithoutParam.contains(propertyName) ||
-                propertyName.startsWith("X-")) &&
-                !mWarningValueMap.contains(propertyName)) {
-            mWarningValueMap.add(propertyName);
-            Log.w(LOG_TAG, "Property name unsupported by vCard 3.0: " + propertyName);
-        }
-        return true;
-    }
-    
-    @Override
-    protected boolean isValidEncoding(String encoding) {
-        return sAcceptableEncodingV30.contains(encoding.toUpperCase());
-    }
-    
-    @Override
-    protected String getLine() throws IOException {
-        if (mPreviousLine != null) {
-            String ret = mPreviousLine;
-            mPreviousLine = null;
-            return ret;
-        } else {
-            return mReader.readLine();
-        }
-    }
-    
-    /**
-     * vCard 3.0 requires that the line with space at the beginning of the line
-     * must be combined with previous line. 
-     */
-    @Override
-    protected String getNonEmptyLine() throws IOException, VCardException {
-        String line;
-        StringBuilder builder = null;
-        while (true) {
-            line = mReader.readLine();
-            if (line == null) {
-                if (builder != null) {
-                    return builder.toString();
-                } else if (mPreviousLine != null) {
-                    String ret = mPreviousLine;
-                    mPreviousLine = null;
-                    return ret;
-                }
-                throw new VCardException("Reached end of buffer.");
-            } else if (line.length() == 0) {
-                if (builder != null) {
-                    return builder.toString();
-                } else if (mPreviousLine != null) {
-                    String ret = mPreviousLine;
-                    mPreviousLine = null;
-                    return ret;
-                }
-            } else if (line.charAt(0) == ' ' || line.charAt(0) == '\t') {
-                if (builder != null) {
-                    // See Section 5.8.1 of RFC 2425 (MIME-DIR document).
-                    // Following is the excerpts from it.  
-                    //
-                    // DESCRIPTION:This is a long description that exists on a long line.
-                    // 
-                    // Can be represented as:
-                    //
-                    // DESCRIPTION:This is a long description
-                    //  that exists on a long line.
-                    //
-                    // It could also be represented as:
-                    //
-                    // DESCRIPTION:This is a long descrip
-                    //  tion that exists o
-                    //  n a long line.
-                    builder.append(line.substring(1));
-                } else if (mPreviousLine != null) {
-                    builder = new StringBuilder();
-                    builder.append(mPreviousLine);
-                    mPreviousLine = null;
-                    builder.append(line.substring(1));
-                } else {
-                    throw new VCardException("Space exists at the beginning of the line");
-                }
-            } else {
-                if (mPreviousLine == null) {
-                    mPreviousLine = line;
-                    if (builder != null) {
-                        return builder.toString();
-                    }
-                } else {
-                    String ret = mPreviousLine;
-                    mPreviousLine = line;
-                    return ret;
-                }
-            }
-        }
-    }
-    
-    
-    /**
-     * vcard = [group "."] "BEGIN" ":" "VCARD" 1*CRLF
-     *         1*(contentline)
-     *         ;A vCard object MUST include the VERSION, FN and N types.
-     *         [group "."] "END" ":" "VCARD" 1*CRLF
-     */
-    @Override
-    protected boolean readBeginVCard(boolean allowGarbage) throws IOException, VCardException {
-        // TODO: vCard 3.0 supports group.
-        return super.readBeginVCard(allowGarbage);
-    }
-    
-    @Override
-    protected void readEndVCard(boolean useCache, boolean allowGarbage)
-            throws IOException, VCardException {
-        // TODO: vCard 3.0 supports group.
-        super.readEndVCard(useCache, allowGarbage);
-    }
-
-    /**
-     * vCard 3.0 allows iana-token as paramType, while vCard 2.1 does not.
-     */
-    @Override
-    protected void handleParams(String params) throws VCardException {
-        try {
-            super.handleParams(params);
-        } catch (VCardException e) {
-            // maybe IANA type
-            String[] strArray = params.split("=", 2);
-            if (strArray.length == 2) {
-                handleAnyParam(strArray[0], strArray[1]);
-            } else {
-                // Must not come here in the current implementation.
-                throw new VCardException(
-                        "Unknown params value: " + params);
-            }
-        }
-    }
-    
-    @Override
-    protected void handleAnyParam(String paramName, String paramValue) {
-        // vCard 3.0 accept comma-separated multiple values, but
-        // current PropertyNode does not accept it.
-        // For now, we do not split the values.
-        //
-        // TODO: fix this.
-        super.handleAnyParam(paramName, paramValue);
-    }
-    
-    /**
-     *  vCard 3.0 defines
-     *  
-     *  param         = param-name "=" param-value *("," param-value)
-     *  param-name    = iana-token / x-name
-     *  param-value   = ptext / quoted-string
-     *  quoted-string = DQUOTE QSAFE-CHAR DQUOTE
-     */
-    @Override
-    protected void handleType(String ptypevalues) {
-        String[] ptypeArray = ptypevalues.split(",");
-        mBuilder.propertyParamType("TYPE");
-        for (String value : ptypeArray) {
-            int length = value.length();
-            if (length >= 2 && value.startsWith("\"") && value.endsWith("\"")) {
-                mBuilder.propertyParamValue(value.substring(1, value.length() - 1));
-            } else {
-                mBuilder.propertyParamValue(value);
-            }
-        }
-    }
-
-    @Override
-    protected void handleAgent(String propertyValue) throws VCardException {
-        // The way how vCard 3.0 supports "AGENT" is completely different from vCard 2.0.
-        //
-        // e.g.
-        // AGENT:BEGIN:VCARD\nFN:Joe Friday\nTEL:+1-919-555-7878\n
-        //  TITLE:Area Administrator\, Assistant\n EMAIL\;TYPE=INTERN\n
-        //  ET:jfriday@host.com\nEND:VCARD\n
-        //
-        // TODO: fix this.
-        //
-        // issue:
-        //  vCard 3.0 also allows this as an example.
-        //
-        // AGENT;VALUE=uri:
-        //  CID:JQPUBLIC.part3.960129T083020.xyzMail@host3.com
-        //
-        // This is not VCARD. Should we support this?
-        throw new VCardException("AGENT in vCard 3.0 is not supported yet.");
-    }
-    
-    /**
-     * vCard 3.0 does not require two CRLF at the last of BASE64 data.
-     * It only requires that data should be MIME-encoded.
-     */
-    @Override
-    protected String getBase64(String firstString) throws IOException, VCardException {
-        StringBuilder builder = new StringBuilder();
-        builder.append(firstString);
-        
-        while (true) {
-            String line = getLine();
-            if (line == null) {
-                throw new VCardException(
-                        "File ended during parsing BASE64 binary");
-            }
-            if (line.length() == 0) {
-                break;
-            } else if (!line.startsWith(" ") && !line.startsWith("\t")) {
-                mPreviousLine = line;
-                break;
-            }
-            builder.append(line);
-        }
-        
-        return builder.toString();
-    }
-    
-    /**
-     * ESCAPED-CHAR = "\\" / "\;" / "\," / "\n" / "\N")
-     *              ; \\ encodes \, \n or \N encodes newline
-     *              ; \; encodes ;, \, encodes ,
-     *              
-     * Note: Apple escape ':' into '\:' while does not escape '\'
-     */ 
-    @Override
-    protected String maybeUnescapeText(String text) {
-        StringBuilder builder = new StringBuilder();
-        int length = text.length();
-        for (int i = 0; i < length; i++) {
-            char ch = text.charAt(i);
-            if (ch == '\\' && i < length - 1) {
-                char next_ch = text.charAt(++i); 
-                if (next_ch == 'n' || next_ch == 'N') {
-                    builder.append("\r\n");
-                } else {
-                    builder.append(next_ch);
-                }
-            } else {
-                builder.append(ch);
-            }
-        }
-        return builder.toString();
-    }
-    
-    @Override
-    protected String maybeUnescape(char ch) {
-        if (ch == 'n' || ch == 'N') {
-            return "\r\n";
-        } else {
-            return String.valueOf(ch);
-        }
-    }
-}
diff --git a/core/java/android/syncml/pim/vcard/VCardSourceDetector.java b/core/java/android/syncml/pim/vcard/VCardSourceDetector.java
deleted file mode 100644
index 75172af..0000000
--- a/core/java/android/syncml/pim/vcard/VCardSourceDetector.java
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.syncml.pim.vcard;
-
-import android.syncml.pim.VBuilder;
-
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-/**
- * Class which tries to detects the source of the vCard from its properties.
- * Currently this implementation is very premature.
- */
-@Deprecated
-public class VCardSourceDetector implements VBuilder {
-    // Should only be used in package. 
-    static final int TYPE_UNKNOWN = 0;
-    static final int TYPE_APPLE = 1;
-    static final int TYPE_JAPANESE_MOBILE_PHONE = 2;  // Used in Japanese mobile phones.
-    static final int TYPE_FOMA = 3;  // Used in some Japanese FOMA mobile phones.
-    static final int TYPE_WINDOWS_MOBILE_JP = 4;
-    // TODO: Excel, etc.
-
-    private static Set<String> APPLE_SIGNS = new HashSet<String>(Arrays.asList(
-            "X-PHONETIC-FIRST-NAME", "X-PHONETIC-MIDDLE-NAME", "X-PHONETIC-LAST-NAME",
-            "X-ABADR", "X-ABUID"));
-    
-    private static Set<String> JAPANESE_MOBILE_PHONE_SIGNS = new HashSet<String>(Arrays.asList(
-            "X-GNO", "X-GN", "X-REDUCTION"));
-    
-    private static Set<String> WINDOWS_MOBILE_PHONE_SIGNS = new HashSet<String>(Arrays.asList(
-            "X-MICROSOFT-ASST_TEL", "X-MICROSOFT-ASSISTANT", "X-MICROSOFT-OFFICELOC"));
-    
-    // Note: these signes appears before the signs of the other type (e.g. "X-GN").
-    // In other words, Japanese FOMA mobile phones are detected as FOMA, not JAPANESE_MOBILE_PHONES.
-    private static Set<String> FOMA_SIGNS = new HashSet<String>(Arrays.asList(
-            "X-SD-VERN", "X-SD-FORMAT_VER", "X-SD-CATEGORIES", "X-SD-CLASS", "X-SD-DCREATED",
-            "X-SD-DESCRIPTION"));
-    private static String TYPE_FOMA_CHARSET_SIGN = "X-SD-CHAR_CODE";
-    
-    private int mType = TYPE_UNKNOWN;
-    // Some mobile phones (like FOMA) tells us the charset of the data.
-    private boolean mNeedParseSpecifiedCharset;
-    private String mSpecifiedCharset;
-    
-    public void start() {
-    }
-    
-    public void end() {
-    }
-
-    public void startRecord(String type) {
-    }    
-
-    public void startProperty() {
-        mNeedParseSpecifiedCharset = false;
-    }
-    
-    public void endProperty() {
-    }
-
-    public void endRecord() {
-    }
-
-    public void propertyGroup(String group) {
-    }
-    
-    public void propertyName(String name) {
-        if (name.equalsIgnoreCase(TYPE_FOMA_CHARSET_SIGN)) {
-            mType = TYPE_FOMA;
-            mNeedParseSpecifiedCharset = true;
-            return;
-        }
-        if (mType != TYPE_UNKNOWN) {
-            return;
-        }
-        if (WINDOWS_MOBILE_PHONE_SIGNS.contains(name)) {
-            mType = TYPE_WINDOWS_MOBILE_JP;
-        } else if (FOMA_SIGNS.contains(name)) {
-            mType = TYPE_FOMA;
-        } else if (JAPANESE_MOBILE_PHONE_SIGNS.contains(name)) {
-            mType = TYPE_JAPANESE_MOBILE_PHONE;
-        } else if (APPLE_SIGNS.contains(name)) {
-            mType = TYPE_APPLE;
-        }
-    }
-
-    public void propertyParamType(String type) {
-    }
-
-    public void propertyParamValue(String value) {
-    }
-
-    public void propertyValues(List<String> values) {
-        if (mNeedParseSpecifiedCharset && values.size() > 0) {
-            mSpecifiedCharset = values.get(0);
-        }
-    }
-
-    int getType() {
-        return mType;
-    }
-    
-    /**
-     * Return charset String guessed from the source's properties.
-     * This method must be called after parsing target file(s).
-     * @return Charset String. Null is returned if guessing the source fails.
-     */
-    public String getEstimatedCharset() {
-        if (mSpecifiedCharset != null) {
-            return mSpecifiedCharset;
-        }
-        switch (mType) {
-        case TYPE_WINDOWS_MOBILE_JP:
-        case TYPE_FOMA:
-        case TYPE_JAPANESE_MOBILE_PHONE:
-            return "SHIFT_JIS";
-        case TYPE_APPLE:
-            return "UTF-8";
-        default:
-            return null;
-        }
-    }
-}
diff --git a/core/java/android/syncml/pim/vcard/VCardVersionException.java b/core/java/android/syncml/pim/vcard/VCardVersionException.java
deleted file mode 100644
index 8afec9b..0000000
--- a/core/java/android/syncml/pim/vcard/VCardVersionException.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.syncml.pim.vcard;
-
-/**
- * VCardException used only when the version of the vCard is different.
- */
-@Deprecated
-public class VCardVersionException extends VCardException {
-    public VCardVersionException() {
-    }
-
-    public VCardVersionException(String message) {
-        super(message);
-    }
-}
diff --git a/core/java/android/syncml/pim/vcard/package.html b/core/java/android/syncml/pim/vcard/package.html
deleted file mode 100644
index cb4ca46..0000000
--- a/core/java/android/syncml/pim/vcard/package.html
+++ /dev/null
@@ -1,6 +0,0 @@
-<HTML>
-<BODY>
-Support classes for SyncML.
-{@hide}
-</BODY>
-</HTML>
\ No newline at end of file
