diff --git a/src/com/android/phone/DumpsysHandler.java b/src/com/android/phone/DumpsysHandler.java
index d2ae38f..a0277fc 100644
--- a/src/com/android/phone/DumpsysHandler.java
+++ b/src/com/android/phone/DumpsysHandler.java
@@ -3,7 +3,7 @@
 
 import android.content.Context;
 
-import com.android.phone.vvm.omtp.utils.VvmDumpHandler;
+import com.android.phone.vvm.VvmDumpHandler;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
diff --git a/src/com/android/phone/NotificationMgr.java b/src/com/android/phone/NotificationMgr.java
index fdbd1a3..9f6f435 100644
--- a/src/com/android/phone/NotificationMgr.java
+++ b/src/com/android/phone/NotificationMgr.java
@@ -56,7 +56,6 @@
 import com.android.internal.telephony.TelephonyCapabilities;
 import com.android.phone.settings.VoicemailNotificationSettingsUtil;
 import com.android.phone.settings.VoicemailSettingsActivity;
-import com.android.phone.vvm.omtp.sync.VoicemailStatusQueryHelper;
 
 import java.util.Iterator;
 import java.util.List;
@@ -249,20 +248,6 @@
         }
 
         Phone phone = PhoneGlobals.getPhone(subId);
-        if (visible && phone != null && shouldCheckVisualVoicemailConfigurationForMwi(subId)) {
-            VoicemailStatusQueryHelper queryHelper = new VoicemailStatusQueryHelper(mContext);
-            PhoneAccountHandle phoneAccount = PhoneUtils.makePstnPhoneAccountHandle(phone);
-            if (queryHelper.isVoicemailSourceConfigured(phoneAccount)) {
-                Log.v(LOG_TAG, "Source configured for visual voicemail, hiding mwi.");
-                // MWI may not be suppressed if the PIN is not set on VVM3 because it is also a
-                // "Not OK" configuration state. But VVM3 never send a MWI after the service is
-                // activated so this should be fine.
-                // TODO(twyen): once unbundled the client should be able to set a flag to suppress
-                // MWI, instead of letting the NotificationMgr try to interpret the states.
-                visible = false;
-            }
-        }
-
         Log.i(LOG_TAG, "updateMwi(): subId " + subId + " update to " + visible);
         mMwiVisible.put(subId, visible);
 
diff --git a/src/com/android/phone/PhoneInterfaceManager.java b/src/com/android/phone/PhoneInterfaceManager.java
index 3f61b34..0e772ab 100644
--- a/src/com/android/phone/PhoneInterfaceManager.java
+++ b/src/com/android/phone/PhoneInterfaceManager.java
@@ -94,9 +94,9 @@
 import com.android.internal.telephony.uicc.UiccCardApplication;
 import com.android.internal.telephony.uicc.UiccController;
 import com.android.internal.util.HexDump;
-import com.android.phone.settings.VisualVoicemailSettingsUtil;
 import com.android.phone.settings.VoicemailNotificationSettingsUtil;
 import com.android.phone.vvm.RemoteVvmTaskManager;
+import com.android.phone.vvm.VisualVoicemailSmsFilterConfig;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
@@ -2017,27 +2017,6 @@
     }
 
     @Override
-    public void setVisualVoicemailEnabled(String callingPackage,
-            PhoneAccountHandle phoneAccountHandle, boolean enabled) {
-        mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
-        if (!TextUtils.equals(callingPackage,
-                TelecomManager.from(mPhone.getContext()).getDefaultDialerPackage())) {
-            enforceModifyPermissionOrCarrierPrivilege(
-                    PhoneUtils.getSubIdForPhoneAccountHandle(phoneAccountHandle));
-        }
-        VisualVoicemailSettingsUtil.setEnabled(mPhone.getContext(), phoneAccountHandle, enabled);
-    }
-
-    @Override
-    public boolean isVisualVoicemailEnabled(String callingPackage,
-            PhoneAccountHandle phoneAccountHandle) {
-        if (!canReadPhoneState(callingPackage, "isVisualVoicemailEnabled")) {
-            return false;
-        }
-        return VisualVoicemailSettingsUtil.isEnabled(mPhone.getContext(), phoneAccountHandle);
-    }
-
-    @Override
     public String getVisualVoicemailPackageName(String callingPackage, int subId) {
         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
         if (!canReadPhoneState(callingPackage, "getVisualVoicemailPackageName")) {
diff --git a/src/com/android/phone/VoicemailStatus.java b/src/com/android/phone/VoicemailStatus.java
deleted file mode 100644
index 00130f1..0000000
--- a/src/com/android/phone/VoicemailStatus.java
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.phone;
-
-import android.annotation.Nullable;
-import android.content.ContentResolver;
-import android.content.ContentValues;
-import android.content.Context;
-import android.net.Uri;
-import android.provider.VoicemailContract;
-import android.provider.VoicemailContract.Status;
-import android.telecom.PhoneAccountHandle;
-import com.android.phone.vvm.omtp.VvmLog;
-
-public class VoicemailStatus {
-
-    private static final String TAG = "VvmStatus";
-
-    public static class Editor {
-
-        private final Context mContext;
-        @Nullable
-        private final PhoneAccountHandle mPhoneAccountHandle;
-
-        private ContentValues mValues = new ContentValues();
-
-        private Editor(Context context, PhoneAccountHandle phoneAccountHandle) {
-            mContext = context;
-            mPhoneAccountHandle = phoneAccountHandle;
-            if (mPhoneAccountHandle == null) {
-                VvmLog.w(TAG, "VoicemailStatus.Editor created with null phone account, status will"
-                        + " not be written");
-            }
-        }
-
-        @Nullable
-        public PhoneAccountHandle getPhoneAccountHandle() {
-            return mPhoneAccountHandle;
-        }
-
-        public Editor setType(String type) {
-            mValues.put(Status.SOURCE_TYPE, type);
-            return this;
-        }
-
-        public Editor setConfigurationState(int configurationState) {
-            mValues.put(Status.CONFIGURATION_STATE, configurationState);
-            return this;
-        }
-
-        public Editor setDataChannelState(int dataChannelState) {
-            mValues.put(Status.DATA_CHANNEL_STATE, dataChannelState);
-            return this;
-        }
-
-        public Editor setNotificationChannelState(int notificationChannelState) {
-            mValues.put(Status.NOTIFICATION_CHANNEL_STATE, notificationChannelState);
-            return this;
-        }
-
-        public Editor setQuota(int occupied, int total) {
-            if (occupied == VoicemailContract.Status.QUOTA_UNAVAILABLE
-                    && total == VoicemailContract.Status.QUOTA_UNAVAILABLE) {
-                return this;
-            }
-
-            mValues.put(Status.QUOTA_OCCUPIED, occupied);
-            mValues.put(Status.QUOTA_TOTAL, total);
-            return this;
-        }
-
-        /**
-         * Apply the changes to the {@link VoicemailStatus} {@link #Editor}.
-         *
-         * @return {@code true} if the changes were successfully applied, {@code false} otherwise.
-         */
-        public boolean apply() {
-            if (mPhoneAccountHandle == null) {
-                return false;
-            }
-            mValues.put(Status.PHONE_ACCOUNT_COMPONENT_NAME,
-                    mPhoneAccountHandle.getComponentName().flattenToString());
-            mValues.put(Status.PHONE_ACCOUNT_ID, mPhoneAccountHandle.getId());
-            ContentResolver contentResolver = mContext.getContentResolver();
-            Uri statusUri = VoicemailContract.Status.buildSourceUri(mContext.getPackageName());
-            try {
-                contentResolver.insert(statusUri, mValues);
-            } catch (IllegalArgumentException iae) {
-                VvmLog.e(TAG, "apply :: failed to insert content resolver ", iae);
-                mValues.clear();
-                return false;
-            }
-            mValues.clear();
-            return true;
-        }
-
-        public ContentValues getValues() {
-            return mValues;
-        }
-    }
-
-    /**
-     * A voicemail status editor that the decision of whether to actually write to the database can
-     * be deferred. This object will be passed around as a usual {@link Editor}, but {@link
-     * #apply()} doesn't do anything. If later the creator of this object decides any status changes
-     * written to it should be committed, {@link #deferredApply()} should be called.
-     */
-    public static class DeferredEditor extends Editor {
-
-        private DeferredEditor(Context context, PhoneAccountHandle phoneAccountHandle) {
-            super(context, phoneAccountHandle);
-        }
-
-        @Override
-        public boolean apply() {
-            // Do nothing
-            return true;
-        }
-
-        public void deferredApply() {
-            super.apply();
-        }
-    }
-
-    public static Editor edit(Context context, PhoneAccountHandle phoneAccountHandle) {
-        return new Editor(context, phoneAccountHandle);
-    }
-
-    /**
-     * Reset the status to the "disabled" state, which the UI should not show anything for this
-     * subId.
-     */
-    public static void disable(Context context, PhoneAccountHandle phoneAccountHandle) {
-        edit(context, phoneAccountHandle)
-                .setConfigurationState(Status.CONFIGURATION_STATE_NOT_CONFIGURED)
-                .setDataChannelState(Status.DATA_CHANNEL_STATE_NO_CONNECTION)
-                .setNotificationChannelState(Status.NOTIFICATION_CHANNEL_STATE_NO_CONNECTION)
-                .apply();
-    }
-
-    public static DeferredEditor deferredEdit(Context context,
-            PhoneAccountHandle phoneAccountHandle) {
-        return new DeferredEditor(context, phoneAccountHandle);
-    }
-}
diff --git a/src/com/android/phone/common/mail/Address.java b/src/com/android/phone/common/mail/Address.java
deleted file mode 100644
index 5928b63..0000000
--- a/src/com/android/phone/common/mail/Address.java
+++ /dev/null
@@ -1,544 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.phone.common.mail;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.text.Html;
-import android.text.TextUtils;
-import android.text.util.Rfc822Token;
-import android.text.util.Rfc822Tokenizer;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.phone.common.mail.utils.LogUtils;
-
-import org.apache.james.mime4j.codec.EncoderUtil;
-import org.apache.james.mime4j.decoder.DecoderUtil;
-
-import java.util.ArrayList;
-import java.util.regex.Pattern;
-
-/**
- * This class represent email address.
- *
- * RFC822 email address may have following format.
- *   "name" <address> (comment)
- *   "name" <address>
- *   name <address>
- *   address
- * Name and comment part should be MIME/base64 encoded in header if necessary.
- *
- */
-public class Address implements Parcelable {
-    public static final String ADDRESS_DELIMETER = ",";
-    /**
-     *  Address part, in the form local_part@domain_part. No surrounding angle brackets.
-     */
-    private String mAddress;
-
-    /**
-     * Name part. No surrounding double quote, and no MIME/base64 encoding.
-     * This must be null if Address has no name part.
-     */
-    private String mPersonal;
-
-    /**
-     * When personal is set, it will return the first token of the personal
-     * string. Otherwise, it will return the e-mail address up to the '@' sign.
-     */
-    private String mSimplifiedName;
-
-    // Regex that matches address surrounded by '<>' optionally. '^<?([^>]+)>?$'
-    private static final Pattern REMOVE_OPTIONAL_BRACKET = Pattern.compile("^<?([^>]+)>?$");
-    // Regex that matches personal name surrounded by '""' optionally. '^"?([^"]+)"?$'
-    private static final Pattern REMOVE_OPTIONAL_DQUOTE = Pattern.compile("^\"?([^\"]*)\"?$");
-    // Regex that matches escaped character '\\([\\"])'
-    private static final Pattern UNQUOTE = Pattern.compile("\\\\([\\\\\"])");
-
-    // TODO: LOCAL_PART and DOMAIN_PART_PART are too permissive and can be improved.
-    // TODO: Fix this to better constrain comments.
-    /** Regex for the local part of an email address. */
-    private static final String LOCAL_PART = "[^@]+";
-    /** Regex for each part of the domain part, i.e. the thing between the dots. */
-    private static final String DOMAIN_PART_PART = "[[\\w][\\d]\\-\\(\\)\\[\\]]+";
-    /** Regex for the domain part, which is two or more {@link #DOMAIN_PART_PART} separated by . */
-    private static final String DOMAIN_PART =
-            "(" + DOMAIN_PART_PART + "\\.)+" + DOMAIN_PART_PART;
-
-    /** Pattern to check if an email address is valid. */
-    private static final Pattern EMAIL_ADDRESS =
-            Pattern.compile("\\A" + LOCAL_PART + "@" + DOMAIN_PART + "\\z");
-
-    private static final Address[] EMPTY_ADDRESS_ARRAY = new Address[0];
-
-    // delimiters are chars that do not appear in an email address, used by fromHeader
-    private static final char LIST_DELIMITER_EMAIL = '\1';
-    private static final char LIST_DELIMITER_PERSONAL = '\2';
-
-    private static final String LOG_TAG = "Email Address";
-
-    @VisibleForTesting
-    public Address(String address) {
-        setAddress(address);
-    }
-
-    public Address(String address, String personal) {
-        setPersonal(personal);
-        setAddress(address);
-    }
-
-    /**
-     * Returns a simplified string for this e-mail address.
-     * When a name is known, it will return the first token of that name. Otherwise, it will
-     * return the e-mail address up to the '@' sign.
-     */
-    public String getSimplifiedName() {
-        if (mSimplifiedName == null) {
-            if (TextUtils.isEmpty(mPersonal) && !TextUtils.isEmpty(mAddress)) {
-                int atSign = mAddress.indexOf('@');
-                mSimplifiedName = (atSign != -1) ? mAddress.substring(0, atSign) : "";
-            } else if (!TextUtils.isEmpty(mPersonal)) {
-
-                // TODO: use Contacts' NameSplitter for more reliable first-name extraction
-
-                int end = mPersonal.indexOf(' ');
-                while (end > 0 && mPersonal.charAt(end - 1) == ',') {
-                    end--;
-                }
-                mSimplifiedName = (end < 1) ? mPersonal : mPersonal.substring(0, end);
-
-            } else {
-                LogUtils.w(LOG_TAG, "Unable to get a simplified name");
-                mSimplifiedName = "";
-            }
-        }
-        return mSimplifiedName;
-    }
-
-    public static synchronized Address getEmailAddress(String rawAddress) {
-        if (TextUtils.isEmpty(rawAddress)) {
-            return null;
-        }
-        String name, address;
-        final Rfc822Token[] tokens = Rfc822Tokenizer.tokenize(rawAddress);
-        if (tokens.length > 0) {
-            final String tokenizedName = tokens[0].getName();
-            name = tokenizedName != null ? Html.fromHtml(tokenizedName.trim()).toString()
-                    : "";
-            address = Html.fromHtml(tokens[0].getAddress()).toString();
-        } else {
-            name = "";
-            address = rawAddress == null ?
-                    "" : Html.fromHtml(rawAddress).toString();
-        }
-        return new Address(address, name);
-    }
-
-    public String getAddress() {
-        return mAddress;
-    }
-
-    public void setAddress(String address) {
-        mAddress = REMOVE_OPTIONAL_BRACKET.matcher(address).replaceAll("$1");
-    }
-
-    /**
-     * Get name part as UTF-16 string. No surrounding double quote, and no MIME/base64 encoding.
-     *
-     * @return Name part of email address. Returns null if it is omitted.
-     */
-    public String getPersonal() {
-        return mPersonal;
-    }
-
-    /**
-     * Set personal part from UTF-16 string. Optional surrounding double quote will be removed.
-     * It will be also unquoted and MIME/base64 decoded.
-     *
-     * @param personal name part of email address as UTF-16 string. Null is acceptable.
-     */
-    public void setPersonal(String personal) {
-        mPersonal = decodeAddressPersonal(personal);
-    }
-
-    /**
-     * Decodes name from UTF-16 string. Optional surrounding double quote will be removed.
-     * It will be also unquoted and MIME/base64 decoded.
-     *
-     * @param personal name part of email address as UTF-16 string. Null is acceptable.
-     */
-    public static String decodeAddressPersonal(String personal) {
-        if (personal != null) {
-            personal = REMOVE_OPTIONAL_DQUOTE.matcher(personal).replaceAll("$1");
-            personal = UNQUOTE.matcher(personal).replaceAll("$1");
-            personal = DecoderUtil.decodeEncodedWords(personal);
-            if (personal.length() == 0) {
-                personal = null;
-            }
-        }
-        return personal;
-    }
-
-    /**
-     * This method is used to check that all the addresses that the user
-     * entered in a list (e.g. To:) are valid, so that none is dropped.
-     */
-    @VisibleForTesting
-    public static boolean isAllValid(String addressList) {
-        // This code mimics the parse() method below.
-        // I don't know how to better avoid the code-duplication.
-        if (addressList != null && addressList.length() > 0) {
-            Rfc822Token[] tokens = Rfc822Tokenizer.tokenize(addressList);
-            for (int i = 0, length = tokens.length; i < length; ++i) {
-                Rfc822Token token = tokens[i];
-                String address = token.getAddress();
-                if (!TextUtils.isEmpty(address) && !isValidAddress(address)) {
-                    return false;
-                }
-            }
-        }
-        return true;
-    }
-
-    /**
-     * Parse a comma-delimited list of addresses in RFC822 format and return an
-     * array of Address objects.
-     *
-     * @param addressList Address list in comma-delimited string.
-     * @return An array of 0 or more Addresses.
-     */
-    public static Address[] parse(String addressList) {
-        if (addressList == null || addressList.length() == 0) {
-            return EMPTY_ADDRESS_ARRAY;
-        }
-        Rfc822Token[] tokens = Rfc822Tokenizer.tokenize(addressList);
-        ArrayList<Address> addresses = new ArrayList<Address>();
-        for (int i = 0, length = tokens.length; i < length; ++i) {
-            Rfc822Token token = tokens[i];
-            String address = token.getAddress();
-            if (!TextUtils.isEmpty(address)) {
-                if (isValidAddress(address)) {
-                    String name = token.getName();
-                    if (TextUtils.isEmpty(name)) {
-                        name = null;
-                    }
-                    addresses.add(new Address(address, name));
-                }
-            }
-        }
-        return addresses.toArray(new Address[addresses.size()]);
-    }
-
-    /**
-     * Checks whether a string email address is valid.
-     * E.g. name@domain.com is valid.
-     */
-    @VisibleForTesting
-    static boolean isValidAddress(final String address) {
-        return EMAIL_ADDRESS.matcher(address).find();
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (o instanceof Address) {
-            // It seems that the spec says that the "user" part is case-sensitive,
-            // while the domain part in case-insesitive.
-            // So foo@yahoo.com and Foo@yahoo.com are different.
-            // This may seem non-intuitive from the user POV, so we
-            // may re-consider it if it creates UI trouble.
-            // A problem case is "replyAll" sending to both
-            // a@b.c and to A@b.c, which turn out to be the same on the server.
-            // Leave unchanged for now (i.e. case-sensitive).
-            return getAddress().equals(((Address) o).getAddress());
-        }
-        return super.equals(o);
-    }
-
-    @Override
-    public int hashCode() {
-        return getAddress().hashCode();
-    }
-
-    /**
-     * Get human readable address string.
-     * Do not use this for email header.
-     *
-     * @return Human readable address string.  Not quoted and not encoded.
-     */
-    @Override
-    public String toString() {
-        if (mPersonal != null && !mPersonal.equals(mAddress)) {
-            if (mPersonal.matches(".*[\\(\\)<>@,;:\\\\\".\\[\\]].*")) {
-                return ensureQuotedString(mPersonal) + " <" + mAddress + ">";
-            } else {
-                return mPersonal + " <" + mAddress + ">";
-            }
-        } else {
-            return mAddress;
-        }
-    }
-
-    /**
-     * Ensures that the given string starts and ends with the double quote character. The string is
-     * not modified in any way except to add the double quote character to start and end if it's not
-     * already there.
-     *
-     * sample -> "sample"
-     * "sample" -> "sample"
-     * ""sample"" -> "sample"
-     * "sample"" -> "sample"
-     * sa"mp"le -> "sa"mp"le"
-     * "sa"mp"le" -> "sa"mp"le"
-     * (empty string) -> ""
-     * " -> ""
-     */
-    private static String ensureQuotedString(String s) {
-        if (s == null) {
-            return null;
-        }
-        if (!s.matches("^\".*\"$")) {
-            return "\"" + s + "\"";
-        } else {
-            return s;
-        }
-    }
-
-    /**
-     * Get human readable comma-delimited address string.
-     *
-     * @param addresses Address array
-     * @return Human readable comma-delimited address string.
-     */
-    @VisibleForTesting
-    public static String toString(Address[] addresses) {
-        return toString(addresses, ADDRESS_DELIMETER);
-    }
-
-    /**
-     * Get human readable address strings joined with the specified separator.
-     *
-     * @param addresses Address array
-     * @param separator Separator
-     * @return Human readable comma-delimited address string.
-     */
-    public static String toString(Address[] addresses, String separator) {
-        if (addresses == null || addresses.length == 0) {
-            return null;
-        }
-        if (addresses.length == 1) {
-            return addresses[0].toString();
-        }
-        StringBuilder sb = new StringBuilder(addresses[0].toString());
-        for (int i = 1; i < addresses.length; i++) {
-            sb.append(separator);
-            // TODO: investigate why this .trim() is needed.
-            sb.append(addresses[i].toString().trim());
-        }
-        return sb.toString();
-    }
-
-    /**
-     * Get RFC822/MIME compatible address string.
-     *
-     * @return RFC822/MIME compatible address string.
-     * It may be surrounded by double quote or quoted and MIME/base64 encoded if necessary.
-     */
-    public String toHeader() {
-        if (mPersonal != null) {
-            return EncoderUtil.encodeAddressDisplayName(mPersonal) + " <" + mAddress + ">";
-        } else {
-            return mAddress;
-        }
-    }
-
-    /**
-     * Get RFC822/MIME compatible comma-delimited address string.
-     *
-     * @param addresses Address array
-     * @return RFC822/MIME compatible comma-delimited address string.
-     * it may be surrounded by double quoted or quoted and MIME/base64 encoded if necessary.
-     */
-    public static String toHeader(Address[] addresses) {
-        if (addresses == null || addresses.length == 0) {
-            return null;
-        }
-        if (addresses.length == 1) {
-            return addresses[0].toHeader();
-        }
-        StringBuilder sb = new StringBuilder(addresses[0].toHeader());
-        for (int i = 1; i < addresses.length; i++) {
-            // We need space character to be able to fold line.
-            sb.append(", ");
-            sb.append(addresses[i].toHeader());
-        }
-        return sb.toString();
-    }
-
-    /**
-     * Get Human friendly address string.
-     *
-     * @return the personal part of this Address, or the address part if the
-     * personal part is not available
-     */
-    @VisibleForTesting
-    public String toFriendly() {
-        if (mPersonal != null && mPersonal.length() > 0) {
-            return mPersonal;
-        } else {
-            return mAddress;
-        }
-    }
-
-    /**
-     * Creates a comma-delimited list of addresses in the "friendly" format (see toFriendly() for
-     * details on the per-address conversion).
-     *
-     * @param addresses Array of Address[] values
-     * @return A comma-delimited string listing all of the addresses supplied.  Null if source
-     * was null or empty.
-     */
-    @VisibleForTesting
-    public static String toFriendly(Address[] addresses) {
-        if (addresses == null || addresses.length == 0) {
-            return null;
-        }
-        if (addresses.length == 1) {
-            return addresses[0].toFriendly();
-        }
-        StringBuilder sb = new StringBuilder(addresses[0].toFriendly());
-        for (int i = 1; i < addresses.length; i++) {
-            sb.append(", ");
-            sb.append(addresses[i].toFriendly());
-        }
-        return sb.toString();
-    }
-
-    /**
-     * Returns exactly the same result as Address.toString(Address.fromHeader(addressList)).
-     */
-    @VisibleForTesting
-    public static String fromHeaderToString(String addressList) {
-        return toString(fromHeader(addressList));
-    }
-
-    /**
-     * Returns exactly the same result as Address.toHeader(Address.parse(addressList)).
-     */
-    @VisibleForTesting
-    public static String parseToHeader(String addressList) {
-        return Address.toHeader(Address.parse(addressList));
-    }
-
-    /**
-     * Returns null if the addressList has 0 addresses, otherwise returns the first address.
-     * The same as Address.fromHeader(addressList)[0] for non-empty list.
-     * This is an utility method that offers some performance optimization opportunities.
-     */
-    @VisibleForTesting
-    public static Address firstAddress(String addressList) {
-        Address[] array = fromHeader(addressList);
-        return array.length > 0 ? array[0] : null;
-    }
-
-    /**
-     * This method exists to convert an address list formatted in a deprecated legacy format to the
-     * standard RFC822 header format. {@link #fromHeader(String)} is capable of reading the legacy
-     * format and the RFC822 format. {@link #toHeader()} always produces the RFC822 format.
-     *
-     * This implementation is brute-force, and could be replaced with a more efficient version
-     * if desired.
-     */
-    public static String reformatToHeader(String addressList) {
-        return toHeader(fromHeader(addressList));
-    }
-
-    /**
-     * @param addressList a CSV of RFC822 addresses or the deprecated legacy string format
-     * @return array of addresses parsed from <code>addressList</code>
-     */
-    @VisibleForTesting
-    public static Address[] fromHeader(String addressList) {
-        if (addressList == null || addressList.length() == 0) {
-            return EMPTY_ADDRESS_ARRAY;
-        }
-        // IF we're CSV, just parse
-        if ((addressList.indexOf(LIST_DELIMITER_PERSONAL) == -1) &&
-                (addressList.indexOf(LIST_DELIMITER_EMAIL) == -1)) {
-            return Address.parse(addressList);
-        }
-        // Otherwise, do backward-compatible unpack
-        ArrayList<Address> addresses = new ArrayList<Address>();
-        int length = addressList.length();
-        int pairStartIndex = 0;
-        int pairEndIndex;
-
-        /* addressEndIndex is only re-scanned (indexOf()) when a LIST_DELIMITER_PERSONAL
-           is used, not for every email address; i.e. not for every iteration of the while().
-           This reduces the theoretical complexity from quadratic to linear,
-           and provides some speed-up in practice by removing redundant scans of the string.
-        */
-        int addressEndIndex = addressList.indexOf(LIST_DELIMITER_PERSONAL);
-
-        while (pairStartIndex < length) {
-            pairEndIndex = addressList.indexOf(LIST_DELIMITER_EMAIL, pairStartIndex);
-            if (pairEndIndex == -1) {
-                pairEndIndex = length;
-            }
-            Address address;
-            if (addressEndIndex == -1 || pairEndIndex <= addressEndIndex) {
-                // in this case the DELIMITER_PERSONAL is in a future pair,
-                // so don't use personal, and don't update addressEndIndex
-                address = new Address(addressList.substring(pairStartIndex, pairEndIndex), null);
-            } else {
-                address = new Address(addressList.substring(pairStartIndex, addressEndIndex),
-                        addressList.substring(addressEndIndex + 1, pairEndIndex));
-                // only update addressEndIndex when we use the LIST_DELIMITER_PERSONAL
-                addressEndIndex = addressList.indexOf(LIST_DELIMITER_PERSONAL, pairEndIndex + 1);
-            }
-            addresses.add(address);
-            pairStartIndex = pairEndIndex + 1;
-        }
-        return addresses.toArray(new Address[addresses.size()]);
-    }
-
-    public static final Creator<Address> CREATOR = new Creator<Address>() {
-        @Override
-        public Address createFromParcel(Parcel parcel) {
-            return new Address(parcel);
-        }
-
-        @Override
-        public Address[] newArray(int size) {
-            return new Address[size];
-        }
-    };
-
-    public Address(Parcel in) {
-        setPersonal(in.readString());
-        setAddress(in.readString());
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(Parcel out, int flags) {
-        out.writeString(mPersonal);
-        out.writeString(mAddress);
-    }
-}
diff --git a/src/com/android/phone/common/mail/AuthenticationFailedException.java b/src/com/android/phone/common/mail/AuthenticationFailedException.java
deleted file mode 100644
index f13ab45..0000000
--- a/src/com/android/phone/common/mail/AuthenticationFailedException.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.phone.common.mail;
-
-public class AuthenticationFailedException extends MessagingException {
-    public static final long serialVersionUID = -1;
-
-    public AuthenticationFailedException(String message) {
-        super(MessagingException.AUTHENTICATION_FAILED, message);
-    }
-
-    public AuthenticationFailedException(int exceptionType, String message) {
-        super(exceptionType, message);
-    }
-
-    public AuthenticationFailedException(String message, Throwable throwable) {
-        super(MessagingException.AUTHENTICATION_FAILED, message, throwable);
-    }
-}
\ No newline at end of file
diff --git a/src/com/android/phone/common/mail/Base64Body.java b/src/com/android/phone/common/mail/Base64Body.java
deleted file mode 100644
index 757b4b7..0000000
--- a/src/com/android/phone/common/mail/Base64Body.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.phone.common.mail;
-
-import android.util.Base64;
-import android.util.Base64OutputStream;
-
-import org.apache.commons.io.IOUtils;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-
-public class Base64Body implements Body {
-    private final InputStream mSource;
-    // Because we consume the input stream, we can only write out once
-    private boolean mAlreadyWritten;
-
-    public Base64Body(InputStream source) {
-        mSource = source;
-    }
-
-    @Override
-    public InputStream getInputStream() throws MessagingException {
-        return mSource;
-    }
-
-    /**
-     * This method consumes the input stream, so can only be called once
-     * @param out Stream to write to
-     * @throws IllegalStateException If called more than once
-     * @throws IOException
-     * @throws MessagingException
-     */
-    @Override
-    public void writeTo(OutputStream out)
-            throws IllegalStateException, IOException, MessagingException {
-        if (mAlreadyWritten) {
-            throw new IllegalStateException("Base64Body can only be written once");
-        }
-        mAlreadyWritten = true;
-        try {
-            final Base64OutputStream b64out = new Base64OutputStream(out, Base64.DEFAULT);
-            IOUtils.copyLarge(mSource, b64out);
-        } finally {
-            mSource.close();
-        }
-    }
-}
diff --git a/src/com/android/phone/common/mail/Body.java b/src/com/android/phone/common/mail/Body.java
deleted file mode 100644
index 8625ef2..0000000
--- a/src/com/android/phone/common/mail/Body.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.phone.common.mail;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-
-public interface Body {
-    public InputStream getInputStream() throws MessagingException;
-    public void writeTo(OutputStream out) throws IOException, MessagingException;
-}
diff --git a/src/com/android/phone/common/mail/BodyPart.java b/src/com/android/phone/common/mail/BodyPart.java
deleted file mode 100644
index 78140c8..0000000
--- a/src/com/android/phone/common/mail/BodyPart.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.phone.common.mail;
-
-public abstract class BodyPart implements Part {
-    protected Multipart mParent;
-
-    public Multipart getParent() {
-        return mParent;
-    }
-}
diff --git a/src/com/android/phone/common/mail/CertificateValidationException.java b/src/com/android/phone/common/mail/CertificateValidationException.java
deleted file mode 100644
index d8ae9b4..0000000
--- a/src/com/android/phone/common/mail/CertificateValidationException.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.phone.common.mail;
-
-public class CertificateValidationException extends MessagingException {
-    public static final long serialVersionUID = -1;
-
-    public CertificateValidationException(String message) {
-        super(MessagingException.CERTIFICATE_VALIDATION_ERROR, message);
-    }
-
-    public CertificateValidationException(String message, Throwable throwable) {
-        super(MessagingException.CERTIFICATE_VALIDATION_ERROR, message, throwable);
-    }
-}
\ No newline at end of file
diff --git a/src/com/android/phone/common/mail/FetchProfile.java b/src/com/android/phone/common/mail/FetchProfile.java
deleted file mode 100644
index d88dc7c..0000000
--- a/src/com/android/phone/common/mail/FetchProfile.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.phone.common.mail;
-
-import java.util.ArrayList;
-
-/**
- * <pre>
- * A FetchProfile is a list of items that should be downloaded in bulk for a set of messages.
- * FetchProfile can contain the following objects:
- *      FetchProfile.Item:      Described below.
- *      Message:                Indicates that the body of the entire message should be fetched.
- *                              Synonymous with FetchProfile.Item.BODY.
- *      Part:                   Indicates that the given Part should be fetched. The provider
- *                              is expected have previously created the given BodyPart and stored
- *                              any information it needs to download the content.
- * </pre>
- */
-public class FetchProfile extends ArrayList<Fetchable> {
-    /**
-     * Default items available for pre-fetching. It should be expected that any
-     * item fetched by using these items could potentially include all of the
-     * previous items.
-     */
-    public enum Item implements Fetchable {
-        /**
-         * Download the flags of the message.
-         */
-        FLAGS,
-
-        /**
-         * Download the envelope of the message. This should include at minimum
-         * the size and the following headers: date, subject, from, content-type, to, cc
-         */
-        ENVELOPE,
-
-        /**
-         * Download the structure of the message. This maps directly to IMAP's BODYSTRUCTURE
-         * and may map to other providers.
-         * The provider should, if possible, fill in a properly formatted MIME structure in
-         * the message without actually downloading any message data. If the provider is not
-         * capable of this operation it should specifically set the body of the message to null
-         * so that upper levels can detect that a full body download is needed.
-         */
-        STRUCTURE,
-
-        /**
-         * A sane portion of the entire message, cut off at a provider determined limit.
-         * This should generally be around 50kB.
-         */
-        BODY_SANE,
-
-        /**
-         * The entire message.
-         */
-        BODY,
-    }
-
-    /**
-     * @return the first {@link Part} in this collection, or null if it doesn't contain
-     * {@link Part}.
-     */
-    public Part getFirstPart() {
-        for (Fetchable o : this) {
-            if (o instanceof Part) {
-                return (Part) o;
-            }
-        }
-        return null;
-    }
-}
diff --git a/src/com/android/phone/common/mail/Fetchable.java b/src/com/android/phone/common/mail/Fetchable.java
deleted file mode 100644
index 829c672..0000000
--- a/src/com/android/phone/common/mail/Fetchable.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.phone.common.mail;
-
-/**
- * Interface for classes that can be added to {@link FetchProfile}.
- * i.e. {@link Part} and its subclasses, and {@link FetchProfile.Item}.
- */
-public interface Fetchable {
-}
diff --git a/src/com/android/phone/common/mail/FixedLengthInputStream.java b/src/com/android/phone/common/mail/FixedLengthInputStream.java
deleted file mode 100644
index 499feca..0000000
--- a/src/com/android/phone/common/mail/FixedLengthInputStream.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.phone.common.mail;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-/**
- * A filtering InputStream that stops allowing reads after the given length has been read. This
- * is used to allow a client to read directly from an underlying protocol stream without reading
- * past where the protocol handler intended the client to read.
- */
-public class FixedLengthInputStream extends InputStream {
-    private final InputStream mIn;
-    private final int mLength;
-    private int mCount;
-
-    public FixedLengthInputStream(InputStream in, int length) {
-        this.mIn = in;
-        this.mLength = length;
-    }
-
-    @Override
-    public int available() throws IOException {
-        return mLength - mCount;
-    }
-
-    @Override
-    public int read() throws IOException {
-        if (mCount < mLength) {
-            mCount++;
-            return mIn.read();
-        } else {
-            return -1;
-        }
-    }
-
-    @Override
-    public int read(byte[] b, int offset, int length) throws IOException {
-        if (mCount < mLength) {
-            int d = mIn.read(b, offset, Math.min(mLength - mCount, length));
-            if (d == -1) {
-                return -1;
-            } else {
-                mCount += d;
-                return d;
-            }
-        } else {
-            return -1;
-        }
-    }
-
-    @Override
-    public int read(byte[] b) throws IOException {
-        return read(b, 0, b.length);
-    }
-
-    public int getLength() {
-        return mLength;
-    }
-
-    @Override
-    public String toString() {
-        return String.format("FixedLengthInputStream(in=%s, length=%d)", mIn.toString(), mLength);
-    }
-}
\ No newline at end of file
diff --git a/src/com/android/phone/common/mail/Flag.java b/src/com/android/phone/common/mail/Flag.java
deleted file mode 100644
index aa5d7e9..0000000
--- a/src/com/android/phone/common/mail/Flag.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.phone.common.mail;
-
-/**
- * Flags that can be applied to Messages.
- */
-public class Flag {
-    // If adding new flags: ALL FLAGS MUST BE UPPER CASE.
-    public static final String DELETED = "deleted";
-    public static final String SEEN = "seen";
-    public static final String ANSWERED = "answered";
-    public static final String FLAGGED = "flagged";
-    public static final String DRAFT = "draft";
-    public static final String RECENT = "recent";
-}
diff --git a/src/com/android/phone/common/mail/MailTransport.java b/src/com/android/phone/common/mail/MailTransport.java
deleted file mode 100644
index 47b273c..0000000
--- a/src/com/android/phone/common/mail/MailTransport.java
+++ /dev/null
@@ -1,347 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.phone.common.mail;
-
-import android.content.Context;
-import android.net.Network;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.phone.common.mail.store.ImapStore;
-import com.android.phone.common.mail.utils.LogUtils;
-import com.android.phone.vvm.omtp.OmtpEvents;
-import com.android.phone.vvm.omtp.imap.ImapHelper;
-
-import java.io.BufferedInputStream;
-import java.io.BufferedOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.net.Socket;
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.net.ssl.HostnameVerifier;
-import javax.net.ssl.HttpsURLConnection;
-import javax.net.ssl.SSLException;
-import javax.net.ssl.SSLPeerUnverifiedException;
-import javax.net.ssl.SSLSession;
-import javax.net.ssl.SSLSocket;
-
-/**
- * Make connection and perform operations on mail server by reading and writing lines.
- */
-public class MailTransport {
-    private static final String TAG = "MailTransport";
-
-    // TODO protected eventually
-    /*protected*/ public static final int SOCKET_CONNECT_TIMEOUT = 10000;
-    /*protected*/ public static final int SOCKET_READ_TIMEOUT = 60000;
-
-    private static final HostnameVerifier HOSTNAME_VERIFIER =
-            HttpsURLConnection.getDefaultHostnameVerifier();
-
-    private final Context mContext;
-    private final ImapHelper mImapHelper;
-    private final Network mNetwork;
-    private final String mHost;
-    private final int mPort;
-    private Socket mSocket;
-    private BufferedInputStream mIn;
-    private BufferedOutputStream mOut;
-    private final int mFlags;
-    private SocketCreator mSocketCreator;
-    private InetSocketAddress mAddress;
-
-    public MailTransport(Context context, ImapHelper imapHelper, Network network, String address,
-            int port, int flags) {
-        mContext = context;
-        mImapHelper = imapHelper;
-        mNetwork = network;
-        mHost = address;
-        mPort = port;
-        mFlags = flags;
-    }
-
-    /**
-     * Returns a new transport, using the current transport as a model. The new transport is
-     * configured identically, but not opened or connected in any way.
-     */
-    @Override
-    public MailTransport clone() {
-        return new MailTransport(mContext, mImapHelper, mNetwork, mHost, mPort, mFlags);
-    }
-
-    public boolean canTrySslSecurity() {
-        return (mFlags & ImapStore.FLAG_SSL) != 0;
-    }
-
-    public boolean canTrustAllCertificates() {
-        return (mFlags & ImapStore.FLAG_TRUST_ALL) != 0;
-    }
-
-    /**
-     * Attempts to open a connection using the Uri supplied for connection parameters.  Will attempt
-     * an SSL connection if indicated.
-     */
-    public void open() throws MessagingException {
-        LogUtils.d(TAG, "*** IMAP open " + mHost + ":" + String.valueOf(mPort));
-
-        List<InetSocketAddress> socketAddresses = new ArrayList<InetSocketAddress>();
-
-        if (mNetwork == null) {
-            socketAddresses.add(new InetSocketAddress(mHost, mPort));
-        } else {
-            try {
-                InetAddress[] inetAddresses = mNetwork.getAllByName(mHost);
-                if (inetAddresses.length == 0) {
-                    throw new MessagingException(MessagingException.IOERROR,
-                            "Host name " + mHost + "cannot be resolved on designated network");
-                }
-                for (int i = 0; i < inetAddresses.length; i++) {
-                    socketAddresses.add(new InetSocketAddress(inetAddresses[i], mPort));
-                }
-            } catch (IOException ioe) {
-                LogUtils.d(TAG, ioe.toString());
-                mImapHelper.handleEvent(OmtpEvents.DATA_CANNOT_RESOLVE_HOST_ON_NETWORK);
-                throw new MessagingException(MessagingException.IOERROR, ioe.toString());
-            }
-        }
-
-        boolean success = false;
-        while (socketAddresses.size() > 0) {
-            mSocket = createSocket();
-            try {
-                mAddress = socketAddresses.remove(0);
-                mSocket.connect(mAddress, SOCKET_CONNECT_TIMEOUT);
-
-                if (canTrySslSecurity()) {
-                    /*
-                    SSLSocket cannot be created with a connection timeout, so instead of doing a
-                    direct SSL connection, we connect with a normal connection and upgrade it into
-                    SSL
-                     */
-                    reopenTls();
-                } else {
-                    mIn = new BufferedInputStream(mSocket.getInputStream(), 1024);
-                    mOut = new BufferedOutputStream(mSocket.getOutputStream(), 512);
-                    mSocket.setSoTimeout(SOCKET_READ_TIMEOUT);
-                }
-                success = true;
-                return;
-            } catch (IOException ioe) {
-                LogUtils.d(TAG, ioe.toString());
-                if (socketAddresses.size() == 0) {
-                    // Only throw an error when there are no more sockets to try.
-                    mImapHelper.handleEvent(OmtpEvents.DATA_ALL_SOCKET_CONNECTION_FAILED);
-                    throw new MessagingException(MessagingException.IOERROR, ioe.toString());
-                }
-            } finally {
-                if (!success) {
-                    try {
-                        mSocket.close();
-                        mSocket = null;
-                    } catch (IOException ioe) {
-                        throw new MessagingException(MessagingException.IOERROR, ioe.toString());
-                    }
-
-                }
-            }
-        }
-    }
-
-    // For testing. We need something that can replace the behavior of "new Socket()"
-    @VisibleForTesting
-    interface SocketCreator {
-
-        Socket createSocket() throws MessagingException;
-    }
-
-    @VisibleForTesting
-    void setSocketCreator(SocketCreator creator) {
-        mSocketCreator = creator;
-    }
-
-    protected Socket createSocket() throws MessagingException {
-        if (mSocketCreator != null) {
-            return mSocketCreator.createSocket();
-        }
-
-        if (mNetwork == null) {
-            LogUtils.v(TAG, "createSocket: network not specified");
-            return new Socket();
-        }
-
-        try {
-            LogUtils.v(TAG, "createSocket: network specified");
-            return mNetwork.getSocketFactory().createSocket();
-        } catch (IOException ioe) {
-            LogUtils.d(TAG, ioe.toString());
-            throw new MessagingException(MessagingException.IOERROR, ioe.toString());
-        }
-    }
-
-    /**
-     * Attempts to reopen a normal connection into a TLS connection.
-     */
-    public void reopenTls() throws MessagingException {
-        try {
-            LogUtils.d(TAG, "open: converting to TLS socket");
-            mSocket = HttpsURLConnection.getDefaultSSLSocketFactory()
-                    .createSocket(mSocket, mAddress.getHostName(), mAddress.getPort(), true);
-            // After the socket connects to an SSL server, confirm that the hostname is as
-            // expected
-            if (!canTrustAllCertificates()) {
-                verifyHostname(mSocket, mHost);
-            }
-            mSocket.setSoTimeout(SOCKET_READ_TIMEOUT);
-            mIn = new BufferedInputStream(mSocket.getInputStream(), 1024);
-            mOut = new BufferedOutputStream(mSocket.getOutputStream(), 512);
-
-        } catch (SSLException e) {
-            LogUtils.d(TAG, e.toString());
-            throw new CertificateValidationException(e.getMessage(), e);
-        } catch (IOException ioe) {
-            LogUtils.d(TAG, ioe.toString());
-            throw new MessagingException(MessagingException.IOERROR, ioe.toString());
-        }
-    }
-
-    /**
-     * Lightweight version of SSLCertificateSocketFactory.verifyHostname, which provides this
-     * service but is not in the public API.
-     *
-     * Verify the hostname of the certificate used by the other end of a
-     * connected socket. It is harmless to call this method redundantly if the hostname has already
-     * been verified.
-     *
-     * <p>Wildcard certificates are allowed to verify any matching hostname,
-     * so "foo.bar.example.com" is verified if the peer has a certificate
-     * for "*.example.com".
-     *
-     * @param socket An SSL socket which has been connected to a server
-     * @param hostname The expected hostname of the remote server
-     * @throws IOException if something goes wrong handshaking with the server
-     * @throws SSLPeerUnverifiedException if the server cannot prove its identity
-      */
-    private void verifyHostname(Socket socket, String hostname) throws IOException {
-        // The code at the start of OpenSSLSocketImpl.startHandshake()
-        // ensures that the call is idempotent, so we can safely call it.
-        SSLSocket ssl = (SSLSocket) socket;
-        ssl.startHandshake();
-
-        SSLSession session = ssl.getSession();
-        if (session == null) {
-            mImapHelper.handleEvent(OmtpEvents.DATA_CANNOT_ESTABLISH_SSL_SESSION);
-            throw new SSLException("Cannot verify SSL socket without session");
-        }
-        // TODO: Instead of reporting the name of the server we think we're connecting to,
-        // we should be reporting the bad name in the certificate.  Unfortunately this is buried
-        // in the verifier code and is not available in the verifier API, and extracting the
-        // CN & alts is beyond the scope of this patch.
-        if (!HOSTNAME_VERIFIER.verify(hostname, session)) {
-            mImapHelper.handleEvent(OmtpEvents.DATA_SSL_INVALID_HOST_NAME);
-            throw new SSLPeerUnverifiedException("Certificate hostname not useable for server: "
-                    + session.getPeerPrincipal());
-        }
-    }
-
-    public boolean isOpen() {
-        return (mIn != null && mOut != null &&
-                mSocket != null && mSocket.isConnected() && !mSocket.isClosed());
-    }
-
-    /**
-     * Close the connection.  MUST NOT return any exceptions - must be "best effort" and safe.
-     */
-    public void close() {
-        try {
-            mIn.close();
-        } catch (Exception e) {
-            // May fail if the connection is already closed.
-        }
-        try {
-            mOut.close();
-        } catch (Exception e) {
-            // May fail if the connection is already closed.
-        }
-        try {
-            mSocket.close();
-        } catch (Exception e) {
-            // May fail if the connection is already closed.
-        }
-        mIn = null;
-        mOut = null;
-        mSocket = null;
-    }
-
-    public String getHost() {
-        return mHost;
-    }
-
-    public InputStream getInputStream() {
-        return mIn;
-    }
-
-    public OutputStream getOutputStream() {
-        return mOut;
-    }
-
-    /**
-     * Writes a single line to the server using \r\n termination.
-     */
-    public void writeLine(String s, String sensitiveReplacement) throws IOException {
-        if (sensitiveReplacement != null) {
-            LogUtils.d(TAG, ">>> " + sensitiveReplacement);
-        } else {
-            LogUtils.d(TAG, ">>> " + s);
-        }
-
-        OutputStream out = getOutputStream();
-        out.write(s.getBytes());
-        out.write('\r');
-        out.write('\n');
-        out.flush();
-    }
-
-    /**
-     * Reads a single line from the server, using either \r\n or \n as the delimiter.  The
-     * delimiter char(s) are not included in the result.
-     */
-    public String readLine(boolean loggable) throws IOException {
-        StringBuffer sb = new StringBuffer();
-        InputStream in = getInputStream();
-        int d;
-        while ((d = in.read()) != -1) {
-            if (((char)d) == '\r') {
-                continue;
-            } else if (((char)d) == '\n') {
-                break;
-            } else {
-                sb.append((char)d);
-            }
-        }
-        if (d == -1) {
-            LogUtils.d(TAG, "End of stream reached while trying to read line.");
-        }
-        String ret = sb.toString();
-        if (loggable) {
-            LogUtils.d(TAG, "<<< " + ret);
-        }
-        return ret;
-    }
-}
diff --git a/src/com/android/phone/common/mail/MeetingInfo.java b/src/com/android/phone/common/mail/MeetingInfo.java
deleted file mode 100644
index 9fbafe7..0000000
--- a/src/com/android/phone/common/mail/MeetingInfo.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.phone.common.mail;
-
-public class MeetingInfo {
-    // Predefined tags; others can be added
-    public static final String MEETING_DTSTAMP = "DTSTAMP";
-    public static final String MEETING_UID = "UID";
-    public static final String MEETING_ORGANIZER_EMAIL = "ORGMAIL";
-    public static final String MEETING_DTSTART = "DTSTART";
-    public static final String MEETING_DTEND = "DTEND";
-    public static final String MEETING_TITLE = "TITLE";
-    public static final String MEETING_LOCATION = "LOC";
-    public static final String MEETING_RESPONSE_REQUESTED = "RESPONSE";
-    public static final String MEETING_ALL_DAY = "ALLDAY";
-}
diff --git a/src/com/android/phone/common/mail/Message.java b/src/com/android/phone/common/mail/Message.java
deleted file mode 100644
index 0a5ed35..0000000
--- a/src/com/android/phone/common/mail/Message.java
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.phone.common.mail;
-
-import com.android.internal.annotations.VisibleForTesting;
-
-import java.util.Date;
-import java.util.HashSet;
-
-public abstract class Message implements Part, Body {
-    public static final Message[] EMPTY_ARRAY = new Message[0];
-
-    public static final String RECIPIENT_TYPE_TO = "to";
-    public static final String RECIPIENT_TYPE_CC = "cc";
-    public static final String RECIPIENT_TYPE_BCC = "bcc";
-    public enum RecipientType {
-        TO, CC, BCC,
-    }
-
-    protected String mUid;
-
-    private HashSet<String> mFlags = null;
-
-    protected Date mInternalDate;
-
-    public String getUid() {
-        return mUid;
-    }
-
-    public void setUid(String uid) {
-        this.mUid = uid;
-    }
-
-    public abstract String getSubject() throws MessagingException;
-
-    public abstract void setSubject(String subject) throws MessagingException;
-
-    public Date getInternalDate() {
-        return mInternalDate;
-    }
-
-    public void setInternalDate(Date internalDate) {
-        this.mInternalDate = internalDate;
-    }
-
-    public abstract Date getReceivedDate() throws MessagingException;
-
-    public abstract Date getSentDate() throws MessagingException;
-
-    public abstract void setSentDate(Date sentDate) throws MessagingException;
-
-    public abstract Address[] getRecipients(String type) throws MessagingException;
-
-    public abstract void setRecipients(String type, Address[] addresses)
-            throws MessagingException;
-
-    public void setRecipient(String type, Address address) throws MessagingException {
-        setRecipients(type, new Address[] {
-            address
-        });
-    }
-
-    public abstract Address[] getFrom() throws MessagingException;
-
-    public abstract void setFrom(Address from) throws MessagingException;
-
-    public abstract Address[] getReplyTo() throws MessagingException;
-
-    public abstract void setReplyTo(Address[] from) throws MessagingException;
-
-    // Always use these instead of getHeader("Message-ID") or setHeader("Message-ID");
-    public abstract void setMessageId(String messageId) throws MessagingException;
-    public abstract String getMessageId() throws MessagingException;
-
-    @Override
-    public boolean isMimeType(String mimeType) throws MessagingException {
-        return getContentType().startsWith(mimeType);
-    }
-
-    private HashSet<String> getFlagSet() {
-        if (mFlags == null) {
-            mFlags = new HashSet<String>();
-        }
-        return mFlags;
-    }
-
-    /*
-     * TODO Refactor Flags at some point to be able to store user defined flags.
-     */
-    public String[] getFlags() {
-        return getFlagSet().toArray(new String[] {});
-    }
-
-    /**
-     * Set/clear a flag directly, without involving overrides of {@link #setFlag} in subclasses.
-     * Only used for testing.
-     */
-    @VisibleForTesting
-    private final void setFlagDirectlyForTest(String flag, boolean set) throws MessagingException {
-        if (set) {
-            getFlagSet().add(flag);
-        } else {
-            getFlagSet().remove(flag);
-        }
-    }
-
-    public void setFlag(String flag, boolean set) throws MessagingException {
-        setFlagDirectlyForTest(flag, set);
-    }
-
-    /**
-     * This method calls setFlag(String, boolean)
-     * @param flags
-     * @param set
-     */
-    public void setFlags(String[] flags, boolean set) throws MessagingException {
-        for (String flag : flags) {
-            setFlag(flag, set);
-        }
-    }
-
-    public boolean isSet(String flag) {
-        return getFlagSet().contains(flag);
-    }
-
-    public abstract void saveChanges() throws MessagingException;
-
-    @Override
-    public String toString() {
-        return getClass().getSimpleName() + ':' + mUid;
-    }
-}
diff --git a/src/com/android/phone/common/mail/MessageDateComparator.java b/src/com/android/phone/common/mail/MessageDateComparator.java
deleted file mode 100644
index 5d8baa7..0000000
--- a/src/com/android/phone/common/mail/MessageDateComparator.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.phone.common.mail;
-
-import java.util.Comparator;
-
-public class MessageDateComparator implements Comparator<Message> {
-    @Override
-    public int compare(Message o1, Message o2) {
-        try {
-            if (o1.getSentDate() == null) {
-                return 1;
-            } else if (o2.getSentDate() == null) {
-                return -1;
-            } else
-                return o2.getSentDate().compareTo(o1.getSentDate());
-        } catch (Exception e) {
-            return 0;
-        }
-    }
-}
diff --git a/src/com/android/phone/common/mail/MessagingException.java b/src/com/android/phone/common/mail/MessagingException.java
deleted file mode 100644
index e4c674a..0000000
--- a/src/com/android/phone/common/mail/MessagingException.java
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.phone.common.mail;
-
-/**
- * This exception is used for most types of failures that occur during server interactions.
- *
- * Data passed through this exception should be considered non-localized.  Any strings should
- * either be internal-only (for debugging) or server-generated.
- *
- * TO DO: Does it make sense to further collapse AuthenticationFailedException and
- * CertificateValidationException and any others into this?
- */
-public class MessagingException extends Exception {
-    public static final long serialVersionUID = -1;
-
-    public static final int NO_ERROR = -1;
-    /** Any exception that does not specify a specific issue */
-    public static final int UNSPECIFIED_EXCEPTION = 0;
-    /** Connection or IO errors */
-    public static final int IOERROR = 1;
-    /** The configuration requested TLS but the server did not support it. */
-    public static final int TLS_REQUIRED = 2;
-    /** Authentication is required but the server did not support it. */
-    public static final int AUTH_REQUIRED = 3;
-    /** General security failures */
-    public static final int GENERAL_SECURITY = 4;
-    /** Authentication failed */
-    public static final int AUTHENTICATION_FAILED = 5;
-    /** Attempt to create duplicate account */
-    public static final int DUPLICATE_ACCOUNT = 6;
-    /** Required security policies reported - advisory only */
-    public static final int SECURITY_POLICIES_REQUIRED = 7;
-   /** Required security policies not supported */
-    public static final int SECURITY_POLICIES_UNSUPPORTED = 8;
-   /** The protocol (or protocol version) isn't supported */
-    public static final int PROTOCOL_VERSION_UNSUPPORTED = 9;
-    /** The server's SSL certificate couldn't be validated */
-    public static final int CERTIFICATE_VALIDATION_ERROR = 10;
-    /** Authentication failed during autodiscover */
-    public static final int AUTODISCOVER_AUTHENTICATION_FAILED = 11;
-    /** Autodiscover completed with a result (non-error) */
-    public static final int AUTODISCOVER_AUTHENTICATION_RESULT = 12;
-    /** Ambiguous failure; server error or bad credentials */
-    public static final int AUTHENTICATION_FAILED_OR_SERVER_ERROR = 13;
-    /** The server refused access */
-    public static final int ACCESS_DENIED = 14;
-    /** The server refused access */
-    public static final int ATTACHMENT_NOT_FOUND = 15;
-    /** A client SSL certificate is required for connections to the server */
-    public static final int CLIENT_CERTIFICATE_REQUIRED = 16;
-    /** The client SSL certificate specified is invalid */
-    public static final int CLIENT_CERTIFICATE_ERROR = 17;
-    /** The server indicates it does not support OAuth authentication */
-    public static final int OAUTH_NOT_SUPPORTED = 18;
-    /** The server indicates it experienced an internal error */
-    public static final int SERVER_ERROR = 19;
-
-    protected int mExceptionType;
-    // Exception type-specific data
-    protected Object mExceptionData;
-
-    public MessagingException(String message, Throwable throwable) {
-        this(UNSPECIFIED_EXCEPTION, message, throwable);
-    }
-
-    public MessagingException(int exceptionType, String message, Throwable throwable) {
-        super(message, throwable);
-        mExceptionType = exceptionType;
-        mExceptionData = null;
-    }
-
-    /**
-     * Constructs a MessagingException with an exceptionType and a null message.
-     * @param exceptionType The exception type to set for this exception.
-     */
-    public MessagingException(int exceptionType) {
-        this(exceptionType, null, null);
-    }
-
-    /**
-     * Constructs a MessagingException with a message.
-     * @param message the message for this exception
-     */
-    public MessagingException(String message) {
-        this(UNSPECIFIED_EXCEPTION, message, null);
-    }
-
-    /**
-     * Constructs a MessagingException with an exceptionType and a message.
-     * @param exceptionType The exception type to set for this exception.
-     */
-    public MessagingException(int exceptionType, String message) {
-        this(exceptionType, message, null);
-    }
-
-    /**
-     * Constructs a MessagingException with an exceptionType, a message, and data
-     * @param exceptionType The exception type to set for this exception.
-     * @param message the message for the exception (or null)
-     * @param data exception-type specific data for the exception (or null)
-     */
-    public MessagingException(int exceptionType, String message, Object data) {
-        super(message);
-        mExceptionType = exceptionType;
-        mExceptionData = data;
-    }
-
-    /**
-     * Return the exception type.  Will be OTHER_EXCEPTION if not explicitly set.
-     *
-     * @return Returns the exception type.
-     */
-    public int getExceptionType() {
-        return mExceptionType;
-    }
-    /**
-     * Return the exception data.  Will be null if not explicitly set.
-     *
-     * @return Returns the exception data.
-     */
-    public Object getExceptionData() {
-        return mExceptionData;
-    }
-}
\ No newline at end of file
diff --git a/src/com/android/phone/common/mail/Multipart.java b/src/com/android/phone/common/mail/Multipart.java
deleted file mode 100644
index 77963c8..0000000
--- a/src/com/android/phone/common/mail/Multipart.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.phone.common.mail;
-
-import java.util.ArrayList;
-
-public abstract class Multipart implements Body {
-    protected Part mParent;
-
-    protected ArrayList<BodyPart> mParts = new ArrayList<BodyPart>();
-
-    protected String mContentType;
-
-    public void addBodyPart(BodyPart part) throws MessagingException {
-        mParts.add(part);
-    }
-
-    public void addBodyPart(BodyPart part, int index) throws MessagingException {
-        mParts.add(index, part);
-    }
-
-    public BodyPart getBodyPart(int index) throws MessagingException {
-        return mParts.get(index);
-    }
-
-    public String getContentType() throws MessagingException {
-        return mContentType;
-    }
-
-    public int getCount() throws MessagingException {
-        return mParts.size();
-    }
-
-    public boolean removeBodyPart(BodyPart part) throws MessagingException {
-        return mParts.remove(part);
-    }
-
-    public void removeBodyPart(int index) throws MessagingException {
-        mParts.remove(index);
-    }
-
-    public Part getParent() throws MessagingException {
-        return mParent;
-    }
-
-    public void setParent(Part parent) throws MessagingException {
-        this.mParent = parent;
-    }
-}
diff --git a/src/com/android/phone/common/mail/PackedString.java b/src/com/android/phone/common/mail/PackedString.java
deleted file mode 100644
index 6cbba9e..0000000
--- a/src/com/android/phone/common/mail/PackedString.java
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.phone.common.mail;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * A utility class for creating and modifying Strings that are tagged and packed together.
- *
- * Uses non-printable (control chars) for internal delimiters;  Intended for regular displayable
- * strings only, so please use base64 or other encoding if you need to hide any binary data here.
- *
- * Binary compatible with Address.pack() format, which should migrate to use this code.
- */
-public class PackedString {
-
-    /**
-     * Packing format is:
-     *   element : [ value ] or [ value TAG-DELIMITER tag ]
-     *   packed-string : [ element ] [ ELEMENT-DELIMITER [ element ] ]*
-     */
-    private static final char DELIMITER_ELEMENT = '\1';
-    private static final char DELIMITER_TAG = '\2';
-
-    private String mString;
-    private HashMap<String, String> mExploded;
-    private static final HashMap<String, String> EMPTY_MAP = new HashMap<String, String>();
-
-    /**
-     * Create a packed string using an already-packed string (e.g. from database)
-     * @param string packed string
-     */
-    public PackedString(String string) {
-        mString = string;
-        mExploded = null;
-    }
-
-    /**
-     * Get the value referred to by a given tag.  If the tag does not exist, return null.
-     * @param tag identifier of string of interest
-     * @return returns value, or null if no string is found
-     */
-    public String get(String tag) {
-        if (mExploded == null) {
-            mExploded = explode(mString);
-        }
-        return mExploded.get(tag);
-    }
-
-    /**
-     * Return a map of all of the values referred to by a given tag.  This is a shallow
-     * copy, don't edit the values.
-     * @return a map of the values in the packed string
-     */
-    public Map<String, String> unpack() {
-        if (mExploded == null) {
-            mExploded = explode(mString);
-        }
-        return new HashMap<String,String>(mExploded);
-    }
-
-    /**
-     * Read out all values into a map.
-     */
-    private static HashMap<String, String> explode(String packed) {
-        if (packed == null || packed.length() == 0) {
-            return EMPTY_MAP;
-        }
-        HashMap<String, String> map = new HashMap<String, String>();
-
-        int length = packed.length();
-        int elementStartIndex = 0;
-        int elementEndIndex = 0;
-        int tagEndIndex = packed.indexOf(DELIMITER_TAG);
-
-        while (elementStartIndex < length) {
-            elementEndIndex = packed.indexOf(DELIMITER_ELEMENT, elementStartIndex);
-            if (elementEndIndex == -1) {
-                elementEndIndex = length;
-            }
-            String tag;
-            String value;
-            if (tagEndIndex == -1 || elementEndIndex <= tagEndIndex) {
-                // in this case the DELIMITER_PERSONAL is in a future pair (or not found)
-                // so synthesize a positional tag for the value, and don't update tagEndIndex
-                value = packed.substring(elementStartIndex, elementEndIndex);
-                tag = Integer.toString(map.size());
-            } else {
-                value = packed.substring(elementStartIndex, tagEndIndex);
-                tag = packed.substring(tagEndIndex + 1, elementEndIndex);
-                // scan forward for next tag, if any
-                tagEndIndex = packed.indexOf(DELIMITER_TAG, elementEndIndex + 1);
-            }
-            map.put(tag, value);
-            elementStartIndex = elementEndIndex + 1;
-        }
-
-        return map;
-    }
-
-    /**
-     * Builder class for creating PackedString values.  Can also be used for editing existing
-     * PackedString representations.
-     */
-    static public class Builder {
-        HashMap<String, String> mMap;
-
-        /**
-         * Create a builder that's empty (for filling)
-         */
-        public Builder() {
-            mMap = new HashMap<String, String>();
-        }
-
-        /**
-         * Create a builder using the values of an existing PackedString (for editing).
-         */
-        public Builder(String packed) {
-            mMap = explode(packed);
-        }
-
-        /**
-         * Add a tagged value
-         * @param tag identifier of string of interest
-         * @param value the value to record in this position.  null to delete entry.
-         */
-        public void put(String tag, String value) {
-            if (value == null) {
-                mMap.remove(tag);
-            } else {
-                mMap.put(tag, value);
-            }
-        }
-
-        /**
-         * Get the value referred to by a given tag.  If the tag does not exist, return null.
-         * @param tag identifier of string of interest
-         * @return returns value, or null if no string is found
-         */
-        public String get(String tag) {
-            return mMap.get(tag);
-        }
-
-        /**
-         * Pack the values and return a single, encoded string
-         */
-        @Override
-        public String toString() {
-            StringBuilder sb = new StringBuilder();
-            for (Map.Entry<String,String> entry : mMap.entrySet()) {
-                if (sb.length() > 0) {
-                    sb.append(DELIMITER_ELEMENT);
-                }
-                sb.append(entry.getValue());
-                sb.append(DELIMITER_TAG);
-                sb.append(entry.getKey());
-            }
-            return sb.toString();
-        }
-    }
-}
diff --git a/src/com/android/phone/common/mail/Part.java b/src/com/android/phone/common/mail/Part.java
deleted file mode 100644
index d064e2a..0000000
--- a/src/com/android/phone/common/mail/Part.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.phone.common.mail;
-
-import java.io.IOException;
-import java.io.OutputStream;
-
-public interface Part extends Fetchable {
-    public void addHeader(String name, String value) throws MessagingException;
-
-    public void removeHeader(String name) throws MessagingException;
-
-    public void setHeader(String name, String value) throws MessagingException;
-
-    public Body getBody() throws MessagingException;
-
-    public String getContentType() throws MessagingException;
-
-    public String getDisposition() throws MessagingException;
-
-    public String getContentId() throws MessagingException;
-
-    public String[] getHeader(String name) throws MessagingException;
-
-    public void setExtendedHeader(String name, String value) throws MessagingException;
-
-    public String getExtendedHeader(String name) throws MessagingException;
-
-    public int getSize() throws MessagingException;
-
-    public boolean isMimeType(String mimeType) throws MessagingException;
-
-    public String getMimeType() throws MessagingException;
-
-    public void setBody(Body body) throws MessagingException;
-
-    public void writeTo(OutputStream out) throws IOException, MessagingException;
-}
diff --git a/src/com/android/phone/common/mail/PeekableInputStream.java b/src/com/android/phone/common/mail/PeekableInputStream.java
deleted file mode 100644
index d29fc6b..0000000
--- a/src/com/android/phone/common/mail/PeekableInputStream.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.phone.common.mail;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-/**
- * A filtering InputStream that allows single byte "peeks" without consuming the byte. The
- * client of this stream can call peek() to see the next available byte in the stream
- * and a subsequent read will still return the peeked byte.
- */
-public class PeekableInputStream extends InputStream {
-    private final InputStream mIn;
-    private boolean mPeeked;
-    private int mPeekedByte;
-
-    public PeekableInputStream(InputStream in) {
-        this.mIn = in;
-    }
-
-    @Override
-    public int read() throws IOException {
-        if (!mPeeked) {
-            return mIn.read();
-        } else {
-            mPeeked = false;
-            return mPeekedByte;
-        }
-    }
-
-    public int peek() throws IOException {
-        if (!mPeeked) {
-            mPeekedByte = read();
-            mPeeked = true;
-        }
-        return mPeekedByte;
-    }
-
-    @Override
-    public int read(byte[] b, int offset, int length) throws IOException {
-        if (!mPeeked) {
-            return mIn.read(b, offset, length);
-        } else {
-            b[0] = (byte)mPeekedByte;
-            mPeeked = false;
-            int r = mIn.read(b, offset + 1, length - 1);
-            if (r == -1) {
-                return 1;
-            } else {
-                return r + 1;
-            }
-        }
-    }
-
-    @Override
-    public int read(byte[] b) throws IOException {
-        return read(b, 0, b.length);
-    }
-
-    @Override
-    public String toString() {
-        return String.format("PeekableInputStream(in=%s, peeked=%b, peekedByte=%d)",
-                mIn.toString(), mPeeked, mPeekedByte);
-    }
-}
\ No newline at end of file
diff --git a/src/com/android/phone/common/mail/TempDirectory.java b/src/com/android/phone/common/mail/TempDirectory.java
deleted file mode 100644
index 8fa0e44..0000000
--- a/src/com/android/phone/common/mail/TempDirectory.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.phone.common.mail;
-
-import android.content.Context;
-
-import java.io.File;
-
-/**
- * TempDirectory caches the directory used for caching file.  It is set up during application
- * initialization.
- */
-public class TempDirectory {
-    private static File sTempDirectory = null;
-
-    public static void setTempDirectory(Context context) {
-        sTempDirectory = context.getCacheDir();
-    }
-
-    public static File getTempDirectory() {
-        if (sTempDirectory == null) {
-            throw new RuntimeException(
-                    "TempDirectory not set.  " +
-                    "If in a unit test, call Email.setTempDirectory(context) in setUp().");
-        }
-        return sTempDirectory;
-    }
-}
\ No newline at end of file
diff --git a/src/com/android/phone/common/mail/internet/BinaryTempFileBody.java b/src/com/android/phone/common/mail/internet/BinaryTempFileBody.java
deleted file mode 100644
index e2bdd89..0000000
--- a/src/com/android/phone/common/mail/internet/BinaryTempFileBody.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.phone.common.mail.internet;
-
-import com.android.phone.common.mail.Body;
-import com.android.phone.common.mail.MessagingException;
-import com.android.phone.common.mail.TempDirectory;
-
-import org.apache.commons.io.IOUtils;
-
-import android.util.Base64;
-import android.util.Base64OutputStream;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.FilterInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-
-/**
- * A Body that is backed by a temp file. The Body exposes a getOutputStream method that allows
- * the user to write to the temp file. After the write the body is available via getInputStream
- * and writeTo one time. After writeTo is called, or the InputStream returned from
- * getInputStream is closed the file is deleted and the Body should be considered disposed of.
- */
-public class BinaryTempFileBody implements Body {
-    private File mFile;
-
-    /**
-     * An alternate way to put data into a BinaryTempFileBody is to simply supply an already-
-     * created file.  Note that this file will be deleted after it is read.
-     * @param filePath The file containing the data to be stored on disk temporarily
-     */
-    public void setFile(String filePath) {
-        mFile = new File(filePath);
-    }
-
-    public OutputStream getOutputStream() throws IOException {
-        mFile = File.createTempFile("body", null, TempDirectory.getTempDirectory());
-        mFile.deleteOnExit();
-        return new FileOutputStream(mFile);
-    }
-
-    @Override
-    public InputStream getInputStream() throws MessagingException {
-        try {
-            return new BinaryTempFileBodyInputStream(new FileInputStream(mFile));
-        }
-        catch (IOException ioe) {
-            throw new MessagingException("Unable to open body", ioe);
-        }
-    }
-
-    @Override
-    public void writeTo(OutputStream out) throws IOException, MessagingException {
-        InputStream in = getInputStream();
-        Base64OutputStream base64Out = new Base64OutputStream(
-            out, Base64.CRLF | Base64.NO_CLOSE);
-        IOUtils.copy(in, base64Out);
-        base64Out.close();
-        mFile.delete();
-        in.close();
-    }
-
-    class BinaryTempFileBodyInputStream extends FilterInputStream {
-        public BinaryTempFileBodyInputStream(InputStream in) {
-            super(in);
-        }
-
-        @Override
-        public void close() throws IOException {
-            super.close();
-            mFile.delete();
-        }
-    }
-}
diff --git a/src/com/android/phone/common/mail/internet/MimeBodyPart.java b/src/com/android/phone/common/mail/internet/MimeBodyPart.java
deleted file mode 100644
index 286a4f2..0000000
--- a/src/com/android/phone/common/mail/internet/MimeBodyPart.java
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.phone.common.mail.internet;
-
-import com.android.phone.common.mail.Body;
-import com.android.phone.common.mail.BodyPart;
-import com.android.phone.common.mail.MessagingException;
-
-import java.io.BufferedWriter;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
-import java.util.regex.Pattern;
-
-/**
- * TODO this is a close approximation of Message, need to update along with
- * Message.
- */
-public class MimeBodyPart extends BodyPart {
-    protected MimeHeader mHeader = new MimeHeader();
-    protected MimeHeader mExtendedHeader;
-    protected Body mBody;
-    protected int mSize;
-
-    // regex that matches content id surrounded by "<>" optionally.
-    private static final Pattern REMOVE_OPTIONAL_BRACKETS = Pattern.compile("^<?([^>]+)>?$");
-    // regex that matches end of line.
-    private static final Pattern END_OF_LINE = Pattern.compile("\r?\n");
-
-    public MimeBodyPart() throws MessagingException {
-        this(null);
-    }
-
-    public MimeBodyPart(Body body) throws MessagingException {
-        this(body, null);
-    }
-
-    public MimeBodyPart(Body body, String mimeType) throws MessagingException {
-        if (mimeType != null) {
-            setHeader(MimeHeader.HEADER_CONTENT_TYPE, mimeType);
-        }
-        setBody(body);
-    }
-
-    protected String getFirstHeader(String name) throws MessagingException {
-        return mHeader.getFirstHeader(name);
-    }
-
-    @Override
-    public void addHeader(String name, String value) throws MessagingException {
-        mHeader.addHeader(name, value);
-    }
-
-    @Override
-    public void setHeader(String name, String value) throws MessagingException {
-        mHeader.setHeader(name, value);
-    }
-
-    @Override
-    public String[] getHeader(String name) throws MessagingException {
-        return mHeader.getHeader(name);
-    }
-
-    @Override
-    public void removeHeader(String name) throws MessagingException {
-        mHeader.removeHeader(name);
-    }
-
-    @Override
-    public Body getBody() throws MessagingException {
-        return mBody;
-    }
-
-    @Override
-    public void setBody(Body body) throws MessagingException {
-        this.mBody = body;
-        if (body instanceof com.android.phone.common.mail.Multipart) {
-            com.android.phone.common.mail.Multipart multipart =
-                ((com.android.phone.common.mail.Multipart)body);
-            multipart.setParent(this);
-            setHeader(MimeHeader.HEADER_CONTENT_TYPE, multipart.getContentType());
-        }
-        else if (body instanceof TextBody) {
-            String contentType = String.format("%s;\n charset=utf-8", getMimeType());
-            String name = MimeUtility.getHeaderParameter(getContentType(), "name");
-            if (name != null) {
-                contentType += String.format(";\n name=\"%s\"", name);
-            }
-            setHeader(MimeHeader.HEADER_CONTENT_TYPE, contentType);
-            setHeader(MimeHeader.HEADER_CONTENT_TRANSFER_ENCODING, "base64");
-        }
-    }
-
-    @Override
-    public String getContentType() throws MessagingException {
-        String contentType = getFirstHeader(MimeHeader.HEADER_CONTENT_TYPE);
-        if (contentType == null) {
-            return "text/plain";
-        } else {
-            return contentType;
-        }
-    }
-
-    @Override
-    public String getDisposition() throws MessagingException {
-        String contentDisposition = getFirstHeader(MimeHeader.HEADER_CONTENT_DISPOSITION);
-        if (contentDisposition == null) {
-            return null;
-        } else {
-            return contentDisposition;
-        }
-    }
-
-    @Override
-    public String getContentId() throws MessagingException {
-        String contentId = getFirstHeader(MimeHeader.HEADER_CONTENT_ID);
-        if (contentId == null) {
-            return null;
-        } else {
-            // remove optionally surrounding brackets.
-            return REMOVE_OPTIONAL_BRACKETS.matcher(contentId).replaceAll("$1");
-        }
-    }
-
-    @Override
-    public String getMimeType() throws MessagingException {
-        return MimeUtility.getHeaderParameter(getContentType(), null);
-    }
-
-    @Override
-    public boolean isMimeType(String mimeType) throws MessagingException {
-        return getMimeType().equals(mimeType);
-    }
-
-    public void setSize(int size) {
-        this.mSize = size;
-    }
-
-    @Override
-    public int getSize() throws MessagingException {
-        return mSize;
-    }
-
-    /**
-     * Set extended header
-     *
-     * @param name Extended header name
-     * @param value header value - flattened by removing CR-NL if any
-     * remove header if value is null
-     * @throws MessagingException
-     */
-    @Override
-    public void setExtendedHeader(String name, String value) throws MessagingException {
-        if (value == null) {
-            if (mExtendedHeader != null) {
-                mExtendedHeader.removeHeader(name);
-            }
-            return;
-        }
-        if (mExtendedHeader == null) {
-            mExtendedHeader = new MimeHeader();
-        }
-        mExtendedHeader.setHeader(name, END_OF_LINE.matcher(value).replaceAll(""));
-    }
-
-    /**
-     * Get extended header
-     *
-     * @param name Extended header name
-     * @return header value - null if header does not exist
-     * @throws MessagingException
-     */
-    @Override
-    public String getExtendedHeader(String name) throws MessagingException {
-        if (mExtendedHeader == null) {
-            return null;
-        }
-        return mExtendedHeader.getFirstHeader(name);
-    }
-
-    /**
-     * Write the MimeMessage out in MIME format.
-     */
-    @Override
-    public void writeTo(OutputStream out) throws IOException, MessagingException {
-        BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(out), 1024);
-        mHeader.writeTo(out);
-        writer.write("\r\n");
-        writer.flush();
-        if (mBody != null) {
-            mBody.writeTo(out);
-        }
-    }
-}
diff --git a/src/com/android/phone/common/mail/internet/MimeHeader.java b/src/com/android/phone/common/mail/internet/MimeHeader.java
deleted file mode 100644
index 7e6a07f..0000000
--- a/src/com/android/phone/common/mail/internet/MimeHeader.java
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.phone.common.mail.internet;
-
-import com.android.phone.common.mail.MessagingException;
-
-import java.io.BufferedWriter;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
-import java.util.ArrayList;
-
-public class MimeHeader {
-    /**
-     * Application specific header that contains Store specific information about an attachment.
-     * In IMAP this contains the IMAP BODYSTRUCTURE part id so that the ImapStore can later
-     * retrieve the attachment at will from the server.
-     * The info is recorded from this header on LocalStore.appendMessage and is put back
-     * into the MIME data by LocalStore.fetch.
-     */
-    public static final String HEADER_ANDROID_ATTACHMENT_STORE_DATA = "X-Android-Attachment-StoreData";
-
-    public static final String HEADER_CONTENT_TYPE = "Content-Type";
-    public static final String HEADER_CONTENT_TRANSFER_ENCODING = "Content-Transfer-Encoding";
-    public static final String HEADER_CONTENT_DISPOSITION = "Content-Disposition";
-    public static final String HEADER_CONTENT_ID = "Content-ID";
-
-    /**
-     * Fields that should be omitted when writing the header using writeTo()
-     */
-    private static final String[] WRITE_OMIT_FIELDS = {
-//        HEADER_ANDROID_ATTACHMENT_DOWNLOADED,
-//        HEADER_ANDROID_ATTACHMENT_ID,
-        HEADER_ANDROID_ATTACHMENT_STORE_DATA
-    };
-
-    protected final ArrayList<Field> mFields = new ArrayList<Field>();
-
-    public void clear() {
-        mFields.clear();
-    }
-
-    public String getFirstHeader(String name) throws MessagingException {
-        String[] header = getHeader(name);
-        if (header == null) {
-            return null;
-        }
-        return header[0];
-    }
-
-    public void addHeader(String name, String value) throws MessagingException {
-        mFields.add(new Field(name, value));
-    }
-
-    public void setHeader(String name, String value) throws MessagingException {
-        if (name == null || value == null) {
-            return;
-        }
-        removeHeader(name);
-        addHeader(name, value);
-    }
-
-    public String[] getHeader(String name) throws MessagingException {
-        ArrayList<String> values = new ArrayList<String>();
-        for (Field field : mFields) {
-            if (field.name.equalsIgnoreCase(name)) {
-                values.add(field.value);
-            }
-        }
-        if (values.size() == 0) {
-            return null;
-        }
-        return values.toArray(new String[] {});
-    }
-
-    public void removeHeader(String name) throws MessagingException {
-        ArrayList<Field> removeFields = new ArrayList<Field>();
-        for (Field field : mFields) {
-            if (field.name.equalsIgnoreCase(name)) {
-                removeFields.add(field);
-            }
-        }
-        mFields.removeAll(removeFields);
-    }
-
-    /**
-     * Write header into String
-     *
-     * @return CR-NL separated header string except the headers in writeOmitFields
-     * null if header is empty
-     */
-    public String writeToString() {
-        if (mFields.size() == 0) {
-            return null;
-        }
-        StringBuilder builder = new StringBuilder();
-        for (Field field : mFields) {
-            if (!arrayContains(WRITE_OMIT_FIELDS, field.name)) {
-                builder.append(field.name + ": " + field.value + "\r\n");
-            }
-        }
-        return builder.toString();
-    }
-
-    public void writeTo(OutputStream out) throws IOException, MessagingException {
-        BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(out), 1024);
-        for (Field field : mFields) {
-            if (!arrayContains(WRITE_OMIT_FIELDS, field.name)) {
-                writer.write(field.name + ": " + field.value + "\r\n");
-            }
-        }
-        writer.flush();
-    }
-
-    private static class Field {
-        final String name;
-        final String value;
-
-        public Field(String name, String value) {
-            this.name = name;
-            this.value = value;
-        }
-
-        @Override
-        public String toString() {
-            return name + "=" + value;
-        }
-    }
-
-    @Override
-    public String toString() {
-        return (mFields == null) ? null : mFields.toString();
-    }
-
-    public final static boolean arrayContains(Object[] a, Object o) {
-        int index = arrayIndex(a, o);
-        return (index >= 0);
-    }
-
-    public final static int arrayIndex(Object[] a, Object o) {
-        for (int i = 0, count = a.length; i < count; i++) {
-            if (a[i].equals(o)) {
-                return i;
-            }
-        }
-        return -1;
-    }
-}
diff --git a/src/com/android/phone/common/mail/internet/MimeMessage.java b/src/com/android/phone/common/mail/internet/MimeMessage.java
deleted file mode 100644
index f4c6c88..0000000
--- a/src/com/android/phone/common/mail/internet/MimeMessage.java
+++ /dev/null
@@ -1,675 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.phone.common.mail.internet;
-
-import com.android.phone.common.mail.Address;
-import com.android.phone.common.mail.Body;
-import com.android.phone.common.mail.BodyPart;
-import com.android.phone.common.mail.Message;
-import com.android.phone.common.mail.MessagingException;
-import com.android.phone.common.mail.Multipart;
-import com.android.phone.common.mail.Part;
-import com.android.phone.common.mail.utils.LogUtils;
-
-import org.apache.james.mime4j.BodyDescriptor;
-import org.apache.james.mime4j.ContentHandler;
-import org.apache.james.mime4j.EOLConvertingInputStream;
-import org.apache.james.mime4j.MimeStreamParser;
-import org.apache.james.mime4j.field.DateTimeField;
-import org.apache.james.mime4j.field.Field;
-
-import android.text.TextUtils;
-
-import java.io.BufferedWriter;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.Locale;
-import java.util.Stack;
-import java.util.regex.Pattern;
-
-/**
- * An implementation of Message that stores all of its metadata in RFC 822 and
- * RFC 2045 style headers.
- *
- * NOTE:  Automatic generation of a local message-id is becoming unwieldy and should be removed.
- * It would be better to simply do it explicitly on local creation of new outgoing messages.
- */
-public class MimeMessage extends Message {
-    private MimeHeader mHeader;
-    private MimeHeader mExtendedHeader;
-
-    // NOTE:  The fields here are transcribed out of headers, and values stored here will supersede
-    // the values found in the headers.  Use caution to prevent any out-of-phase errors.  In
-    // particular, any adds/changes/deletes here must be echoed by changes in the parse() function.
-    private Address[] mFrom;
-    private Address[] mTo;
-    private Address[] mCc;
-    private Address[] mBcc;
-    private Address[] mReplyTo;
-    private Date mSentDate;
-    private Body mBody;
-    protected int mSize;
-    private boolean mInhibitLocalMessageId = false;
-    private boolean mComplete = true;
-
-    // Shared random source for generating local message-id values
-    private static final java.util.Random sRandom = new java.util.Random();
-
-    // In MIME, en_US-like date format should be used. In other words "MMM" should be encoded to
-    // "Jan", not the other localized format like "Ene" (meaning January in locale es).
-    // This conversion is used when generating outgoing MIME messages. Incoming MIME date
-    // headers are parsed by org.apache.james.mime4j.field.DateTimeField which does not have any
-    // localization code.
-    private static final SimpleDateFormat DATE_FORMAT =
-        new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss Z", Locale.US);
-
-    // regex that matches content id surrounded by "<>" optionally.
-    private static final Pattern REMOVE_OPTIONAL_BRACKETS = Pattern.compile("^<?([^>]+)>?$");
-    // regex that matches end of line.
-    private static final Pattern END_OF_LINE = Pattern.compile("\r?\n");
-
-    public MimeMessage() {
-        mHeader = null;
-    }
-
-    /**
-     * Generate a local message id.  This is only used when none has been assigned, and is
-     * installed lazily.  Any remote (typically server-assigned) message id takes precedence.
-     * @return a long, locally-generated message-ID value
-     */
-    private static String generateMessageId() {
-        final StringBuilder sb = new StringBuilder();
-        sb.append("<");
-        for (int i = 0; i < 24; i++) {
-            // We'll use a 5-bit range (0..31)
-            final int value = sRandom.nextInt() & 31;
-            final char c = "0123456789abcdefghijklmnopqrstuv".charAt(value);
-            sb.append(c);
-        }
-        sb.append(".");
-        sb.append(Long.toString(System.currentTimeMillis()));
-        sb.append("@email.android.com>");
-        return sb.toString();
-    }
-
-    /**
-     * Parse the given InputStream using Apache Mime4J to build a MimeMessage.
-     *
-     * @param in InputStream providing message content
-     * @throws IOException
-     * @throws MessagingException
-     */
-    public MimeMessage(InputStream in) throws IOException, MessagingException {
-        parse(in);
-    }
-
-    private MimeStreamParser init() {
-        // Before parsing the input stream, clear all local fields that may be superceded by
-        // the new incoming message.
-        getMimeHeaders().clear();
-        mInhibitLocalMessageId = true;
-        mFrom = null;
-        mTo = null;
-        mCc = null;
-        mBcc = null;
-        mReplyTo = null;
-        mSentDate = null;
-        mBody = null;
-
-        final MimeStreamParser parser = new MimeStreamParser();
-        parser.setContentHandler(new MimeMessageBuilder());
-        return parser;
-    }
-
-    protected void parse(InputStream in) throws IOException, MessagingException {
-        final MimeStreamParser parser = init();
-        parser.parse(new EOLConvertingInputStream(in));
-        mComplete = !parser.getPrematureEof();
-    }
-
-    public void parse(InputStream in, EOLConvertingInputStream.Callback callback)
-            throws IOException, MessagingException {
-        final MimeStreamParser parser = init();
-        parser.parse(new EOLConvertingInputStream(in, getSize(), callback));
-        mComplete = !parser.getPrematureEof();
-    }
-
-    /**
-     * Return the internal mHeader value, with very lazy initialization.
-     * The goal is to save memory by not creating the headers until needed.
-     */
-    private MimeHeader getMimeHeaders() {
-        if (mHeader == null) {
-            mHeader = new MimeHeader();
-        }
-        return mHeader;
-    }
-
-    @Override
-    public Date getReceivedDate() throws MessagingException {
-        return null;
-    }
-
-    @Override
-    public Date getSentDate() throws MessagingException {
-        if (mSentDate == null) {
-            try {
-                DateTimeField field = (DateTimeField)Field.parse("Date: "
-                        + MimeUtility.unfoldAndDecode(getFirstHeader("Date")));
-                mSentDate = field.getDate();
-                // TODO: We should make it more clear what exceptions can be thrown here,
-                // and whether they reflect a normal or error condition.
-            } catch (Exception e) {
-                LogUtils.v(LogUtils.TAG, "Message missing Date header");
-            }
-        }
-        if (mSentDate == null) {
-            // If we still don't have a date, fall back to "Delivery-date"
-            try {
-                DateTimeField field = (DateTimeField)Field.parse("Date: "
-                        + MimeUtility.unfoldAndDecode(getFirstHeader("Delivery-date")));
-                mSentDate = field.getDate();
-                // TODO: We should make it more clear what exceptions can be thrown here,
-                // and whether they reflect a normal or error condition.
-            } catch (Exception e) {
-                LogUtils.v(LogUtils.TAG, "Message also missing Delivery-Date header");
-            }
-        }
-        return mSentDate;
-    }
-
-    @Override
-    public void setSentDate(Date sentDate) throws MessagingException {
-        setHeader("Date", DATE_FORMAT.format(sentDate));
-        this.mSentDate = sentDate;
-    }
-
-    @Override
-    public String getContentType() throws MessagingException {
-        final String contentType = getFirstHeader(MimeHeader.HEADER_CONTENT_TYPE);
-        if (contentType == null) {
-            return "text/plain";
-        } else {
-            return contentType;
-        }
-    }
-
-    @Override
-    public String getDisposition() throws MessagingException {
-        return getFirstHeader(MimeHeader.HEADER_CONTENT_DISPOSITION);
-    }
-
-    @Override
-    public String getContentId() throws MessagingException {
-        final String contentId = getFirstHeader(MimeHeader.HEADER_CONTENT_ID);
-        if (contentId == null) {
-            return null;
-        } else {
-            // remove optionally surrounding brackets.
-            return REMOVE_OPTIONAL_BRACKETS.matcher(contentId).replaceAll("$1");
-        }
-    }
-
-    public boolean isComplete() {
-        return mComplete;
-    }
-
-    @Override
-    public String getMimeType() throws MessagingException {
-        return MimeUtility.getHeaderParameter(getContentType(), null);
-    }
-
-    @Override
-    public int getSize() throws MessagingException {
-        return mSize;
-    }
-
-    /**
-     * Returns a list of the given recipient type from this message. If no addresses are
-     * found the method returns an empty array.
-     */
-    @Override
-    public Address[] getRecipients(String type) throws MessagingException {
-        if (type == RECIPIENT_TYPE_TO) {
-            if (mTo == null) {
-                mTo = Address.parse(MimeUtility.unfold(getFirstHeader("To")));
-            }
-            return mTo;
-        } else if (type == RECIPIENT_TYPE_CC) {
-            if (mCc == null) {
-                mCc = Address.parse(MimeUtility.unfold(getFirstHeader("CC")));
-            }
-            return mCc;
-        } else if (type == RECIPIENT_TYPE_BCC) {
-            if (mBcc == null) {
-                mBcc = Address.parse(MimeUtility.unfold(getFirstHeader("BCC")));
-            }
-            return mBcc;
-        } else {
-            throw new MessagingException("Unrecognized recipient type.");
-        }
-    }
-
-    @Override
-    public void setRecipients(String type, Address[] addresses) throws MessagingException {
-        final int TO_LENGTH = 4;  // "To: "
-        final int CC_LENGTH = 4;  // "Cc: "
-        final int BCC_LENGTH = 5; // "Bcc: "
-        if (type == RECIPIENT_TYPE_TO) {
-            if (addresses == null || addresses.length == 0) {
-                removeHeader("To");
-                this.mTo = null;
-            } else {
-                setHeader("To", MimeUtility.fold(Address.toHeader(addresses), TO_LENGTH));
-                this.mTo = addresses;
-            }
-        } else if (type == RECIPIENT_TYPE_CC) {
-            if (addresses == null || addresses.length == 0) {
-                removeHeader("CC");
-                this.mCc = null;
-            } else {
-                setHeader("CC", MimeUtility.fold(Address.toHeader(addresses), CC_LENGTH));
-                this.mCc = addresses;
-            }
-        } else if (type == RECIPIENT_TYPE_BCC) {
-            if (addresses == null || addresses.length == 0) {
-                removeHeader("BCC");
-                this.mBcc = null;
-            } else {
-                setHeader("BCC", MimeUtility.fold(Address.toHeader(addresses), BCC_LENGTH));
-                this.mBcc = addresses;
-            }
-        } else {
-            throw new MessagingException("Unrecognized recipient type.");
-        }
-    }
-
-    /**
-     * Returns the unfolded, decoded value of the Subject header.
-     */
-    @Override
-    public String getSubject() throws MessagingException {
-        return MimeUtility.unfoldAndDecode(getFirstHeader("Subject"));
-    }
-
-    @Override
-    public void setSubject(String subject) throws MessagingException {
-        final int HEADER_NAME_LENGTH = 9;     // "Subject: "
-        setHeader("Subject", MimeUtility.foldAndEncode2(subject, HEADER_NAME_LENGTH));
-    }
-
-    @Override
-    public Address[] getFrom() throws MessagingException {
-        if (mFrom == null) {
-            String list = MimeUtility.unfold(getFirstHeader("From"));
-            if (list == null || list.length() == 0) {
-                list = MimeUtility.unfold(getFirstHeader("Sender"));
-            }
-            mFrom = Address.parse(list);
-        }
-        return mFrom;
-    }
-
-    @Override
-    public void setFrom(Address from) throws MessagingException {
-        final int FROM_LENGTH = 6;  // "From: "
-        if (from != null) {
-            setHeader("From", MimeUtility.fold(from.toHeader(), FROM_LENGTH));
-            this.mFrom = new Address[] {
-                    from
-                };
-        } else {
-            this.mFrom = null;
-        }
-    }
-
-    @Override
-    public Address[] getReplyTo() throws MessagingException {
-        if (mReplyTo == null) {
-            mReplyTo = Address.parse(MimeUtility.unfold(getFirstHeader("Reply-to")));
-        }
-        return mReplyTo;
-    }
-
-    @Override
-    public void setReplyTo(Address[] replyTo) throws MessagingException {
-        final int REPLY_TO_LENGTH = 10;  // "Reply-to: "
-        if (replyTo == null || replyTo.length == 0) {
-            removeHeader("Reply-to");
-            mReplyTo = null;
-        } else {
-            setHeader("Reply-to", MimeUtility.fold(Address.toHeader(replyTo), REPLY_TO_LENGTH));
-            mReplyTo = replyTo;
-        }
-    }
-
-    /**
-     * Set the mime "Message-ID" header
-     * @param messageId the new Message-ID value
-     * @throws MessagingException
-     */
-    @Override
-    public void setMessageId(String messageId) throws MessagingException {
-        setHeader("Message-ID", messageId);
-    }
-
-    /**
-     * Get the mime "Message-ID" header.  This value will be preloaded with a locally-generated
-     * random ID, if the value has not previously been set.  Local generation can be inhibited/
-     * overridden by explicitly clearing the headers, removing the message-id header, etc.
-     * @return the Message-ID header string, or null if explicitly has been set to null
-     */
-    @Override
-    public String getMessageId() throws MessagingException {
-        String messageId = getFirstHeader("Message-ID");
-        if (messageId == null && !mInhibitLocalMessageId) {
-            messageId = generateMessageId();
-            setMessageId(messageId);
-        }
-        return messageId;
-    }
-
-    @Override
-    public void saveChanges() throws MessagingException {
-        throw new MessagingException("saveChanges not yet implemented");
-    }
-
-    @Override
-    public Body getBody() throws MessagingException {
-        return mBody;
-    }
-
-    @Override
-    public void setBody(Body body) throws MessagingException {
-        this.mBody = body;
-        if (body instanceof Multipart) {
-            final Multipart multipart = ((Multipart)body);
-            multipart.setParent(this);
-            setHeader(MimeHeader.HEADER_CONTENT_TYPE, multipart.getContentType());
-            setHeader("MIME-Version", "1.0");
-        }
-        else if (body instanceof TextBody) {
-            setHeader(MimeHeader.HEADER_CONTENT_TYPE, String.format("%s;\n charset=utf-8",
-                    getMimeType()));
-            setHeader(MimeHeader.HEADER_CONTENT_TRANSFER_ENCODING, "base64");
-        }
-    }
-
-    protected String getFirstHeader(String name) throws MessagingException {
-        return getMimeHeaders().getFirstHeader(name);
-    }
-
-    @Override
-    public void addHeader(String name, String value) throws MessagingException {
-        getMimeHeaders().addHeader(name, value);
-    }
-
-    @Override
-    public void setHeader(String name, String value) throws MessagingException {
-        getMimeHeaders().setHeader(name, value);
-    }
-
-    @Override
-    public String[] getHeader(String name) throws MessagingException {
-        return getMimeHeaders().getHeader(name);
-    }
-
-    @Override
-    public void removeHeader(String name) throws MessagingException {
-        getMimeHeaders().removeHeader(name);
-        if ("Message-ID".equalsIgnoreCase(name)) {
-            mInhibitLocalMessageId = true;
-        }
-    }
-
-    /**
-     * Set extended header
-     *
-     * @param name Extended header name
-     * @param value header value - flattened by removing CR-NL if any
-     * remove header if value is null
-     * @throws MessagingException
-     */
-    @Override
-    public void setExtendedHeader(String name, String value) throws MessagingException {
-        if (value == null) {
-            if (mExtendedHeader != null) {
-                mExtendedHeader.removeHeader(name);
-            }
-            return;
-        }
-        if (mExtendedHeader == null) {
-            mExtendedHeader = new MimeHeader();
-        }
-        mExtendedHeader.setHeader(name, END_OF_LINE.matcher(value).replaceAll(""));
-    }
-
-    /**
-     * Get extended header
-     *
-     * @param name Extended header name
-     * @return header value - null if header does not exist
-     * @throws MessagingException
-     */
-    @Override
-    public String getExtendedHeader(String name) throws MessagingException {
-        if (mExtendedHeader == null) {
-            return null;
-        }
-        return mExtendedHeader.getFirstHeader(name);
-    }
-
-    /**
-     * Set entire extended headers from String
-     *
-     * @param headers Extended header and its value - "CR-NL-separated pairs
-     * if null or empty, remove entire extended headers
-     * @throws MessagingException
-     */
-    public void setExtendedHeaders(String headers) throws MessagingException {
-        if (TextUtils.isEmpty(headers)) {
-            mExtendedHeader = null;
-        } else {
-            mExtendedHeader = new MimeHeader();
-            for (final String header : END_OF_LINE.split(headers)) {
-                final String[] tokens = header.split(":", 2);
-                if (tokens.length != 2) {
-                    throw new MessagingException("Illegal extended headers: " + headers);
-                }
-                mExtendedHeader.setHeader(tokens[0].trim(), tokens[1].trim());
-            }
-        }
-    }
-
-    /**
-     * Get entire extended headers as String
-     *
-     * @return "CR-NL-separated extended headers - null if extended header does not exist
-     */
-    public String getExtendedHeaders() {
-        if (mExtendedHeader != null) {
-            return mExtendedHeader.writeToString();
-        }
-        return null;
-    }
-
-    /**
-     * Write message header and body to output stream
-     *
-     * @param out Output steam to write message header and body.
-     */
-    @Override
-    public void writeTo(OutputStream out) throws IOException, MessagingException {
-        final BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(out), 1024);
-        // Force creation of local message-id
-        getMessageId();
-        getMimeHeaders().writeTo(out);
-        // mExtendedHeader will not be write out to external output stream,
-        // because it is intended to internal use.
-        writer.write("\r\n");
-        writer.flush();
-        if (mBody != null) {
-            mBody.writeTo(out);
-        }
-    }
-
-    @Override
-    public InputStream getInputStream() throws MessagingException {
-        return null;
-    }
-
-    class MimeMessageBuilder implements ContentHandler {
-        private final Stack<Object> stack = new Stack<Object>();
-
-        public MimeMessageBuilder() {
-        }
-
-        private void expect(Class<?> c) {
-            if (!c.isInstance(stack.peek())) {
-                throw new IllegalStateException("Internal stack error: " + "Expected '"
-                        + c.getName() + "' found '" + stack.peek().getClass().getName() + "'");
-            }
-        }
-
-        @Override
-        public void startMessage() {
-            if (stack.isEmpty()) {
-                stack.push(MimeMessage.this);
-            } else {
-                expect(Part.class);
-                try {
-                    final MimeMessage m = new MimeMessage();
-                    ((Part)stack.peek()).setBody(m);
-                    stack.push(m);
-                } catch (MessagingException me) {
-                    throw new Error(me);
-                }
-            }
-        }
-
-        @Override
-        public void endMessage() {
-            expect(MimeMessage.class);
-            stack.pop();
-        }
-
-        @Override
-        public void startHeader() {
-            expect(Part.class);
-        }
-
-        @Override
-        public void field(String fieldData) {
-            expect(Part.class);
-            try {
-                final String[] tokens = fieldData.split(":", 2);
-                ((Part)stack.peek()).addHeader(tokens[0], tokens[1].trim());
-            } catch (MessagingException me) {
-                throw new Error(me);
-            }
-        }
-
-        @Override
-        public void endHeader() {
-            expect(Part.class);
-        }
-
-        @Override
-        public void startMultipart(BodyDescriptor bd) {
-            expect(Part.class);
-
-            final Part e = (Part)stack.peek();
-            try {
-                final MimeMultipart multiPart = new MimeMultipart(e.getContentType());
-                e.setBody(multiPart);
-                stack.push(multiPart);
-            } catch (MessagingException me) {
-                throw new Error(me);
-            }
-        }
-
-        @Override
-        public void body(BodyDescriptor bd, InputStream in) throws IOException {
-            expect(Part.class);
-            final Body body = MimeUtility.decodeBody(in, bd.getTransferEncoding());
-            try {
-                ((Part)stack.peek()).setBody(body);
-            } catch (MessagingException me) {
-                throw new Error(me);
-            }
-        }
-
-        @Override
-        public void endMultipart() {
-            stack.pop();
-        }
-
-        @Override
-        public void startBodyPart() {
-            expect(MimeMultipart.class);
-
-            try {
-                final MimeBodyPart bodyPart = new MimeBodyPart();
-                ((MimeMultipart)stack.peek()).addBodyPart(bodyPart);
-                stack.push(bodyPart);
-            } catch (MessagingException me) {
-                throw new Error(me);
-            }
-        }
-
-        @Override
-        public void endBodyPart() {
-            expect(BodyPart.class);
-            stack.pop();
-        }
-
-        @Override
-        public void epilogue(InputStream is) throws IOException {
-            expect(MimeMultipart.class);
-            final StringBuilder sb = new StringBuilder();
-            int b;
-            while ((b = is.read()) != -1) {
-                sb.append((char)b);
-            }
-            // TODO: why is this commented out?
-            // ((Multipart) stack.peek()).setEpilogue(sb.toString());
-        }
-
-        @Override
-        public void preamble(InputStream is) throws IOException {
-            expect(MimeMultipart.class);
-            final StringBuilder sb = new StringBuilder();
-            int b;
-            while ((b = is.read()) != -1) {
-                sb.append((char)b);
-            }
-            try {
-                ((MimeMultipart)stack.peek()).setPreamble(sb.toString());
-            } catch (MessagingException me) {
-                throw new Error(me);
-            }
-        }
-
-        @Override
-        public void raw(InputStream is) throws IOException {
-            throw new UnsupportedOperationException("Not supported");
-        }
-    }
-}
diff --git a/src/com/android/phone/common/mail/internet/MimeMultipart.java b/src/com/android/phone/common/mail/internet/MimeMultipart.java
deleted file mode 100644
index 3e118e4..0000000
--- a/src/com/android/phone/common/mail/internet/MimeMultipart.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.phone.common.mail.internet;
-
-import com.android.phone.common.mail.BodyPart;
-import com.android.phone.common.mail.MessagingException;
-import com.android.phone.common.mail.Multipart;
-
-import java.io.BufferedWriter;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
-
-public class MimeMultipart extends Multipart {
-    protected String mPreamble;
-
-    protected String mContentType;
-
-    protected String mBoundary;
-
-    protected String mSubType;
-
-    public MimeMultipart() throws MessagingException {
-        mBoundary = generateBoundary();
-        setSubType("mixed");
-    }
-
-    public MimeMultipart(String contentType) throws MessagingException {
-        this.mContentType = contentType;
-        try {
-            mSubType = MimeUtility.getHeaderParameter(contentType, null).split("/")[1];
-            mBoundary = MimeUtility.getHeaderParameter(contentType, "boundary");
-            if (mBoundary == null) {
-                throw new MessagingException("MultiPart does not contain boundary: " + contentType);
-            }
-        } catch (Exception e) {
-            throw new MessagingException(
-                    "Invalid MultiPart Content-Type; must contain subtype and boundary. ("
-                            + contentType + ")", e);
-        }
-    }
-
-    public String generateBoundary() {
-        StringBuffer sb = new StringBuffer();
-        sb.append("----");
-        for (int i = 0; i < 30; i++) {
-            sb.append(Integer.toString((int)(Math.random() * 35), 36));
-        }
-        return sb.toString().toUpperCase();
-    }
-
-    public String getPreamble() throws MessagingException {
-        return mPreamble;
-    }
-
-    public void setPreamble(String preamble) throws MessagingException {
-        this.mPreamble = preamble;
-    }
-
-    @Override
-    public String getContentType() throws MessagingException {
-        return mContentType;
-    }
-
-    public void setSubType(String subType) throws MessagingException {
-        this.mSubType = subType;
-        mContentType = String.format("multipart/%s; boundary=\"%s\"", subType, mBoundary);
-    }
-
-    @Override
-    public void writeTo(OutputStream out) throws IOException, MessagingException {
-        BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(out), 1024);
-
-        if (mPreamble != null) {
-            writer.write(mPreamble + "\r\n");
-        }
-
-        for (int i = 0, count = mParts.size(); i < count; i++) {
-            BodyPart bodyPart = mParts.get(i);
-            writer.write("--" + mBoundary + "\r\n");
-            writer.flush();
-            bodyPart.writeTo(out);
-            writer.write("\r\n");
-        }
-
-        writer.write("--" + mBoundary + "--\r\n");
-        writer.flush();
-    }
-
-    @Override
-    public InputStream getInputStream() throws MessagingException {
-        return null;
-    }
-
-    public String getSubTypeForTest() {
-        return mSubType;
-    }
-}
diff --git a/src/com/android/phone/common/mail/internet/MimeUtility.java b/src/com/android/phone/common/mail/internet/MimeUtility.java
deleted file mode 100644
index 7402a4c..0000000
--- a/src/com/android/phone/common/mail/internet/MimeUtility.java
+++ /dev/null
@@ -1,416 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.phone.common.mail.internet;
-
-import android.text.TextUtils;
-import android.util.Base64;
-import android.util.Base64DataException;
-import android.util.Base64InputStream;
-
-import com.android.phone.common.mail.Body;
-import com.android.phone.common.mail.BodyPart;
-import com.android.phone.common.mail.Message;
-import com.android.phone.common.mail.MessagingException;
-import com.android.phone.common.mail.Multipart;
-import com.android.phone.common.mail.Part;
-import com.android.phone.vvm.omtp.VvmLog;
-
-import org.apache.commons.io.IOUtils;
-import org.apache.james.mime4j.codec.EncoderUtil;
-import org.apache.james.mime4j.decoder.DecoderUtil;
-import org.apache.james.mime4j.decoder.QuotedPrintableInputStream;
-import org.apache.james.mime4j.util.CharsetUtil;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.ArrayList;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-public class MimeUtility {
-    private static final String LOG_TAG = "Email";
-
-    public static final String MIME_TYPE_RFC822 = "message/rfc822";
-    private final static Pattern PATTERN_CR_OR_LF = Pattern.compile("\r|\n");
-
-    /**
-     * Replace sequences of CRLF+WSP with WSP.  Tries to preserve original string
-     * object whenever possible.
-     */
-    public static String unfold(String s) {
-        if (s == null) {
-            return null;
-        }
-        Matcher patternMatcher = PATTERN_CR_OR_LF.matcher(s);
-        if (patternMatcher.find()) {
-            patternMatcher.reset();
-            s = patternMatcher.replaceAll("");
-        }
-        return s;
-    }
-
-    public static String decode(String s) {
-        if (s == null) {
-            return null;
-        }
-        return DecoderUtil.decodeEncodedWords(s);
-    }
-
-    public static String unfoldAndDecode(String s) {
-        return decode(unfold(s));
-    }
-
-    // TODO implement proper foldAndEncode
-    // NOTE: When this really works, we *must* remove all calls to foldAndEncode2() to prevent
-    // duplication of encoding.
-    public static String foldAndEncode(String s) {
-        return s;
-    }
-
-    /**
-     * INTERIM version of foldAndEncode that will be used only by Subject: headers.
-     * This is safer than implementing foldAndEncode() (see above) and risking unknown damage
-     * to other headers.
-     *
-     * TODO: Copy this code to foldAndEncode(), get rid of this function, confirm all working OK.
-     *
-     * @param s original string to encode and fold
-     * @param usedCharacters number of characters already used up by header name
-
-     * @return the String ready to be transmitted
-     */
-    public static String foldAndEncode2(String s, int usedCharacters) {
-        // james.mime4j.codec.EncoderUtil.java
-        // encode:  encodeIfNecessary(text, usage, numUsedInHeaderName)
-        // Usage.TEXT_TOKENlooks like the right thing for subjects
-        // use WORD_ENTITY for address/names
-
-        String encoded = EncoderUtil.encodeIfNecessary(s, EncoderUtil.Usage.TEXT_TOKEN,
-                usedCharacters);
-
-        return fold(encoded, usedCharacters);
-    }
-
-    /**
-     * INTERIM:  From newer version of org.apache.james (but we don't want to import
-     * the entire MimeUtil class).
-     *
-     * Splits the specified string into a multiple-line representation with
-     * lines no longer than 76 characters (because the line might contain
-     * encoded words; see <a href='http://www.faqs.org/rfcs/rfc2047.html'>RFC
-     * 2047</a> section 2). If the string contains non-whitespace sequences
-     * longer than 76 characters a line break is inserted at the whitespace
-     * character following the sequence resulting in a line longer than 76
-     * characters.
-     *
-     * @param s
-     *            string to split.
-     * @param usedCharacters
-     *            number of characters already used up. Usually the number of
-     *            characters for header field name plus colon and one space.
-     * @return a multiple-line representation of the given string.
-     */
-    public static String fold(String s, int usedCharacters) {
-        final int maxCharacters = 76;
-
-        final int length = s.length();
-        if (usedCharacters + length <= maxCharacters)
-            return s;
-
-        StringBuilder sb = new StringBuilder();
-
-        int lastLineBreak = -usedCharacters;
-        int wspIdx = indexOfWsp(s, 0);
-        while (true) {
-            if (wspIdx == length) {
-                sb.append(s.substring(Math.max(0, lastLineBreak)));
-                return sb.toString();
-            }
-
-            int nextWspIdx = indexOfWsp(s, wspIdx + 1);
-
-            if (nextWspIdx - lastLineBreak > maxCharacters) {
-                sb.append(s.substring(Math.max(0, lastLineBreak), wspIdx));
-                sb.append("\r\n");
-                lastLineBreak = wspIdx;
-            }
-
-            wspIdx = nextWspIdx;
-        }
-    }
-
-    /**
-     * INTERIM:  From newer version of org.apache.james (but we don't want to import
-     * the entire MimeUtil class).
-     *
-     * Search for whitespace.
-     */
-    private static int indexOfWsp(String s, int fromIndex) {
-        final int len = s.length();
-        for (int index = fromIndex; index < len; index++) {
-            char c = s.charAt(index);
-            if (c == ' ' || c == '\t')
-                return index;
-        }
-        return len;
-    }
-
-    /**
-     * Returns the named parameter of a header field. If name is null the first
-     * parameter is returned, or if there are no additional parameters in the
-     * field the entire field is returned. Otherwise the named parameter is
-     * searched for in a case insensitive fashion and returned. If the parameter
-     * cannot be found the method returns null.
-     *
-     * TODO: quite inefficient with the inner trimming & splitting.
-     * TODO: Also has a latent bug: uses "startsWith" to match the name, which can false-positive.
-     * TODO: The doc says that for a null name you get the first param, but you get the header.
-     *    Should probably just fix the doc, but if other code assumes that behavior, fix the code.
-     * TODO: Need to decode %-escaped strings, as in: filename="ab%22d".
-     *       ('+' -> ' ' conversion too? check RFC)
-     *
-     * @param header
-     * @param name
-     * @return the entire header (if name=null), the found parameter, or null
-     */
-    public static String getHeaderParameter(String header, String name) {
-        if (header == null) {
-            return null;
-        }
-        String[] parts = unfold(header).split(";");
-        if (name == null) {
-            return parts[0].trim();
-        }
-        String lowerCaseName = name.toLowerCase();
-        for (String part : parts) {
-            if (part.trim().toLowerCase().startsWith(lowerCaseName)) {
-                String[] parameterParts = part.split("=", 2);
-                if (parameterParts.length < 2) {
-                    return null;
-                }
-                String parameter = parameterParts[1].trim();
-                if (parameter.startsWith("\"") && parameter.endsWith("\"")) {
-                    return parameter.substring(1, parameter.length() - 1);
-                } else {
-                    return parameter;
-                }
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Reads the Part's body and returns a String based on any charset conversion that needed
-     * to be done.
-     * @param part The part containing a body
-     * @return a String containing the converted text in the body, or null if there was no text
-     * or an error during conversion.
-     */
-    public static String getTextFromPart(Part part) {
-        try {
-            if (part != null && part.getBody() != null) {
-                InputStream in = part.getBody().getInputStream();
-                String mimeType = part.getMimeType();
-                if (mimeType != null && MimeUtility.mimeTypeMatches(mimeType, "text/*")) {
-                    /*
-                     * Now we read the part into a buffer for further processing. Because
-                     * the stream is now wrapped we'll remove any transfer encoding at this point.
-                     */
-                    ByteArrayOutputStream out = new ByteArrayOutputStream();
-                    IOUtils.copy(in, out);
-                    in.close();
-                    in = null;      // we want all of our memory back, and close might not release
-
-                    /*
-                     * We've got a text part, so let's see if it needs to be processed further.
-                     */
-                    String charset = getHeaderParameter(part.getContentType(), "charset");
-                    if (charset != null) {
-                        /*
-                         * See if there is conversion from the MIME charset to the Java one.
-                         */
-                        charset = CharsetUtil.toJavaCharset(charset);
-                    }
-                    /*
-                     * No encoding, so use us-ascii, which is the standard.
-                     */
-                    if (charset == null) {
-                        charset = "ASCII";
-                    }
-                    /*
-                     * Convert and return as new String
-                     */
-                    String result = out.toString(charset);
-                    out.close();
-                    return result;
-                }
-            }
-
-        }
-        catch (OutOfMemoryError oom) {
-            /*
-             * If we are not able to process the body there's nothing we can do about it. Return
-             * null and let the upper layers handle the missing content.
-             */
-            VvmLog.e(LOG_TAG, "Unable to getTextFromPart " + oom.toString());
-        }
-        catch (Exception e) {
-            /*
-             * If we are not able to process the body there's nothing we can do about it. Return
-             * null and let the upper layers handle the missing content.
-             */
-            VvmLog.e(LOG_TAG, "Unable to getTextFromPart " + e.toString());
-        }
-        return null;
-    }
-
-    /**
-     * Returns true if the given mimeType matches the matchAgainst specification.  The comparison
-     * ignores case and the matchAgainst string may include "*" for a wildcard (e.g. "image/*").
-     *
-     * @param mimeType A MIME type to check.
-     * @param matchAgainst A MIME type to check against. May include wildcards.
-     * @return true if the mimeType matches
-     */
-    public static boolean mimeTypeMatches(String mimeType, String matchAgainst) {
-        Pattern p = Pattern.compile(matchAgainst.replaceAll("\\*", "\\.\\*"),
-                Pattern.CASE_INSENSITIVE);
-        return p.matcher(mimeType).matches();
-    }
-
-    /**
-     * Returns true if the given mimeType matches any of the matchAgainst specifications.  The
-     * comparison ignores case and the matchAgainst strings may include "*" for a wildcard
-     * (e.g. "image/*").
-     *
-     * @param mimeType A MIME type to check.
-     * @param matchAgainst An array of MIME types to check against. May include wildcards.
-     * @return true if the mimeType matches any of the matchAgainst strings
-     */
-    public static boolean mimeTypeMatches(String mimeType, String[] matchAgainst) {
-        for (String matchType : matchAgainst) {
-            if (mimeTypeMatches(mimeType, matchType)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Given an input stream and a transfer encoding, return a wrapped input stream for that
-     * encoding (or the original if none is required)
-     * @param in the input stream
-     * @param contentTransferEncoding the content transfer encoding
-     * @return a properly wrapped stream
-     */
-    public static InputStream getInputStreamForContentTransferEncoding(InputStream in,
-            String contentTransferEncoding) {
-        if (contentTransferEncoding != null) {
-            contentTransferEncoding =
-                MimeUtility.getHeaderParameter(contentTransferEncoding, null);
-            if ("quoted-printable".equalsIgnoreCase(contentTransferEncoding)) {
-                in = new QuotedPrintableInputStream(in);
-            }
-            else if ("base64".equalsIgnoreCase(contentTransferEncoding)) {
-                in = new Base64InputStream(in, Base64.DEFAULT);
-            }
-        }
-        return in;
-    }
-
-    /**
-     * Removes any content transfer encoding from the stream and returns a Body.
-     */
-    public static Body decodeBody(InputStream in, String contentTransferEncoding)
-            throws IOException {
-        /*
-         * We'll remove any transfer encoding by wrapping the stream.
-         */
-        in = getInputStreamForContentTransferEncoding(in, contentTransferEncoding);
-        BinaryTempFileBody tempBody = new BinaryTempFileBody();
-        OutputStream out = tempBody.getOutputStream();
-        try {
-            IOUtils.copy(in, out);
-        } catch (Base64DataException bde) {
-            // TODO Need to fix this somehow
-            //String warning = "\n\n" + Email.getMessageDecodeErrorString();
-            //out.write(warning.getBytes());
-        } finally {
-            out.close();
-        }
-        return tempBody;
-    }
-
-    /**
-     * Recursively scan a Part (usually a Message) and sort out which of its children will be
-     * "viewable" and which will be attachments.
-     *
-     * @param part The part to be broken down
-     * @param viewables This arraylist will be populated with all parts that appear to be
-     * the "message" (e.g. text/plain & text/html)
-     * @param attachments This arraylist will be populated with all parts that appear to be
-     * attachments (including inlines)
-     * @throws MessagingException
-     */
-    public static void collectParts(Part part, ArrayList<Part> viewables,
-            ArrayList<Part> attachments) throws MessagingException {
-        String disposition = part.getDisposition();
-        String dispositionType = MimeUtility.getHeaderParameter(disposition, null);
-        // If a disposition is not specified, default to "inline"
-        boolean inline =
-                TextUtils.isEmpty(dispositionType) || "inline".equalsIgnoreCase(dispositionType);
-        // The lower-case mime type
-        String mimeType = part.getMimeType().toLowerCase();
-
-        if (part.getBody() instanceof Multipart) {
-            // If the part is Multipart but not alternative it's either mixed or
-            // something we don't know about, which means we treat it as mixed
-            // per the spec. We just process its pieces recursively.
-            MimeMultipart mp = (MimeMultipart)part.getBody();
-            boolean foundHtml = false;
-            if (mp.getSubTypeForTest().equals("alternative")) {
-                for (int i = 0; i < mp.getCount(); i++) {
-                    if (mp.getBodyPart(i).isMimeType("text/html")) {
-                        foundHtml = true;
-                        break;
-                    }
-                }
-            }
-            for (int i = 0; i < mp.getCount(); i++) {
-                // See if we have text and html
-                BodyPart bp = mp.getBodyPart(i);
-                // If there's html, don't bother loading text
-                if (foundHtml && bp.isMimeType("text/plain")) {
-                    continue;
-                }
-                collectParts(bp, viewables, attachments);
-            }
-        } else if (part.getBody() instanceof Message) {
-            // If the part is an embedded message we just continue to process
-            // it, pulling any viewables or attachments into the running list.
-            Message message = (Message)part.getBody();
-            collectParts(message, viewables, attachments);
-        } else if (inline && (mimeType.startsWith("text") || (mimeType.startsWith("image")))) {
-            // We'll treat text and images as viewables
-            viewables.add(part);
-        } else {
-            // Everything else is an attachment.
-            attachments.add(part);
-        }
-    }
-}
diff --git a/src/com/android/phone/common/mail/internet/TextBody.java b/src/com/android/phone/common/mail/internet/TextBody.java
deleted file mode 100644
index 77bbd65..0000000
--- a/src/com/android/phone/common/mail/internet/TextBody.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.phone.common.mail.internet;
-
-import android.util.Base64;
-
-import com.android.phone.common.mail.Body;
-import com.android.phone.common.mail.MessagingException;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.UnsupportedEncodingException;
-
-public class TextBody implements Body {
-    String mBody;
-
-    public TextBody(String body) {
-        this.mBody = body;
-    }
-
-    @Override
-    public void writeTo(OutputStream out) throws IOException, MessagingException {
-        byte[] bytes = mBody.getBytes("UTF-8");
-        out.write(Base64.encode(bytes, Base64.CRLF));
-    }
-
-    /**
-     * Get the text of the body in it's unencoded format.
-     * @return
-     */
-    public String getText() {
-        return mBody;
-    }
-
-    /**
-     * Returns an InputStream that reads this body's text in UTF-8 format.
-     */
-    @Override
-    public InputStream getInputStream() throws MessagingException {
-        try {
-            byte[] b = mBody.getBytes("UTF-8");
-            return new ByteArrayInputStream(b);
-        }
-        catch (UnsupportedEncodingException usee) {
-            return null;
-        }
-    }
-}
diff --git a/src/com/android/phone/common/mail/store/ImapConnection.java b/src/com/android/phone/common/mail/store/ImapConnection.java
deleted file mode 100644
index af8773b..0000000
--- a/src/com/android/phone/common/mail/store/ImapConnection.java
+++ /dev/null
@@ -1,413 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.phone.common.mail.store;
-
-import android.util.ArraySet;
-import android.util.Base64;
-import com.android.phone.common.mail.AuthenticationFailedException;
-import com.android.phone.common.mail.CertificateValidationException;
-import com.android.phone.common.mail.MailTransport;
-import com.android.phone.common.mail.MessagingException;
-import com.android.phone.common.mail.store.ImapStore.ImapException;
-import com.android.phone.common.mail.store.imap.DigestMd5Utils;
-import com.android.phone.common.mail.store.imap.ImapConstants;
-import com.android.phone.common.mail.store.imap.ImapResponse;
-import com.android.phone.common.mail.store.imap.ImapResponseParser;
-import com.android.phone.common.mail.store.imap.ImapUtility;
-import com.android.phone.common.mail.utils.LogUtils;
-import com.android.phone.vvm.omtp.OmtpEvents;
-import com.android.phone.vvm.omtp.VvmLog;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.atomic.AtomicInteger;
-import javax.net.ssl.SSLException;
-
-/**
- * A cacheable class that stores the details for a single IMAP connection.
- */
-public class ImapConnection {
-    private final String TAG = "ImapConnection";
-
-    private String mLoginPhrase;
-    private ImapStore mImapStore;
-    private MailTransport mTransport;
-    private ImapResponseParser mParser;
-    private Set<String> mCapabilities = new ArraySet<>();
-
-    static final String IMAP_REDACTED_LOG = "[IMAP command redacted]";
-
-    /**
-     * Next tag to use.  All connections associated to the same ImapStore instance share the same
-     * counter to make tests simpler.
-     * (Some of the tests involve multiple connections but only have a single counter to track the
-     * tag.)
-     */
-    private final AtomicInteger mNextCommandTag = new AtomicInteger(0);
-
-    ImapConnection(ImapStore store) {
-        setStore(store);
-    }
-
-    void setStore(ImapStore store) {
-        // TODO: maybe we should throw an exception if the connection is not closed here,
-        // if it's not currently closed, then we won't reopen it, so if the credentials have
-        // changed, the connection will not be reestablished.
-        mImapStore = store;
-        mLoginPhrase = null;
-    }
-
-    /**
-     * Generates and returns the phrase to be used for authentication. This will be a LOGIN with
-     * username and password.
-     *
-     * @return the login command string to sent to the IMAP server
-     */
-    String getLoginPhrase() {
-        if (mLoginPhrase == null) {
-            if (mImapStore.getUsername() != null && mImapStore.getPassword() != null) {
-                // build the LOGIN string once (instead of over-and-over again.)
-                // apply the quoting here around the built-up password
-                mLoginPhrase = ImapConstants.LOGIN + " " + mImapStore.getUsername() + " "
-                        + ImapUtility.imapQuoted(mImapStore.getPassword());
-            }
-        }
-        return mLoginPhrase;
-    }
-
-    public void open() throws IOException, MessagingException {
-        if (mTransport != null && mTransport.isOpen()) {
-            return;
-        }
-
-        try {
-            // copy configuration into a clean transport, if necessary
-            if (mTransport == null) {
-                mTransport = mImapStore.cloneTransport();
-            }
-
-            mTransport.open();
-
-            createParser();
-
-            // The server should greet us with something like
-            // * OK IMAP4rev1 Server
-            // consume the response before doing anything else.
-            ImapResponse response = mParser.readResponse(false);
-            if (!response.isOk()) {
-                mImapStore.getImapHelper()
-                        .handleEvent(OmtpEvents.DATA_INVALID_INITIAL_SERVER_RESPONSE);
-                throw new MessagingException(
-                        MessagingException.AUTHENTICATION_FAILED_OR_SERVER_ERROR,
-                        "Invalid server initial response");
-            }
-
-            queryCapability();
-
-            maybeDoStartTls();
-
-            // LOGIN
-            doLogin();
-        } catch (SSLException e) {
-            LogUtils.d(TAG, "SSLException ", e);
-            mImapStore.getImapHelper().handleEvent(OmtpEvents.DATA_SSL_EXCEPTION);
-            throw new CertificateValidationException(e.getMessage(), e);
-        } catch (IOException ioe) {
-            LogUtils.d(TAG, "IOException", ioe);
-            mImapStore.getImapHelper().handleEvent(OmtpEvents.DATA_IOE_ON_OPEN);
-            throw ioe;
-        } finally {
-            destroyResponses();
-        }
-    }
-
-    void logout() {
-        try {
-            sendCommand(ImapConstants.LOGOUT, false);
-            if (!mParser.readResponse(true).is(0, ImapConstants.BYE)) {
-                VvmLog.e(TAG, "Server did not respond LOGOUT with BYE");
-            }
-            if (!mParser.readResponse(false).isOk()) {
-                VvmLog.e(TAG, "Server did not respond OK after LOGOUT");
-            }
-        } catch (IOException | MessagingException e) {
-            VvmLog.e(TAG, "Error while logging out:" + e);
-        }
-    }
-
-    /**
-     * Closes the connection and releases all resources. This connection can not be used again
-     * until {@link #setStore(ImapStore)} is called.
-     */
-    void close() {
-        if (mTransport != null) {
-            logout();
-            mTransport.close();
-            mTransport = null;
-        }
-        destroyResponses();
-        mParser = null;
-        mImapStore = null;
-    }
-
-    /**
-     * Attempts to convert the connection into secure connection.
-     */
-    private void maybeDoStartTls() throws IOException, MessagingException {
-        // STARTTLS is required in the OMTP standard but not every implementation support it.
-        // Make sure the server does have this capability
-        if (hasCapability(ImapConstants.CAPABILITY_STARTTLS)) {
-            executeSimpleCommand(ImapConstants.STARTTLS);
-            mTransport.reopenTls();
-            createParser();
-            // The cached capabilities should be refreshed after TLS is established.
-            queryCapability();
-        }
-    }
-
-    /**
-     * Logs into the IMAP server
-     */
-    private void doLogin() throws IOException, MessagingException, AuthenticationFailedException {
-        try {
-            if (mCapabilities.contains(ImapConstants.CAPABILITY_AUTH_DIGEST_MD5)) {
-                doDigestMd5Auth();
-            } else {
-                executeSimpleCommand(getLoginPhrase(), true);
-            }
-        } catch (ImapException ie) {
-            LogUtils.d(TAG, "ImapException", ie);
-            String status = ie.getStatus();
-            String statusMessage = ie.getStatusMessage();
-            String alertText = ie.getAlertText();
-
-            if (ImapConstants.NO.equals(status)) {
-                switch (statusMessage) {
-                    case ImapConstants.NO_UNKNOWN_USER:
-                        mImapStore.getImapHelper().handleEvent(OmtpEvents.DATA_AUTH_UNKNOWN_USER);
-                        break;
-                    case ImapConstants.NO_UNKNOWN_CLIENT:
-                        mImapStore.getImapHelper().handleEvent(OmtpEvents.DATA_AUTH_UNKNOWN_DEVICE);
-                        break;
-                    case ImapConstants.NO_INVALID_PASSWORD:
-                        mImapStore.getImapHelper()
-                                .handleEvent(OmtpEvents.DATA_AUTH_INVALID_PASSWORD);
-                        break;
-                    case ImapConstants.NO_MAILBOX_NOT_INITIALIZED:
-                        mImapStore.getImapHelper()
-                                .handleEvent(OmtpEvents.DATA_AUTH_MAILBOX_NOT_INITIALIZED);
-                        break;
-                    case ImapConstants.NO_SERVICE_IS_NOT_PROVISIONED:
-                        mImapStore.getImapHelper()
-                                .handleEvent(OmtpEvents.DATA_AUTH_SERVICE_NOT_PROVISIONED);
-                        break;
-                    case ImapConstants.NO_SERVICE_IS_NOT_ACTIVATED:
-                        mImapStore.getImapHelper()
-                                .handleEvent(OmtpEvents.DATA_AUTH_SERVICE_NOT_ACTIVATED);
-                        break;
-                    case ImapConstants.NO_USER_IS_BLOCKED:
-                        mImapStore.getImapHelper()
-                                .handleEvent(OmtpEvents.DATA_AUTH_USER_IS_BLOCKED);
-                        break;
-                    case ImapConstants.NO_APPLICATION_ERROR:
-                        mImapStore.getImapHelper()
-                                .handleEvent(OmtpEvents.DATA_REJECTED_SERVER_RESPONSE);
-                    default:
-                        mImapStore.getImapHelper().handleEvent(OmtpEvents.DATA_BAD_IMAP_CREDENTIAL);
-                }
-                throw new AuthenticationFailedException(alertText, ie);
-            }
-
-            mImapStore.getImapHelper().handleEvent(OmtpEvents.DATA_REJECTED_SERVER_RESPONSE);
-            throw new MessagingException(alertText, ie);
-        }
-    }
-
-    private void doDigestMd5Auth() throws IOException, MessagingException {
-
-        //  Initiate the authentication.
-        //  The server will issue us a challenge, asking to run MD5 on the nonce with our password
-        //  and other data, including the cnonce we randomly generated.
-        //
-        //  C: a AUTHENTICATE DIGEST-MD5
-        //  S: (BASE64) realm="elwood.innosoft.com",nonce="OA6MG9tEQGm2hh",qop="auth",
-        //             algorithm=md5-sess,charset=utf-8
-        List<ImapResponse> responses = executeSimpleCommand(
-            ImapConstants.AUTHENTICATE + " " + ImapConstants.AUTH_DIGEST_MD5);
-        String decodedChallenge = decodeBase64(responses.get(0).getStringOrEmpty(0).getString());
-
-        Map<String, String> challenge = DigestMd5Utils.parseDigestMessage(decodedChallenge);
-        DigestMd5Utils.Data data = new DigestMd5Utils.Data(mImapStore, mTransport, challenge);
-
-        String response = data.createResponse();
-        //  Respond to the challenge. If the server accepts it, it will reply a response-auth which
-        //  is the MD5 of our password and the cnonce we've provided, to prove the server does know
-        //  the password.
-        //
-        //  C: (BASE64) charset=utf-8,username="chris",realm="elwood.innosoft.com",
-        //              nonce="OA6MG9tEQGm2hh",nc=00000001,cnonce="OA6MHXh6VqTrRk",
-        //              digest-uri="imap/elwood.innosoft.com",
-        //              response=d388dad90d4bbd760a152321f2143af7,qop=auth
-        //  S: (BASE64) rspauth=ea40f60335c427b5527b84dbabcdfffd
-
-        responses = executeContinuationResponse(encodeBase64(response), true);
-
-        // Verify response-auth.
-        // If failed verifyResponseAuth() will throw a MessagingException, terminating the
-        // connection
-        String decodedResponseAuth = decodeBase64(responses.get(0).getStringOrEmpty(0).getString());
-        data.verifyResponseAuth(decodedResponseAuth);
-
-        //  Send a empty response to indicate we've accepted the response-auth
-        //
-        //  C: (empty)
-        //  S: a OK User logged in
-        executeContinuationResponse("", false);
-
-    }
-
-    private static String decodeBase64(String string) {
-        return new String(Base64.decode(string, Base64.DEFAULT));
-    }
-
-    private static String encodeBase64(String string) {
-        return Base64.encodeToString(string.getBytes(), Base64.NO_WRAP);
-    }
-
-    private void queryCapability() throws IOException, MessagingException {
-        List<ImapResponse> responses = executeSimpleCommand(ImapConstants.CAPABILITY);
-        mCapabilities.clear();
-        Set<String> disabledCapabilities = mImapStore.getImapHelper().getConfig()
-                .getDisabledCapabilities();
-        for (ImapResponse response : responses) {
-            if (response.isTagged()) {
-                continue;
-            }
-            for (int i = 0; i < response.size(); i++) {
-                String capability = response.getStringOrEmpty(i).getString();
-                if (disabledCapabilities != null) {
-                    if (!disabledCapabilities.contains(capability)) {
-                        mCapabilities.add(capability);
-                    }
-                } else {
-                    mCapabilities.add(capability);
-                }
-            }
-        }
-
-        LogUtils.d(TAG, "Capabilities: " + mCapabilities.toString());
-    }
-
-    private boolean hasCapability(String capability) {
-        return mCapabilities.contains(capability);
-    }
-    /**
-     * Create an {@link ImapResponseParser} from {@code mTransport.getInputStream()} and
-     * set it to {@link #mParser}.
-     *
-     * If we already have an {@link ImapResponseParser}, we
-     * {@link #destroyResponses()} and throw it away.
-     */
-    private void createParser() {
-        destroyResponses();
-        mParser = new ImapResponseParser(mTransport.getInputStream());
-    }
-
-
-    public void destroyResponses() {
-        if (mParser != null) {
-            mParser.destroyResponses();
-        }
-    }
-
-    public ImapResponse readResponse() throws IOException, MessagingException {
-        return mParser.readResponse(false);
-    }
-
-    public List<ImapResponse> executeSimpleCommand(String command)
-            throws IOException, MessagingException{
-        return executeSimpleCommand(command, false);
-    }
-
-    /**
-     * Send a single command to the server.  The command will be preceded by an IMAP command
-     * tag and followed by \r\n (caller need not supply them).
-     * Execute a simple command at the server, a simple command being one that is sent in a single
-     * line of text
-     *
-     * @param command the command to send to the server
-     * @param sensitive whether the command should be redacted in logs (used for login)
-     * @return a list of ImapResponses
-     * @throws IOException
-     * @throws MessagingException
-     */
-    public List<ImapResponse> executeSimpleCommand(String command, boolean sensitive)
-            throws IOException, MessagingException {
-        // TODO: It may be nice to catch IOExceptions and close the connection here.
-        // Currently, we expect callers to do that, but if they fail to we'll be in a broken state.
-        sendCommand(command, sensitive);
-        return getCommandResponses();
-    }
-
-    public String sendCommand(String command, boolean sensitive)
-            throws IOException, MessagingException {
-        open();
-
-        if (mTransport == null) {
-            throw new IOException("Null transport");
-        }
-        String tag = Integer.toString(mNextCommandTag.incrementAndGet());
-        String commandToSend = tag + " " + command;
-        mTransport.writeLine(commandToSend, (sensitive ? IMAP_REDACTED_LOG : command));
-        return tag;
-    }
-
-    List<ImapResponse> executeContinuationResponse(String response, boolean sensitive)
-            throws IOException, MessagingException {
-        mTransport.writeLine(response, (sensitive ? IMAP_REDACTED_LOG : response));
-        return getCommandResponses();
-    }
-
-    /**
-     * Read and return all of the responses from the most recent command sent to the server
-     *
-     * @return a list of ImapResponses
-     * @throws IOException
-     * @throws MessagingException
-     */
-    List<ImapResponse> getCommandResponses()
-            throws IOException, MessagingException {
-        final List<ImapResponse> responses = new ArrayList<ImapResponse>();
-        ImapResponse response;
-        do {
-            response = mParser.readResponse(false);
-            responses.add(response);
-        } while (!(response.isTagged() || response.isContinuationRequest()));
-
-        if (!(response.isOk() || response.isContinuationRequest())) {
-            final String toString = response.toString();
-            final String status = response.getStatusOrEmpty().getString();
-            final String statusMessage = response.getStatusResponseTextOrEmpty().getString();
-            final String alert = response.getAlertTextOrEmpty().getString();
-            final String responseCode = response.getResponseCodeOrEmpty().getString();
-            destroyResponses();
-            throw new ImapException(toString, status, statusMessage, alert, responseCode);
-        }
-        return responses;
-    }
-}
diff --git a/src/com/android/phone/common/mail/store/ImapFolder.java b/src/com/android/phone/common/mail/store/ImapFolder.java
deleted file mode 100644
index 4abb7f5..0000000
--- a/src/com/android/phone/common/mail/store/ImapFolder.java
+++ /dev/null
@@ -1,787 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.phone.common.mail.store;
-
-import android.annotation.Nullable;
-import android.content.Context;
-import android.text.TextUtils;
-import android.util.Base64DataException;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.phone.common.R;
-import com.android.phone.common.mail.AuthenticationFailedException;
-import com.android.phone.common.mail.Body;
-import com.android.phone.common.mail.FetchProfile;
-import com.android.phone.common.mail.Flag;
-import com.android.phone.common.mail.Message;
-import com.android.phone.common.mail.MessagingException;
-import com.android.phone.common.mail.Part;
-import com.android.phone.common.mail.internet.BinaryTempFileBody;
-import com.android.phone.common.mail.internet.MimeBodyPart;
-import com.android.phone.common.mail.internet.MimeHeader;
-import com.android.phone.common.mail.internet.MimeMultipart;
-import com.android.phone.common.mail.internet.MimeUtility;
-import com.android.phone.common.mail.store.ImapStore.ImapException;
-import com.android.phone.common.mail.store.ImapStore.ImapMessage;
-import com.android.phone.common.mail.store.imap.ImapConstants;
-import com.android.phone.common.mail.store.imap.ImapElement;
-import com.android.phone.common.mail.store.imap.ImapList;
-import com.android.phone.common.mail.store.imap.ImapResponse;
-import com.android.phone.common.mail.store.imap.ImapString;
-import com.android.phone.common.mail.utils.LogUtils;
-import com.android.phone.common.mail.utils.Utility;
-import com.android.phone.vvm.omtp.OmtpEvents;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Locale;
-
-public class ImapFolder {
-    private static final String TAG = "ImapFolder";
-    private final static String[] PERMANENT_FLAGS =
-        { Flag.DELETED, Flag.SEEN, Flag.FLAGGED, Flag.ANSWERED };
-    private static final int COPY_BUFFER_SIZE = 16*1024;
-
-    private final ImapStore mStore;
-    private final String mName;
-    private int mMessageCount = -1;
-    private ImapConnection mConnection;
-    private String mMode;
-    private boolean mExists;
-    /** A set of hashes that can be used to track dirtiness */
-    Object mHash[];
-
-    public static final String MODE_READ_ONLY = "mode_read_only";
-    public static final String MODE_READ_WRITE = "mode_read_write";
-
-    public ImapFolder(ImapStore store, String name) {
-        mStore = store;
-        mName = name;
-    }
-
-    /**
-     * Callback for each message retrieval.
-     */
-    public interface MessageRetrievalListener {
-        public void messageRetrieved(Message message);
-    }
-
-    private void destroyResponses() {
-        if (mConnection != null) {
-            mConnection.destroyResponses();
-        }
-    }
-
-    public void open(String mode) throws MessagingException {
-        try {
-            if (isOpen()) {
-                throw new AssertionError("Duplicated open on ImapFolder");
-            }
-            synchronized (this) {
-                mConnection = mStore.getConnection();
-            }
-            // * FLAGS (\Answered \Flagged \Deleted \Seen \Draft NonJunk
-            // $MDNSent)
-            // * OK [PERMANENTFLAGS (\Answered \Flagged \Deleted \Seen \Draft
-            // NonJunk $MDNSent \*)] Flags permitted.
-            // * 23 EXISTS
-            // * 0 RECENT
-            // * OK [UIDVALIDITY 1125022061] UIDs valid
-            // * OK [UIDNEXT 57576] Predicted next UID
-            // 2 OK [READ-WRITE] Select completed.
-            try {
-                doSelect();
-            } catch (IOException ioe) {
-                throw ioExceptionHandler(mConnection, ioe);
-            } finally {
-                destroyResponses();
-            }
-        } catch (AuthenticationFailedException e) {
-            // Don't cache this connection, so we're forced to try connecting/login again
-            mConnection = null;
-            close(false);
-            throw e;
-        } catch (MessagingException e) {
-            mExists = false;
-            close(false);
-            throw e;
-        }
-    }
-
-    public boolean isOpen() {
-        return mExists && mConnection != null;
-    }
-
-    public String getMode() {
-        return mMode;
-    }
-
-    public void close(boolean expunge) {
-        if (expunge) {
-            try {
-                expunge();
-            } catch (MessagingException e) {
-                LogUtils.e(TAG, e, "Messaging Exception");
-            }
-        }
-        mMessageCount = -1;
-        synchronized (this) {
-            mConnection = null;
-        }
-    }
-
-    public int getMessageCount() {
-        return mMessageCount;
-    }
-
-    String[] getSearchUids(List<ImapResponse> responses) {
-        // S: * SEARCH 2 3 6
-        final ArrayList<String> uids = new ArrayList<String>();
-        for (ImapResponse response : responses) {
-            if (!response.isDataResponse(0, ImapConstants.SEARCH)) {
-                continue;
-            }
-            // Found SEARCH response data
-            for (int i = 1; i < response.size(); i++) {
-                ImapString s = response.getStringOrEmpty(i);
-                if (s.isString()) {
-                    uids.add(s.getString());
-                }
-            }
-        }
-        return uids.toArray(Utility.EMPTY_STRINGS);
-    }
-
-    @VisibleForTesting
-    String[] searchForUids(String searchCriteria) throws MessagingException {
-        checkOpen();
-        try {
-            try {
-                final String command = ImapConstants.UID_SEARCH + " " + searchCriteria;
-                final String[] result = getSearchUids(mConnection.executeSimpleCommand(command));
-                LogUtils.d(TAG, "searchForUids '" + searchCriteria + "' results: " +
-                        result.length);
-                return result;
-            } catch (ImapException me) {
-                LogUtils.d(TAG, "ImapException in search: " + searchCriteria, me);
-                return Utility.EMPTY_STRINGS; // Not found
-            } catch (IOException ioe) {
-                LogUtils.d(TAG, "IOException in search: " + searchCriteria, ioe);
-                mStore.getImapHelper().handleEvent(OmtpEvents.DATA_GENERIC_IMAP_IOE);
-                throw ioExceptionHandler(mConnection, ioe);
-            }
-        } finally {
-            destroyResponses();
-        }
-    }
-
-    @Nullable
-    public Message getMessage(String uid) throws MessagingException {
-        checkOpen();
-
-        final String[] uids = searchForUids(ImapConstants.UID + " " + uid);
-        for (int i = 0; i < uids.length; i++) {
-            if (uids[i].equals(uid)) {
-                return new ImapMessage(uid, this);
-            }
-        }
-        LogUtils.e(TAG, "UID " + uid + " not found on server");
-        return null;
-    }
-
-    @VisibleForTesting
-    protected static boolean isAsciiString(String str) {
-        int len = str.length();
-        for (int i = 0; i < len; i++) {
-            char c = str.charAt(i);
-            if (c >= 128) return false;
-        }
-        return true;
-    }
-
-    public Message[] getMessages(String[] uids) throws MessagingException {
-        if (uids == null) {
-            uids = searchForUids("1:* NOT DELETED");
-        }
-        return getMessagesInternal(uids);
-    }
-
-    public Message[] getMessagesInternal(String[] uids) {
-        final ArrayList<Message> messages = new ArrayList<Message>(uids.length);
-        for (int i = 0; i < uids.length; i++) {
-            final String uid = uids[i];
-            final ImapMessage message = new ImapMessage(uid, this);
-            messages.add(message);
-        }
-        return messages.toArray(Message.EMPTY_ARRAY);
-    }
-
-    public void fetch(Message[] messages, FetchProfile fp,
-            MessageRetrievalListener listener) throws MessagingException {
-        try {
-            fetchInternal(messages, fp, listener);
-        } catch (RuntimeException e) { // Probably a parser error.
-            LogUtils.w(TAG, "Exception detected: " + e.getMessage());
-            throw e;
-        }
-    }
-
-    public void fetchInternal(Message[] messages, FetchProfile fp,
-            MessageRetrievalListener listener) throws MessagingException {
-        if (messages.length == 0) {
-            return;
-        }
-        checkOpen();
-        HashMap<String, Message> messageMap = new HashMap<String, Message>();
-        for (Message m : messages) {
-            messageMap.put(m.getUid(), m);
-        }
-
-        /*
-         * Figure out what command we are going to run:
-         * FLAGS     - UID FETCH (FLAGS)
-         * ENVELOPE  - UID FETCH (INTERNALDATE UID RFC822.SIZE FLAGS BODY.PEEK[
-         *                            HEADER.FIELDS (date subject from content-type to cc)])
-         * STRUCTURE - UID FETCH (BODYSTRUCTURE)
-         * BODY_SANE - UID FETCH (BODY.PEEK[]<0.N>) where N = max bytes returned
-         * BODY      - UID FETCH (BODY.PEEK[])
-         * Part      - UID FETCH (BODY.PEEK[ID]) where ID = mime part ID
-         */
-
-        final LinkedHashSet<String> fetchFields = new LinkedHashSet<String>();
-
-        fetchFields.add(ImapConstants.UID);
-        if (fp.contains(FetchProfile.Item.FLAGS)) {
-            fetchFields.add(ImapConstants.FLAGS);
-        }
-        if (fp.contains(FetchProfile.Item.ENVELOPE)) {
-            fetchFields.add(ImapConstants.INTERNALDATE);
-            fetchFields.add(ImapConstants.RFC822_SIZE);
-            fetchFields.add(ImapConstants.FETCH_FIELD_HEADERS);
-        }
-        if (fp.contains(FetchProfile.Item.STRUCTURE)) {
-            fetchFields.add(ImapConstants.BODYSTRUCTURE);
-        }
-
-        if (fp.contains(FetchProfile.Item.BODY_SANE)) {
-            fetchFields.add(ImapConstants.FETCH_FIELD_BODY_PEEK_SANE);
-        }
-        if (fp.contains(FetchProfile.Item.BODY)) {
-            fetchFields.add(ImapConstants.FETCH_FIELD_BODY_PEEK);
-        }
-
-        // TODO Why are we only fetching the first part given?
-        final Part fetchPart = fp.getFirstPart();
-        if (fetchPart != null) {
-            final String[] partIds =
-                    fetchPart.getHeader(MimeHeader.HEADER_ANDROID_ATTACHMENT_STORE_DATA);
-            // TODO Why can a single part have more than one Id? And why should we only fetch
-            // the first id if there are more than one?
-            if (partIds != null) {
-                fetchFields.add(ImapConstants.FETCH_FIELD_BODY_PEEK_BARE
-                        + "[" + partIds[0] + "]");
-            }
-        }
-
-        try {
-            mConnection.sendCommand(String.format(Locale.US,
-                    ImapConstants.UID_FETCH + " %s (%s)", ImapStore.joinMessageUids(messages),
-                    Utility.combine(fetchFields.toArray(new String[fetchFields.size()]), ' ')
-            ), false);
-            ImapResponse response;
-            do {
-                response = null;
-                try {
-                    response = mConnection.readResponse();
-
-                    if (!response.isDataResponse(1, ImapConstants.FETCH)) {
-                        continue; // Ignore
-                    }
-                    final ImapList fetchList = response.getListOrEmpty(2);
-                    final String uid = fetchList.getKeyedStringOrEmpty(ImapConstants.UID)
-                            .getString();
-                    if (TextUtils.isEmpty(uid)) continue;
-
-                    ImapMessage message = (ImapMessage) messageMap.get(uid);
-                    if (message == null) continue;
-
-                    if (fp.contains(FetchProfile.Item.FLAGS)) {
-                        final ImapList flags =
-                            fetchList.getKeyedListOrEmpty(ImapConstants.FLAGS);
-                        for (int i = 0, count = flags.size(); i < count; i++) {
-                            final ImapString flag = flags.getStringOrEmpty(i);
-                            if (flag.is(ImapConstants.FLAG_DELETED)) {
-                                message.setFlagInternal(Flag.DELETED, true);
-                            } else if (flag.is(ImapConstants.FLAG_ANSWERED)) {
-                                message.setFlagInternal(Flag.ANSWERED, true);
-                            } else if (flag.is(ImapConstants.FLAG_SEEN)) {
-                                message.setFlagInternal(Flag.SEEN, true);
-                            } else if (flag.is(ImapConstants.FLAG_FLAGGED)) {
-                                message.setFlagInternal(Flag.FLAGGED, true);
-                            }
-                        }
-                    }
-                    if (fp.contains(FetchProfile.Item.ENVELOPE)) {
-                        final Date internalDate = fetchList.getKeyedStringOrEmpty(
-                                ImapConstants.INTERNALDATE).getDateOrNull();
-                        final int size = fetchList.getKeyedStringOrEmpty(
-                                ImapConstants.RFC822_SIZE).getNumberOrZero();
-                        final String header = fetchList.getKeyedStringOrEmpty(
-                                ImapConstants.BODY_BRACKET_HEADER, true).getString();
-
-                        message.setInternalDate(internalDate);
-                        message.setSize(size);
-                        message.parse(Utility.streamFromAsciiString(header));
-                    }
-                    if (fp.contains(FetchProfile.Item.STRUCTURE)) {
-                        ImapList bs = fetchList.getKeyedListOrEmpty(
-                                ImapConstants.BODYSTRUCTURE);
-                        if (!bs.isEmpty()) {
-                            try {
-                                parseBodyStructure(bs, message, ImapConstants.TEXT);
-                            } catch (MessagingException e) {
-                                LogUtils.v(TAG, e, "Error handling message");
-                                message.setBody(null);
-                            }
-                        }
-                    }
-                    if (fp.contains(FetchProfile.Item.BODY)
-                            || fp.contains(FetchProfile.Item.BODY_SANE)) {
-                        // Body is keyed by "BODY[]...".
-                        // Previously used "BODY[..." but this can be confused with "BODY[HEADER..."
-                        // TODO Should we accept "RFC822" as well??
-                        ImapString body = fetchList.getKeyedStringOrEmpty("BODY[]", true);
-                        InputStream bodyStream = body.getAsStream();
-                        message.parse(bodyStream);
-                    }
-                    if (fetchPart != null) {
-                        InputStream bodyStream =
-                                fetchList.getKeyedStringOrEmpty("BODY[", true).getAsStream();
-                        String encodings[] = fetchPart.getHeader(
-                                MimeHeader.HEADER_CONTENT_TRANSFER_ENCODING);
-
-                        String contentTransferEncoding = null;
-                        if (encodings != null && encodings.length > 0) {
-                            contentTransferEncoding = encodings[0];
-                        } else {
-                            // According to http://tools.ietf.org/html/rfc2045#section-6.1
-                            // "7bit" is the default.
-                            contentTransferEncoding = "7bit";
-                        }
-
-                        try {
-                            // TODO Don't create 2 temp files.
-                            // decodeBody creates BinaryTempFileBody, but we could avoid this
-                            // if we implement ImapStringBody.
-                            // (We'll need to share a temp file.  Protect it with a ref-count.)
-                            message.setBody(decodeBody(mStore.getContext(), bodyStream,
-                                    contentTransferEncoding, fetchPart.getSize(), listener));
-                        } catch(Exception e) {
-                            // TODO: Figure out what kinds of exceptions might actually be thrown
-                            // from here. This blanket catch-all is because we're not sure what to
-                            // do if we don't have a contentTransferEncoding, and we don't have
-                            // time to figure out what exceptions might be thrown.
-                            LogUtils.e(TAG, "Error fetching body %s", e);
-                        }
-                    }
-
-                    if (listener != null) {
-                        listener.messageRetrieved(message);
-                    }
-                } finally {
-                    destroyResponses();
-                }
-            } while (!response.isTagged());
-        } catch (IOException ioe) {
-            mStore.getImapHelper().handleEvent(OmtpEvents.DATA_GENERIC_IMAP_IOE);
-            throw ioExceptionHandler(mConnection, ioe);
-        }
-    }
-
-    /**
-     * Removes any content transfer encoding from the stream and returns a Body.
-     * This code is taken/condensed from MimeUtility.decodeBody
-     */
-    private static Body decodeBody(Context context,InputStream in, String contentTransferEncoding,
-            int size, MessageRetrievalListener listener) throws IOException {
-        // Get a properly wrapped input stream
-        in = MimeUtility.getInputStreamForContentTransferEncoding(in, contentTransferEncoding);
-        BinaryTempFileBody tempBody = new BinaryTempFileBody();
-        OutputStream out = tempBody.getOutputStream();
-        try {
-            byte[] buffer = new byte[COPY_BUFFER_SIZE];
-            int n = 0;
-            int count = 0;
-            while (-1 != (n = in.read(buffer))) {
-                out.write(buffer, 0, n);
-                count += n;
-            }
-        } catch (Base64DataException bde) {
-            String warning = "\n\n" + context.getString(R.string.message_decode_error);
-            out.write(warning.getBytes());
-        } finally {
-            out.close();
-        }
-        return tempBody;
-    }
-
-    public String[] getPermanentFlags() {
-        return PERMANENT_FLAGS;
-    }
-
-    /**
-     * Handle any untagged responses that the caller doesn't care to handle themselves.
-     * @param responses
-     */
-    private void handleUntaggedResponses(List<ImapResponse> responses) {
-        for (ImapResponse response : responses) {
-            handleUntaggedResponse(response);
-        }
-    }
-
-    /**
-     * Handle an untagged response that the caller doesn't care to handle themselves.
-     * @param response
-     */
-    private void handleUntaggedResponse(ImapResponse response) {
-        if (response.isDataResponse(1, ImapConstants.EXISTS)) {
-            mMessageCount = response.getStringOrEmpty(0).getNumberOrZero();
-        }
-    }
-
-    private static void parseBodyStructure(ImapList bs, Part part, String id)
-            throws MessagingException {
-        if (bs.getElementOrNone(0).isList()) {
-            /*
-             * This is a multipart/*
-             */
-            MimeMultipart mp = new MimeMultipart();
-            for (int i = 0, count = bs.size(); i < count; i++) {
-                ImapElement e = bs.getElementOrNone(i);
-                if (e.isList()) {
-                    /*
-                     * For each part in the message we're going to add a new BodyPart and parse
-                     * into it.
-                     */
-                    MimeBodyPart bp = new MimeBodyPart();
-                    if (id.equals(ImapConstants.TEXT)) {
-                        parseBodyStructure(bs.getListOrEmpty(i), bp, Integer.toString(i + 1));
-
-                    } else {
-                        parseBodyStructure(bs.getListOrEmpty(i), bp, id + "." + (i + 1));
-                    }
-                    mp.addBodyPart(bp);
-
-                } else {
-                    if (e.isString()) {
-                        mp.setSubType(bs.getStringOrEmpty(i).getString().toLowerCase(Locale.US));
-                    }
-                    break; // Ignore the rest of the list.
-                }
-            }
-            part.setBody(mp);
-        } else {
-            /*
-             * This is a body. We need to add as much information as we can find out about
-             * it to the Part.
-             */
-
-            /*
-             body type
-             body subtype
-             body parameter parenthesized list
-             body id
-             body description
-             body encoding
-             body size
-             */
-
-            final ImapString type = bs.getStringOrEmpty(0);
-            final ImapString subType = bs.getStringOrEmpty(1);
-            final String mimeType =
-                    (type.getString() + "/" + subType.getString()).toLowerCase(Locale.US);
-
-            final ImapList bodyParams = bs.getListOrEmpty(2);
-            final ImapString cid = bs.getStringOrEmpty(3);
-            final ImapString encoding = bs.getStringOrEmpty(5);
-            final int size = bs.getStringOrEmpty(6).getNumberOrZero();
-
-            if (MimeUtility.mimeTypeMatches(mimeType, MimeUtility.MIME_TYPE_RFC822)) {
-                // A body type of type MESSAGE and subtype RFC822
-                // contains, immediately after the basic fields, the
-                // envelope structure, body structure, and size in
-                // text lines of the encapsulated message.
-                // [MESSAGE, RFC822, [NAME, filename.eml], NIL, NIL, 7BIT, 5974, NIL,
-                //     [INLINE, [FILENAME*0, Fwd: Xxx..., FILENAME*1, filename.eml]], NIL]
-                /*
-                 * This will be caught by fetch and handled appropriately.
-                 */
-                throw new MessagingException("BODYSTRUCTURE " + MimeUtility.MIME_TYPE_RFC822
-                        + " not yet supported.");
-            }
-
-            /*
-             * Set the content type with as much information as we know right now.
-             */
-            final StringBuilder contentType = new StringBuilder(mimeType);
-
-            /*
-             * If there are body params we might be able to get some more information out
-             * of them.
-             */
-            for (int i = 1, count = bodyParams.size(); i < count; i += 2) {
-
-                // TODO We need to convert " into %22, but
-                // because MimeUtility.getHeaderParameter doesn't recognize it,
-                // we can't fix it for now.
-                contentType.append(String.format(";\n %s=\"%s\"",
-                        bodyParams.getStringOrEmpty(i - 1).getString(),
-                        bodyParams.getStringOrEmpty(i).getString()));
-            }
-
-            part.setHeader(MimeHeader.HEADER_CONTENT_TYPE, contentType.toString());
-
-            // Extension items
-            final ImapList bodyDisposition;
-
-            if (type.is(ImapConstants.TEXT) && bs.getElementOrNone(9).isList()) {
-                // If media-type is TEXT, 9th element might be: [body-fld-lines] := number
-                // So, if it's not a list, use 10th element.
-                // (Couldn't find evidence in the RFC if it's ALWAYS 10th element.)
-                bodyDisposition = bs.getListOrEmpty(9);
-            } else {
-                bodyDisposition = bs.getListOrEmpty(8);
-            }
-
-            final StringBuilder contentDisposition = new StringBuilder();
-
-            if (bodyDisposition.size() > 0) {
-                final String bodyDisposition0Str =
-                        bodyDisposition.getStringOrEmpty(0).getString().toLowerCase(Locale.US);
-                if (!TextUtils.isEmpty(bodyDisposition0Str)) {
-                    contentDisposition.append(bodyDisposition0Str);
-                }
-
-                final ImapList bodyDispositionParams = bodyDisposition.getListOrEmpty(1);
-                if (!bodyDispositionParams.isEmpty()) {
-                    /*
-                     * If there is body disposition information we can pull some more
-                     * information about the attachment out.
-                     */
-                    for (int i = 1, count = bodyDispositionParams.size(); i < count; i += 2) {
-
-                        // TODO We need to convert " into %22.  See above.
-                        contentDisposition.append(String.format(Locale.US, ";\n %s=\"%s\"",
-                                bodyDispositionParams.getStringOrEmpty(i - 1)
-                                        .getString().toLowerCase(Locale.US),
-                                bodyDispositionParams.getStringOrEmpty(i).getString()));
-                    }
-                }
-            }
-
-            if ((size > 0)
-                    && (MimeUtility.getHeaderParameter(contentDisposition.toString(), "size")
-                            == null)) {
-                contentDisposition.append(String.format(Locale.US, ";\n size=%d", size));
-            }
-
-            if (contentDisposition.length() > 0) {
-                /*
-                 * Set the content disposition containing at least the size. Attachment
-                 * handling code will use this down the road.
-                 */
-                part.setHeader(MimeHeader.HEADER_CONTENT_DISPOSITION,
-                        contentDisposition.toString());
-            }
-
-            /*
-             * Set the Content-Transfer-Encoding header. Attachment code will use this
-             * to parse the body.
-             */
-            if (!encoding.isEmpty()) {
-                part.setHeader(MimeHeader.HEADER_CONTENT_TRANSFER_ENCODING,
-                        encoding.getString());
-            }
-
-            /*
-             * Set the Content-ID header.
-             */
-            if (!cid.isEmpty()) {
-                part.setHeader(MimeHeader.HEADER_CONTENT_ID, cid.getString());
-            }
-
-            if (size > 0) {
-                if (part instanceof ImapMessage) {
-                    ((ImapMessage) part).setSize(size);
-                } else if (part instanceof MimeBodyPart) {
-                    ((MimeBodyPart) part).setSize(size);
-                } else {
-                    throw new MessagingException("Unknown part type " + part.toString());
-                }
-            }
-            part.setHeader(MimeHeader.HEADER_ANDROID_ATTACHMENT_STORE_DATA, id);
-        }
-
-    }
-
-    public Message[] expunge() throws MessagingException {
-        checkOpen();
-        try {
-            handleUntaggedResponses(mConnection.executeSimpleCommand(ImapConstants.EXPUNGE));
-        } catch (IOException ioe) {
-            mStore.getImapHelper().handleEvent(OmtpEvents.DATA_GENERIC_IMAP_IOE);
-            throw ioExceptionHandler(mConnection, ioe);
-        } finally {
-            destroyResponses();
-        }
-        return null;
-    }
-
-    public void setFlags(Message[] messages, String[] flags, boolean value)
-            throws MessagingException {
-        checkOpen();
-
-        String allFlags = "";
-        if (flags.length > 0) {
-            StringBuilder flagList = new StringBuilder();
-            for (int i = 0, count = flags.length; i < count; i++) {
-                String flag = flags[i];
-                if (flag == Flag.SEEN) {
-                    flagList.append(" " + ImapConstants.FLAG_SEEN);
-                } else if (flag == Flag.DELETED) {
-                    flagList.append(" " + ImapConstants.FLAG_DELETED);
-                } else if (flag == Flag.FLAGGED) {
-                    flagList.append(" " + ImapConstants.FLAG_FLAGGED);
-                } else if (flag == Flag.ANSWERED) {
-                    flagList.append(" " + ImapConstants.FLAG_ANSWERED);
-                }
-            }
-            allFlags = flagList.substring(1);
-        }
-        try {
-            mConnection.executeSimpleCommand(String.format(Locale.US,
-                    ImapConstants.UID_STORE + " %s %s" + ImapConstants.FLAGS_SILENT + " (%s)",
-                    ImapStore.joinMessageUids(messages),
-                    value ? "+" : "-",
-                    allFlags));
-
-        } catch (IOException ioe) {
-            mStore.getImapHelper().handleEvent(OmtpEvents.DATA_GENERIC_IMAP_IOE);
-            throw ioExceptionHandler(mConnection, ioe);
-        } finally {
-            destroyResponses();
-        }
-    }
-
-    /**
-     * Selects the folder for use. Before performing any operations on this folder, it
-     * must be selected.
-     */
-    private void doSelect() throws IOException, MessagingException {
-        final List<ImapResponse> responses = mConnection.executeSimpleCommand(
-                String.format(Locale.US, ImapConstants.SELECT + " \"%s\"", mName));
-
-        // Assume the folder is opened read-write; unless we are notified otherwise
-        mMode = MODE_READ_WRITE;
-        int messageCount = -1;
-        for (ImapResponse response : responses) {
-            if (response.isDataResponse(1, ImapConstants.EXISTS)) {
-                messageCount = response.getStringOrEmpty(0).getNumberOrZero();
-            } else if (response.isOk()) {
-                final ImapString responseCode = response.getResponseCodeOrEmpty();
-                if (responseCode.is(ImapConstants.READ_ONLY)) {
-                    mMode = MODE_READ_ONLY;
-                } else if (responseCode.is(ImapConstants.READ_WRITE)) {
-                    mMode = MODE_READ_WRITE;
-                }
-            } else if (response.isTagged()) { // Not OK
-                mStore.getImapHelper().handleEvent(OmtpEvents.DATA_MAILBOX_OPEN_FAILED);
-                throw new MessagingException("Can't open mailbox: "
-                        + response.getStatusResponseTextOrEmpty());
-            }
-        }
-        if (messageCount == -1) {
-            throw new MessagingException("Did not find message count during select");
-        }
-        mMessageCount = messageCount;
-        mExists = true;
-    }
-
-    public class Quota {
-
-        public final int occupied;
-        public final int total;
-
-        public Quota(int occupied, int total) {
-            this.occupied = occupied;
-            this.total = total;
-        }
-    }
-
-    public Quota getQuota() throws MessagingException {
-        try {
-            final List<ImapResponse> responses = mConnection.executeSimpleCommand(
-                    String.format(Locale.US, ImapConstants.GETQUOTAROOT + " \"%s\"", mName));
-
-            for (ImapResponse response : responses) {
-                if (!response.isDataResponse(0, ImapConstants.QUOTA)) {
-                    continue;
-                }
-                ImapList list = response.getListOrEmpty(2);
-                for (int i = 0; i < list.size(); i += 3) {
-                    if (!list.getStringOrEmpty(i).is("voice")) {
-                        continue;
-                    }
-                    return new Quota(
-                            list.getStringOrEmpty(i + 1).getNumber(-1),
-                            list.getStringOrEmpty(i + 2).getNumber(-1));
-                }
-            }
-        } catch (IOException ioe) {
-            mStore.getImapHelper().handleEvent(OmtpEvents.DATA_GENERIC_IMAP_IOE);
-            throw ioExceptionHandler(mConnection, ioe);
-        } finally {
-            destroyResponses();
-        }
-        return null;
-    }
-
-    private void checkOpen() throws MessagingException {
-        if (!isOpen()) {
-            throw new MessagingException("Folder " + mName + " is not open.");
-        }
-    }
-
-    private MessagingException ioExceptionHandler(ImapConnection connection, IOException ioe) {
-        LogUtils.d(TAG, "IO Exception detected: ", ioe);
-        connection.close();
-        if (connection == mConnection) {
-            mConnection = null; // To prevent close() from returning the connection to the pool.
-            close(false);
-        }
-        return new MessagingException(MessagingException.IOERROR, "IO Error", ioe);
-    }
-
-    public Message createMessage(String uid) {
-        return new ImapMessage(uid, this);
-    }
-}
\ No newline at end of file
diff --git a/src/com/android/phone/common/mail/store/ImapStore.java b/src/com/android/phone/common/mail/store/ImapStore.java
deleted file mode 100644
index 179d0f2..0000000
--- a/src/com/android/phone/common/mail/store/ImapStore.java
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.phone.common.mail.store;
-
-import android.content.Context;
-import android.net.Network;
-
-import com.android.phone.common.mail.MailTransport;
-import com.android.phone.common.mail.Message;
-import com.android.phone.common.mail.MessagingException;
-import com.android.phone.common.mail.internet.MimeMessage;
-import com.android.phone.vvm.omtp.imap.ImapHelper;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-public class ImapStore {
-    /**
-     * A global suggestion to Store implementors on how much of the body
-     * should be returned on FetchProfile.Item.BODY_SANE requests. We'll use 125k now.
-     */
-    public static final int FETCH_BODY_SANE_SUGGESTED_SIZE = (125 * 1024);
-    private final Context mContext;
-    private final ImapHelper mHelper;
-    private final String mUsername;
-    private final String mPassword;
-    private final MailTransport mTransport;
-    private ImapConnection mConnection;
-
-    public static final int FLAG_NONE         = 0x00;    // No flags
-    public static final int FLAG_SSL          = 0x01;    // Use SSL
-    public static final int FLAG_TLS          = 0x02;    // Use TLS
-    public static final int FLAG_AUTHENTICATE = 0x04;    // Use name/password for authentication
-    public static final int FLAG_TRUST_ALL    = 0x08;    // Trust all certificates
-    public static final int FLAG_OAUTH        = 0x10;    // Use OAuth for authentication
-
-    /**
-     * Contains all the information necessary to log into an imap server
-     */
-    public ImapStore(Context context, ImapHelper helper, String username, String password, int port,
-            String serverName, int flags, Network network) {
-        mContext = context;
-        mHelper = helper;
-        mUsername = username;
-        mPassword = password;
-        mTransport = new MailTransport(context, this.getImapHelper(),
-                network, serverName, port, flags);
-    }
-
-    public Context getContext() {
-        return mContext;
-    }
-
-    public ImapHelper getImapHelper() {
-        return mHelper;
-    }
-
-    public String getUsername() {
-        return mUsername;
-    }
-
-    public String getPassword() {
-        return mPassword;
-    }
-
-    /** Returns a clone of the transport associated with this store. */
-    MailTransport cloneTransport() {
-        return mTransport.clone();
-    }
-
-    /**
-     * Returns UIDs of Messages joined with "," as the separator.
-     */
-    static String joinMessageUids(Message[] messages) {
-        StringBuilder sb = new StringBuilder();
-        boolean notFirst = false;
-        for (Message m : messages) {
-            if (notFirst) {
-                sb.append(',');
-            }
-            sb.append(m.getUid());
-            notFirst = true;
-        }
-        return sb.toString();
-    }
-
-    static class ImapMessage extends MimeMessage {
-        private ImapFolder mFolder;
-
-        ImapMessage(String uid, ImapFolder folder) {
-            mUid = uid;
-            mFolder = folder;
-        }
-
-        public void setSize(int size) {
-            mSize = size;
-        }
-
-        @Override
-        public void parse(InputStream in) throws IOException, MessagingException {
-            super.parse(in);
-        }
-
-        public void setFlagInternal(String flag, boolean set) throws MessagingException {
-            super.setFlag(flag, set);
-        }
-
-        @Override
-        public void setFlag(String flag, boolean set) throws MessagingException {
-            super.setFlag(flag, set);
-            mFolder.setFlags(new Message[] { this }, new String[] { flag }, set);
-        }
-    }
-
-    static class ImapException extends MessagingException {
-        private static final long serialVersionUID = 1L;
-
-        private final String mStatus;
-        private final String mStatusMessage;
-        private final String mAlertText;
-        private final String mResponseCode;
-
-        public ImapException(String message, String status, String statusMessage, String alertText,
-                String responseCode) {
-            super(message);
-            mStatus = status;
-            mStatusMessage = statusMessage;
-            mAlertText = alertText;
-            mResponseCode = responseCode;
-        }
-
-        public String getStatus() {
-            return mStatus;
-        }
-
-        public String getStatusMessage() {
-            return mStatusMessage;
-        }
-
-        public String getAlertText() {
-            return mAlertText;
-        }
-
-        public String getResponseCode() {
-            return mResponseCode;
-        }
-    }
-
-    public void closeConnection() {
-        if (mConnection != null) {
-            mConnection.close();
-            mConnection = null;
-        }
-    }
-
-    public ImapConnection getConnection() {
-        if (mConnection == null) {
-            mConnection = new ImapConnection(this);
-        }
-        return mConnection;
-    }
-}
\ No newline at end of file
diff --git a/src/com/android/phone/common/mail/store/imap/DigestMd5Utils.java b/src/com/android/phone/common/mail/store/imap/DigestMd5Utils.java
deleted file mode 100644
index 436d03c..0000000
--- a/src/com/android/phone/common/mail/store/imap/DigestMd5Utils.java
+++ /dev/null
@@ -1,333 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.phone.common.mail.store.imap;
-
-import android.annotation.Nullable;
-import android.util.ArrayMap;
-import android.util.Base64;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.phone.common.mail.MailTransport;
-import com.android.phone.common.mail.MessagingException;
-import com.android.phone.common.mail.store.ImapStore;
-import com.android.phone.vvm.omtp.VvmLog;
-
-import java.nio.charset.StandardCharsets;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.security.SecureRandom;
-import java.util.Map;
-
-public class DigestMd5Utils {
-
-    private static final String TAG = "DigestMd5Utils";
-
-    private static final String DIGEST_CHARSET = "CHARSET";
-    private static final String DIGEST_USERNAME = "username";
-    private static final String DIGEST_REALM = "realm";
-    private static final String DIGEST_NONCE = "nonce";
-    private static final String DIGEST_NC = "nc";
-    private static final String DIGEST_CNONCE = "cnonce";
-    private static final String DIGEST_URI = "digest-uri";
-    private static final String DIGEST_RESPONSE = "response";
-    private static final String DIGEST_QOP = "qop";
-
-    private static final String RESPONSE_AUTH_HEADER = "rspauth=";
-    private static final String HEX_CHARS = "0123456789abcdef";
-
-    /**
-     * Represents the set of data we need to generate the DIGEST-MD5 response.
-     */
-    public static class Data {
-
-        private static final String CHARSET = "utf-8";
-
-        public String username;
-        public String password;
-        public String realm;
-        public String nonce;
-        public String nc;
-        public String cnonce;
-        public String digestUri;
-        public String qop;
-
-        @VisibleForTesting
-        Data() {
-            // Do nothing
-        }
-
-        public Data(ImapStore imapStore, MailTransport transport, Map<String, String> challenge) {
-            username = imapStore.getUsername();
-            password = imapStore.getPassword();
-            realm = challenge.getOrDefault(DIGEST_REALM, "");
-            nonce = challenge.get(DIGEST_NONCE);
-            cnonce = createCnonce();
-            nc = "00000001"; // Subsequent Authentication not supported, nounce count always 1.
-            qop = "auth"; // Other config not supported
-            digestUri = "imap/" + transport.getHost();
-        }
-
-        private static String createCnonce() {
-            SecureRandom generator = new SecureRandom();
-
-            // At least 64 bits of entropy is required
-            byte[] rawBytes = new byte[8];
-            generator.nextBytes(rawBytes);
-
-            return Base64.encodeToString(rawBytes, Base64.NO_WRAP);
-        }
-
-        /**
-         * Verify the response-auth returned by the server is correct.
-         */
-        public void verifyResponseAuth(String response)
-                throws MessagingException {
-            if (!response.startsWith(RESPONSE_AUTH_HEADER)) {
-                throw new MessagingException("response-auth expected");
-            }
-            if (!response.substring(RESPONSE_AUTH_HEADER.length())
-                    .equals(DigestMd5Utils.getResponse(this, true))) {
-                throw new MessagingException("invalid response-auth return from the server.");
-            }
-        }
-
-        public String createResponse() {
-            String response = getResponse(this, false);
-            ResponseBuilder builder = new ResponseBuilder();
-            builder
-                    .append(DIGEST_CHARSET, CHARSET)
-                    .appendQuoted(DIGEST_USERNAME, username)
-                    .appendQuoted(DIGEST_REALM, realm)
-                    .appendQuoted(DIGEST_NONCE, nonce)
-                    .append(DIGEST_NC, nc)
-                    .appendQuoted(DIGEST_CNONCE, cnonce)
-                    .appendQuoted(DIGEST_URI, digestUri)
-                    .append(DIGEST_RESPONSE, response)
-                    .append(DIGEST_QOP, qop);
-            return builder.toString();
-        }
-
-        private static class ResponseBuilder {
-
-            private StringBuilder mBuilder = new StringBuilder();
-
-            public ResponseBuilder appendQuoted(String key, String value) {
-                if (mBuilder.length() != 0) {
-                    mBuilder.append(",");
-                }
-                mBuilder.append(key).append("=\"").append(value).append("\"");
-                return this;
-            }
-
-            public ResponseBuilder append(String key, String value) {
-                if (mBuilder.length() != 0) {
-                    mBuilder.append(",");
-                }
-                mBuilder.append(key).append("=").append(value);
-                return this;
-            }
-
-            @Override
-            public String toString() {
-                return mBuilder.toString();
-            }
-        }
-    }
-
-    /*
-        response-value  =
-            toHex( getKeyDigest ( toHex(getMd5(a1)),
-            { nonce-value, ":" nc-value, ":",
-              cnonce-value, ":", qop-value, ":", toHex(getMd5(a2)) }))
-     * @param isResponseAuth is the response the one the server is returning us. response-auth has
-     * different a2 format.
-     */
-    @VisibleForTesting
-    static String getResponse(Data data, boolean isResponseAuth) {
-        StringBuilder a1 = new StringBuilder();
-        a1.append(new String(
-                getMd5(data.username + ":" + data.realm + ":" + data.password),
-                StandardCharsets.ISO_8859_1));
-        a1.append(":").append(data.nonce).append(":").append(data.cnonce);
-
-        StringBuilder a2 = new StringBuilder();
-        if (!isResponseAuth) {
-            a2.append("AUTHENTICATE");
-        }
-        a2.append(":").append(data.digestUri);
-
-        return toHex(getKeyDigest(
-                toHex(getMd5(a1.toString())),
-                data.nonce + ":" + data.nc + ":" + data.cnonce + ":" + data.qop + ":" + toHex(
-                        getMd5(a2.toString()))
-        ));
-    }
-
-    /**
-     * Let getMd5(s) be the 16 octet MD5 hash [RFC 1321] of the octet string s.
-     */
-    private static byte[] getMd5(String s) {
-        try {
-            MessageDigest digester = MessageDigest.getInstance("MD5");
-            digester.update(s.getBytes(StandardCharsets.ISO_8859_1));
-            return digester.digest();
-        } catch (NoSuchAlgorithmException e) {
-            throw new AssertionError(e);
-        }
-    }
-
-    /**
-     * Let getKeyDigest(k, s) be getMd5({k, ":", s}), i.e., the 16 octet hash of the string k, a colon and the
-     * string s.
-     */
-    private static byte[] getKeyDigest(String k, String s) {
-        StringBuilder builder = new StringBuilder(k).append(":").append(s);
-        return getMd5(builder.toString());
-    }
-
-    /**
-     * Let toHex(n) be the representation of the 16 octet MD5 hash n as a string of 32 hex digits
-     * (with alphabetic characters always in lower case, since MD5 is case sensitive).
-     */
-    private static String toHex(byte[] n) {
-        StringBuilder result = new StringBuilder();
-        for (byte b : n) {
-            int unsignedByte = b & 0xFF;
-            result.append(HEX_CHARS.charAt(unsignedByte / 16))
-                    .append(HEX_CHARS.charAt(unsignedByte % 16));
-        }
-        return result.toString();
-    }
-
-    public static Map<String, String> parseDigestMessage(String message) throws MessagingException {
-        Map<String, String> result = new DigestMessageParser(message).parse();
-        if (!result.containsKey(DIGEST_NONCE)) {
-            throw new MessagingException("nonce missing from server DIGEST-MD5 challenge");
-        }
-        return result;
-    }
-
-    /**
-     * Parse the key-value pair returned by the server.
-     */
-    private static class DigestMessageParser {
-
-        private final String mMessage;
-        private int mPosition = 0;
-        private Map<String, String> mResult = new ArrayMap<>();
-
-        public DigestMessageParser(String message) {
-            mMessage = message;
-        }
-
-        @Nullable
-        public Map<String, String> parse() {
-            try {
-                while (mPosition < mMessage.length()) {
-                    parsePair();
-                    if (mPosition != mMessage.length()) {
-                        expect(',');
-                    }
-                }
-            } catch (IndexOutOfBoundsException e) {
-                VvmLog.e(TAG, e.toString());
-                return null;
-            }
-            return mResult;
-        }
-
-        private void parsePair() {
-            String key = parseKey();
-            expect('=');
-            String value = parseValue();
-            mResult.put(key, value);
-        }
-
-        private void expect(char c) {
-            if (pop() != c) {
-                throw new IllegalStateException(
-                        "unexpected character " + mMessage.charAt(mPosition));
-            }
-        }
-
-        private char pop() {
-            char result = peek();
-            mPosition++;
-            return result;
-        }
-
-        private char peek() {
-            return mMessage.charAt(mPosition);
-        }
-
-        private void goToNext(char c) {
-            while (peek() != c) {
-                mPosition++;
-            }
-        }
-
-        private String parseKey() {
-            int start = mPosition;
-            goToNext('=');
-            return mMessage.substring(start, mPosition);
-        }
-
-        private String parseValue() {
-            if (peek() == '"') {
-                return parseQuotedValue();
-            } else {
-                return parseUnquotedValue();
-            }
-        }
-
-        private String parseQuotedValue() {
-            expect('"');
-            StringBuilder result = new StringBuilder();
-            while (true) {
-                char c = pop();
-                if (c == '\\') {
-                    result.append(pop());
-                } else if (c == '"') {
-                    break;
-                } else {
-                    result.append(c);
-                }
-            }
-            return result.toString();
-        }
-
-        private String parseUnquotedValue() {
-            StringBuilder result = new StringBuilder();
-            while (true) {
-                char c = pop();
-                if (c == '\\') {
-                    result.append(pop());
-                } else if (c == ',') {
-                    mPosition--;
-                    break;
-                } else {
-                    result.append(c);
-                }
-
-                if (mPosition == mMessage.length()) {
-                    break;
-                }
-            }
-            return result.toString();
-        }
-    }
-}
diff --git a/src/com/android/phone/common/mail/store/imap/ImapConstants.java b/src/com/android/phone/common/mail/store/imap/ImapConstants.java
deleted file mode 100644
index a2eab13..0000000
--- a/src/com/android/phone/common/mail/store/imap/ImapConstants.java
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.phone.common.mail.store.imap;
-
-import com.android.phone.common.mail.store.ImapStore;
-
-import java.util.Locale;
-
-public final class ImapConstants {
-    private ImapConstants() {}
-
-    public static final String FETCH_FIELD_BODY_PEEK_BARE = "BODY.PEEK";
-    public static final String FETCH_FIELD_BODY_PEEK = FETCH_FIELD_BODY_PEEK_BARE + "[]";
-    public static final String FETCH_FIELD_BODY_PEEK_SANE = String.format(
-            Locale.US, "BODY.PEEK[]<0.%d>", ImapStore.FETCH_BODY_SANE_SUGGESTED_SIZE);
-    public static final String FETCH_FIELD_HEADERS =
-            "BODY.PEEK[HEADER.FIELDS (date subject from content-type to cc message-id)]";
-
-    public static final String ALERT = "ALERT";
-    public static final String APPEND = "APPEND";
-    public static final String AUTHENTICATE = "AUTHENTICATE";
-    public static final String BAD = "BAD";
-    public static final String BADCHARSET = "BADCHARSET";
-    public static final String BODY = "BODY";
-    public static final String BODY_BRACKET_HEADER = "BODY[HEADER";
-    public static final String BODYSTRUCTURE = "BODYSTRUCTURE";
-    public static final String BYE = "BYE";
-    public static final String CAPABILITY = "CAPABILITY";
-    public static final String CHECK = "CHECK";
-    public static final String CLOSE = "CLOSE";
-    public static final String COPY = "COPY";
-    public static final String COPYUID = "COPYUID";
-    public static final String CREATE = "CREATE";
-    public static final String DELETE = "DELETE";
-    public static final String EXAMINE = "EXAMINE";
-    public static final String EXISTS = "EXISTS";
-    public static final String EXPUNGE = "EXPUNGE";
-    public static final String FETCH = "FETCH";
-    public static final String FLAG_ANSWERED = "\\ANSWERED";
-    public static final String FLAG_DELETED = "\\DELETED";
-    public static final String FLAG_FLAGGED = "\\FLAGGED";
-    public static final String FLAG_NO_SELECT = "\\NOSELECT";
-    public static final String FLAG_SEEN = "\\SEEN";
-    public static final String FLAGS = "FLAGS";
-    public static final String FLAGS_SILENT = "FLAGS.SILENT";
-    public static final String ID = "ID";
-    public static final String INBOX = "INBOX";
-    public static final String INTERNALDATE = "INTERNALDATE";
-    public static final String LIST = "LIST";
-    public static final String LOGIN = "LOGIN";
-    public static final String LOGOUT = "LOGOUT";
-    public static final String LSUB = "LSUB";
-    public static final String NAMESPACE = "NAMESPACE";
-    public static final String NO = "NO";
-    public static final String NOOP = "NOOP";
-    public static final String OK = "OK";
-    public static final String PARSE = "PARSE";
-    public static final String PERMANENTFLAGS = "PERMANENTFLAGS";
-    public static final String PREAUTH = "PREAUTH";
-    public static final String READ_ONLY = "READ-ONLY";
-    public static final String READ_WRITE = "READ-WRITE";
-    public static final String RENAME = "RENAME";
-    public static final String RFC822_SIZE = "RFC822.SIZE";
-    public static final String SEARCH = "SEARCH";
-    public static final String SELECT = "SELECT";
-    public static final String STARTTLS = "STARTTLS";
-    public static final String STATUS = "STATUS";
-    public static final String STORE = "STORE";
-    public static final String SUBSCRIBE = "SUBSCRIBE";
-    public static final String TEXT = "TEXT";
-    public static final String TRYCREATE = "TRYCREATE";
-    public static final String UID = "UID";
-    public static final String UID_COPY = "UID COPY";
-    public static final String UID_FETCH = "UID FETCH";
-    public static final String UID_SEARCH = "UID SEARCH";
-    public static final String UID_STORE = "UID STORE";
-    public static final String UIDNEXT = "UIDNEXT";
-    public static final String UIDPLUS = "UIDPLUS";
-    public static final String UIDVALIDITY = "UIDVALIDITY";
-    public static final String UNSEEN = "UNSEEN";
-    public static final String UNSUBSCRIBE = "UNSUBSCRIBE";
-    public static final String XOAUTH2 = "XOAUTH2";
-    public static final String APPENDUID = "APPENDUID";
-    public static final String NIL = "NIL";
-
-    /**
-     * NO responses
-     */
-    public static final String NO_COMMAND_NOT_ALLOWED = "command not allowed";
-    public static final String NO_RESERVATION_FAILED = "reservation failed";
-    public static final String NO_APPLICATION_ERROR = "application error";
-    public static final String NO_INVALID_PARAMETER = "invalid parameter";
-    public static final String NO_INVALID_COMMAND = "invalid command";
-    public static final String NO_UNKNOWN_COMMAND = "unknown command";
-    // AUTHENTICATE
-    // The subscriber can not be located in the system.
-    public static final String NO_UNKNOWN_USER = "unknown user";
-    // The Client Type or Protocol Version is unknown.
-    public static final String NO_UNKNOWN_CLIENT = "unknown client";
-    // The password received from the client does not match the password defined in the subscriber's profile.
-    public static final String NO_INVALID_PASSWORD = "invalid password";
-    // The subscriber's mailbox has not yet been initialised via the TUI
-    public static final String NO_MAILBOX_NOT_INITIALIZED = "mailbox not initialized";
-    // The subscriber has not been provisioned for the VVM service.
-    public static final String NO_SERVICE_IS_NOT_PROVISIONED =
-            "service is not provisioned";
-    // The subscriber is provisioned for the VVM service but the VVM service is currently not active
-    public static final String NO_SERVICE_IS_NOT_ACTIVATED = "service is not activated";
-    // The Voice Mail Blocked flag in the subscriber's profile is set to YES.
-    public static final String NO_USER_IS_BLOCKED = "user is blocked";
-
-    /**
-     * extensions
-     */
-    public static final String GETQUOTA = "GETQUOTA";
-    public static final String GETQUOTAROOT = "GETQUOTAROOT";
-    public static final String QUOTAROOT = "QUOTAROOT";
-    public static final String QUOTA = "QUOTA";
-
-    /**
-     * capabilities
-     */
-    public static final String CAPABILITY_AUTH_DIGEST_MD5 = "AUTH=DIGEST-MD5";
-    public static final String CAPABILITY_STARTTLS = "STARTTLS";
-
-    /**
-     * authentication
-     */
-    public static final String AUTH_DIGEST_MD5 = "DIGEST-MD5";
-}
\ No newline at end of file
diff --git a/src/com/android/phone/common/mail/store/imap/ImapElement.java b/src/com/android/phone/common/mail/store/imap/ImapElement.java
deleted file mode 100644
index 2d1824e..0000000
--- a/src/com/android/phone/common/mail/store/imap/ImapElement.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.phone.common.mail.store.imap;
-
-/**
- * Class representing "element"s in IMAP responses.
- *
- * <p>Class hierarchy:
- * <pre>
- * ImapElement
- *   |
- *   |-- ImapElement.NONE (for 'index out of range')
- *   |
- *   |-- ImapList (isList() == true)
- *   |   |
- *   |   |-- ImapList.EMPTY
- *   |   |
- *   |   --- ImapResponse
- *   |
- *   --- ImapString (isString() == true)
- *       |
- *       |-- ImapString.EMPTY
- *       |
- *       |-- ImapSimpleString
- *       |
- *       |-- ImapMemoryLiteral
- *       |
- *       --- ImapTempFileLiteral
- * </pre>
- */
-public abstract class ImapElement {
-    /**
-     * An element that is returned by {@link ImapList#getElementOrNone} to indicate an index
-     * is out of range.
-     */
-    public static final ImapElement NONE = new ImapElement() {
-        @Override public void destroy() {
-            // Don't call super.destroy().
-            // It's a shared object.  We don't want the mDestroyed to be set on this.
-        }
-
-        @Override public boolean isList() {
-            return false;
-        }
-
-        @Override public boolean isString() {
-            return false;
-        }
-
-        @Override public String toString() {
-            return "[NO ELEMENT]";
-        }
-
-        @Override
-        public boolean equalsForTest(ImapElement that) {
-            return super.equalsForTest(that);
-        }
-    };
-
-    private boolean mDestroyed = false;
-
-    public abstract boolean isList();
-
-    public abstract boolean isString();
-
-    protected boolean isDestroyed() {
-        return mDestroyed;
-    }
-
-    /**
-     * Clean up the resources used by the instance.
-     * It's for removing a temp file used by {@link ImapTempFileLiteral}.
-     */
-    public void destroy() {
-        mDestroyed = true;
-    }
-
-    /**
-     * Throws {@link RuntimeException} if it's already destroyed.
-     */
-    protected final void checkNotDestroyed() {
-        if (mDestroyed) {
-            throw new RuntimeException("Already destroyed");
-        }
-    }
-
-    /**
-     * Return a string that represents this object; it's purely for the debug purpose.  Don't
-     * mistake it for {@link ImapString#getString}.
-     *
-     * Abstract to force subclasses to implement it.
-     */
-    @Override
-    public abstract String toString();
-
-    /**
-     * The equals implementation that is intended to be used only for unit testing.
-     * (Because it may be heavy and has a special sense of "equal" for testing.)
-     */
-    public boolean equalsForTest(ImapElement that) {
-        if (that == null) {
-            return false;
-        }
-        return this.getClass() == that.getClass(); // Has to be the same class.
-    }
-}
\ No newline at end of file
diff --git a/src/com/android/phone/common/mail/store/imap/ImapList.java b/src/com/android/phone/common/mail/store/imap/ImapList.java
deleted file mode 100644
index 93adc4f..0000000
--- a/src/com/android/phone/common/mail/store/imap/ImapList.java
+++ /dev/null
@@ -1,235 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.phone.common.mail.store.imap;
-
-import java.util.ArrayList;
-
-/**
- * Class represents an IMAP list.
- */
-public class ImapList extends ImapElement {
-    /**
-     * {@link ImapList} representing an empty list.
-     */
-    public static final ImapList EMPTY = new ImapList() {
-        @Override public void destroy() {
-            // Don't call super.destroy().
-            // It's a shared object.  We don't want the mDestroyed to be set on this.
-        }
-
-        @Override void add(ImapElement e) {
-            throw new RuntimeException();
-        }
-    };
-
-    private ArrayList<ImapElement> mList = new ArrayList<ImapElement>();
-
-    /* package */ void add(ImapElement e) {
-        if (e == null) {
-            throw new RuntimeException("Can't add null");
-        }
-        mList.add(e);
-    }
-
-    @Override
-    public final boolean isString() {
-        return false;
-    }
-
-    @Override
-    public final boolean isList() {
-        return true;
-    }
-
-    public final int size() {
-        return mList.size();
-    }
-
-    public final boolean isEmpty() {
-        return size() == 0;
-    }
-
-    /**
-     * Return true if the element at {@code index} exists, is string, and equals to {@code s}.
-     * (case insensitive)
-     */
-    public final boolean is(int index, String s) {
-        return is(index, s, false);
-    }
-
-    /**
-     * Same as {@link #is(int, String)}, but does the prefix match if {@code prefixMatch}.
-     */
-    public final boolean is(int index, String s, boolean prefixMatch) {
-        if (!prefixMatch) {
-            return getStringOrEmpty(index).is(s);
-        } else {
-            return getStringOrEmpty(index).startsWith(s);
-        }
-    }
-
-    /**
-     * Return the element at {@code index}.
-     * If {@code index} is out of range, returns {@link ImapElement#NONE}.
-     */
-    public final ImapElement getElementOrNone(int index) {
-        return (index >= mList.size()) ? ImapElement.NONE : mList.get(index);
-    }
-
-    /**
-     * Return the element at {@code index} if it's a list.
-     * If {@code index} is out of range or not a list, returns {@link ImapList#EMPTY}.
-     */
-    public final ImapList getListOrEmpty(int index) {
-        ImapElement el = getElementOrNone(index);
-        return el.isList() ? (ImapList) el : EMPTY;
-    }
-
-    /**
-     * Return the element at {@code index} if it's a string.
-     * If {@code index} is out of range or not a string, returns {@link ImapString#EMPTY}.
-     */
-    public final ImapString getStringOrEmpty(int index) {
-        ImapElement el = getElementOrNone(index);
-        return el.isString() ? (ImapString) el : ImapString.EMPTY;
-    }
-
-    /**
-     * Return an element keyed by {@code key}.  Return null if not found.  {@code key} has to be
-     * at an even index.
-     */
-    /* package */ final ImapElement getKeyedElementOrNull(String key, boolean prefixMatch) {
-        for (int i = 1; i < size(); i += 2) {
-            if (is(i-1, key, prefixMatch)) {
-                return mList.get(i);
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Return an {@link ImapList} keyed by {@code key}.
-     * Return {@link ImapList#EMPTY} if not found.
-     */
-    public final ImapList getKeyedListOrEmpty(String key) {
-        return getKeyedListOrEmpty(key, false);
-    }
-
-    /**
-     * Return an {@link ImapList} keyed by {@code key}.
-     * Return {@link ImapList#EMPTY} if not found.
-     */
-    public final ImapList getKeyedListOrEmpty(String key, boolean prefixMatch) {
-        ImapElement e = getKeyedElementOrNull(key, prefixMatch);
-        return (e != null) ? ((ImapList) e) : ImapList.EMPTY;
-    }
-
-    /**
-     * Return an {@link ImapString} keyed by {@code key}.
-     * Return {@link ImapString#EMPTY} if not found.
-     */
-    public final ImapString getKeyedStringOrEmpty(String key) {
-        return getKeyedStringOrEmpty(key, false);
-    }
-
-    /**
-     * Return an {@link ImapString} keyed by {@code key}.
-     * Return {@link ImapString#EMPTY} if not found.
-     */
-    public final ImapString getKeyedStringOrEmpty(String key, boolean prefixMatch) {
-        ImapElement e = getKeyedElementOrNull(key, prefixMatch);
-        return (e != null) ? ((ImapString) e) : ImapString.EMPTY;
-    }
-
-    /**
-     * Return true if it contains {@code s}.
-     */
-    public final boolean contains(String s) {
-        for (int i = 0; i < size(); i++) {
-            if (getStringOrEmpty(i).is(s)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    @Override
-    public void destroy() {
-        if (mList != null) {
-            for (ImapElement e : mList) {
-                e.destroy();
-            }
-            mList = null;
-        }
-        super.destroy();
-    }
-
-    @Override
-    public String toString() {
-        return mList.toString();
-    }
-
-    /**
-     * Return the text representations of the contents concatenated with ",".
-     */
-    public final String flatten() {
-        return flatten(new StringBuilder()).toString();
-    }
-
-    /**
-     * Returns text representations (i.e. getString()) of contents joined together with
-     * "," as the separator.
-     *
-     * Only used for building the capability string passed to vendor policies.
-     *
-     * We can't use toString(), because it's for debugging (meaning the format may change any time),
-     * and it won't expand literals.
-     */
-    private final StringBuilder flatten(StringBuilder sb) {
-        sb.append('[');
-        for (int i = 0; i < mList.size(); i++) {
-            if (i > 0) {
-                sb.append(',');
-            }
-            final ImapElement e = getElementOrNone(i);
-            if (e.isList()) {
-                getListOrEmpty(i).flatten(sb);
-            } else if (e.isString()) {
-                sb.append(getStringOrEmpty(i).getString());
-            }
-        }
-        sb.append(']');
-        return sb;
-    }
-
-    @Override
-    public boolean equalsForTest(ImapElement that) {
-        if (!super.equalsForTest(that)) {
-            return false;
-        }
-        ImapList thatList = (ImapList) that;
-        if (size() != thatList.size()) {
-            return false;
-        }
-        for (int i = 0; i < size(); i++) {
-            if (!mList.get(i).equalsForTest(thatList.getElementOrNone(i))) {
-                return false;
-            }
-        }
-        return true;
-    }
-}
\ No newline at end of file
diff --git a/src/com/android/phone/common/mail/store/imap/ImapMemoryLiteral.java b/src/com/android/phone/common/mail/store/imap/ImapMemoryLiteral.java
deleted file mode 100644
index 4811590..0000000
--- a/src/com/android/phone/common/mail/store/imap/ImapMemoryLiteral.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.phone.common.mail.store.imap;
-
-import com.android.phone.common.mail.FixedLengthInputStream;
-import com.android.phone.vvm.omtp.VvmLog;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.UnsupportedEncodingException;
-
-/**
- * Subclass of {@link ImapString} used for literals backed by an in-memory byte array.
- */
-public class ImapMemoryLiteral extends ImapString {
-    private final String TAG = "ImapMemoryLiteral";
-    private byte[] mData;
-
-    /* package */ ImapMemoryLiteral(FixedLengthInputStream in) throws IOException {
-        // We could use ByteArrayOutputStream and IOUtils.copy, but it'd perform an unnecessary
-        // copy....
-        mData = new byte[in.getLength()];
-        int pos = 0;
-        while (pos < mData.length) {
-            int read = in.read(mData, pos, mData.length - pos);
-            if (read < 0) {
-                break;
-            }
-            pos += read;
-        }
-        if (pos != mData.length) {
-            VvmLog.w(TAG, "length mismatch");
-        }
-    }
-
-    @Override
-    public void destroy() {
-        mData = null;
-        super.destroy();
-    }
-
-    @Override
-    public String getString() {
-        try {
-            return new String(mData, "US-ASCII");
-        } catch (UnsupportedEncodingException e) {
-            VvmLog.e(TAG, "Unsupported encoding: ", e);
-        }
-        return null;
-    }
-
-    @Override
-    public InputStream getAsStream() {
-        return new ByteArrayInputStream(mData);
-    }
-
-    @Override
-    public String toString() {
-        return String.format("{%d byte literal(memory)}", mData.length);
-    }
-}
\ No newline at end of file
diff --git a/src/com/android/phone/common/mail/store/imap/ImapResponse.java b/src/com/android/phone/common/mail/store/imap/ImapResponse.java
deleted file mode 100644
index 4891966..0000000
--- a/src/com/android/phone/common/mail/store/imap/ImapResponse.java
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.phone.common.mail.store.imap;
-
-/**
- * Class represents an IMAP response.
- */
-public class ImapResponse extends ImapList {
-    private final String mTag;
-    private final boolean mIsContinuationRequest;
-
-    /* package */ ImapResponse(String tag, boolean isContinuationRequest) {
-        mTag = tag;
-        mIsContinuationRequest = isContinuationRequest;
-    }
-
-    /* package */ static boolean isStatusResponse(String symbol) {
-        return     ImapConstants.OK.equalsIgnoreCase(symbol)
-                || ImapConstants.NO.equalsIgnoreCase(symbol)
-                || ImapConstants.BAD.equalsIgnoreCase(symbol)
-                || ImapConstants.PREAUTH.equalsIgnoreCase(symbol)
-                || ImapConstants.BYE.equalsIgnoreCase(symbol);
-    }
-
-    /**
-     * @return whether it's a tagged response.
-     */
-    public boolean isTagged() {
-        return mTag != null;
-    }
-
-    /**
-     * @return whether it's a continuation request.
-     */
-    public boolean isContinuationRequest() {
-        return mIsContinuationRequest;
-    }
-
-    public boolean isStatusResponse() {
-        return isStatusResponse(getStringOrEmpty(0).getString());
-    }
-
-    /**
-     * @return whether it's an OK response.
-     */
-    public boolean isOk() {
-        return is(0, ImapConstants.OK);
-    }
-
-    /**
-     * @return whether it's an BAD response.
-     */
-    public boolean isBad() {
-        return is(0, ImapConstants.BAD);
-    }
-
-    /**
-     * @return whether it's an NO response.
-     */
-    public boolean isNo() {
-        return is(0, ImapConstants.NO);
-    }
-
-    /**
-     * @return whether it's an {@code responseType} data response.  (i.e. not tagged).
-     * @param index where {@code responseType} should appear.  e.g. 1 for "FETCH"
-     * @param responseType e.g. "FETCH"
-     */
-    public final boolean isDataResponse(int index, String responseType) {
-        return !isTagged() && getStringOrEmpty(index).is(responseType);
-    }
-
-    /**
-     * @return Response code (RFC 3501 7.1) if it's a status response.
-     *
-     * e.g. "ALERT" for "* OK [ALERT] System shutdown in 10 minutes"
-     */
-    public ImapString getResponseCodeOrEmpty() {
-        if (!isStatusResponse()) {
-            return ImapString.EMPTY; // Not a status response.
-        }
-        return getListOrEmpty(1).getStringOrEmpty(0);
-    }
-
-    /**
-     * @return Alert message it it has ALERT response code.
-     *
-     * e.g. "System shutdown in 10 minutes" for "* OK [ALERT] System shutdown in 10 minutes"
-     */
-    public ImapString getAlertTextOrEmpty() {
-        if (!getResponseCodeOrEmpty().is(ImapConstants.ALERT)) {
-            return ImapString.EMPTY; // Not an ALERT
-        }
-        // The 3rd element contains all the rest of line.
-        return getStringOrEmpty(2);
-    }
-
-    /**
-     * @return Response text in a status response.
-     */
-    public ImapString getStatusResponseTextOrEmpty() {
-        if (!isStatusResponse()) {
-            return ImapString.EMPTY;
-        }
-        return getStringOrEmpty(getElementOrNone(1).isList() ? 2 : 1);
-    }
-
-    public ImapString getStatusOrEmpty() {
-        if (!isStatusResponse()) {
-            return ImapString.EMPTY;
-        }
-        return getStringOrEmpty(0);
-    }
-
-    @Override
-    public String toString() {
-        String tag = mTag;
-        if (isContinuationRequest()) {
-            tag = "+";
-        }
-        return "#" + tag + "# " + super.toString();
-    }
-
-    @Override
-    public boolean equalsForTest(ImapElement that) {
-        if (!super.equalsForTest(that)) {
-            return false;
-        }
-        final ImapResponse thatResponse = (ImapResponse) that;
-        if (mTag == null) {
-            if (thatResponse.mTag != null) {
-                return false;
-            }
-        } else {
-            if (!mTag.equals(thatResponse.mTag)) {
-                return false;
-            }
-        }
-        if (mIsContinuationRequest != thatResponse.mIsContinuationRequest) {
-            return false;
-        }
-        return true;
-    }
-}
\ No newline at end of file
diff --git a/src/com/android/phone/common/mail/store/imap/ImapResponseParser.java b/src/com/android/phone/common/mail/store/imap/ImapResponseParser.java
deleted file mode 100644
index 6fc5abe..0000000
--- a/src/com/android/phone/common/mail/store/imap/ImapResponseParser.java
+++ /dev/null
@@ -1,432 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.phone.common.mail.store.imap;
-
-import android.text.TextUtils;
-import android.util.Log;
-
-import com.android.phone.common.mail.FixedLengthInputStream;
-import com.android.phone.common.mail.MessagingException;
-import com.android.phone.common.mail.PeekableInputStream;
-import com.android.phone.vvm.omtp.VvmLog;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.ArrayList;
-
-/**
- * IMAP response parser.
- */
-public class ImapResponseParser {
-    private static final String TAG = "ImapResponseParser";
-
-    /**
-     * Literal larger than this will be stored in temp file.
-     */
-    public static final int LITERAL_KEEP_IN_MEMORY_THRESHOLD = 2 * 1024 * 1024;
-
-    /** Input stream */
-    private final PeekableInputStream mIn;
-
-    private final int mLiteralKeepInMemoryThreshold;
-
-    /** StringBuilder used by readUntil() */
-    private final StringBuilder mBufferReadUntil = new StringBuilder();
-
-    /** StringBuilder used by parseBareString() */
-    private final StringBuilder mParseBareString = new StringBuilder();
-
-    /**
-     * We store all {@link ImapResponse} in it.  {@link #destroyResponses()} must be called from
-     * time to time to destroy them and clear it.
-     */
-    private final ArrayList<ImapResponse> mResponsesToDestroy = new ArrayList<ImapResponse>();
-
-    /**
-     * Exception thrown when we receive BYE.  It derives from IOException, so it'll be treated
-     * in the same way EOF does.
-     */
-    public static class ByeException extends IOException {
-        public static final String MESSAGE = "Received BYE";
-        public ByeException() {
-            super(MESSAGE);
-        }
-    }
-
-    /**
-     * Public constructor for normal use.
-     */
-    public ImapResponseParser(InputStream in) {
-        this(in, LITERAL_KEEP_IN_MEMORY_THRESHOLD);
-    }
-
-    /**
-     * Constructor for testing to override the literal size threshold.
-     */
-    /* package for test */ ImapResponseParser(InputStream in, int literalKeepInMemoryThreshold) {
-        mIn = new PeekableInputStream(in);
-        mLiteralKeepInMemoryThreshold = literalKeepInMemoryThreshold;
-    }
-
-    private static IOException newEOSException() {
-        final String message = "End of stream reached";
-        VvmLog.d(TAG, message);
-        return new IOException(message);
-    }
-
-    /**
-     * Peek next one byte.
-     *
-     * Throws IOException() if reaches EOF.  As long as logical response lines end with \r\n,
-     * we shouldn't see EOF during parsing.
-     */
-    private int peek() throws IOException {
-        final int next = mIn.peek();
-        if (next == -1) {
-            throw newEOSException();
-        }
-        return next;
-    }
-
-    /**
-     * Read and return one byte from {@link #mIn}, and put it in {@link #mDiscourseLogger}.
-     *
-     * Throws IOException() if reaches EOF.  As long as logical response lines end with \r\n,
-     * we shouldn't see EOF during parsing.
-     */
-    private int readByte() throws IOException {
-        int next = mIn.read();
-        if (next == -1) {
-            throw newEOSException();
-        }
-        return next;
-    }
-
-    /**
-     * Destroy all the {@link ImapResponse}s stored in the internal storage and clear it.
-     *
-     * @see #readResponse()
-     */
-    public void destroyResponses() {
-        for (ImapResponse r : mResponsesToDestroy) {
-            r.destroy();
-        }
-        mResponsesToDestroy.clear();
-    }
-
-    /**
-     * Reads the next response available on the stream and returns an
-     * {@link ImapResponse} object that represents it.
-     *
-     * <p>When this method successfully returns an {@link ImapResponse}, the {@link ImapResponse}
-     * is stored in the internal storage.  When the {@link ImapResponse} is no longer used
-     * {@link #destroyResponses} should be called to destroy all the responses in the array.
-     *
-     * @param byeExpected is a untagged BYE response expected? If not proper cleanup will be done
-     * and {@link ByeException} will be thrown.
-     * @return the parsed {@link ImapResponse} object.
-     * @exception ByeException when detects BYE and <code>byeExpected</code> is false.
-     */
-    public ImapResponse readResponse(boolean byeExpected) throws IOException, MessagingException {
-        ImapResponse response = null;
-        try {
-            response = parseResponse();
-        } catch (RuntimeException e) {
-            // Parser crash -- log network activities.
-            onParseError(e);
-            throw e;
-        } catch (IOException e) {
-            // Network error, or received an unexpected char.
-            onParseError(e);
-            throw e;
-        }
-
-        // Handle this outside of try-catch.  We don't have to dump protocol log when getting BYE.
-        if (!byeExpected && response.is(0, ImapConstants.BYE)) {
-            Log.w(TAG, ByeException.MESSAGE);
-            response.destroy();
-            throw new ByeException();
-        }
-        mResponsesToDestroy.add(response);
-        return response;
-    }
-
-    private void onParseError(Exception e) {
-        // Read a few more bytes, so that the log will contain some more context, even if the parser
-        // crashes in the middle of a response.
-        // This also makes sure the byte in question will be logged, no matter where it crashes.
-        // e.g. when parseAtom() peeks and finds at an unexpected char, it throws an exception
-        // before actually reading it.
-        // However, we don't want to read too much, because then it may get into an email message.
-        try {
-            for (int i = 0; i < 4; i++) {
-                int b = readByte();
-                if (b == -1 || b == '\n') {
-                    break;
-                }
-            }
-        } catch (IOException ignore) {
-        }
-        VvmLog.w(TAG, "Exception detected: " + e.getMessage());
-    }
-
-    /**
-     * Read next byte from stream and throw it away.  If the byte is different from {@code expected}
-     * throw {@link MessagingException}.
-     */
-    /* package for test */ void expect(char expected) throws IOException {
-        final int next = readByte();
-        if (expected != next) {
-            throw new IOException(String.format("Expected %04x (%c) but got %04x (%c)",
-                    (int) expected, expected, next, (char) next));
-        }
-    }
-
-    /**
-     * Read bytes until we find {@code end}, and return all as string.
-     * The {@code end} will be read (rather than peeked) and won't be included in the result.
-     */
-    /* package for test */ String readUntil(char end) throws IOException {
-        mBufferReadUntil.setLength(0);
-        for (;;) {
-            final int ch = readByte();
-            if (ch != end) {
-                mBufferReadUntil.append((char) ch);
-            } else {
-                return mBufferReadUntil.toString();
-            }
-        }
-    }
-
-    /**
-     * Read all bytes until \r\n.
-     */
-    /* package */ String readUntilEol() throws IOException {
-        String ret = readUntil('\r');
-        expect('\n'); // TODO Should this really be error?
-        return ret;
-    }
-
-    /**
-     * Parse and return the response line.
-     */
-    private ImapResponse parseResponse() throws IOException, MessagingException {
-        // We need to destroy the response if we get an exception.
-        // So, we first store the response that's being built in responseToDestroy, until it's
-        // completely built, at which point we copy it into responseToReturn and null out
-        // responseToDestroyt.
-        // If responseToDestroy is not null in finally, we destroy it because that means
-        // we got an exception somewhere.
-        ImapResponse responseToDestroy = null;
-        final ImapResponse responseToReturn;
-
-        try {
-            final int ch = peek();
-            if (ch == '+') { // Continuation request
-                readByte(); // skip +
-                expect(' ');
-                responseToDestroy = new ImapResponse(null, true);
-
-                // If it's continuation request, we don't really care what's in it.
-                responseToDestroy.add(new ImapSimpleString(readUntilEol()));
-
-                // Response has successfully been built.  Let's return it.
-                responseToReturn = responseToDestroy;
-                responseToDestroy = null;
-            } else {
-                // Status response or response data
-                final String tag;
-                if (ch == '*') {
-                    tag = null;
-                    readByte(); // skip *
-                    expect(' ');
-                } else {
-                    tag = readUntil(' ');
-                }
-                responseToDestroy = new ImapResponse(tag, false);
-
-                final ImapString firstString = parseBareString();
-                responseToDestroy.add(firstString);
-
-                // parseBareString won't eat a space after the string, so we need to skip it,
-                // if exists.
-                // If the next char is not ' ', it should be EOL.
-                if (peek() == ' ') {
-                    readByte(); // skip ' '
-
-                    if (responseToDestroy.isStatusResponse()) { // It's a status response
-
-                        // Is there a response code?
-                        final int next = peek();
-                        if (next == '[') {
-                            responseToDestroy.add(parseList('[', ']'));
-                            if (peek() == ' ') { // Skip following space
-                                readByte();
-                            }
-                        }
-
-                        String rest = readUntilEol();
-                        if (!TextUtils.isEmpty(rest)) {
-                            // The rest is free-form text.
-                            responseToDestroy.add(new ImapSimpleString(rest));
-                        }
-                    } else { // It's a response data.
-                        parseElements(responseToDestroy, '\0');
-                    }
-                } else {
-                    expect('\r');
-                    expect('\n');
-                }
-
-                // Response has successfully been built.  Let's return it.
-                responseToReturn = responseToDestroy;
-                responseToDestroy = null;
-            }
-        } finally {
-            if (responseToDestroy != null) {
-                // We get an exception.
-                responseToDestroy.destroy();
-            }
-        }
-
-        return responseToReturn;
-    }
-
-    private ImapElement parseElement() throws IOException, MessagingException {
-        final int next = peek();
-        switch (next) {
-            case '(':
-                return parseList('(', ')');
-            case '[':
-                return parseList('[', ']');
-            case '"':
-                readByte(); // Skip "
-                return new ImapSimpleString(readUntil('"'));
-            case '{':
-                return parseLiteral();
-            case '\r':  // CR
-                readByte(); // Consume \r
-                expect('\n'); // Should be followed by LF.
-                return null;
-            case '\n': // LF // There shouldn't be a bare LF, but just in case.
-                readByte(); // Consume \n
-                return null;
-            default:
-                return parseBareString();
-        }
-    }
-
-    /**
-     * Parses an atom.
-     *
-     * Special case: If an atom contains '[', everything until the next ']' will be considered
-     * a part of the atom.
-     * (e.g. "BODY[HEADER.FIELDS ("DATE" ...)]" will become a single ImapString)
-     *
-     * If the value is "NIL", returns an empty string.
-     */
-    private ImapString parseBareString() throws IOException, MessagingException {
-        mParseBareString.setLength(0);
-        for (;;) {
-            final int ch = peek();
-
-            // TODO Can we clean this up?  (This condition is from the old parser.)
-            if (ch == '(' || ch == ')' || ch == '{' || ch == ' ' ||
-                    // ']' is not part of atom (it's in resp-specials)
-                    ch == ']' ||
-                    // docs claim that flags are \ atom but atom isn't supposed to
-                    // contain
-                    // * and some flags contain *
-                    // ch == '%' || ch == '*' ||
-                    ch == '%' ||
-                    // TODO probably should not allow \ and should recognize
-                    // it as a flag instead
-                    // ch == '"' || ch == '\' ||
-                    ch == '"' || (0x00 <= ch && ch <= 0x1f) || ch == 0x7f) {
-                if (mParseBareString.length() == 0) {
-                    throw new MessagingException("Expected string, none found.");
-                }
-                String s = mParseBareString.toString();
-
-                // NIL will be always converted into the empty string.
-                if (ImapConstants.NIL.equalsIgnoreCase(s)) {
-                    return ImapString.EMPTY;
-                }
-                return new ImapSimpleString(s);
-            } else if (ch == '[') {
-                // Eat all until next ']'
-                mParseBareString.append((char) readByte());
-                mParseBareString.append(readUntil(']'));
-                mParseBareString.append(']'); // readUntil won't include the end char.
-            } else {
-                mParseBareString.append((char) readByte());
-            }
-        }
-    }
-
-    private void parseElements(ImapList list, char end)
-            throws IOException, MessagingException {
-        for (;;) {
-            for (;;) {
-                final int next = peek();
-                if (next == end) {
-                    return;
-                }
-                if (next != ' ') {
-                    break;
-                }
-                // Skip space
-                readByte();
-            }
-            final ImapElement el = parseElement();
-            if (el == null) { // EOL
-                return;
-            }
-            list.add(el);
-        }
-    }
-
-    private ImapList parseList(char opening, char closing)
-            throws IOException, MessagingException {
-        expect(opening);
-        final ImapList list = new ImapList();
-        parseElements(list, closing);
-        expect(closing);
-        return list;
-    }
-
-    private ImapString parseLiteral() throws IOException, MessagingException {
-        expect('{');
-        final int size;
-        try {
-            size = Integer.parseInt(readUntil('}'));
-        } catch (NumberFormatException nfe) {
-            throw new MessagingException("Invalid length in literal");
-        }
-        if (size < 0) {
-            throw new MessagingException("Invalid negative length in literal");
-        }
-        expect('\r');
-        expect('\n');
-        FixedLengthInputStream in = new FixedLengthInputStream(mIn, size);
-        if (size > mLiteralKeepInMemoryThreshold) {
-            return new ImapTempFileLiteral(in);
-        } else {
-            return new ImapMemoryLiteral(in);
-        }
-    }
-}
\ No newline at end of file
diff --git a/src/com/android/phone/common/mail/store/imap/ImapSimpleString.java b/src/com/android/phone/common/mail/store/imap/ImapSimpleString.java
deleted file mode 100644
index 9d65236..0000000
--- a/src/com/android/phone/common/mail/store/imap/ImapSimpleString.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.phone.common.mail.store.imap;
-
-import com.android.phone.vvm.omtp.VvmLog;
-
-import java.io.ByteArrayInputStream;
-import java.io.InputStream;
-import java.io.UnsupportedEncodingException;
-
-/**
- * Subclass of {@link ImapString} used for non literals.
- */
-public class ImapSimpleString extends ImapString {
-    private final String TAG = "ImapSimpleString";
-    private String mString;
-
-    /* package */  ImapSimpleString(String string) {
-        mString = (string != null) ? string : "";
-    }
-
-    @Override
-    public void destroy() {
-        mString = null;
-        super.destroy();
-    }
-
-    @Override
-    public String getString() {
-        return mString;
-    }
-
-    @Override
-    public InputStream getAsStream() {
-        try {
-            return new ByteArrayInputStream(mString.getBytes("US-ASCII"));
-        } catch (UnsupportedEncodingException e) {
-            VvmLog.e(TAG, "Unsupported encoding: ", e);
-        }
-        return null;
-    }
-
-    @Override
-    public String toString() {
-        // Purposefully not return just mString, in order to prevent using it instead of getString.
-        return "\"" + mString + "\"";
-    }
-}
\ No newline at end of file
diff --git a/src/com/android/phone/common/mail/store/imap/ImapString.java b/src/com/android/phone/common/mail/store/imap/ImapString.java
deleted file mode 100644
index dd7133c..0000000
--- a/src/com/android/phone/common/mail/store/imap/ImapString.java
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.phone.common.mail.store.imap;
-
-import com.android.phone.vvm.omtp.VvmLog;
-
-import java.io.ByteArrayInputStream;
-import java.io.InputStream;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.Locale;
-
-/**
- * Class represents an IMAP "element" that is not a list.
- *
- * An atom, quoted string, literal, are all represented by this.  Values like OK, STATUS are too.
- * Also, this class class may contain more arbitrary value like "BODY[HEADER.FIELDS ("DATE")]".
- * See {@link ImapResponseParser}.
- */
-public abstract class ImapString extends ImapElement {
-    private static final byte[] EMPTY_BYTES = new byte[0];
-
-    public static final ImapString EMPTY = new ImapString() {
-        @Override public void destroy() {
-            // Don't call super.destroy().
-            // It's a shared object.  We don't want the mDestroyed to be set on this.
-        }
-
-        @Override public String getString() {
-            return "";
-        }
-
-        @Override public InputStream getAsStream() {
-            return new ByteArrayInputStream(EMPTY_BYTES);
-        }
-
-        @Override public String toString() {
-            return "";
-        }
-    };
-
-    // This is used only for parsing IMAP's FETCH ENVELOPE command, in which
-    // en_US-like date format is used like "01-Jan-2009 11:20:39 -0800", so this should be
-    // handled by Locale.US
-    private final static SimpleDateFormat DATE_TIME_FORMAT =
-            new SimpleDateFormat("dd-MMM-yyyy HH:mm:ss Z", Locale.US);
-
-    private boolean mIsInteger;
-    private int mParsedInteger;
-    private Date mParsedDate;
-
-    @Override
-    public final boolean isList() {
-        return false;
-    }
-
-    @Override
-    public final boolean isString() {
-        return true;
-    }
-
-    /**
-     * @return true if and only if the length of the string is larger than 0.
-     *
-     * Note: IMAP NIL is considered an empty string. See {@link ImapResponseParser
-     * #parseBareString}.
-     * On the other hand, a quoted/literal string with value NIL (i.e. "NIL" and {3}\r\nNIL) is
-     * treated literally.
-     */
-    public final boolean isEmpty() {
-        return getString().length() == 0;
-    }
-
-    public abstract String getString();
-
-    public abstract InputStream getAsStream();
-
-    /**
-     * @return whether it can be parsed as a number.
-     */
-    public final boolean isNumber() {
-        if (mIsInteger) {
-            return true;
-        }
-        try {
-            mParsedInteger = Integer.parseInt(getString());
-            mIsInteger = true;
-            return true;
-        } catch (NumberFormatException e) {
-            return false;
-        }
-    }
-
-    /**
-     * @return value parsed as a number, or 0 if the string is not a number.
-     */
-    public final int getNumberOrZero() {
-        return getNumber(0);
-    }
-
-    /**
-     * @return value parsed as a number, or {@code defaultValue} if the string is not a number.
-     */
-    public final int getNumber(int defaultValue) {
-        if (!isNumber()) {
-            return defaultValue;
-        }
-        return mParsedInteger;
-    }
-
-    /**
-     * @return whether it can be parsed as a date using {@link #DATE_TIME_FORMAT}.
-     */
-    public final boolean isDate() {
-        if (mParsedDate != null) {
-            return true;
-        }
-        if (isEmpty()) {
-            return false;
-        }
-        try {
-            mParsedDate = DATE_TIME_FORMAT.parse(getString());
-            return true;
-        } catch (ParseException e) {
-            VvmLog.w("ImapString", getString() + " can't be parsed as a date.");
-            return false;
-        }
-    }
-
-    /**
-     * @return value it can be parsed as a {@link Date}, or null otherwise.
-     */
-    public final Date getDateOrNull() {
-        if (!isDate()) {
-            return null;
-        }
-        return mParsedDate;
-    }
-
-    /**
-     * @return whether the value case-insensitively equals to {@code s}.
-     */
-    public final boolean is(String s) {
-        if (s == null) {
-            return false;
-        }
-        return getString().equalsIgnoreCase(s);
-    }
-
-
-    /**
-     * @return whether the value case-insensitively starts with {@code s}.
-     */
-    public final boolean startsWith(String prefix) {
-        if (prefix == null) {
-            return false;
-        }
-        final String me = this.getString();
-        if (me.length() < prefix.length()) {
-            return false;
-        }
-        return me.substring(0, prefix.length()).equalsIgnoreCase(prefix);
-    }
-
-    // To force subclasses to implement it.
-    @Override
-    public abstract String toString();
-
-    @Override
-    public final boolean equalsForTest(ImapElement that) {
-        if (!super.equalsForTest(that)) {
-            return false;
-        }
-        ImapString thatString = (ImapString) that;
-        return getString().equals(thatString.getString());
-    }
-}
\ No newline at end of file
diff --git a/src/com/android/phone/common/mail/store/imap/ImapTempFileLiteral.java b/src/com/android/phone/common/mail/store/imap/ImapTempFileLiteral.java
deleted file mode 100644
index 67d5026..0000000
--- a/src/com/android/phone/common/mail/store/imap/ImapTempFileLiteral.java
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.phone.common.mail.store.imap;
-
-import com.android.phone.common.mail.FixedLengthInputStream;
-import com.android.phone.common.mail.TempDirectory;
-import com.android.phone.common.mail.utils.Utility;
-import com.android.phone.common.mail.utils.LogUtils;
-
-import org.apache.commons.io.IOUtils;
-
-import java.io.ByteArrayInputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-
-/**
- * Subclass of {@link ImapString} used for literals backed by a temp file.
- */
-public class ImapTempFileLiteral extends ImapString {
-    private final String TAG = "ImapTempFileLiteral";
-
-    /* package for test */ final File mFile;
-
-    /** Size is purely for toString() */
-    private final int mSize;
-
-    /* package */  ImapTempFileLiteral(FixedLengthInputStream stream) throws IOException {
-        mSize = stream.getLength();
-        mFile = File.createTempFile("imap", ".tmp", TempDirectory.getTempDirectory());
-
-        // Unfortunately, we can't really use deleteOnExit(), because temp filenames are random
-        // so it'd simply cause a memory leak.
-        // deleteOnExit() simply adds filenames to a static list and the list will never shrink.
-        // mFile.deleteOnExit();
-        OutputStream out = new FileOutputStream(mFile);
-        IOUtils.copy(stream, out);
-        out.close();
-    }
-
-    /**
-     * Make sure we delete the temp file.
-     *
-     * We should always be calling {@link ImapResponse#destroy()}, but it's here as a last resort.
-     */
-    @Override
-    protected void finalize() throws Throwable {
-        try {
-            destroy();
-        } finally {
-            super.finalize();
-        }
-    }
-
-    @Override
-    public InputStream getAsStream() {
-        checkNotDestroyed();
-        try {
-            return new FileInputStream(mFile);
-        } catch (FileNotFoundException e) {
-            // It's probably possible if we're low on storage and the system clears the cache dir.
-            LogUtils.w(TAG, "ImapTempFileLiteral: Temp file not found");
-
-            // Return 0 byte stream as a dummy...
-            return new ByteArrayInputStream(new byte[0]);
-        }
-    }
-
-    @Override
-    public String getString() {
-        checkNotDestroyed();
-        try {
-            byte[] bytes = IOUtils.toByteArray(getAsStream());
-            // Prevent crash from OOM; we've seen this, but only rarely and not reproducibly
-            if (bytes.length > ImapResponseParser.LITERAL_KEEP_IN_MEMORY_THRESHOLD) {
-                throw new IOException();
-            }
-            return Utility.fromAscii(bytes);
-        } catch (IOException e) {
-            LogUtils.w(TAG, "ImapTempFileLiteral: Error while reading temp file", e);
-            return "";
-        }
-    }
-
-    @Override
-    public void destroy() {
-        try {
-            if (!isDestroyed() && mFile.exists()) {
-                mFile.delete();
-            }
-        } catch (RuntimeException re) {
-            // Just log and ignore.
-            LogUtils.w(TAG, "Failed to remove temp file: " + re.getMessage());
-        }
-        super.destroy();
-    }
-
-    @Override
-    public String toString() {
-        return String.format("{%d byte literal(file)}", mSize);
-    }
-
-    public boolean tempFileExistsForTest() {
-        return mFile.exists();
-    }
-}
\ No newline at end of file
diff --git a/src/com/android/phone/common/mail/store/imap/ImapUtility.java b/src/com/android/phone/common/mail/store/imap/ImapUtility.java
deleted file mode 100644
index 8551d44..0000000
--- a/src/com/android/phone/common/mail/store/imap/ImapUtility.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.phone.common.mail.store.imap;
-
-import com.android.phone.common.mail.utils.LogUtils;
-
-import java.util.ArrayList;
-
-/**
- * Utility methods for use with IMAP.
- */
-public class ImapUtility {
-    public static final String TAG = "ImapUtility";
-    /**
-     * Apply quoting rules per IMAP RFC,
-     * quoted          = DQUOTE *QUOTED-CHAR DQUOTE
-     * QUOTED-CHAR     = <any TEXT-CHAR except quoted-specials> / "\" quoted-specials
-     * quoted-specials = DQUOTE / "\"
-     *
-     * This is used primarily for IMAP login, but might be useful elsewhere.
-     *
-     * NOTE:  Not very efficient - you may wish to preflight this, or perhaps it should check
-     * for trouble chars before calling the replace functions.
-     *
-     * @param s The string to be quoted.
-     * @return A copy of the string, having undergone quoting as described above
-     */
-    public static String imapQuoted(String s) {
-
-        // First, quote any backslashes by replacing \ with \\
-        // regex Pattern:  \\    (Java string const = \\\\)
-        // Substitute:     \\\\  (Java string const = \\\\\\\\)
-        String result = s.replaceAll("\\\\", "\\\\\\\\");
-
-        // Then, quote any double-quotes by replacing " with \"
-        // regex Pattern:  "    (Java string const = \")
-        // Substitute:     \\"  (Java string const = \\\\\")
-        result = result.replaceAll("\"", "\\\\\"");
-
-        // return string with quotes around it
-        return "\"" + result + "\"";
-    }
-
-    /**
-     * Gets all of the values in a sequence set per RFC 3501. Any ranges are expanded into a
-     * list of individual numbers. If the set is invalid, an empty array is returned.
-     * <pre>
-     * sequence-number = nz-number / "*"
-     * sequence-range  = sequence-number ":" sequence-number
-     * sequence-set    = (sequence-number / sequence-range) *("," sequence-set)
-     * </pre>
-     */
-    public static String[] getImapSequenceValues(String set) {
-        ArrayList<String> list = new ArrayList<String>();
-        if (set != null) {
-            String[] setItems = set.split(",");
-            for (String item : setItems) {
-                if (item.indexOf(':') == -1) {
-                    // simple item
-                    try {
-                        Integer.parseInt(item); // Don't need the value; just ensure it's valid
-                        list.add(item);
-                    } catch (NumberFormatException e) {
-                        LogUtils.d(TAG, "Invalid UID value", e);
-                    }
-                } else {
-                    // range
-                    for (String rangeItem : getImapRangeValues(item)) {
-                        list.add(rangeItem);
-                    }
-                }
-            }
-        }
-        String[] stringList = new String[list.size()];
-        return list.toArray(stringList);
-    }
-
-    /**
-     * Expand the given number range into a list of individual numbers. If the range is not valid,
-     * an empty array is returned.
-     * <pre>
-     * sequence-number = nz-number / "*"
-     * sequence-range  = sequence-number ":" sequence-number
-     * sequence-set    = (sequence-number / sequence-range) *("," sequence-set)
-     * </pre>
-     */
-    public static String[] getImapRangeValues(String range) {
-        ArrayList<String> list = new ArrayList<String>();
-        try {
-            if (range != null) {
-                int colonPos = range.indexOf(':');
-                if (colonPos > 0) {
-                    int first  = Integer.parseInt(range.substring(0, colonPos));
-                    int second = Integer.parseInt(range.substring(colonPos + 1));
-                    if (first < second) {
-                        for (int i = first; i <= second; i++) {
-                            list.add(Integer.toString(i));
-                        }
-                    } else {
-                        for (int i = first; i >= second; i--) {
-                            list.add(Integer.toString(i));
-                        }
-                    }
-                }
-            }
-        } catch (NumberFormatException e) {
-            LogUtils.d(TAG, "Invalid range value", e);
-        }
-        String[] stringList = new String[list.size()];
-        return list.toArray(stringList);
-    }
-}
\ No newline at end of file
diff --git a/src/com/android/phone/common/mail/utility/CountingOutputStream.java b/src/com/android/phone/common/mail/utility/CountingOutputStream.java
deleted file mode 100644
index f631c3e..0000000
--- a/src/com/android/phone/common/mail/utility/CountingOutputStream.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.phone.common.mail.utility;
-
-import java.io.IOException;
-import java.io.OutputStream;
-
-/**
- * A simple pass-thru OutputStream that also counts how many bytes are written to it and
- * makes that count available to callers.
- */
-public class CountingOutputStream extends OutputStream {
-    private long mCount;
-    private final OutputStream mOutputStream;
-
-    public CountingOutputStream(OutputStream outputStream) {
-        mOutputStream = outputStream;
-    }
-
-    public long getCount() {
-        return mCount;
-    }
-
-    @Override
-    public void write(byte[] buffer, int offset, int count) throws IOException {
-        mOutputStream.write(buffer, offset, count);
-        mCount += count;
-    }
-
-    @Override
-    public void write(int oneByte) throws IOException {
-        mOutputStream.write(oneByte);
-        mCount++;
-    }
-}
\ No newline at end of file
diff --git a/src/com/android/phone/common/mail/utility/EOLConvertingOutputStream.java b/src/com/android/phone/common/mail/utility/EOLConvertingOutputStream.java
deleted file mode 100644
index 1d55152..0000000
--- a/src/com/android/phone/common/mail/utility/EOLConvertingOutputStream.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.phone.common.mail.utility;
-
-import java.io.FilterOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-
-public class EOLConvertingOutputStream extends FilterOutputStream {
-    int lastChar;
-
-    public EOLConvertingOutputStream(OutputStream out) {
-        super(out);
-    }
-
-    @Override
-    public void write(int oneByte) throws IOException {
-        if (oneByte == '\n') {
-            if (lastChar != '\r') {
-                super.write('\r');
-            }
-        }
-        super.write(oneByte);
-        lastChar = oneByte;
-    }
-
-    @Override
-    public void flush() throws IOException {
-        if (lastChar == '\r') {
-            super.write('\n');
-            lastChar = '\n';
-        }
-        super.flush();
-    }
-}
\ No newline at end of file
diff --git a/src/com/android/phone/common/mail/utils/LogUtils.java b/src/com/android/phone/common/mail/utils/LogUtils.java
deleted file mode 100644
index 6bd7be6..0000000
--- a/src/com/android/phone/common/mail/utils/LogUtils.java
+++ /dev/null
@@ -1,417 +0,0 @@
-/**
- * Copyright (c) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.phone.common.mail.utils;
-
-import android.net.Uri;
-import android.text.TextUtils;
-import android.util.Log;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.phone.vvm.omtp.VvmLog;
-
-import java.util.List;
-import java.util.regex.Pattern;
-
-public class LogUtils {
-    public static final String TAG = "Email Log";
-
-    // "GMT" + "+" or "-" + 4 digits
-    private static final Pattern DATE_CLEANUP_PATTERN_WRONG_TIMEZONE =
-            Pattern.compile("GMT([-+]\\d{4})$");
-
-    private static final String ACCOUNT_PREFIX = "account:";
-
-    /**
-     * Priority constant for the println method; use LogUtils.v.
-     */
-    public static final int VERBOSE = Log.VERBOSE;
-
-    /**
-     * Priority constant for the println method; use LogUtils.d.
-     */
-    public static final int DEBUG = Log.DEBUG;
-
-    /**
-     * Priority constant for the println method; use LogUtils.i.
-     */
-    public static final int INFO = Log.INFO;
-
-    /**
-     * Priority constant for the println method; use LogUtils.w.
-     */
-    public static final int WARN = Log.WARN;
-
-    /**
-     * Priority constant for the println method; use LogUtils.e.
-     */
-    public static final int ERROR = Log.ERROR;
-
-    /**
-     * Used to enable/disable logging that we don't want included in
-     * production releases.  This should be set to DEBUG for production releases, and VERBOSE for
-     * internal builds.
-     */
-    // STOPSHIP: ship with DEBUG set
-    private static final int MAX_ENABLED_LOG_LEVEL = VERBOSE;
-
-    private static Boolean sDebugLoggingEnabledForTests = null;
-
-    /**
-     * Enable debug logging for unit tests.
-     */
-    @VisibleForTesting
-    public static void setDebugLoggingEnabledForTests(boolean enabled) {
-        setDebugLoggingEnabledForTestsInternal(enabled);
-    }
-
-    protected static void setDebugLoggingEnabledForTestsInternal(boolean enabled) {
-        sDebugLoggingEnabledForTests = Boolean.valueOf(enabled);
-    }
-
-    /**
-     * Returns true if the build configuration prevents debug logging.
-     */
-    @VisibleForTesting
-    public static boolean buildPreventsDebugLogging() {
-        return MAX_ENABLED_LOG_LEVEL > VERBOSE;
-    }
-
-    /**
-     * Returns a boolean indicating whether debug logging is enabled.
-     */
-    protected static boolean isDebugLoggingEnabled(String tag) {
-        if (buildPreventsDebugLogging()) {
-            return false;
-        }
-        if (sDebugLoggingEnabledForTests != null) {
-            return sDebugLoggingEnabledForTests.booleanValue();
-        }
-        return Log.isLoggable(tag, Log.DEBUG) || Log.isLoggable(TAG, Log.DEBUG);
-    }
-
-    /**
-     * Returns a String for the specified content provider uri.  This will do
-     * sanitation of the uri to remove PII if debug logging is not enabled.
-     */
-    public static String contentUriToString(final Uri uri) {
-        return contentUriToString(TAG, uri);
-    }
-
-    /**
-     * Returns a String for the specified content provider uri.  This will do
-     * sanitation of the uri to remove PII if debug logging is not enabled.
-     */
-    public static String contentUriToString(String tag, Uri uri) {
-        if (isDebugLoggingEnabled(tag)) {
-            // Debug logging has been enabled, so log the uri as is
-            return uri.toString();
-        } else {
-            // Debug logging is not enabled, we want to remove the email address from the uri.
-            List<String> pathSegments = uri.getPathSegments();
-
-            Uri.Builder builder = new Uri.Builder()
-                    .scheme(uri.getScheme())
-                    .authority(uri.getAuthority())
-                    .query(uri.getQuery())
-                    .fragment(uri.getFragment());
-
-            // This assumes that the first path segment is the account
-            final String account = pathSegments.get(0);
-
-            builder = builder.appendPath(sanitizeAccountName(account));
-            for (int i = 1; i < pathSegments.size(); i++) {
-                builder.appendPath(pathSegments.get(i));
-            }
-            return builder.toString();
-        }
-    }
-
-    /**
-     * Sanitizes an account name.  If debug logging is not enabled, a sanitized name
-     * is returned.
-     */
-    public static String sanitizeAccountName(String accountName) {
-        if (TextUtils.isEmpty(accountName)) {
-            return "";
-        }
-
-        return ACCOUNT_PREFIX + sanitizeName(TAG, accountName);
-    }
-
-    public static String sanitizeName(final String tag, final String name) {
-        if (TextUtils.isEmpty(name)) {
-            return "";
-        }
-
-        if (isDebugLoggingEnabled(tag)) {
-            return name;
-        }
-
-        return String.valueOf(name.hashCode());
-    }
-
-    /**
-     * Checks to see whether or not a log for the specified tag is loggable at the specified level.
-     */
-    public static boolean isLoggable(String tag, int level) {
-        if (MAX_ENABLED_LOG_LEVEL > level) {
-            return false;
-        }
-        return Log.isLoggable(tag, level) || Log.isLoggable(TAG, level);
-    }
-
-    /**
-     * Send a {@link #VERBOSE} log message.
-     * @param tag Used to identify the source of a log message.  It usually identifies
-     *        the class or activity where the log call occurs.
-     * @param format the format string (see {@link java.util.Formatter#format})
-     * @param args
-     *            the list of arguments passed to the formatter. If there are
-     *            more arguments than required by {@code format},
-     *            additional arguments are ignored.
-     */
-    public static int v(String tag, String format, Object... args) {
-        if (isLoggable(tag, VERBOSE)) {
-            return VvmLog.v(tag, String.format(format, args));
-        }
-        return 0;
-    }
-
-    /**
-     * Send a {@link #VERBOSE} log message.
-     * @param tag Used to identify the source of a log message.  It usually identifies
-     *        the class or activity where the log call occurs.
-     * @param tr An exception to log
-     * @param format the format string (see {@link java.util.Formatter#format})
-     * @param args
-     *            the list of arguments passed to the formatter. If there are
-     *            more arguments than required by {@code format},
-     *            additional arguments are ignored.
-     */
-    public static int v(String tag, Throwable tr, String format, Object... args) {
-        if (isLoggable(tag, VERBOSE)) {
-            return VvmLog.v(tag, String.format(format, args), tr);
-        }
-        return 0;
-    }
-
-    /**
-     * Send a {@link #DEBUG} log message.
-     * @param tag Used to identify the source of a log message.  It usually identifies
-     *        the class or activity where the log call occurs.
-     * @param format the format string (see {@link java.util.Formatter#format})
-     * @param args
-     *            the list of arguments passed to the formatter. If there are
-     *            more arguments than required by {@code format},
-     *            additional arguments are ignored.
-     */
-    public static int d(String tag, String format, Object... args) {
-        if (isLoggable(tag, DEBUG)) {
-            return VvmLog.d(tag, String.format(format, args));
-        }
-        return 0;
-    }
-
-    /**
-     * Send a {@link #DEBUG} log message.
-     * @param tag Used to identify the source of a log message.  It usually identifies
-     *        the class or activity where the log call occurs.
-     * @param tr An exception to log
-     * @param format the format string (see {@link java.util.Formatter#format})
-     * @param args
-     *            the list of arguments passed to the formatter. If there are
-     *            more arguments than required by {@code format},
-     *            additional arguments are ignored.
-     */
-    public static int d(String tag, Throwable tr, String format, Object... args) {
-        if (isLoggable(tag, DEBUG)) {
-            return VvmLog.d(tag, String.format(format, args), tr);
-        }
-        return 0;
-    }
-
-    /**
-     * Send a {@link #INFO} log message.
-     * @param tag Used to identify the source of a log message.  It usually identifies
-     *        the class or activity where the log call occurs.
-     * @param format the format string (see {@link java.util.Formatter#format})
-     * @param args
-     *            the list of arguments passed to the formatter. If there are
-     *            more arguments than required by {@code format},
-     *            additional arguments are ignored.
-     */
-    public static int i(String tag, String format, Object... args) {
-        if (isLoggable(tag, INFO)) {
-            return VvmLog.i(tag, String.format(format, args));
-        }
-        return 0;
-    }
-
-    /**
-     * Send a {@link #INFO} log message.
-     * @param tag Used to identify the source of a log message.  It usually identifies
-     *        the class or activity where the log call occurs.
-     * @param tr An exception to log
-     * @param format the format string (see {@link java.util.Formatter#format})
-     * @param args
-     *            the list of arguments passed to the formatter. If there are
-     *            more arguments than required by {@code format},
-     *            additional arguments are ignored.
-     */
-    public static int i(String tag, Throwable tr, String format, Object... args) {
-        if (isLoggable(tag, INFO)) {
-            return VvmLog.i(tag, String.format(format, args), tr);
-        }
-        return 0;
-    }
-
-    /**
-     * Send a {@link #WARN} log message.
-     * @param tag Used to identify the source of a log message.  It usually identifies
-     *        the class or activity where the log call occurs.
-     * @param format the format string (see {@link java.util.Formatter#format})
-     * @param args
-     *            the list of arguments passed to the formatter. If there are
-     *            more arguments than required by {@code format},
-     *            additional arguments are ignored.
-     */
-    public static int w(String tag, String format, Object... args) {
-        if (isLoggable(tag, WARN)) {
-            return VvmLog.w(tag, String.format(format, args));
-        }
-        return 0;
-    }
-
-    /**
-     * Send a {@link #WARN} log message.
-     * @param tag Used to identify the source of a log message.  It usually identifies
-     *        the class or activity where the log call occurs.
-     * @param tr An exception to log
-     * @param format the format string (see {@link java.util.Formatter#format})
-     * @param args
-     *            the list of arguments passed to the formatter. If there are
-     *            more arguments than required by {@code format},
-     *            additional arguments are ignored.
-     */
-    public static int w(String tag, Throwable tr, String format, Object... args) {
-        if (isLoggable(tag, WARN)) {
-            return VvmLog.w(tag, String.format(format, args), tr);
-        }
-        return 0;
-    }
-
-    /**
-     * Send a {@link #ERROR} log message.
-     * @param tag Used to identify the source of a log message.  It usually identifies
-     *        the class or activity where the log call occurs.
-     * @param format the format string (see {@link java.util.Formatter#format})
-     * @param args
-     *            the list of arguments passed to the formatter. If there are
-     *            more arguments than required by {@code format},
-     *            additional arguments are ignored.
-     */
-    public static int e(String tag, String format, Object... args) {
-        if (isLoggable(tag, ERROR)) {
-            return VvmLog.e(tag, String.format(format, args));
-        }
-        return 0;
-    }
-
-    /**
-     * Send a {@link #ERROR} log message.
-     * @param tag Used to identify the source of a log message.  It usually identifies
-     *        the class or activity where the log call occurs.
-     * @param tr An exception to log
-     * @param format the format string (see {@link java.util.Formatter#format})
-     * @param args
-     *            the list of arguments passed to the formatter. If there are
-     *            more arguments than required by {@code format},
-     *            additional arguments are ignored.
-     */
-    public static int e(String tag, Throwable tr, String format, Object... args) {
-        if (isLoggable(tag, ERROR)) {
-            return VvmLog.e(tag, String.format(format, args), tr);
-        }
-        return 0;
-    }
-
-    /**
-     * What a Terrible Failure: Report a condition that should never happen.
-     * The error will always be logged at level ASSERT with the call stack.
-     * Depending on system configuration, a report may be added to the
-     * {@link android.os.DropBoxManager} and/or the process may be terminated
-     * immediately with an error dialog.
-     * @param tag Used to identify the source of a log message.  It usually identifies
-     *        the class or activity where the log call occurs.
-     * @param format the format string (see {@link java.util.Formatter#format})
-     * @param args
-     *            the list of arguments passed to the formatter. If there are
-     *            more arguments than required by {@code format},
-     *            additional arguments are ignored.
-     */
-    public static int wtf(String tag, String format, Object... args) {
-        return VvmLog.wtf(tag, String.format(format, args), new Error());
-    }
-
-    /**
-     * What a Terrible Failure: Report a condition that should never happen.
-     * The error will always be logged at level ASSERT with the call stack.
-     * Depending on system configuration, a report may be added to the
-     * {@link android.os.DropBoxManager} and/or the process may be terminated
-     * immediately with an error dialog.
-     * @param tag Used to identify the source of a log message.  It usually identifies
-     *        the class or activity where the log call occurs.
-     * @param tr An exception to log
-     * @param format the format string (see {@link java.util.Formatter#format})
-     * @param args
-     *            the list of arguments passed to the formatter. If there are
-     *            more arguments than required by {@code format},
-     *            additional arguments are ignored.
-     */
-    public static int wtf(String tag, Throwable tr, String format, Object... args) {
-        return VvmLog.wtf(tag, String.format(format, args), tr);
-    }
-
-
-    /**
-     * Try to make a date MIME(RFC 2822/5322)-compliant.
-     *
-     * It fixes:
-     * - "Thu, 10 Dec 09 15:08:08 GMT-0700" to "Thu, 10 Dec 09 15:08:08 -0700"
-     *   (4 digit zone value can't be preceded by "GMT")
-     *   We got a report saying eBay sends a date in this format
-     */
-    public static String cleanUpMimeDate(String date) {
-        if (TextUtils.isEmpty(date)) {
-            return date;
-        }
-        date = DATE_CLEANUP_PATTERN_WRONG_TIMEZONE.matcher(date).replaceFirst("$1");
-        return date;
-    }
-
-
-    public static String byteToHex(int b) {
-        return byteToHex(new StringBuilder(), b).toString();
-    }
-
-    public static StringBuilder byteToHex(StringBuilder sb, int b) {
-        b &= 0xFF;
-        sb.append("0123456789ABCDEF".charAt(b >> 4));
-        sb.append("0123456789ABCDEF".charAt(b & 0xF));
-        return sb;
-    }
-
-}
\ No newline at end of file
diff --git a/src/com/android/phone/common/mail/utils/Utility.java b/src/com/android/phone/common/mail/utils/Utility.java
deleted file mode 100644
index d71b25e..0000000
--- a/src/com/android/phone/common/mail/utils/Utility.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/**
- * Copyright (c) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.phone.common.mail.utils;
-
-import java.io.ByteArrayInputStream;
-import java.nio.ByteBuffer;
-import java.nio.CharBuffer;
-import java.nio.charset.Charset;
-
-/**
- * Simple utility methods used in email functions.
- */
-public class Utility {
-    public static final Charset ASCII = Charset.forName("US-ASCII");
-
-    public static final String[] EMPTY_STRINGS = new String[0];
-
-    /**
-     * Returns a concatenated string containing the output of every Object's
-     * toString() method, each separated by the given separator character.
-     */
-    public static String combine(Object[] parts, char separator) {
-        if (parts == null) {
-            return null;
-        }
-        StringBuilder sb = new StringBuilder();
-        for (int i = 0; i < parts.length; i++) {
-            sb.append(parts[i].toString());
-            if (i < parts.length - 1) {
-                sb.append(separator);
-            }
-        }
-        return sb.toString();
-    }
-
-    /** Converts a String to ASCII bytes */
-    public static byte[] toAscii(String s) {
-        return encode(ASCII, s);
-    }
-
-    /** Builds a String from ASCII bytes */
-    public static String fromAscii(byte[] b) {
-        return decode(ASCII, b);
-    }
-
-    private static byte[] encode(Charset charset, String s) {
-        if (s == null) {
-            return null;
-        }
-        final ByteBuffer buffer = charset.encode(CharBuffer.wrap(s));
-        final byte[] bytes = new byte[buffer.limit()];
-        buffer.get(bytes);
-        return bytes;
-    }
-
-    private static String decode(Charset charset, byte[] b) {
-        if (b == null) {
-            return null;
-        }
-        final CharBuffer cb = charset.decode(ByteBuffer.wrap(b));
-        return new String(cb.array(), 0, cb.length());
-    }
-
-    public static ByteArrayInputStream streamFromAsciiString(String ascii) {
-        return new ByteArrayInputStream(toAscii(ascii));
-    }
-}
diff --git a/src/com/android/phone/settings/VoicemailChangePinActivity.java b/src/com/android/phone/settings/VoicemailChangePinActivity.java
deleted file mode 100644
index 33da27a..0000000
--- a/src/com/android/phone/settings/VoicemailChangePinActivity.java
+++ /dev/null
@@ -1,656 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.phone.settings;
-
-import android.annotation.Nullable;
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.app.ProgressDialog;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.DialogInterface.OnDismissListener;
-import android.content.SharedPreferences;
-import android.net.Network;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Message;
-import android.preference.PreferenceManager;
-import android.telecom.PhoneAccountHandle;
-import android.text.Editable;
-import android.text.InputFilter;
-import android.text.InputFilter.LengthFilter;
-import android.text.TextWatcher;
-import android.view.KeyEvent;
-import android.view.MenuItem;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.view.WindowManager;
-import android.view.inputmethod.EditorInfo;
-import android.widget.Button;
-import android.widget.EditText;
-import android.widget.TextView;
-import android.widget.TextView.OnEditorActionListener;
-import android.widget.Toast;
-import com.android.phone.PhoneUtils;
-import com.android.phone.R;
-import com.android.phone.VoicemailStatus;
-import com.android.phone.common.mail.MessagingException;
-import com.android.phone.vvm.omtp.OmtpConstants;
-import com.android.phone.vvm.omtp.OmtpConstants.ChangePinResult;
-import com.android.phone.vvm.omtp.OmtpEvents;
-import com.android.phone.vvm.omtp.OmtpVvmCarrierConfigHelper;
-import com.android.phone.vvm.omtp.VisualVoicemailPreferences;
-import com.android.phone.vvm.omtp.VvmLog;
-import com.android.phone.vvm.omtp.imap.ImapHelper;
-import com.android.phone.vvm.omtp.imap.ImapHelper.InitializingException;
-import com.android.phone.vvm.omtp.sync.VvmNetworkRequestCallback;
-
-/**
- * Dialog to change the voicemail PIN. The TUI (Telephony User Interface) PIN is used when accessing
- * traditional voicemail through phone call. The intent to launch this activity must contain {@link
- * #EXTRA_PHONE_ACCOUNT_HANDLE}
- */
-public class VoicemailChangePinActivity extends Activity implements OnClickListener,
-        OnEditorActionListener, TextWatcher {
-
-    private static final String TAG = "VmChangePinActivity";
-
-    public static final String EXTRA_PHONE_ACCOUNT_HANDLE = "extra_phone_account_handle";
-
-    private static final String KEY_DEFAULT_OLD_PIN = "default_old_pin";
-
-    private static final int MESSAGE_HANDLE_RESULT = 1;
-
-    private PhoneAccountHandle mPhoneAccountHandle;
-    private OmtpVvmCarrierConfigHelper mConfig;
-
-    private int mPinMinLength;
-    private int mPinMaxLength;
-
-    private State mUiState = State.Initial;
-    private String mOldPin;
-    private String mFirstPin;
-
-    private ProgressDialog mProgressDialog;
-
-    private TextView mHeaderText;
-    private TextView mHintText;
-    private TextView mErrorText;
-    private EditText mPinEntry;
-    private Button mCancelButton;
-    private Button mNextButton;
-
-    private Handler mHandler = new Handler() {
-        @Override
-        public void handleMessage(Message message) {
-            if (message.what == MESSAGE_HANDLE_RESULT) {
-                mUiState.handleResult(VoicemailChangePinActivity.this, message.arg1);
-            }
-        }
-    };
-
-    private enum State {
-        /**
-         * Empty state to handle initial state transition. Will immediately switch into {@link
-         * #VerifyOldPin} if a default PIN has been set by the OMTP client, or {@link #EnterOldPin}
-         * if not.
-         */
-        Initial,
-        /**
-         * Prompt the user to enter old PIN. The PIN will be verified with the server before
-         * proceeding to {@link #EnterNewPin}.
-         */
-        EnterOldPin {
-            @Override
-            public void onEnter(VoicemailChangePinActivity activity) {
-                activity.setHeader(R.string.change_pin_enter_old_pin_header);
-                activity.mHintText.setText(R.string.change_pin_enter_old_pin_hint);
-                activity.mNextButton.setText(R.string.change_pin_continue_label);
-                activity.mErrorText.setText(null);
-            }
-
-            @Override
-            public void onInputChanged(VoicemailChangePinActivity activity) {
-                activity.setNextEnabled(activity.getCurrentPasswordInput().length() > 0);
-            }
-
-
-            @Override
-            public void handleNext(VoicemailChangePinActivity activity) {
-                activity.mOldPin = activity.getCurrentPasswordInput();
-                activity.verifyOldPin();
-            }
-
-            @Override
-            public void handleResult(VoicemailChangePinActivity activity,
-                    @ChangePinResult int result) {
-                if (result == OmtpConstants.CHANGE_PIN_SUCCESS) {
-                    activity.updateState(State.EnterNewPin);
-                } else {
-                    CharSequence message = activity.getChangePinResultMessage(result);
-                    activity.showError(message);
-                    activity.mPinEntry.setText("");
-                }
-            }
-        },
-        /**
-         * The default old PIN is found. Show a blank screen while verifying with the server to make
-         * sure the PIN is still valid. If the PIN is still valid, proceed to {@link #EnterNewPin}.
-         * If not, the user probably changed the PIN through other means, proceed to {@link
-         * #EnterOldPin}. If any other issue caused the verifying to fail, show an error and exit.
-         */
-        VerifyOldPin {
-            @Override
-            public void onEnter(VoicemailChangePinActivity activity) {
-                activity.findViewById(android.R.id.content).setVisibility(View.INVISIBLE);
-                activity.verifyOldPin();
-            }
-
-            @Override
-            public void handleResult(VoicemailChangePinActivity activity,
-                    @ChangePinResult int result) {
-                if (result == OmtpConstants.CHANGE_PIN_SUCCESS) {
-                    activity.updateState(State.EnterNewPin);
-                } else if (result == OmtpConstants.CHANGE_PIN_SYSTEM_ERROR) {
-                    activity.getWindow().setSoftInputMode(
-                            WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
-                    activity.showError(activity.getString(R.string.change_pin_system_error),
-                            new OnDismissListener() {
-                                @Override
-                                public void onDismiss(DialogInterface dialog) {
-                                    activity.finish();
-                                }
-                            });
-                } else {
-                    VvmLog.e(TAG, "invalid default old PIN: " + activity
-                            .getChangePinResultMessage(result));
-                    // If the default old PIN is rejected by the server, the PIN is probably changed
-                    // through other means, or the generated pin is invalid
-                    // Wipe the default old PIN so the old PIN input box will be shown to the user
-                    // on the next time.
-                    setDefaultOldPIN(activity, activity.mPhoneAccountHandle, null);
-                    activity.handleOmtpEvent(OmtpEvents.CONFIG_PIN_SET);
-                    activity.updateState(State.EnterOldPin);
-                }
-            }
-
-            @Override
-            public void onLeave(VoicemailChangePinActivity activity) {
-                activity.findViewById(android.R.id.content).setVisibility(View.VISIBLE);
-            }
-        },
-        /**
-         * Let the user enter the new PIN and validate the format. Only length is enforced, PIN
-         * strength check relies on the server. After a valid PIN is entered, proceed to {@link
-         * #ConfirmNewPin}
-         */
-        EnterNewPin {
-            @Override
-            public void onEnter(VoicemailChangePinActivity activity) {
-                activity.mHeaderText.setText(R.string.change_pin_enter_new_pin_header);
-                activity.mNextButton.setText(R.string.change_pin_continue_label);
-                activity.mHintText.setText(
-                        activity.getString(R.string.change_pin_enter_new_pin_hint,
-                                activity.mPinMinLength, activity.mPinMaxLength));
-            }
-
-            @Override
-            public void onInputChanged(VoicemailChangePinActivity activity) {
-                String password = activity.getCurrentPasswordInput();
-                if (password.length() == 0) {
-                    activity.setNextEnabled(false);
-                    return;
-                }
-                CharSequence error = activity.validatePassword(password);
-                if (error != null) {
-                    activity.mErrorText.setText(error);
-                    activity.setNextEnabled(false);
-                } else {
-                    activity.mErrorText.setText(null);
-                    activity.setNextEnabled(true);
-                }
-            }
-
-            @Override
-            public void handleNext(VoicemailChangePinActivity activity) {
-                CharSequence errorMsg;
-                errorMsg = activity.validatePassword(activity.getCurrentPasswordInput());
-                if (errorMsg != null) {
-                    activity.showError(errorMsg);
-                    return;
-                }
-                activity.mFirstPin = activity.getCurrentPasswordInput();
-                activity.updateState(State.ConfirmNewPin);
-            }
-        },
-        /**
-         * Let the user type in the same PIN again to avoid typos. If the PIN matches then perform a
-         * PIN change to the server. Finish the activity if succeeded. Return to {@link
-         * #EnterOldPin} if the old PIN is rejected, {@link #EnterNewPin} for other failure.
-         */
-        ConfirmNewPin {
-            @Override
-            public void onEnter(VoicemailChangePinActivity activity) {
-                activity.mHeaderText.setText(R.string.change_pin_confirm_pin_header);
-                activity.mHintText.setText(null);
-                activity.mNextButton.setText(R.string.change_pin_ok_label);
-            }
-
-            @Override
-            public void onInputChanged(VoicemailChangePinActivity activity) {
-                if (activity.getCurrentPasswordInput().length() == 0) {
-                    activity.setNextEnabled(false);
-                    return;
-                }
-                if (activity.getCurrentPasswordInput().equals(activity.mFirstPin)) {
-                    activity.setNextEnabled(true);
-                    activity.mErrorText.setText(null);
-                } else {
-                    activity.setNextEnabled(false);
-                    activity.mErrorText.setText(R.string.change_pin_confirm_pins_dont_match);
-                }
-            }
-
-            @Override
-            public void handleResult(VoicemailChangePinActivity activity,
-                    @ChangePinResult int result) {
-                if (result == OmtpConstants.CHANGE_PIN_SUCCESS) {
-                    // If the PIN change succeeded we no longer know what the old (current) PIN is.
-                    // Wipe the default old PIN so the old PIN input box will be shown to the user
-                    // on the next time.
-                    setDefaultOldPIN(activity, activity.mPhoneAccountHandle, null);
-                    activity.handleOmtpEvent(OmtpEvents.CONFIG_PIN_SET);
-
-                    activity.finish();
-
-                    Toast.makeText(activity, activity.getString(R.string.change_pin_succeeded),
-                            Toast.LENGTH_SHORT).show();
-                } else {
-                    CharSequence message = activity.getChangePinResultMessage(result);
-                    VvmLog.i(TAG, "Change PIN failed: " + message);
-                    activity.showError(message);
-                    if (result == OmtpConstants.CHANGE_PIN_MISMATCH) {
-                        // Somehow the PIN has changed, prompt to enter the old PIN again.
-                        activity.updateState(State.EnterOldPin);
-                    } else {
-                        // The new PIN failed to fulfil other restrictions imposed by the server.
-                        activity.updateState(State.EnterNewPin);
-                    }
-
-                }
-
-            }
-
-            @Override
-            public void handleNext(VoicemailChangePinActivity activity) {
-                activity.processPinChange(activity.mOldPin, activity.mFirstPin);
-            }
-        };
-
-        /**
-         * The activity has switched from another state to this one.
-         */
-        public void onEnter(VoicemailChangePinActivity activity) {
-            // Do nothing
-        }
-
-        /**
-         * The user has typed something into the PIN input field. Also called after {@link
-         * #onEnter(VoicemailChangePinActivity)}
-         */
-        public void onInputChanged(VoicemailChangePinActivity activity) {
-            // Do nothing
-        }
-
-        /**
-         * The asynchronous call to change the PIN on the server has returned.
-         */
-        public void handleResult(VoicemailChangePinActivity activity, @ChangePinResult int result) {
-            // Do nothing
-        }
-
-        /**
-         * The user has pressed the "next" button.
-         */
-        public void handleNext(VoicemailChangePinActivity activity) {
-            // Do nothing
-        }
-
-        /**
-         * The activity has switched from this state to another one.
-         */
-        public void onLeave(VoicemailChangePinActivity activity) {
-            // Do nothing
-        }
-
-    }
-
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-
-        mPhoneAccountHandle = getIntent().getParcelableExtra(EXTRA_PHONE_ACCOUNT_HANDLE);
-        mConfig = new OmtpVvmCarrierConfigHelper(this, mPhoneAccountHandle);
-        setContentView(R.layout.voicemail_change_pin);
-        setTitle(R.string.change_pin_title);
-
-        readPinLength();
-
-        View view = findViewById(android.R.id.content);
-
-        mCancelButton = (Button) view.findViewById(R.id.cancel_button);
-        mCancelButton.setOnClickListener(this);
-        mNextButton = (Button) view.findViewById(R.id.next_button);
-        mNextButton.setOnClickListener(this);
-
-        mPinEntry = (EditText) view.findViewById(R.id.pin_entry);
-        mPinEntry.setOnEditorActionListener(this);
-        mPinEntry.addTextChangedListener(this);
-        if (mPinMaxLength != 0) {
-            mPinEntry.setFilters(new InputFilter[]{new LengthFilter(mPinMaxLength)});
-        }
-
-
-        mHeaderText = (TextView) view.findViewById(R.id.headerText);
-        mHintText = (TextView) view.findViewById(R.id.hintText);
-        mErrorText = (TextView) view.findViewById(R.id.errorText);
-
-        migrateDefaultOldPin();
-
-        if (isDefaultOldPinSet(this, mPhoneAccountHandle)) {
-            mOldPin = getDefaultOldPin(this, mPhoneAccountHandle);
-            updateState(State.VerifyOldPin);
-        } else {
-            updateState(State.EnterOldPin);
-        }
-    }
-
-    private void handleOmtpEvent(OmtpEvents event) {
-        mConfig.handleEvent(getVoicemailStatusEditor(), event);
-    }
-
-    private VoicemailStatus.Editor getVoicemailStatusEditor() {
-        // This activity does not have any automatic retry mechanism, errors should be written right
-        // away.
-        return VoicemailStatus.edit(this, mPhoneAccountHandle);
-    }
-
-    /**
-     * Extracts the pin length requirement sent by the server with a STATUS SMS.
-     */
-    private void readPinLength() {
-        VisualVoicemailPreferences preferences = new VisualVoicemailPreferences(this,
-                mPhoneAccountHandle);
-        // The OMTP pin length format is {min}-{max}
-        String[] lengths = preferences.getString(OmtpConstants.TUI_PASSWORD_LENGTH, "").split("-");
-        if (lengths.length == 2) {
-            try {
-                mPinMinLength = Integer.parseInt(lengths[0]);
-                mPinMaxLength = Integer.parseInt(lengths[1]);
-            } catch (NumberFormatException e) {
-                mPinMinLength = 0;
-                mPinMaxLength = 0;
-            }
-        } else {
-            mPinMinLength = 0;
-            mPinMaxLength = 0;
-        }
-    }
-
-    @Override
-    public void onResume() {
-        super.onResume();
-        updateState(mUiState);
-
-    }
-
-    public void handleNext() {
-        if (mPinEntry.length() == 0) {
-            return;
-        }
-        mUiState.handleNext(this);
-    }
-
-    public void onClick(View v) {
-        switch (v.getId()) {
-            case R.id.next_button:
-                handleNext();
-                break;
-
-            case R.id.cancel_button:
-                finish();
-                break;
-        }
-    }
-
-    @Override
-    public boolean onOptionsItemSelected(MenuItem item) {
-        if (item.getItemId() == android.R.id.home) {
-            onBackPressed();
-            return true;
-        }
-        return super.onOptionsItemSelected(item);
-    }
-
-    public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
-      if (!mNextButton.isEnabled()) {
-        return true;
-      }
-        // Check if this was the result of hitting the enter or "done" key
-        if (actionId == EditorInfo.IME_NULL
-                || actionId == EditorInfo.IME_ACTION_DONE
-                || actionId == EditorInfo.IME_ACTION_NEXT) {
-            handleNext();
-            return true;
-        }
-        return false;
-    }
-
-    public void afterTextChanged(Editable s) {
-        mUiState.onInputChanged(this);
-    }
-
-    public void beforeTextChanged(CharSequence s, int start, int count, int after) {
-        // Do nothing
-    }
-
-    public void onTextChanged(CharSequence s, int start, int before, int count) {
-        // Do nothing
-    }
-
-    /**
-     * After replacing the default PIN with a random PIN, call this to store the random PIN. The
-     * stored PIN will be automatically entered when the user attempts to change the PIN.
-     */
-    public static void setDefaultOldPIN(Context context, PhoneAccountHandle phoneAccountHandle,
-            String pin) {
-        new VisualVoicemailPreferences(context, phoneAccountHandle)
-                .edit().putString(KEY_DEFAULT_OLD_PIN, pin).apply();
-    }
-
-    public static boolean isDefaultOldPinSet(Context context,
-            PhoneAccountHandle phoneAccountHandle) {
-        return getDefaultOldPin(context, phoneAccountHandle) != null;
-    }
-
-    private static String getDefaultOldPin(Context context, PhoneAccountHandle phoneAccountHandle) {
-        return new VisualVoicemailPreferences(context, phoneAccountHandle)
-                .getString(KEY_DEFAULT_OLD_PIN);
-    }
-
-    /**
-     * Storage location has changed mid development. Migrate from the old location to avoid losing
-     * tester's default old pin.
-     */
-    private void migrateDefaultOldPin() {
-        String key = "voicemail_pin_dialog_preference_"
-                + PhoneUtils.getSubIdForPhoneAccountHandle(mPhoneAccountHandle)
-                + "_default_old_pin";
-
-        SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
-        if (preferences.contains(key)) {
-            setDefaultOldPIN(this, mPhoneAccountHandle, preferences.getString(key, null));
-            preferences.edit().putString(key, null).apply();
-        }
-    }
-
-    private String getCurrentPasswordInput() {
-        return mPinEntry.getText().toString();
-    }
-
-    private void updateState(State state) {
-        State previousState = mUiState;
-        mUiState = state;
-        if (previousState != state) {
-            previousState.onLeave(this);
-            mPinEntry.setText("");
-            mUiState.onEnter(this);
-        }
-        mUiState.onInputChanged(this);
-    }
-
-    /**
-     * Validates PIN and returns a message to display if PIN fails test.
-     *
-     * @param password the raw password the user typed in
-     * @return error message to show to user or null if password is OK
-     */
-    private CharSequence validatePassword(String password) {
-        if (mPinMinLength == 0 && mPinMaxLength == 0) {
-            // Invalid length requirement is sent by the server, just accept anything and let the
-            // server decide.
-            return null;
-        }
-
-        if (password.length() < mPinMinLength) {
-            return getString(R.string.vm_change_pin_error_too_short);
-        }
-        return null;
-    }
-
-    private void setHeader(int text) {
-        mHeaderText.setText(text);
-        mPinEntry.setContentDescription(mHeaderText.getText());
-    }
-
-    /**
-     * Get the corresponding message for the {@link ChangePinResult}.<code>result</code> must not
-     * {@link OmtpConstants#CHANGE_PIN_SUCCESS}
-     */
-    private CharSequence getChangePinResultMessage(@ChangePinResult int result) {
-        switch (result) {
-            case OmtpConstants.CHANGE_PIN_TOO_SHORT:
-                return getString(R.string.vm_change_pin_error_too_short);
-            case OmtpConstants.CHANGE_PIN_TOO_LONG:
-                return getString(R.string.vm_change_pin_error_too_long);
-            case OmtpConstants.CHANGE_PIN_TOO_WEAK:
-                return getString(R.string.vm_change_pin_error_too_weak);
-            case OmtpConstants.CHANGE_PIN_INVALID_CHARACTER:
-                return getString(R.string.vm_change_pin_error_invalid);
-            case OmtpConstants.CHANGE_PIN_MISMATCH:
-                return getString(R.string.vm_change_pin_error_mismatch);
-            case OmtpConstants.CHANGE_PIN_SYSTEM_ERROR:
-                return getString(R.string.vm_change_pin_error_system_error);
-            default:
-                VvmLog.wtf(TAG, "Unexpected ChangePinResult " + result);
-                return null;
-        }
-    }
-
-    private void verifyOldPin() {
-        processPinChange(mOldPin, mOldPin);
-    }
-
-    private void setNextEnabled(boolean enabled) {
-        mNextButton.setEnabled(enabled);
-    }
-
-
-    private void showError(CharSequence message) {
-        showError(message, null);
-    }
-
-    private void showError(CharSequence message, @Nullable OnDismissListener callback) {
-        new AlertDialog.Builder(this)
-                .setMessage(message)
-                .setPositiveButton(android.R.string.ok, null)
-                .setOnDismissListener(callback)
-                .show();
-    }
-
-    /**
-     * Asynchronous call to change the PIN on the server.
-     */
-    private void processPinChange(String oldPin, String newPin) {
-        mProgressDialog = new ProgressDialog(this);
-        mProgressDialog.setCancelable(false);
-        mProgressDialog.setMessage(getString(R.string.vm_change_pin_progress_message));
-        mProgressDialog.show();
-
-        ChangePinNetworkRequestCallback callback = new ChangePinNetworkRequestCallback(oldPin,
-                newPin);
-        callback.requestNetwork();
-    }
-
-    private class ChangePinNetworkRequestCallback extends VvmNetworkRequestCallback {
-
-        private final String mOldPin;
-        private final String mNewPin;
-
-        public ChangePinNetworkRequestCallback(String oldPin, String newPin) {
-            super(mConfig, mPhoneAccountHandle,
-                VoicemailChangePinActivity.this.getVoicemailStatusEditor());
-            mOldPin = oldPin;
-            mNewPin = newPin;
-        }
-
-        @Override
-        public void onAvailable(Network network) {
-            super.onAvailable(network);
-            try (ImapHelper helper =
-                new ImapHelper(VoicemailChangePinActivity.this, mPhoneAccountHandle, network,
-                    getVoicemailStatusEditor())) {
-
-                @ChangePinResult int result =
-                        helper.changePin(mOldPin, mNewPin);
-                sendResult(result);
-            } catch (InitializingException | MessagingException e) {
-                VvmLog.e(TAG, "ChangePinNetworkRequestCallback: onAvailable: ", e);
-                sendResult(OmtpConstants.CHANGE_PIN_SYSTEM_ERROR);
-            }
-        }
-
-        @Override
-        public void onFailed(String reason) {
-            super.onFailed(reason);
-            sendResult(OmtpConstants.CHANGE_PIN_SYSTEM_ERROR);
-        }
-
-        private void sendResult(@ChangePinResult int result) {
-            VvmLog.i(TAG, "Change PIN result: " + result);
-            if (mProgressDialog.isShowing() && !VoicemailChangePinActivity.this.isDestroyed() &&
-                    !VoicemailChangePinActivity.this.isFinishing()) {
-                mProgressDialog.dismiss();
-            } else {
-                VvmLog.i(TAG, "Dialog not visible, not dismissing");
-            }
-            mHandler.obtainMessage(MESSAGE_HANDLE_RESULT, result, 0).sendToTarget();
-            releaseNetwork();
-        }
-    }
-
-}
diff --git a/src/com/android/phone/settings/VoicemailSettingsActivity.java b/src/com/android/phone/settings/VoicemailSettingsActivity.java
index 3c9a300..213baa0 100644
--- a/src/com/android/phone/settings/VoicemailSettingsActivity.java
+++ b/src/com/android/phone/settings/VoicemailSettingsActivity.java
@@ -29,9 +29,7 @@
 import android.preference.Preference;
 import android.preference.PreferenceActivity;
 import android.preference.PreferenceScreen;
-import android.preference.SwitchPreference;
 import android.provider.ContactsContract.CommonDataKinds;
-import android.telecom.PhoneAccountHandle;
 import android.telephony.TelephonyManager;
 import android.text.BidiFormatter;
 import android.text.TextDirectionHeuristics;
@@ -46,12 +44,9 @@
 import com.android.internal.telephony.PhoneConstants;
 import com.android.phone.EditPhoneNumberPreference;
 import com.android.phone.PhoneGlobals;
-import com.android.phone.PhoneUtils;
 import com.android.phone.R;
 import com.android.phone.SubscriptionInfoHelper;
-import com.android.phone.vvm.omtp.OmtpConstants;
-import com.android.phone.vvm.omtp.OmtpVvmCarrierConfigHelper;
-import com.android.phone.vvm.omtp.VisualVoicemailPreferences;
+
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -199,17 +194,13 @@
 
     private boolean mForeground;
     private Phone mPhone;
-    private PhoneAccountHandle mPhoneAccountHandle;
     private SubscriptionInfoHelper mSubscriptionInfoHelper;
-    private OmtpVvmCarrierConfigHelper mOmtpVvmCarrierConfigHelper;
 
     private EditPhoneNumberPreference mSubMenuVoicemailSettings = null;
     private VoicemailProviderListPreference mVoicemailProviders;
     private PreferenceScreen mVoicemailSettings;
     private VoicemailRingtonePreference mVoicemailNotificationRingtone;
     private CheckBoxPreference mVoicemailNotificationVibrate;
-    private SwitchPreference mVoicemailVisualVoicemail;
-    private Preference mVoicemailChangePinPreference;
 
     //*********************************************************************************************
     // Preference Activity Methods
@@ -235,9 +226,6 @@
         mSubscriptionInfoHelper.setActionBarTitle(
                 getActionBar(), getResources(), R.string.voicemail_settings_with_label);
         mPhone = mSubscriptionInfoHelper.getPhone();
-        mPhoneAccountHandle = PhoneUtils.makePstnPhoneAccountHandle(mPhone);
-        mOmtpVvmCarrierConfigHelper = new OmtpVvmCarrierConfigHelper(
-                mPhone.getContext(), mPhone.getSubId());
         addPreferencesFromResource(R.xml.voicemail_settings);
     }
 
@@ -277,36 +265,6 @@
 
         maybeHidePublicSettings();
 
-        mVoicemailVisualVoicemail = (SwitchPreference) findPreference(
-                getResources().getString(R.string.voicemail_visual_voicemail_key));
-
-        mVoicemailChangePinPreference = prefSet.findPreference(
-                getResources().getString(R.string.voicemail_change_pin_key));
-        if (mVoicemailChangePinPreference != null) {
-            Intent changePinIntent = new Intent(new Intent(this, VoicemailChangePinActivity.class));
-            changePinIntent.putExtra(VoicemailChangePinActivity.EXTRA_PHONE_ACCOUNT_HANDLE,
-                    mPhoneAccountHandle);
-
-            mVoicemailChangePinPreference.setIntent(changePinIntent);
-            if (VoicemailChangePinActivity.isDefaultOldPinSet(this, mPhoneAccountHandle)) {
-                mVoicemailChangePinPreference.setTitle(R.string.voicemail_set_pin_dialog_title);
-            } else {
-                mVoicemailChangePinPreference.setTitle(R.string.voicemail_change_pin_dialog_title);
-            }
-        }
-        if (mVoicemailVisualVoicemail != null) {
-            if (mOmtpVvmCarrierConfigHelper.isValid()) {
-                mVoicemailVisualVoicemail.setOnPreferenceChangeListener(this);
-                mVoicemailVisualVoicemail.setChecked(
-                        VisualVoicemailSettingsUtil.isEnabled(this, mPhoneAccountHandle));
-                if (!isVisualVoicemailActivated()) {
-                    prefSet.removePreference(mVoicemailChangePinPreference);
-                }
-            } else {
-                prefSet.removePreference(mVoicemailVisualVoicemail);
-                prefSet.removePreference(mVoicemailChangePinPreference);
-            }
-        }
         updateVMPreferenceWidgets(mVoicemailProviders.getValue());
 
         // check the intent that started this activity and pop up the voicemail
@@ -449,18 +407,7 @@
             // TODO: Revert to checking reference after migrating voicemail to its own activity.
             VoicemailNotificationSettingsUtil.setVibrationEnabled(
                     mPhone, Boolean.TRUE.equals(objValue));
-        } else if (preference.getKey().equals(mVoicemailVisualVoicemail.getKey())) {
-            boolean isEnabled = (boolean) objValue;
-            VisualVoicemailSettingsUtil
-                    .setEnabled(mPhone.getContext(), mPhoneAccountHandle, isEnabled);
-            PreferenceScreen prefSet = getPreferenceScreen();
-            if (isVisualVoicemailActivated()) {
-                prefSet.addPreference(mVoicemailChangePinPreference);
-            } else {
-                prefSet.removePreference(mVoicemailChangePinPreference);
-            }
         }
-
         // Always let the preference setting proceed.
         return true;
     }
@@ -1198,16 +1145,6 @@
         return true;
     }
 
-    private boolean isVisualVoicemailActivated() {
-        if (!VisualVoicemailSettingsUtil.isEnabled(this, mPhoneAccountHandle)) {
-            return false;
-        }
-        VisualVoicemailPreferences preferences = new VisualVoicemailPreferences(this,
-                mPhoneAccountHandle);
-        return preferences.getString(OmtpConstants.SERVER_ADDRESS, null) != null;
-
-    }
-
     private static void log(String msg) {
         Log.d(LOG_TAG, msg);
     }
diff --git a/src/com/android/phone/vvm/omtp/utils/PhoneAccountHandleConverter.java b/src/com/android/phone/vvm/PhoneAccountHandleConverter.java
similarity index 95%
rename from src/com/android/phone/vvm/omtp/utils/PhoneAccountHandleConverter.java
rename to src/com/android/phone/vvm/PhoneAccountHandleConverter.java
index ad4c423..cb05215 100644
--- a/src/com/android/phone/vvm/omtp/utils/PhoneAccountHandleConverter.java
+++ b/src/com/android/phone/vvm/PhoneAccountHandleConverter.java
@@ -14,7 +14,7 @@
  * limitations under the License
  */
 
-package com.android.phone.vvm.omtp.utils;
+package com.android.phone.vvm;
 
 import android.annotation.Nullable;
 import android.telecom.PhoneAccountHandle;
@@ -22,7 +22,7 @@
 import com.android.internal.telephony.Phone;
 import com.android.internal.telephony.PhoneFactory;
 import com.android.phone.PhoneUtils;
-import com.android.phone.vvm.omtp.VvmLog;
+import com.android.phone.vvm.VvmLog;
 
 /**
  * Utility to convert between PhoneAccountHandle and subId, which is a common operation in OMTP
diff --git a/src/com/android/phone/vvm/RemoteVvmTaskManager.java b/src/com/android/phone/vvm/RemoteVvmTaskManager.java
index bd76bee..4fc8c57 100644
--- a/src/com/android/phone/vvm/RemoteVvmTaskManager.java
+++ b/src/com/android/phone/vvm/RemoteVvmTaskManager.java
@@ -40,8 +40,6 @@
 
 import com.android.phone.Assert;
 import com.android.phone.R;
-import com.android.phone.vvm.omtp.VvmLog;
-import com.android.phone.vvm.omtp.utils.PhoneAccountHandleConverter;
 
 import java.util.ArrayList;
 import java.util.LinkedList;
diff --git a/src/com/android/phone/vvm/omtp/VisualVoicemailPreferences.java b/src/com/android/phone/vvm/VisualVoicemailPreferences.java
similarity index 98%
rename from src/com/android/phone/vvm/omtp/VisualVoicemailPreferences.java
rename to src/com/android/phone/vvm/VisualVoicemailPreferences.java
index be51ea9..b28cea4 100644
--- a/src/com/android/phone/vvm/omtp/VisualVoicemailPreferences.java
+++ b/src/com/android/phone/vvm/VisualVoicemailPreferences.java
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License
  */
-package com.android.phone.vvm.omtp;
+package com.android.phone.vvm;
 
 import android.annotation.Nullable;
 import android.content.Context;
diff --git a/src/com/android/phone/settings/VisualVoicemailSettingsUtil.java b/src/com/android/phone/vvm/VisualVoicemailSettingsUtil.java
similarity index 67%
rename from src/com/android/phone/settings/VisualVoicemailSettingsUtil.java
rename to src/com/android/phone/vvm/VisualVoicemailSettingsUtil.java
index 22fb70e..6829daf 100644
--- a/src/com/android/phone/settings/VisualVoicemailSettingsUtil.java
+++ b/src/com/android/phone/vvm/VisualVoicemailSettingsUtil.java
@@ -13,15 +13,11 @@
  * See the License for the specific language governing permissions and
  * limitations under the License
  */
-package com.android.phone.settings;
+package com.android.phone.vvm;
 
 import android.content.Context;
 import android.telecom.PhoneAccountHandle;
 import com.android.phone.R;
-import com.android.phone.vvm.omtp.OmtpVvmCarrierConfigHelper;
-import com.android.phone.vvm.omtp.VisualVoicemailPreferences;
-import com.android.phone.vvm.omtp.sync.OmtpVvmSourceManager;
-import com.android.phone.vvm.omtp.utils.PhoneAccountHandleConverter;
 
 /**
  * Save whether or not a particular account is enabled in shared to be retrieved later.
@@ -36,14 +32,6 @@
         new VisualVoicemailPreferences(context, phoneAccount).edit()
                 .putBoolean(IS_ENABLED_KEY, isEnabled)
                 .apply();
-        OmtpVvmCarrierConfigHelper config = new OmtpVvmCarrierConfigHelper(context, phoneAccount);
-        if (isEnabled) {
-            OmtpVvmSourceManager.getInstance(context).addPhoneStateListener(phoneAccount);
-            config.startActivation();
-        } else {
-            OmtpVvmSourceManager.getInstance(context).removeSource(phoneAccount);
-            config.startDeactivation();
-        }
     }
 
     public static boolean isEnabled(Context context,
@@ -56,13 +44,7 @@
         }
 
         VisualVoicemailPreferences prefs = new VisualVoicemailPreferences(context, phoneAccount);
-        if (prefs.contains(IS_ENABLED_KEY)) {
-            // isEnableByDefault is a bit expensive, so don't use it as default value of
-            // getBoolean(). The "false" here should never be actually used.
-            return prefs.getBoolean(IS_ENABLED_KEY, false);
-        }
-        return new OmtpVvmCarrierConfigHelper(context,
-                PhoneAccountHandleConverter.toSubId(phoneAccount)).isEnabledByDefault();
+        return prefs.getBoolean(IS_ENABLED_KEY, false);
     }
 
     /**
diff --git a/src/com/android/phone/VisualVoicemailSmsFilterConfig.java b/src/com/android/phone/vvm/VisualVoicemailSmsFilterConfig.java
similarity index 99%
rename from src/com/android/phone/VisualVoicemailSmsFilterConfig.java
rename to src/com/android/phone/vvm/VisualVoicemailSmsFilterConfig.java
index db79e2b..058f18e 100644
--- a/src/com/android/phone/VisualVoicemailSmsFilterConfig.java
+++ b/src/com/android/phone/vvm/VisualVoicemailSmsFilterConfig.java
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.android.phone;
+package com.android.phone.vvm;
 
 import android.annotation.Nullable;
 import android.content.ComponentName;
diff --git a/src/com/android/phone/vvm/omtp/utils/VvmDumpHandler.java b/src/com/android/phone/vvm/VvmDumpHandler.java
similarity index 63%
rename from src/com/android/phone/vvm/omtp/utils/VvmDumpHandler.java
rename to src/com/android/phone/vvm/VvmDumpHandler.java
index 227cf42..866927e 100644
--- a/src/com/android/phone/vvm/omtp/utils/VvmDumpHandler.java
+++ b/src/com/android/phone/vvm/VvmDumpHandler.java
@@ -1,12 +1,11 @@
-package com.android.phone.vvm.omtp.utils;
+package com.android.phone.vvm;
 
 import android.content.Context;
 import android.telecom.PhoneAccountHandle;
 import android.telecom.TelecomManager;
+import android.telephony.TelephonyManager;
 
 import com.android.internal.util.IndentingPrintWriter;
-import com.android.phone.vvm.omtp.OmtpVvmCarrierConfigHelper;
-import com.android.phone.vvm.omtp.VvmLog;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
@@ -15,6 +14,7 @@
 
     public static void dump(Context context, FileDescriptor fd, PrintWriter writer,
             String[] args) {
+        TelephonyManager telephonyManager = TelephonyManager.from(context);
         IndentingPrintWriter indentedWriter = new IndentingPrintWriter(writer, "  ");
         indentedWriter.println("******* OmtpVvm *******");
         indentedWriter.println("======= Configs =======");
@@ -22,8 +22,12 @@
         for (PhoneAccountHandle handle : TelecomManager.from(context)
                 .getCallCapablePhoneAccounts()) {
             int subId = PhoneAccountHandleConverter.toSubId(handle);
-            OmtpVvmCarrierConfigHelper config = new OmtpVvmCarrierConfigHelper(context, subId);
-            indentedWriter.println(config.toString());
+            indentedWriter.println(
+                    "VisualVoicemailPackageName:" + telephonyManager.createForSubscriptionId(subId)
+                            .getVisualVoicemailPackageName());
+            indentedWriter.println(
+                    "VisualVoicemailSmsFilterSettings(" + subId + "):" + telephonyManager
+                            .getActiveVisualVoicemailSmsFilterSettings(subId));
         }
         indentedWriter.decreaseIndent();
         indentedWriter.println("======== Logs =========");
diff --git a/src/com/android/phone/vvm/omtp/VvmLog.java b/src/com/android/phone/vvm/VvmLog.java
similarity index 98%
rename from src/com/android/phone/vvm/omtp/VvmLog.java
rename to src/com/android/phone/vvm/VvmLog.java
index 82d42af..9ee58b3 100644
--- a/src/com/android/phone/vvm/omtp/VvmLog.java
+++ b/src/com/android/phone/vvm/VvmLog.java
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License
  */
-package com.android.phone.vvm.omtp;
+package com.android.phone.vvm;
 
 import android.util.LocalLog;
 import android.util.Log;
diff --git a/src/com/android/phone/vvm/VvmSimStateTracker.java b/src/com/android/phone/vvm/VvmSimStateTracker.java
index fd6aaee..24b78c4 100644
--- a/src/com/android/phone/vvm/VvmSimStateTracker.java
+++ b/src/com/android/phone/vvm/VvmSimStateTracker.java
@@ -35,8 +35,6 @@
 import com.android.internal.telephony.PhoneConstants;
 import com.android.internal.telephony.TelephonyIntents;
 import com.android.phone.PhoneUtils;
-import com.android.phone.vvm.omtp.VvmLog;
-import com.android.phone.vvm.omtp.utils.PhoneAccountHandleConverter;
 
 import java.util.Map;
 import java.util.Set;
diff --git a/src/com/android/phone/vvm/VvmSmsReceiver.java b/src/com/android/phone/vvm/VvmSmsReceiver.java
index feaa46b..4bffa97 100644
--- a/src/com/android/phone/vvm/VvmSmsReceiver.java
+++ b/src/com/android/phone/vvm/VvmSmsReceiver.java
@@ -23,10 +23,6 @@
 import android.telephony.SubscriptionManager;
 import android.telephony.VisualVoicemailSms;
 
-import com.android.phone.vvm.omtp.VvmLog;
-import com.android.phone.vvm.omtp.sms.OmtpMessageReceiver;
-import com.android.phone.vvm.omtp.utils.PhoneAccountHandleConverter;
-
 /**
  * Receives the SMS filtered by {@link com.android.internal.telephony.VisualVoicemailSmsFilter} and
  * redirect it to the visual voicemail client. The redirection is required to let telephony service
@@ -56,10 +52,8 @@
         if (RemoteVvmTaskManager.hasRemoteService(context, subId)) {
             VvmLog.i(TAG, "Sending SMS received event to remote service");
             RemoteVvmTaskManager.startSmsReceived(context, sms);
-            return;
-        }
-
-        OmtpMessageReceiver
-                .onReceive(context, sms);
+        } else {
+            VvmLog.w(TAG, "Sending SMS received event to remote service");
+        };
     }
 }
diff --git a/src/com/android/phone/vvm/omtp/ActivationTask.java b/src/com/android/phone/vvm/omtp/ActivationTask.java
deleted file mode 100644
index 6fd42fd..0000000
--- a/src/com/android/phone/vvm/omtp/ActivationTask.java
+++ /dev/null
@@ -1,308 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.phone.vvm.omtp;
-
-import android.annotation.Nullable;
-import android.annotation.WorkerThread;
-import android.content.Context;
-import android.content.Intent;
-import android.database.ContentObserver;
-import android.os.Bundle;
-import android.provider.Settings;
-import android.provider.Settings.Global;
-import android.telecom.PhoneAccountHandle;
-import android.telephony.ServiceState;
-import android.telephony.TelephonyManager;
-import com.android.phone.Assert;
-import com.android.phone.PhoneGlobals;
-import com.android.phone.VoicemailStatus;
-import com.android.phone.vvm.omtp.protocol.VisualVoicemailProtocol;
-import com.android.phone.vvm.omtp.scheduling.BaseTask;
-import com.android.phone.vvm.omtp.scheduling.RetryPolicy;
-import com.android.phone.vvm.omtp.sms.StatusMessage;
-import com.android.phone.vvm.omtp.sms.StatusSmsFetcher;
-import com.android.phone.vvm.omtp.sync.OmtpVvmSourceManager;
-import com.android.phone.vvm.omtp.sync.OmtpVvmSyncService;
-import com.android.phone.vvm.omtp.sync.SyncTask;
-import com.android.phone.vvm.omtp.utils.PhoneAccountHandleConverter;
-import java.io.IOException;
-import java.util.HashSet;
-import java.util.Set;
-import java.util.concurrent.CancellationException;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.TimeoutException;
-
-/**
- * Task to activate the visual voicemail service. A request to activate VVM will be sent to the
- * carrier, which will respond with a STATUS SMS. The credentials will be updated from the SMS. If
- * the user is not provisioned provisioning will be attempted. Activation happens when the phone
- * boots, the SIM is inserted, signal returned when VVM is not activated yet, and when the carrier
- * spontaneously sent a STATUS SMS.
- */
-public class ActivationTask extends BaseTask {
-
-    private static final String TAG = "VvmActivationTask";
-
-    private static final int RETRY_TIMES = 4;
-    private static final int RETRY_INTERVAL_MILLIS = 5_000;
-
-    private static final String EXTRA_MESSAGE_DATA_BUNDLE = "extra_message_data_bundle";
-
-    @Nullable
-    private static DeviceProvisionedObserver sDeviceProvisionedObserver;
-
-    private final RetryPolicy mRetryPolicy;
-
-    private Bundle mMessageData;
-
-    public ActivationTask() {
-        super(TASK_ACTIVATION);
-        mRetryPolicy = new RetryPolicy(RETRY_TIMES, RETRY_INTERVAL_MILLIS);
-        addPolicy(mRetryPolicy);
-    }
-
-    /**
-     * Has the user gone through the setup wizard yet.
-     */
-    private static boolean isDeviceProvisioned(Context context) {
-        return Settings.Global.getInt(
-            context.getContentResolver(), Settings.Global.DEVICE_PROVISIONED, 0) == 1;
-    }
-
-    /**
-     * @param messageData The optional bundle from {@link android.provider.VoicemailContract#
-     * EXTRA_VOICEMAIL_SMS_FIELDS}, if the task is initiated by a status SMS. If null the task will
-     * request a status SMS itself.
-     */
-    public static void start(Context context, int subId, @Nullable Bundle messageData) {
-        if (!isDeviceProvisioned(context)) {
-            VvmLog.i(TAG, "Activation requested while device is not provisioned, postponing");
-            // Activation might need information such as system language to be set, so wait until
-            // the setup wizard is finished. The data bundle from the SMS will be re-requested upon
-            // activation.
-            queueActivationAfterProvisioned(context, subId);
-            return;
-        }
-
-        Intent intent = BaseTask.createIntent(context, ActivationTask.class, subId);
-        if (messageData != null) {
-            intent.putExtra(EXTRA_MESSAGE_DATA_BUNDLE, messageData);
-        }
-        context.startService(intent);
-    }
-
-    public void onCreate(Context context, Intent intent, int flags, int startId) {
-        super.onCreate(context, intent, flags, startId);
-        mMessageData = intent.getParcelableExtra(EXTRA_MESSAGE_DATA_BUNDLE);
-    }
-
-    @Override
-    public Intent createRestartIntent() {
-        Intent intent = super.createRestartIntent();
-        // mMessageData is discarded, request a fresh STATUS SMS for retries.
-        return intent;
-    }
-
-    @Override
-    @WorkerThread
-    public void onExecuteInBackgroundThread() {
-        Assert.isNotMainThread();
-        int subId = getSubId();
-
-        PhoneAccountHandle phoneAccountHandle = PhoneAccountHandleConverter.fromSubId(subId);
-        if (phoneAccountHandle == null) {
-            // This should never happen
-            VvmLog.e(TAG, "null phone account for subId " + subId);
-            return;
-        }
-
-        OmtpVvmCarrierConfigHelper helper = new OmtpVvmCarrierConfigHelper(getContext(), subId);
-        if (!helper.isValid()) {
-            VvmLog.i(TAG, "VVM not supported on subId " + subId);
-            OmtpVvmSourceManager.getInstance(getContext()).removeSource(phoneAccountHandle);
-            return;
-        }
-
-        // OmtpVvmCarrierConfigHelper can start the activation process; it will pass in a vvm
-        // content provider URI which we will use.  On some occasions, setting that URI will
-        // fail, so we will perform a few attempts to ensure that the vvm content provider has
-        // a good chance of being started up.
-        if (!VoicemailStatus.edit(getContext(), phoneAccountHandle)
-            .setType(helper.getVvmType())
-            .apply()) {
-            VvmLog.e(TAG, "Failed to configure content provider - " + helper.getVvmType());
-            fail();
-        }
-        VvmLog.i(TAG, "VVM content provider configured - " + helper.getVvmType());
-
-        if (!OmtpVvmSourceManager.getInstance(getContext())
-                .isVvmSourceRegistered(phoneAccountHandle)) {
-            // This account has not been activated before during the lifetime of this boot.
-            VisualVoicemailPreferences preferences = new VisualVoicemailPreferences(getContext(),
-                    phoneAccountHandle);
-            if (preferences.getString(OmtpConstants.SERVER_ADDRESS, null) == null) {
-                // Only show the "activating" message if activation has not been completed before.
-                // Subsequent activations are more of a status check and usually does not
-                // concern the user.
-                helper.handleEvent(VoicemailStatus.edit(getContext(), phoneAccountHandle),
-                        OmtpEvents.CONFIG_ACTIVATING);
-            } else {
-                // The account has been activated on this device before. Pretend it is already
-                // activated. If there are any activation error it will overwrite this status.
-                helper.handleEvent(VoicemailStatus.edit(getContext(), phoneAccountHandle),
-                        OmtpEvents.CONFIG_ACTIVATING_SUBSEQUENT);
-            }
-
-        }
-        if (!hasSignal(getContext(), subId)) {
-            VvmLog.i(TAG, "Service lost during activation, aborting");
-            // Restore the "NO SIGNAL" state since it will be overwritten by the CONFIG_ACTIVATING
-            // event.
-            helper.handleEvent(VoicemailStatus.edit(getContext(), phoneAccountHandle),
-                    OmtpEvents.NOTIFICATION_SERVICE_LOST);
-            // Don't retry, a new activation will be started after the signal returned.
-            return;
-        }
-
-        helper.activateSmsFilter();
-        VoicemailStatus.Editor status = mRetryPolicy.getVoicemailStatusEditor();
-
-        VisualVoicemailProtocol protocol = helper.getProtocol();
-
-        Bundle data;
-        if (mMessageData != null) {
-            // The content of STATUS SMS is provided to launch this task, no need to request it
-            // again.
-            data = mMessageData;
-        } else {
-            try (StatusSmsFetcher fetcher = new StatusSmsFetcher(getContext(), subId)) {
-                protocol.startActivation(helper, fetcher.getSentIntent());
-                // Both the fetcher and OmtpMessageReceiver will be triggered, but
-                // OmtpMessageReceiver will just route the SMS back to ActivationTask, which will be
-                // rejected because the task is still running.
-                data = fetcher.get();
-            } catch (TimeoutException e) {
-                // The carrier is expected to return an STATUS SMS within STATUS_SMS_TIMEOUT_MILLIS
-                // handleEvent() will do the logging.
-                helper.handleEvent(status, OmtpEvents.CONFIG_STATUS_SMS_TIME_OUT);
-                fail();
-                return;
-            } catch (CancellationException e) {
-                VvmLog.e(TAG, "Unable to send status request SMS");
-                fail();
-                return;
-            } catch (InterruptedException | ExecutionException | IOException e) {
-                VvmLog.e(TAG, "can't get future STATUS SMS", e);
-                fail();
-                return;
-            }
-        }
-
-        StatusMessage message = new StatusMessage(data);
-        VvmLog.d(TAG, "STATUS SMS received: st=" + message.getProvisioningStatus()
-                + ", rc=" + message.getReturnCode());
-
-        if (message.getProvisioningStatus().equals(OmtpConstants.SUBSCRIBER_READY)) {
-            VvmLog.d(TAG, "subscriber ready, no activation required");
-            updateSource(getContext(), phoneAccountHandle, getSubId(), status, message);
-        } else {
-            if (helper.supportsProvisioning()) {
-                VvmLog.i(TAG, "Subscriber not ready, start provisioning");
-                helper.startProvisioning(this, phoneAccountHandle, status, message, data);
-
-            } else if (message.getProvisioningStatus().equals(OmtpConstants.SUBSCRIBER_NEW)) {
-                VvmLog.i(TAG, "Subscriber new but provisioning is not supported");
-                // Ignore the non-ready state and attempt to use the provided info as is.
-                // This is probably caused by not completing the new user tutorial.
-                updateSource(getContext(), phoneAccountHandle, getSubId(), status, message);
-            } else {
-                VvmLog.i(TAG, "Subscriber not ready but provisioning is not supported");
-                helper.handleEvent(status, OmtpEvents.CONFIG_SERVICE_NOT_AVAILABLE);
-                PhoneGlobals.getInstance().setShouldCheckVisualVoicemailConfigurationForMwi(subId, false);
-            }
-        }
-    }
-
-    public static void updateSource(Context context, PhoneAccountHandle phone, int subId,
-            VoicemailStatus.Editor status, StatusMessage message) {
-        OmtpVvmSourceManager vvmSourceManager =
-                OmtpVvmSourceManager.getInstance(context);
-
-        if (OmtpConstants.SUCCESS.equals(message.getReturnCode())) {
-            OmtpVvmCarrierConfigHelper helper = new OmtpVvmCarrierConfigHelper(context, subId);
-            helper.handleEvent(status, OmtpEvents.CONFIG_REQUEST_STATUS_SUCCESS);
-
-            // Save the IMAP credentials in preferences so they are persistent and can be retrieved.
-            VisualVoicemailPreferences prefs = new VisualVoicemailPreferences(context, phone);
-            message.putStatus(prefs.edit()).apply();
-
-            // Add the source to indicate that it is active.
-            vvmSourceManager.addSource(phone);
-
-            SyncTask.start(context, phone, OmtpVvmSyncService.SYNC_FULL_SYNC);
-            // Remove the message waiting indicator, which is a sticky notification for traditional
-            // voicemails.
-            PhoneGlobals.getInstance()
-                    .setShouldCheckVisualVoicemailConfigurationForMwi(subId, true);
-            PhoneGlobals.getInstance().clearMwiIndicator(subId);
-        } else {
-            VvmLog.e(TAG, "Visual voicemail not available for subscriber.");
-        }
-    }
-
-    private static boolean hasSignal(Context context, int subId) {
-        return context.getSystemService(TelephonyManager.class)
-                .getServiceStateForSubscriber(subId).getState() == ServiceState.STATE_IN_SERVICE;
-    }
-
-    private static void queueActivationAfterProvisioned(Context context, int subId) {
-        if (sDeviceProvisionedObserver == null) {
-            sDeviceProvisionedObserver = new DeviceProvisionedObserver(context);
-            context.getContentResolver()
-                .registerContentObserver(Settings.Global.getUriFor(Global.DEVICE_PROVISIONED),
-                    false, sDeviceProvisionedObserver);
-        }
-        sDeviceProvisionedObserver.addSubId(subId);
-    }
-
-    private static class DeviceProvisionedObserver extends ContentObserver {
-
-        private final Context mContext;
-        private final Set<Integer> mSubIds = new HashSet<>();
-
-        private DeviceProvisionedObserver(Context context) {
-            super(null);
-            mContext = context;
-        }
-
-        public void addSubId(int subId) {
-            mSubIds.add(subId);
-        }
-
-        @Override
-        public void onChange(boolean selfChange) {
-            if (isDeviceProvisioned(mContext)) {
-                VvmLog.i(TAG, "device provisioned, resuming activation");
-                for (int subId : mSubIds) {
-                    start(mContext, subId, null);
-                }
-                mContext.getContentResolver().unregisterContentObserver(sDeviceProvisionedObserver);
-                sDeviceProvisionedObserver = null;
-            }
-        }
-    }
-}
diff --git a/src/com/android/phone/vvm/omtp/DefaultOmtpEventHandler.java b/src/com/android/phone/vvm/omtp/DefaultOmtpEventHandler.java
deleted file mode 100644
index 0c19a6a..0000000
--- a/src/com/android/phone/vvm/omtp/DefaultOmtpEventHandler.java
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.phone.vvm.omtp;
-
-import android.content.Context;
-import android.provider.VoicemailContract;
-import android.provider.VoicemailContract.Status;
-
-import com.android.phone.VoicemailStatus;
-import com.android.phone.vvm.omtp.OmtpEvents.Type;
-
-public class DefaultOmtpEventHandler {
-
-    private static final String TAG = "DefErrorCodeHandler";
-
-    public static void handleEvent(Context context, OmtpVvmCarrierConfigHelper config,
-        VoicemailStatus.Editor status, OmtpEvents event) {
-        switch (event.getType()) {
-            case Type.CONFIGURATION:
-                handleConfigurationEvent(context, status, event);
-                break;
-            case Type.DATA_CHANNEL:
-                handleDataChannelEvent(context, status, event);
-                break;
-            case Type.NOTIFICATION_CHANNEL:
-                handleNotificationChannelEvent(context, config, status, event);
-                break;
-            case Type.OTHER:
-                handleOtherEvent(context, status, event);
-                break;
-            default:
-                VvmLog.wtf(TAG, "invalid event type " + event.getType() + " for " + event);
-        }
-    }
-
-    private static void handleConfigurationEvent(Context context, VoicemailStatus.Editor status,
-            OmtpEvents event) {
-        switch (event) {
-            case CONFIG_DEFAULT_PIN_REPLACED:
-            case CONFIG_REQUEST_STATUS_SUCCESS:
-            case CONFIG_PIN_SET:
-                status
-                        .setConfigurationState(VoicemailContract.Status.CONFIGURATION_STATE_OK)
-                        .setNotificationChannelState(Status.NOTIFICATION_CHANNEL_STATE_OK)
-                        .apply();
-                break;
-            case CONFIG_ACTIVATING:
-                // Wipe all errors from the last activation. All errors shown should be new errors
-                // for this activation.
-                status
-                        .setConfigurationState(Status.CONFIGURATION_STATE_CONFIGURING)
-                        .setNotificationChannelState(Status.NOTIFICATION_CHANNEL_STATE_OK)
-                        .setDataChannelState(Status.DATA_CHANNEL_STATE_OK).apply();
-                break;
-            case CONFIG_ACTIVATING_SUBSEQUENT:
-                status
-                        .setConfigurationState(Status.CONFIGURATION_STATE_OK)
-                        .setNotificationChannelState(Status.NOTIFICATION_CHANNEL_STATE_OK)
-                        .setDataChannelState(Status.DATA_CHANNEL_STATE_OK).apply();
-                break;
-            case CONFIG_SERVICE_NOT_AVAILABLE:
-                status
-                    .setConfigurationState(Status.CONFIGURATION_STATE_FAILED)
-                    .apply();
-                break;
-            case CONFIG_STATUS_SMS_TIME_OUT:
-                status
-                        .setConfigurationState(Status.CONFIGURATION_STATE_FAILED)
-                        .apply();
-                break;
-            default:
-                VvmLog.wtf(TAG, "invalid configuration event " + event);
-        }
-    }
-
-    private static void handleDataChannelEvent(Context context, VoicemailStatus.Editor status,
-            OmtpEvents event) {
-        switch (event) {
-            case DATA_IMAP_OPERATION_STARTED:
-            case DATA_IMAP_OPERATION_COMPLETED:
-                status
-                        .setDataChannelState(Status.DATA_CHANNEL_STATE_OK)
-                        .apply();
-                break;
-
-            case DATA_NO_CONNECTION:
-                status
-                        .setDataChannelState(Status.DATA_CHANNEL_STATE_NO_CONNECTION)
-                        .apply();
-                break;
-
-            case DATA_NO_CONNECTION_CELLULAR_REQUIRED:
-                status
-                        .setDataChannelState(
-                                Status.DATA_CHANNEL_STATE_NO_CONNECTION_CELLULAR_REQUIRED)
-                        .apply();
-                break;
-            case DATA_INVALID_PORT:
-                status
-                        .setDataChannelState(
-                                VoicemailContract.Status.DATA_CHANNEL_STATE_BAD_CONFIGURATION)
-                        .apply();
-                break;
-            case DATA_CANNOT_RESOLVE_HOST_ON_NETWORK:
-                status
-                        .setDataChannelState(
-                                VoicemailContract.Status.DATA_CHANNEL_STATE_SERVER_CONNECTION_ERROR)
-                        .apply();
-                break;
-            case DATA_SSL_INVALID_HOST_NAME:
-            case DATA_CANNOT_ESTABLISH_SSL_SESSION:
-            case DATA_IOE_ON_OPEN:
-            case DATA_GENERIC_IMAP_IOE:
-                status
-                        .setDataChannelState(
-                                VoicemailContract.Status.DATA_CHANNEL_STATE_COMMUNICATION_ERROR)
-                        .apply();
-                break;
-            case DATA_BAD_IMAP_CREDENTIAL:
-            case DATA_AUTH_UNKNOWN_USER:
-            case DATA_AUTH_UNKNOWN_DEVICE:
-            case DATA_AUTH_INVALID_PASSWORD:
-            case DATA_AUTH_MAILBOX_NOT_INITIALIZED:
-            case DATA_AUTH_SERVICE_NOT_PROVISIONED:
-            case DATA_AUTH_SERVICE_NOT_ACTIVATED:
-            case DATA_AUTH_USER_IS_BLOCKED:
-                status
-                        .setDataChannelState(
-                                VoicemailContract.Status.DATA_CHANNEL_STATE_BAD_CONFIGURATION)
-                        .apply();
-                break;
-
-            case DATA_REJECTED_SERVER_RESPONSE:
-            case DATA_INVALID_INITIAL_SERVER_RESPONSE:
-            case DATA_MAILBOX_OPEN_FAILED:
-            case DATA_SSL_EXCEPTION:
-            case DATA_ALL_SOCKET_CONNECTION_FAILED:
-                status
-                        .setDataChannelState(
-                                VoicemailContract.Status.DATA_CHANNEL_STATE_SERVER_ERROR)
-                        .apply();
-                break;
-
-            default:
-                VvmLog.wtf(TAG, "invalid data channel event " + event);
-        }
-    }
-
-    private static void handleNotificationChannelEvent(Context context,
-        OmtpVvmCarrierConfigHelper config, VoicemailStatus.Editor status, OmtpEvents event) {
-        switch (event) {
-            case NOTIFICATION_IN_SERVICE:
-                status
-                        .setNotificationChannelState(Status.NOTIFICATION_CHANNEL_STATE_OK)
-                        // Clear the error state. A sync should follow signal return so any error
-                        // will be reposted.
-                        .setDataChannelState(Status.DATA_CHANNEL_STATE_OK)
-                        .apply();
-                break;
-            case NOTIFICATION_SERVICE_LOST:
-                status.setNotificationChannelState(Status.NOTIFICATION_CHANNEL_STATE_NO_CONNECTION);
-                if (config.isCellularDataRequired()) {
-                    status.setDataChannelState(
-                            Status.DATA_CHANNEL_STATE_NO_CONNECTION_CELLULAR_REQUIRED);
-                }
-                status.apply();
-                break;
-            default:
-                VvmLog.wtf(TAG, "invalid notification channel event " + event);
-        }
-    }
-
-    private static void handleOtherEvent(Context context, VoicemailStatus.Editor status,
-            OmtpEvents event) {
-        switch (event) {
-            case OTHER_SOURCE_REMOVED:
-                status
-                        .setConfigurationState(Status.CONFIGURATION_STATE_NOT_CONFIGURED)
-                        .setNotificationChannelState(
-                                Status.NOTIFICATION_CHANNEL_STATE_NO_CONNECTION)
-                        .setDataChannelState(Status.DATA_CHANNEL_STATE_NO_CONNECTION)
-                        .apply();
-                break;
-            default:
-                VvmLog.wtf(TAG, "invalid other event " + event);
-        }
-    }
-}
diff --git a/src/com/android/phone/vvm/omtp/OmtpConstants.java b/src/com/android/phone/vvm/omtp/OmtpConstants.java
deleted file mode 100644
index 3f5722f..0000000
--- a/src/com/android/phone/vvm/omtp/OmtpConstants.java
+++ /dev/null
@@ -1,249 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-package com.android.phone.vvm.omtp;
-
-import android.annotation.IntDef;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Wrapper class to hold relevant OMTP constants as defined in the OMTP spec. <p> In essence this is
- * a programmatic representation of the relevant portions of OMTP spec.
- */
-public class OmtpConstants {
-    public static final String SMS_FIELD_SEPARATOR = ";";
-    public static final String SMS_KEY_VALUE_SEPARATOR = "=";
-    public static final String SMS_PREFIX_SEPARATOR = ":";
-
-    public static final String SYNC_SMS_PREFIX = "SYNC";
-    public static final String STATUS_SMS_PREFIX = "STATUS";
-
-    // This is the format designated by the OMTP spec.
-    public static final String DATE_TIME_FORMAT = "dd/MM/yyyy HH:mm Z";
-
-    /** OMTP protocol versions. */
-    public static final String PROTOCOL_VERSION1_1 = "11";
-    public static final String PROTOCOL_VERSION1_2 = "12";
-    public static final String PROTOCOL_VERSION1_3 = "13";
-
-    ///////////////////////// Client/Mobile originated SMS //////////////////////
-
-    /** Mobile Originated requests */
-    public static final String ACTIVATE_REQUEST = "Activate";
-    public static final String DEACTIVATE_REQUEST = "Deactivate";
-    public static final String STATUS_REQUEST = "Status";
-
-    /** fields that can be present in a Mobile Originated OMTP SMS */
-    public static final String CLIENT_TYPE = "ct";
-    public static final String APPLICATION_PORT = "pt";
-    public static final String PROTOCOL_VERSION = "pv";
-
-
-    //////////////////////////////// Sync SMS fields ////////////////////////////
-
-    /**
-     * Sync SMS fields.
-     * <p>
-     * Each string constant is the field's key in the SMS body which is used by the parser to
-     * identify the field's value, if present, in the SMS body.
-     */
-
-    /**
-     * The event that triggered this SYNC SMS.
-     * See {@link OmtpConstants#SYNC_TRIGGER_EVENT_VALUES}
-     */
-    public static final String SYNC_TRIGGER_EVENT = "ev";
-    public static final String MESSAGE_UID = "id";
-    public static final String MESSAGE_LENGTH = "l";
-    public static final String NUM_MESSAGE_COUNT = "c";
-    /** See {@link OmtpConstants#CONTENT_TYPE_VALUES} */
-    public static final String CONTENT_TYPE = "t";
-    public static final String SENDER = "s";
-    public static final String TIME = "dt";
-
-    /**
-     * SYNC message trigger events.
-     * <p>
-     * These are the possible values of {@link OmtpConstants#SYNC_TRIGGER_EVENT}.
-     */
-    public static final String NEW_MESSAGE = "NM";
-    public static final String MAILBOX_UPDATE = "MBU";
-    public static final String GREETINGS_UPDATE = "GU";
-
-    public static final String[] SYNC_TRIGGER_EVENT_VALUES = {
-        NEW_MESSAGE,
-        MAILBOX_UPDATE,
-        GREETINGS_UPDATE
-    };
-
-    /**
-     * Content types supported by OMTP VVM.
-     * <p>
-     * These are the possible values of {@link OmtpConstants#CONTENT_TYPE}.
-     */
-    public static final String VOICE = "v";
-    public static final String VIDEO = "o";
-    public static final String FAX = "f";
-    /** Voice message deposited by an external application */
-    public static final String INFOTAINMENT = "i";
-    /** Empty Call Capture - i.e. voicemail with no voice message. */
-    public static final String ECC = "e";
-
-    public static final String[] CONTENT_TYPE_VALUES = {VOICE, VIDEO, FAX, INFOTAINMENT, ECC};
-
-    ////////////////////////////// Status SMS fields ////////////////////////////
-
-    /**
-     * Status SMS fields.
-     * <p>
-     * Each string constant is the field's key in the SMS body which is used by the parser to
-     * identify the field's value, if present, in the SMS body.
-     */
-    /** See {@link OmtpConstants#PROVISIONING_STATUS_VALUES} */
-    public static final String PROVISIONING_STATUS = "st";
-    /** See {@link OmtpConstants#RETURN_CODE_VALUES} */
-    public static final String RETURN_CODE = "rc";
-    /** URL to send users to for activation VVM */
-    public static final String SUBSCRIPTION_URL = "rs";
-    /** IMAP4/SMTP server IP address or fully qualified domain name */
-    public static final String SERVER_ADDRESS = "srv";
-    /** Phone number to access voicemails through Telephony User Interface */
-    public static final String TUI_ACCESS_NUMBER = "tui";
-    public static final String TUI_PASSWORD_LENGTH = "pw_len";
-    /** Number to send client origination SMS */
-    public static final String CLIENT_SMS_DESTINATION_NUMBER = "dn";
-    public static final String IMAP_PORT = "ipt";
-    public static final String IMAP_USER_NAME = "u";
-    public static final String IMAP_PASSWORD = "pw";
-    public static final String SMTP_PORT = "spt";
-    public static final String SMTP_USER_NAME = "smtp_u";
-    public static final String SMTP_PASSWORD = "smtp_pw";
-
-    /**
-     * User provisioning status values.
-     * <p>
-     * Referred by {@link OmtpConstants#PROVISIONING_STATUS}.
-     */
-    public static final String SUBSCRIBER_NEW = "N";
-    public static final String SUBSCRIBER_READY = "R";
-    public static final String SUBSCRIBER_PROVISIONED = "P";
-    public static final String SUBSCRIBER_UNKNOWN = "U";
-    public static final String SUBSCRIBER_BLOCKED = "B";
-
-    public static final String[] PROVISIONING_STATUS_VALUES = {
-        SUBSCRIBER_NEW,
-        SUBSCRIBER_READY,
-        SUBSCRIBER_PROVISIONED,
-        SUBSCRIBER_UNKNOWN,
-        SUBSCRIBER_BLOCKED
-    };
-
-    /**
-     * The return code included in a status message.
-     * <p>
-     * These are the possible values of {@link OmtpConstants#RETURN_CODE}.
-     */
-    public static final String SUCCESS = "0";
-    public static final String SYSTEM_ERROR = "1";
-    public static final String SUBSCRIBER_ERROR = "2";
-    public static final String MAILBOX_UNKNOWN = "3";
-    public static final String VVM_NOT_ACTIVATED = "4";
-    public static final String VVM_NOT_PROVISIONED = "5";
-    public static final String VVM_CLIENT_UKNOWN = "6";
-    public static final String VVM_MAILBOX_NOT_INITIALIZED = "7";
-
-    public static final String[] RETURN_CODE_VALUES = {
-        SUCCESS,
-        SYSTEM_ERROR,
-        SUBSCRIBER_ERROR,
-        MAILBOX_UNKNOWN,
-        VVM_NOT_ACTIVATED,
-        VVM_NOT_PROVISIONED,
-        VVM_CLIENT_UKNOWN,
-        VVM_MAILBOX_NOT_INITIALIZED,
-    };
-
-    /**
-     * A map of all the field keys to the possible values they can have.
-     */
-    public static final Map<String, String[]> possibleValuesMap = new HashMap<String, String[]>() {{
-        put(SYNC_TRIGGER_EVENT, SYNC_TRIGGER_EVENT_VALUES);
-        put(CONTENT_TYPE, CONTENT_TYPE_VALUES);
-        put(PROVISIONING_STATUS, PROVISIONING_STATUS_VALUES);
-        put(RETURN_CODE, RETURN_CODE_VALUES);
-    }};
-
-    /**
-     * IMAP command extensions
-     */
-
-    /**
-     * OMTP spec v1.3 2.3.1 Change password request syntax
-     *
-     * This changes the PIN to access the Telephone User Interface, the traditional voicemail
-     * system.
-     */
-    public static final String IMAP_CHANGE_TUI_PWD_FORMAT = "XCHANGE_TUI_PWD PWD=%1$s OLD_PWD=%2$s";
-
-    /**
-     * OMTP spec v1.3 2.4.1 Change languate request syntax
-     *
-     * This changes the language in the Telephone User Interface.
-     */
-    public static final String IMAP_CHANGE_VM_LANG_FORMAT = "XCHANGE_VM_LANG LANG=%1$s";
-
-    /**
-     * OMTP spec v1.3 2.5.1 Close NUT Request syntax
-     *
-     * This disables the new user tutorial, the message played to new users calling in the Telephone
-     * User Interface.
-     */
-    public static final String IMAP_CLOSE_NUT = "XCLOSE_NUT";
-
-    /**
-     * Possible NO responses for CHANGE_TUI_PWD
-     */
-
-    public static final String RESPONSE_CHANGE_PIN_TOO_SHORT = "password too short";
-    public static final String RESPONSE_CHANGE_PIN_TOO_LONG = "password too long";
-    public static final String RESPONSE_CHANGE_PIN_TOO_WEAK = "password too weak";
-    public static final String RESPONSE_CHANGE_PIN_MISMATCH = "old password mismatch";
-    public static final String RESPONSE_CHANGE_PIN_INVALID_CHARACTER =
-            "password contains invalid characters";
-
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef(value = {CHANGE_PIN_SUCCESS, CHANGE_PIN_TOO_SHORT, CHANGE_PIN_TOO_LONG,
-            CHANGE_PIN_TOO_WEAK, CHANGE_PIN_MISMATCH, CHANGE_PIN_INVALID_CHARACTER,
-            CHANGE_PIN_SYSTEM_ERROR})
-
-    public @interface ChangePinResult {
-
-    }
-
-    public static final int CHANGE_PIN_SUCCESS = 0;
-    public static final int CHANGE_PIN_TOO_SHORT = 1;
-    public static final int CHANGE_PIN_TOO_LONG = 2;
-    public static final int CHANGE_PIN_TOO_WEAK = 3;
-    public static final int CHANGE_PIN_MISMATCH = 4;
-    public static final int CHANGE_PIN_INVALID_CHARACTER = 5;
-    public static final int CHANGE_PIN_SYSTEM_ERROR = 6;
-
-    /** Indicates the client is Google visual voicemail version 1.0. */
-    public static final String CLIENT_TYPE_GOOGLE_10 = "google.vvm.10";
-}
diff --git a/src/com/android/phone/vvm/omtp/OmtpEvents.java b/src/com/android/phone/vvm/omtp/OmtpEvents.java
deleted file mode 100644
index 7a89418..0000000
--- a/src/com/android/phone/vvm/omtp/OmtpEvents.java
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.phone.vvm.omtp;
-
-import android.annotation.IntDef;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * Events internal to the OMTP client. These should be translated into {@link
- * android.provider.VoicemailContract.Status} error codes before writing into the voicemail status
- * table.
- */
-public enum OmtpEvents {
-
-    // Configuration State
-    CONFIG_REQUEST_STATUS_SUCCESS(Type.CONFIGURATION, true),
-
-    CONFIG_PIN_SET(Type.CONFIGURATION, true),
-    // The voicemail PIN is replaced with a generated PIN, user should change it.
-    CONFIG_DEFAULT_PIN_REPLACED(Type.CONFIGURATION, true),
-    CONFIG_ACTIVATING(Type.CONFIGURATION, true),
-    // There are already activation records, this is only a book-keeping activation.
-    CONFIG_ACTIVATING_SUBSEQUENT(Type.CONFIGURATION, true),
-    CONFIG_STATUS_SMS_TIME_OUT(Type.CONFIGURATION),
-    CONFIG_SERVICE_NOT_AVAILABLE(Type.CONFIGURATION),
-
-    // Data channel State
-
-    // A new sync has started, old errors in data channel should be cleared.
-    DATA_IMAP_OPERATION_STARTED(Type.DATA_CHANNEL, true),
-    // Successfully downloaded/uploaded data from the server, which means the data channel is clear.
-    DATA_IMAP_OPERATION_COMPLETED(Type.DATA_CHANNEL, true),
-    // The port provided in the STATUS SMS is invalid.
-    DATA_INVALID_PORT(Type.DATA_CHANNEL),
-    // No connection to the internet, and the carrier requires cellular data
-    DATA_NO_CONNECTION_CELLULAR_REQUIRED(Type.DATA_CHANNEL),
-    // No connection to the internet.
-    DATA_NO_CONNECTION(Type.DATA_CHANNEL),
-    // Address lookup for the server hostname failed. DNS error?
-    DATA_CANNOT_RESOLVE_HOST_ON_NETWORK(Type.DATA_CHANNEL),
-    // All destination address that resolves to the server hostname are rejected or timed out
-    DATA_ALL_SOCKET_CONNECTION_FAILED(Type.DATA_CHANNEL),
-    // Failed to establish SSL with the server, either with a direct SSL connection or by
-    // STARTTLS command
-    DATA_CANNOT_ESTABLISH_SSL_SESSION(Type.DATA_CHANNEL),
-    // Identity of the server cannot be verified.
-    DATA_SSL_INVALID_HOST_NAME(Type.DATA_CHANNEL),
-    // The server rejected our username/password
-    DATA_BAD_IMAP_CREDENTIAL(Type.DATA_CHANNEL),
-
-    DATA_AUTH_UNKNOWN_USER(Type.DATA_CHANNEL),
-    DATA_AUTH_UNKNOWN_DEVICE(Type.DATA_CHANNEL),
-    DATA_AUTH_INVALID_PASSWORD(Type.DATA_CHANNEL),
-    DATA_AUTH_MAILBOX_NOT_INITIALIZED(Type.DATA_CHANNEL),
-    DATA_AUTH_SERVICE_NOT_PROVISIONED(Type.DATA_CHANNEL),
-    DATA_AUTH_SERVICE_NOT_ACTIVATED(Type.DATA_CHANNEL),
-    DATA_AUTH_USER_IS_BLOCKED(Type.DATA_CHANNEL),
-
-    // A command to the server didn't result with an "OK" or continuation request
-    DATA_REJECTED_SERVER_RESPONSE(Type.DATA_CHANNEL),
-    // The server did not greet us with a "OK", possibly not a IMAP server.
-    DATA_INVALID_INITIAL_SERVER_RESPONSE(Type.DATA_CHANNEL),
-    // An IOException occurred while trying to open an ImapConnection
-    // TODO: reduce scope
-    DATA_IOE_ON_OPEN(Type.DATA_CHANNEL),
-    // The SELECT command on a mailbox is rejected
-    DATA_MAILBOX_OPEN_FAILED(Type.DATA_CHANNEL),
-    // An IOException has occurred
-    // TODO: reduce scope
-    DATA_GENERIC_IMAP_IOE(Type.DATA_CHANNEL),
-    // An SslException has occurred while opening an ImapConnection
-    // TODO: reduce scope
-    DATA_SSL_EXCEPTION(Type.DATA_CHANNEL),
-
-    // Notification Channel
-
-    // Cell signal restored, can received VVM SMSs
-    NOTIFICATION_IN_SERVICE(Type.NOTIFICATION_CHANNEL, true),
-    // Cell signal lost, cannot received VVM SMSs
-    NOTIFICATION_SERVICE_LOST(Type.NOTIFICATION_CHANNEL, false),
-
-
-    // Other
-    OTHER_SOURCE_REMOVED(Type.OTHER, false),
-
-    // VVM3
-    VVM3_NEW_USER_SETUP_FAILED,
-    // Table 4. client internal error handling
-    VVM3_VMG_DNS_FAILURE,
-    VVM3_SPG_DNS_FAILURE,
-    VVM3_VMG_CONNECTION_FAILED,
-    VVM3_SPG_CONNECTION_FAILED,
-    VVM3_VMG_TIMEOUT,
-    VVM3_STATUS_SMS_TIMEOUT,
-
-    VVM3_SUBSCRIBER_PROVISIONED,
-    VVM3_SUBSCRIBER_BLOCKED,
-    VVM3_SUBSCRIBER_UNKNOWN;
-
-    public static class Type {
-
-        @Retention(RetentionPolicy.SOURCE)
-        @IntDef({CONFIGURATION, DATA_CHANNEL, NOTIFICATION_CHANNEL, OTHER})
-        public @interface Values {
-
-        }
-
-        public static final int CONFIGURATION = 1;
-        public static final int DATA_CHANNEL = 2;
-        public static final int NOTIFICATION_CHANNEL = 3;
-        public static final int OTHER = 4;
-    }
-
-    private final int mType;
-    private final boolean mIsSuccess;
-
-    OmtpEvents(int type, boolean isSuccess) {
-        mType = type;
-        mIsSuccess = isSuccess;
-    }
-
-    OmtpEvents(int type) {
-        mType = type;
-        mIsSuccess = false;
-    }
-
-    OmtpEvents() {
-        mType = Type.OTHER;
-        mIsSuccess = false;
-    }
-
-    @Type.Values
-    public int getType() {
-        return mType;
-    }
-
-    public boolean isSuccess() {
-        return mIsSuccess;
-    }
-
-}
diff --git a/src/com/android/phone/vvm/omtp/OmtpVvmCarrierConfigHelper.java b/src/com/android/phone/vvm/omtp/OmtpVvmCarrierConfigHelper.java
deleted file mode 100644
index 486b07c..0000000
--- a/src/com/android/phone/vvm/omtp/OmtpVvmCarrierConfigHelper.java
+++ /dev/null
@@ -1,453 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-package com.android.phone.vvm.omtp;
-
-import android.annotation.Nullable;
-import android.app.PendingIntent;
-import android.content.Context;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.os.Bundle;
-import android.os.PersistableBundle;
-import android.telecom.PhoneAccountHandle;
-import android.telephony.CarrierConfigManager;
-import android.telephony.SubscriptionManager;
-import android.telephony.TelephonyManager;
-import android.telephony.VisualVoicemailSmsFilterSettings;
-import android.text.TextUtils;
-import android.util.ArraySet;
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.phone.VoicemailStatus;
-import com.android.phone.vvm.omtp.protocol.VisualVoicemailProtocol;
-import com.android.phone.vvm.omtp.protocol.VisualVoicemailProtocolFactory;
-import com.android.phone.vvm.omtp.sms.StatusMessage;
-import com.android.phone.vvm.omtp.utils.PhoneAccountHandleConverter;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Set;
-
-/**
- * Manages carrier dependent visual voicemail configuration values. The primary source is the value
- * retrieved from CarrierConfigManager. If CarrierConfigManager does not provide the config
- * (KEY_VVM_TYPE_STRING is empty, or "hidden" configs), then the value hardcoded in telephony will
- * be used (in res/xml/vvm_config.xml)
- *
- * Hidden configs are new configs that are planned for future APIs, or miscellaneous settings that
- * may clutter CarrierConfigManager too much.
- *
- * The current hidden configs are: {@link #getSslPort()} {@link #getDisabledCapabilities()}
- */
-public class OmtpVvmCarrierConfigHelper {
-
-    private static final String TAG = "OmtpVvmCarrierCfgHlpr";
-
-    static final String KEY_VVM_TYPE_STRING = CarrierConfigManager.KEY_VVM_TYPE_STRING;
-    static final String KEY_VVM_DESTINATION_NUMBER_STRING =
-            CarrierConfigManager.KEY_VVM_DESTINATION_NUMBER_STRING;
-    static final String KEY_VVM_PORT_NUMBER_INT =
-            CarrierConfigManager.KEY_VVM_PORT_NUMBER_INT;
-    static final String KEY_CARRIER_VVM_PACKAGE_NAME_STRING =
-            CarrierConfigManager.KEY_CARRIER_VVM_PACKAGE_NAME_STRING;
-    static final String KEY_CARRIER_VVM_PACKAGE_NAME_STRING_ARRAY =
-            "carrier_vvm_package_name_string_array";
-    static final String KEY_VVM_PREFETCH_BOOL =
-            CarrierConfigManager.KEY_VVM_PREFETCH_BOOL;
-    static final String KEY_VVM_CELLULAR_DATA_REQUIRED_BOOL =
-            CarrierConfigManager.KEY_VVM_CELLULAR_DATA_REQUIRED_BOOL;
-
-    /**
-     * @see #getSslPort()
-     */
-    static final String KEY_VVM_SSL_PORT_NUMBER_INT =
-            "vvm_ssl_port_number_int";
-
-    /**
-     * @see #isLegacyModeEnabled()
-     */
-    static final String KEY_VVM_LEGACY_MODE_ENABLED_BOOL =
-            "vvm_legacy_mode_enabled_bool";
-
-    /**
-     * Ban a capability reported by the server from being used. The array of string should be a
-     * subset of the capabilities returned IMAP CAPABILITY command.
-     *
-     * @see #getDisabledCapabilities()
-     */
-    static final String KEY_VVM_DISABLED_CAPABILITIES_STRING_ARRAY =
-            "vvm_disabled_capabilities_string_array";
-    static final String KEY_VVM_CLIENT_PREFIX_STRING =
-            "vvm_client_prefix_string";
-
-    private final Context mContext;
-    private final int mSubId;
-    private final PersistableBundle mCarrierConfig;
-    private final String mVvmType;
-    private final VisualVoicemailProtocol mProtocol;
-    private final PersistableBundle mTelephonyConfig;
-
-    private PhoneAccountHandle mPhoneAccountHandle;
-
-    public OmtpVvmCarrierConfigHelper(Context context, int subId) {
-        mContext = context;
-        mSubId = subId;
-        mCarrierConfig = getCarrierConfig();
-
-        TelephonyManager telephonyManager =
-                (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
-        mTelephonyConfig = new TelephonyVvmConfigManager(context.getResources())
-                .getConfig(telephonyManager.getSimOperator(subId));
-
-        mVvmType = getVvmType();
-        mProtocol = VisualVoicemailProtocolFactory.create(mContext.getResources(), mVvmType);
-    }
-
-    public OmtpVvmCarrierConfigHelper(Context context, PhoneAccountHandle handle) {
-        this(context, PhoneAccountHandleConverter.toSubId(handle));
-        mPhoneAccountHandle = handle;
-    }
-
-    @VisibleForTesting
-    OmtpVvmCarrierConfigHelper(Context context, PersistableBundle carrierConfig,
-            PersistableBundle telephonyConfig) {
-        mContext = context;
-        mSubId = 0;
-        mCarrierConfig = carrierConfig;
-        mTelephonyConfig = telephonyConfig;
-        mVvmType = getVvmType();
-        mProtocol = VisualVoicemailProtocolFactory.create(mContext.getResources(), mVvmType);
-    }
-
-    public Context getContext() {
-        return mContext;
-    }
-
-    public int getSubId() {
-        return mSubId;
-    }
-
-    @Nullable
-    public PhoneAccountHandle getPhoneAccountHandle() {
-        if (mPhoneAccountHandle == null) {
-            mPhoneAccountHandle = PhoneAccountHandleConverter.fromSubId(mSubId);
-            if (mPhoneAccountHandle == null) {
-                VvmLog.e(TAG, "null phone account for subId " + mSubId);
-            }
-        }
-        return mPhoneAccountHandle;
-    }
-
-    /**
-     * return whether the carrier's visual voicemail is supported, with KEY_VVM_TYPE_STRING set as a
-     * known protocol.
-     */
-    public boolean isValid() {
-        return mProtocol != null;
-    }
-
-    @Nullable
-    public String getVvmType() {
-        return (String) getValue(KEY_VVM_TYPE_STRING);
-    }
-
-    @Nullable
-    public VisualVoicemailProtocol getProtocol() {
-        return mProtocol;
-    }
-
-    /**
-     * @returns arbitrary String stored in the config file. Used for protocol specific values.
-     */
-    @Nullable
-    public String getString(String key) {
-        return (String) getValue(key);
-    }
-
-    @Nullable
-    public Set<String> getCarrierVvmPackageNames() {
-        Set<String> names = getCarrierVvmPackageNames(mCarrierConfig);
-        if (names != null) {
-            return names;
-        }
-        return getCarrierVvmPackageNames(mTelephonyConfig);
-    }
-
-    private static Set<String> getCarrierVvmPackageNames(@Nullable PersistableBundle bundle) {
-        if (bundle == null) {
-            return null;
-        }
-        Set<String> names = new ArraySet<>();
-        if (bundle.containsKey(KEY_CARRIER_VVM_PACKAGE_NAME_STRING)) {
-            names.add(bundle.getString(KEY_CARRIER_VVM_PACKAGE_NAME_STRING));
-        }
-        if (bundle.containsKey(KEY_CARRIER_VVM_PACKAGE_NAME_STRING_ARRAY)) {
-            String[] vvmPackages = bundle.getStringArray(KEY_CARRIER_VVM_PACKAGE_NAME_STRING_ARRAY);
-            if (vvmPackages != null && vvmPackages.length > 0) {
-                names.addAll(Arrays.asList(
-                        bundle.getStringArray(KEY_CARRIER_VVM_PACKAGE_NAME_STRING_ARRAY)));
-            }
-        }
-        if (names.isEmpty()) {
-            return null;
-        }
-        return names;
-    }
-
-    /**
-     * For checking upon sim insertion whether visual voicemail should be enabled. This method does
-     * so by checking if the carrier's voicemail app is installed.
-     */
-    public boolean isEnabledByDefault() {
-        if (!isValid()) {
-            return false;
-        }
-
-        Set<String> carrierPackages = getCarrierVvmPackageNames();
-        if (carrierPackages == null) {
-            return true;
-        }
-        for (String packageName : carrierPackages) {
-            try {
-                mContext.getPackageManager().getPackageInfo(packageName, 0);
-                return false;
-            } catch (NameNotFoundException e) {
-                // Do nothing.
-            }
-        }
-        return true;
-    }
-
-    public boolean isCellularDataRequired() {
-        return (boolean) getValue(KEY_VVM_CELLULAR_DATA_REQUIRED_BOOL, false);
-    }
-
-    public boolean isPrefetchEnabled() {
-        return (boolean) getValue(KEY_VVM_PREFETCH_BOOL, true);
-    }
-
-
-    public int getApplicationPort() {
-        return (int) getValue(KEY_VVM_PORT_NUMBER_INT, 0);
-    }
-
-    @Nullable
-    public String getDestinationNumber() {
-        return (String) getValue(KEY_VVM_DESTINATION_NUMBER_STRING);
-    }
-
-    /**
-     * Hidden config.
-     *
-     * @return Port to start a SSL IMAP connection directly.
-     *
-     * TODO: make config public and add to CarrierConfigManager
-     */
-    public int getSslPort() {
-        return (int) getValue(KEY_VVM_SSL_PORT_NUMBER_INT, 0);
-    }
-
-    /**
-     * Hidden Config.
-     *
-     * <p>Sometimes the server states it supports a certain feature but we found they have bug on
-     * the server side. For example, in b/28717550 the server reported AUTH=DIGEST-MD5 capability
-     * but using it to login will cause subsequent response to be erroneous.
-     *
-     * @return A set of capabilities that is reported by the IMAP CAPABILITY command, but determined
-     * to have issues and should not be used.
-     */
-    @Nullable
-    public Set<String> getDisabledCapabilities() {
-        Set<String> disabledCapabilities = getDisabledCapabilities(mCarrierConfig);
-        if (disabledCapabilities != null) {
-            return disabledCapabilities;
-        }
-        return getDisabledCapabilities(mTelephonyConfig);
-    }
-
-    @Nullable
-    private static Set<String> getDisabledCapabilities(@Nullable PersistableBundle bundle) {
-        if (bundle == null) {
-            return null;
-        }
-        if (!bundle.containsKey(KEY_VVM_DISABLED_CAPABILITIES_STRING_ARRAY)) {
-            return null;
-        }
-        String[] disabledCapabilities =
-                bundle.getStringArray(KEY_VVM_DISABLED_CAPABILITIES_STRING_ARRAY);
-        if (disabledCapabilities != null && disabledCapabilities.length > 0) {
-            ArraySet<String> result = new ArraySet<>();
-            Collections.addAll(result, disabledCapabilities);
-            return result;
-        }
-        return null;
-    }
-
-    public String getClientPrefix() {
-        String prefix = (String) getValue(KEY_VVM_CLIENT_PREFIX_STRING);
-        if (prefix != null) {
-            return prefix;
-        }
-        return "//VVM";
-    }
-
-    /**
-     * Should legacy mode be used when the OMTP VVM client is disabled?
-     *
-     * <p>Legacy mode is a mode that on the carrier side visual voicemail is still activated, but on
-     * the client side all network operations are disabled. SMSs are still monitored so a new
-     * message SYNC SMS will be translated to show a message waiting indicator, like traditional
-     * voicemails.
-     *
-     * <p>This is for carriers that does not support VVM deactivation so voicemail can continue to
-     * function without the data cost.
-     */
-    public boolean isLegacyModeEnabled() {
-        return (boolean) getValue(KEY_VVM_LEGACY_MODE_ENABLED_BOOL, false);
-    }
-
-    public void startActivation() {
-        PhoneAccountHandle phoneAccountHandle = getPhoneAccountHandle();
-        if (phoneAccountHandle == null) {
-            // This should never happen
-            // Error logged in getPhoneAccountHandle().
-            return;
-        }
-
-        if (mVvmType == null || mVvmType.isEmpty()) {
-            // The VVM type is invalid; we should never have gotten here in the first place since
-            // this is loaded initially in the constructor, and callers should check isValid()
-            // before trying to start activation anyways.
-            VvmLog.e(TAG, "startActivation : vvmType is null or empty for account " +
-                    phoneAccountHandle);
-            return;
-        }
-
-        activateSmsFilter();
-
-        if (mProtocol != null) {
-            ActivationTask.start(mContext, mSubId, null);
-        }
-    }
-
-    public void activateSmsFilter() {
-        TelephonyManager telephonyManager = mContext.getSystemService(TelephonyManager.class);
-        telephonyManager.enableVisualVoicemailSmsFilter(mSubId,
-                new VisualVoicemailSmsFilterSettings.Builder().setClientPrefix(getClientPrefix())
-                        .build());
-    }
-
-    public void startDeactivation() {
-        if (!isLegacyModeEnabled()) {
-            // SMS should still be filtered in legacy mode
-            mContext.getSystemService(TelephonyManager.class)
-                    .disableVisualVoicemailSmsFilter(mSubId);
-        }
-        if (mProtocol != null) {
-            mProtocol.startDeactivation(this);
-        }
-    }
-
-    public boolean supportsProvisioning() {
-        if (mProtocol != null) {
-            return mProtocol.supportsProvisioning();
-        }
-        return false;
-    }
-
-    public void startProvisioning(ActivationTask task, PhoneAccountHandle phone,
-        VoicemailStatus.Editor status, StatusMessage message, Bundle data) {
-        if (mProtocol != null) {
-            mProtocol.startProvisioning(task, phone, this, status, message, data);
-        }
-    }
-
-    public void requestStatus(@Nullable PendingIntent sentIntent) {
-        if (mProtocol != null) {
-            mProtocol.requestStatus(this, sentIntent);
-        }
-    }
-
-    public void handleEvent(VoicemailStatus.Editor status, OmtpEvents event) {
-        VvmLog.i(TAG, "OmtpEvent:" + event);
-        if (mProtocol != null) {
-            mProtocol.handleEvent(mContext, this, status, event);
-        }
-    }
-
-    @Override
-    public String toString() {
-        StringBuilder builder = new StringBuilder("OmtpVvmCarrierConfigHelper [");
-        builder.append("subId: ").append(getSubId())
-                .append(", carrierConfig: ").append(mCarrierConfig != null)
-                .append(", telephonyConfig: ").append(mTelephonyConfig != null)
-                .append(", type: ").append(getVvmType())
-                .append(", destinationNumber: ").append(getDestinationNumber())
-                .append(", applicationPort: ").append(getApplicationPort())
-                .append(", sslPort: ").append(getSslPort())
-                .append(", isEnabledByDefault: ").append(isEnabledByDefault())
-                .append(", isCellularDataRequired: ").append(isCellularDataRequired())
-                .append(", isPrefetchEnabled: ").append(isPrefetchEnabled())
-                .append(", isLegacyModeEnabled: ").append(isLegacyModeEnabled())
-                .append("]");
-        return builder.toString();
-    }
-
-    @Nullable
-    private PersistableBundle getCarrierConfig() {
-        if (!SubscriptionManager.isValidSubscriptionId(mSubId)) {
-            VvmLog
-                    .w(TAG, "Invalid subscriptionId or subscriptionId not provided in intent.");
-            return null;
-        }
-
-        CarrierConfigManager carrierConfigManager = (CarrierConfigManager)
-                mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE);
-        if (carrierConfigManager == null) {
-            VvmLog.w(TAG, "No carrier config service found.");
-            return null;
-        }
-
-        PersistableBundle config = carrierConfigManager.getConfigForSubId(mSubId);
-
-        if (TextUtils.isEmpty(config.getString(CarrierConfigManager.KEY_VVM_TYPE_STRING))) {
-            return null;
-        }
-        return config;
-    }
-
-    @Nullable
-    private Object getValue(String key) {
-        return getValue(key, null);
-    }
-
-    @Nullable
-    private Object getValue(String key, Object defaultValue) {
-        Object result;
-        if (mCarrierConfig != null) {
-            result = mCarrierConfig.get(key);
-            if (result != null) {
-                return result;
-            }
-        }
-        if (mTelephonyConfig != null) {
-            result = mTelephonyConfig.get(key);
-            if (result != null) {
-                return result;
-            }
-        }
-        return defaultValue;
-    }
-
-}
\ No newline at end of file
diff --git a/src/com/android/phone/vvm/omtp/SimChangeReceiver.java b/src/com/android/phone/vvm/omtp/SimChangeReceiver.java
deleted file mode 100644
index fb8f02d..0000000
--- a/src/com/android/phone/vvm/omtp/SimChangeReceiver.java
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-package com.android.phone.vvm.omtp;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.IPackageManager;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.os.UserManager;
-import android.telecom.PhoneAccountHandle;
-import android.telephony.CarrierConfigManager;
-import android.telephony.ServiceState;
-import android.telephony.SubscriptionManager;
-import android.telephony.TelephonyManager;
-import android.text.TextUtils;
-
-import com.android.internal.telephony.IccCardConstants;
-import com.android.internal.telephony.PhoneConstants;
-import com.android.internal.telephony.TelephonyIntents;
-import com.android.phone.settings.VisualVoicemailSettingsUtil;
-import com.android.phone.vvm.RemoteVvmTaskManager;
-import com.android.phone.vvm.omtp.sync.OmtpVvmSourceManager;
-import com.android.phone.vvm.omtp.utils.PhoneAccountHandleConverter;
-
-/**
- * This class listens to the {@link CarrierConfigManager#ACTION_CARRIER_CONFIG_CHANGED} and {@link
- * TelephonyIntents#ACTION_SIM_STATE_CHANGED} to determine when a SIM is added, replaced, or
- * removed.
- *
- * When a SIM is added, send an activate SMS. When a SIM is removed, remove the sync accounts and
- * change the status in the voicemail_status table.
- */
-public class SimChangeReceiver extends BroadcastReceiver {
-
-    private static final String TAG = "VvmSimChangeReceiver";
-
-    @Override
-    public void onReceive(Context context, Intent intent) {
-        final String action = intent.getAction();
-        if (action == null) {
-            VvmLog.w(TAG, "Null action for intent.");
-            return;
-        }
-
-        int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY,
-                SubscriptionManager.INVALID_SUBSCRIPTION_ID);
-
-        if (!SubscriptionManager.isValidSubscriptionId(subId)) {
-            VvmLog.i(TAG, "Received SIM change for invalid subscription id.");
-            return;
-        }
-
-        if (RemoteVvmTaskManager.hasRemoteService(context, subId)) {
-            return;
-        }
-
-        switch (action) {
-            case TelephonyIntents.ACTION_SIM_STATE_CHANGED:
-                if (IccCardConstants.INTENT_VALUE_ICC_ABSENT.equals(
-                        intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE))) {
-                    VvmLog.i(TAG, "Sim removed, removing inactive accounts");
-                    OmtpVvmSourceManager.getInstance(context).removeInactiveSources();
-                }
-                break;
-            case CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED:
-
-
-                TelephonyManager telephonyManager = context
-                        .getSystemService(TelephonyManager.class);
-                if(TextUtils.isEmpty(telephonyManager.getSimOperator())){
-                    VvmLog.e(TAG,
-                            "Empty MCCMNC, possible modem crash."
-                                    + " Ignoring carrier config changed event");
-                    return;
-                }
-
-                PhoneAccountHandle phoneAccountHandle = PhoneAccountHandleConverter
-                        .fromSubId(subId);
-                if("null".equals(phoneAccountHandle.getId())){
-                    VvmLog.e(TAG,
-                            "null phone account handle ID, possible modem crash."
-                                    + " Ignoring carrier config changed event");
-                    return;
-                }
-
-                VvmLog.d(TAG, "Carrier config changed");
-
-                if (UserManager.get(context).isUserUnlocked() && !isCryptKeeperMode()) {
-                    processSubId(context, subId);
-                } else {
-                    VvmLog.d(TAG, "User locked, activation request delayed until unlock");
-                    // After the device is unlocked, VvmBootCompletedReceiver will iterate through
-                    // all call capable subIds, nothing need to be done here.
-                }
-                break;
-        }
-    }
-
-    public static void processSubId(Context context, int subId) {
-        PhoneAccountHandle phoneAccount = PhoneAccountHandleConverter.fromSubId(subId);
-        if (phoneAccount == null) {
-            // This should never happen
-            VvmLog.e(TAG, "unable to convert subId " + subId + " to PhoneAccountHandle");
-            return;
-        }
-
-        OmtpVvmCarrierConfigHelper carrierConfigHelper =
-                new OmtpVvmCarrierConfigHelper(context, subId);
-        if (carrierConfigHelper.isValid()) {
-            if (VisualVoicemailSettingsUtil.isEnabled(context, phoneAccount)) {
-                VvmLog.i(TAG, "Sim state or carrier config changed for " + subId);
-                // Add a phone state listener so that changes to the communication channels
-                // can be recorded.
-                OmtpVvmSourceManager.getInstance(context).addPhoneStateListener(
-                        phoneAccount);
-                if (context.getSystemService(TelephonyManager.class)
-                        .getServiceStateForSubscriber(subId).getState()
-                        != ServiceState.STATE_IN_SERVICE) {
-                    VvmLog.i(TAG, "Cellular signal not available, not activating");
-                    return;
-                }
-                carrierConfigHelper.startActivation();
-            } else {
-                if (carrierConfigHelper.isLegacyModeEnabled()) {
-                    // SMS still need to be filtered under legacy mode.
-                    VvmLog.i(TAG, "activating SMS filter for legacy mode");
-                    carrierConfigHelper.activateSmsFilter();
-                }
-                // It may be that the source was not registered to begin with but we want
-                // to run through the steps to remove the source just in case.
-                OmtpVvmSourceManager.getInstance(context).removeSource(phoneAccount);
-                VvmLog.v(TAG, "Sim change for disabled account.");
-            }
-        } else {
-            String mccMnc = context.getSystemService(TelephonyManager.class).getSimOperator(subId);
-            VvmLog.d(TAG,
-                    "visual voicemail not supported for carrier " + mccMnc + " on subId " + subId);
-            OmtpVvmSourceManager.getInstance(context).removeSource(phoneAccount);
-        }
-    }
-
-    /**
-     * CryptKeeper mode is the pre-file based encryption locked state, when the user has selected
-     * "Require password to boot" and the device hasn't been unlocked yet during a reboot. {@link
-     * UserManager#isUserUnlocked()} will still return true in this mode, but storage in /data and
-     * all content providers will not be available(including SharedPreference).
-     */
-    private static boolean isCryptKeeperMode() {
-        try {
-            return IPackageManager.Stub.asInterface(ServiceManager.getService("package")).
-                    isOnlyCoreApps();
-        } catch (RemoteException e) {
-        }
-        return false;
-    }
-}
\ No newline at end of file
diff --git a/src/com/android/phone/vvm/omtp/TelephonyVvmConfigManager.java b/src/com/android/phone/vvm/omtp/TelephonyVvmConfigManager.java
deleted file mode 100644
index e91481e..0000000
--- a/src/com/android/phone/vvm/omtp/TelephonyVvmConfigManager.java
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.phone.vvm.omtp;
-
-import android.annotation.Nullable;
-import android.content.res.Resources;
-import android.os.PersistableBundle;
-import android.util.ArrayMap;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.phone.R;
-import com.android.phone.vvm.omtp.utils.XmlUtils;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Map;
-import java.util.Map.Entry;
-
-/**
- * Load and caches telephony vvm config from res/xml/vvm_config.xml
- */
-public class TelephonyVvmConfigManager {
-
-    private static final String TAG = "TelephonyVvmCfgMgr";
-
-    private static final boolean USE_DEBUG_CONFIG = false; //STOPSHIP if true
-
-    private static final String TAG_PERSISTABLEMAP = "pbundle_as_map";
-
-    static final String KEY_MCCMNC = "mccmnc";
-
-    private static Map<String, PersistableBundle> sCachedConfigs;
-
-    private final Map<String, PersistableBundle> mConfigs;
-
-    public TelephonyVvmConfigManager(Resources resources) {
-        if (sCachedConfigs == null) {
-            sCachedConfigs = loadConfigs(resources.getXml(R.xml.vvm_config));
-        }
-        mConfigs = sCachedConfigs;
-    }
-
-    @VisibleForTesting
-    TelephonyVvmConfigManager(XmlPullParser parser) {
-        mConfigs = loadConfigs(parser);
-    }
-
-    @Nullable
-    public PersistableBundle getConfig(String mccMnc) {
-        if (USE_DEBUG_CONFIG) {
-            return mConfigs.get("TEST");
-        }
-        return mConfigs.get(mccMnc);
-    }
-
-    private static Map<String, PersistableBundle> loadConfigs(XmlPullParser parser) {
-        Map<String, PersistableBundle> configs = new ArrayMap<>();
-        try {
-            ArrayList list = readBundleList(parser);
-            for (Object object : list) {
-                if (!(object instanceof PersistableBundle)) {
-                    throw new IllegalArgumentException("PersistableBundle expected, got " + object);
-                }
-                PersistableBundle bundle = (PersistableBundle) object;
-                String[] mccMncs = bundle.getStringArray(KEY_MCCMNC);
-                if (mccMncs == null) {
-                    throw new IllegalArgumentException("MCCMNC is null");
-                }
-                for (String mccMnc : mccMncs) {
-                    configs.put(mccMnc, bundle);
-                }
-            }
-        } catch (IOException | XmlPullParserException e) {
-            throw new RuntimeException(e);
-        }
-        return configs;
-    }
-
-    @Nullable
-    public static ArrayList readBundleList(XmlPullParser in) throws IOException,
-            XmlPullParserException {
-        final int outerDepth = in.getDepth();
-        int event;
-        while (((event = in.next()) != XmlPullParser.END_DOCUMENT) &&
-                (event != XmlPullParser.END_TAG || in.getDepth() < outerDepth)) {
-            if (event == XmlPullParser.START_TAG) {
-                final String startTag = in.getName();
-                final String[] tagName = new String[1];
-                in.next();
-                return XmlUtils.readThisListXml(in, startTag, tagName,
-                        new MyReadMapCallback(), false);
-            }
-        }
-        return null;
-    }
-
-    public static PersistableBundle restoreFromXml(XmlPullParser in) throws IOException,
-            XmlPullParserException {
-        final int outerDepth = in.getDepth();
-        final String startTag = in.getName();
-        final String[] tagName = new String[1];
-        int event;
-        while (((event = in.next()) != XmlPullParser.END_DOCUMENT) &&
-                (event != XmlPullParser.END_TAG || in.getDepth() < outerDepth)) {
-            if (event == XmlPullParser.START_TAG) {
-                ArrayMap<String, ?> map =
-                        XmlUtils.readThisArrayMapXml(in, startTag, tagName,
-                                new MyReadMapCallback());
-                PersistableBundle result = new PersistableBundle();
-                for (Entry<String, ?> entry : map.entrySet()) {
-                    Object value = entry.getValue();
-                    if (value instanceof Integer) {
-                        result.putInt(entry.getKey(), (int) value);
-                    } else if (value instanceof Boolean) {
-                        result.putBoolean(entry.getKey(), (boolean) value);
-                    } else if (value instanceof String) {
-                        result.putString(entry.getKey(), (String) value);
-                    } else if (value instanceof String[]) {
-                        result.putStringArray(entry.getKey(), (String[]) value);
-                    } else if (value instanceof PersistableBundle) {
-                        result.putPersistableBundle(entry.getKey(), (PersistableBundle) value);
-                    }
-                }
-                return result;
-            }
-        }
-        return PersistableBundle.EMPTY;
-    }
-
-    static class MyReadMapCallback implements XmlUtils.ReadMapCallback {
-
-        @Override
-        public Object readThisUnknownObjectXml(XmlPullParser in, String tag)
-                throws XmlPullParserException, IOException {
-            if (TAG_PERSISTABLEMAP.equals(tag)) {
-                return restoreFromXml(in);
-            }
-            throw new XmlPullParserException("Unknown tag=" + tag);
-        }
-    }
-}
diff --git a/src/com/android/phone/vvm/omtp/VvmBootCompletedReceiver.java b/src/com/android/phone/vvm/omtp/VvmBootCompletedReceiver.java
deleted file mode 100644
index f725f96..0000000
--- a/src/com/android/phone/vvm/omtp/VvmBootCompletedReceiver.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.phone.vvm.omtp;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.telecom.PhoneAccountHandle;
-import android.telecom.TelecomManager;
-import android.telephony.SubscriptionManager;
-
-import com.android.phone.vvm.RemoteVvmTaskManager;
-import com.android.phone.vvm.omtp.utils.PhoneAccountHandleConverter;
-
-/**
- * Upon boot iterate through all callable phone account to activate visual voicemail. This happens
- * after the device has been unlocked. {@link android.telephony.CarrierConfigManager#
- * ACTION_CARRIER_CONFIG_CHANGED} can also trigger activation upon boot but it can happen before the
- * device is unlocked and visual voicemail will not be activated.
- *
- * <p>TODO: An additional duplicated activation request will be sent as a result of this receiver,
- * but similar issues is already covered in b/28730056 and a scheduling system should be used to
- * resolve this.
- */
-public class VvmBootCompletedReceiver extends BroadcastReceiver {
-
-    private static final String TAG = "VvmBootCompletedRcvr";
-
-    @Override
-    public void onReceive(Context context, Intent intent) {
-        // Listens to android.intent.action.BOOT_COMPLETED
-        if (!intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) {
-            return;
-        }
-
-        VvmLog.v(TAG, "processing subId list");
-        for (PhoneAccountHandle handle : TelecomManager.from(context)
-                .getCallCapablePhoneAccounts()) {
-            int subId = PhoneAccountHandleConverter.toSubId(handle);
-            if (!SubscriptionManager.isValidSubscriptionId(subId)) {
-                // getCallCapablePhoneAccounts() might return a PhoneAccountHandle with invalid
-                // subId if no SIM is inserted. This is intended as it is for emergency calls.
-                VvmLog.e(TAG, "phone account " + handle + " has invalid subId " + subId);
-                continue;
-            }
-            if (RemoteVvmTaskManager.hasRemoteService(context, subId)) {
-                return;
-            }
-
-            VvmLog.v(TAG, "processing subId " + subId);
-            SimChangeReceiver.processSubId(context, subId);
-        }
-    }
-}
diff --git a/src/com/android/phone/vvm/omtp/VvmPackageInstallReceiver.java b/src/com/android/phone/vvm/omtp/VvmPackageInstallReceiver.java
deleted file mode 100644
index 7c20065..0000000
--- a/src/com/android/phone/vvm/omtp/VvmPackageInstallReceiver.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-package com.android.phone.vvm.omtp;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.telecom.PhoneAccountHandle;
-
-import com.android.phone.PhoneUtils;
-import com.android.phone.settings.VisualVoicemailSettingsUtil;
-import com.android.phone.vvm.omtp.sync.OmtpVvmSourceManager;
-
-import java.util.Set;
-
-/**
- * When a new package is installed, check if it matches any of the vvm carrier apps of the currently
- * enabled dialer vvm sources.
- */
-public class VvmPackageInstallReceiver extends BroadcastReceiver {
-
-    private static final String TAG = "VvmPkgInstallReceiver";
-
-    @Override
-    public void onReceive(Context context, Intent intent) {
-        if (intent.getData() == null) {
-            return;
-        }
-
-        String packageName = intent.getData().getSchemeSpecificPart();
-        if (packageName == null) {
-            return;
-        }
-
-        OmtpVvmSourceManager vvmSourceManager = OmtpVvmSourceManager.getInstance(context);
-        Set<PhoneAccountHandle> phoneAccounts = vvmSourceManager.getOmtpVvmSources();
-        for (PhoneAccountHandle phoneAccount : phoneAccounts) {
-            if (VisualVoicemailSettingsUtil.isEnabledUserSet(context, phoneAccount)) {
-                // Skip the check if this voicemail source's setting is overridden by the user.
-                continue;
-            }
-
-            OmtpVvmCarrierConfigHelper carrierConfigHelper = new OmtpVvmCarrierConfigHelper(
-                    context, PhoneUtils.getSubIdForPhoneAccountHandle(phoneAccount));
-            if (carrierConfigHelper.getCarrierVvmPackageNames() == null) {
-                continue;
-            }
-            if (carrierConfigHelper.getCarrierVvmPackageNames().contains(packageName)) {
-                // Force deactivate the client. The user can re-enable it in the settings.
-                // There are no need to update the settings for deactivation. At this point, if the
-                // default value is used it should be false because a carrier package is present.
-                VvmLog.i(TAG, "Carrier VVM package installed, disabling system VVM client");
-                OmtpVvmSourceManager.getInstance(context).removeSource(phoneAccount);
-                carrierConfigHelper.startDeactivation();
-            }
-        }
-    }
-}
diff --git a/src/com/android/phone/vvm/omtp/VvmPhoneStateListener.java b/src/com/android/phone/vvm/omtp/VvmPhoneStateListener.java
deleted file mode 100644
index 75ffc71..0000000
--- a/src/com/android/phone/vvm/omtp/VvmPhoneStateListener.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-package com.android.phone.vvm.omtp;
-
-import android.content.Context;
-import android.telecom.PhoneAccountHandle;
-import android.telephony.PhoneStateListener;
-import android.telephony.ServiceState;
-import android.telephony.SubscriptionManager;
-
-import com.android.phone.PhoneUtils;
-import com.android.phone.VoicemailStatus;
-import com.android.phone.vvm.RemoteVvmTaskManager;
-import com.android.phone.vvm.omtp.sync.OmtpVvmSourceManager;
-import com.android.phone.vvm.omtp.sync.OmtpVvmSyncService;
-import com.android.phone.vvm.omtp.sync.SyncTask;
-import com.android.phone.vvm.omtp.sync.VoicemailStatusQueryHelper;
-import com.android.phone.vvm.omtp.utils.PhoneAccountHandleConverter;
-
-/**
- * Check if service is lost and indicate this in the voicemail status.
- */
-public class VvmPhoneStateListener extends PhoneStateListener {
-
-    private static final String TAG = "VvmPhoneStateListener";
-
-    private PhoneAccountHandle mPhoneAccount;
-    private Context mContext;
-    private int mPreviousState = -1;
-
-    public VvmPhoneStateListener(Context context, PhoneAccountHandle accountHandle) {
-        super(PhoneUtils.getSubIdForPhoneAccountHandle(accountHandle));
-        mContext = context;
-        mPhoneAccount = accountHandle;
-    }
-
-    @Override
-    public void onServiceStateChanged(ServiceState serviceState) {
-        int subId = PhoneAccountHandleConverter.toSubId(mPhoneAccount);
-        if (!SubscriptionManager.isValidSubscriptionId(subId)) {
-            VvmLog.e(TAG, "onServiceStateChanged on phoneAccount " + mPhoneAccount
-                    + " with invalid subId, ignoring");
-            return;
-        }
-
-        if (RemoteVvmTaskManager.hasRemoteService(mContext, subId)) {
-            return;
-        }
-
-        int state = serviceState.getState();
-        if (state == mPreviousState || (state != ServiceState.STATE_IN_SERVICE
-                && mPreviousState != ServiceState.STATE_IN_SERVICE)) {
-            // Only interested in state changes or transitioning into or out of "in service".
-            // Otherwise just quit.
-            mPreviousState = state;
-            return;
-        }
-
-        OmtpVvmCarrierConfigHelper helper = new OmtpVvmCarrierConfigHelper(mContext, subId);
-
-        if (state == ServiceState.STATE_IN_SERVICE) {
-
-            VoicemailStatusQueryHelper voicemailStatusQueryHelper =
-                    new VoicemailStatusQueryHelper(mContext);
-            if (voicemailStatusQueryHelper.isVoicemailSourceConfigured(mPhoneAccount)) {
-                if (!voicemailStatusQueryHelper.isNotificationsChannelActive(mPhoneAccount)) {
-                    VvmLog
-                            .v(TAG, "Notifications channel is active for " + subId);
-                    helper.handleEvent(VoicemailStatus.edit(mContext, mPhoneAccount),
-                        OmtpEvents.NOTIFICATION_IN_SERVICE);
-                }
-            }
-
-            if (OmtpVvmSourceManager.getInstance(mContext).isVvmSourceRegistered(mPhoneAccount)) {
-                VvmLog
-                        .v(TAG, "Signal returned: requesting resync for " + subId);
-                // If the source is already registered, run a full sync in case something was missed
-                // while signal was down.
-                SyncTask.start(mContext, mPhoneAccount, OmtpVvmSyncService.SYNC_FULL_SYNC);
-            } else {
-                VvmLog.v(TAG,
-                        "Signal returned: reattempting activation for " + subId);
-                // Otherwise initiate an activation because this means that an OMTP source was
-                // recognized but either the activation text was not successfully sent or a response
-                // was not received.
-                helper.startActivation();
-            }
-        } else {
-            VvmLog.v(TAG, "Notifications channel is inactive for " + subId);
-
-            if (!OmtpVvmSourceManager.getInstance(mContext).isVvmSourceRegistered(mPhoneAccount)) {
-                return;
-            }
-            helper.handleEvent(VoicemailStatus.edit(mContext, mPhoneAccount),
-                OmtpEvents.NOTIFICATION_SERVICE_LOST);
-        }
-        mPreviousState = state;
-    }
-}
diff --git a/src/com/android/phone/vvm/omtp/fetch/FetchVoicemailReceiver.java b/src/com/android/phone/vvm/omtp/fetch/FetchVoicemailReceiver.java
deleted file mode 100644
index 9bda638..0000000
--- a/src/com/android/phone/vvm/omtp/fetch/FetchVoicemailReceiver.java
+++ /dev/null
@@ -1,215 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-package com.android.phone.vvm.omtp.fetch;
-
-import android.annotation.Nullable;
-import android.content.BroadcastReceiver;
-import android.content.ComponentName;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.Intent;
-import android.database.Cursor;
-import android.net.ConnectivityManager;
-import android.net.Network;
-import android.net.NetworkRequest;
-import android.net.Uri;
-import android.provider.VoicemailContract;
-import android.provider.VoicemailContract.Voicemails;
-import android.telecom.PhoneAccountHandle;
-import android.telephony.TelephonyManager;
-import android.text.TextUtils;
-import com.android.internal.telephony.Phone;
-import com.android.phone.PhoneUtils;
-import com.android.phone.VoicemailStatus;
-import com.android.phone.vvm.omtp.OmtpVvmCarrierConfigHelper;
-import com.android.phone.vvm.omtp.VvmLog;
-import com.android.phone.vvm.omtp.imap.ImapHelper;
-import com.android.phone.vvm.omtp.imap.ImapHelper.InitializingException;
-import com.android.phone.vvm.omtp.sync.OmtpVvmSourceManager;
-import com.android.phone.vvm.omtp.sync.VvmNetworkRequestCallback;
-import java.util.concurrent.Executor;
-import java.util.concurrent.Executors;
-
-public class FetchVoicemailReceiver extends BroadcastReceiver {
-
-    private static final String TAG = "FetchVoicemailReceiver";
-
-    final static String[] PROJECTION = new String[]{
-            Voicemails.SOURCE_DATA,      // 0
-            Voicemails.PHONE_ACCOUNT_ID, // 1
-            Voicemails.PHONE_ACCOUNT_COMPONENT_NAME, // 2
-    };
-
-    public static final int SOURCE_DATA = 0;
-    public static final int PHONE_ACCOUNT_ID = 1;
-    public static final int PHONE_ACCOUNT_COMPONENT_NAME = 2;
-
-    // Timeout used to call ConnectivityManager.requestNetwork
-    private static final int NETWORK_REQUEST_TIMEOUT_MILLIS = 60 * 1000;
-
-    // Number of retries
-    private static final int NETWORK_RETRY_COUNT = 3;
-
-    private ContentResolver mContentResolver;
-    private Uri mUri;
-    private NetworkRequest mNetworkRequest;
-    private VvmNetworkRequestCallback mNetworkCallback;
-    private Context mContext;
-    private String mUid;
-    private ConnectivityManager mConnectivityManager;
-    private PhoneAccountHandle mPhoneAccount;
-    private int mRetryCount = NETWORK_RETRY_COUNT;
-
-    @Override
-    public void onReceive(final Context context, Intent intent) {
-        if (VoicemailContract.ACTION_FETCH_VOICEMAIL.equals(intent.getAction())) {
-            VvmLog.i(TAG, "ACTION_FETCH_VOICEMAIL received");
-            mContext = context;
-            mContentResolver = context.getContentResolver();
-            mUri = intent.getData();
-
-            if (mUri == null) {
-                VvmLog.w(TAG,
-                        VoicemailContract.ACTION_FETCH_VOICEMAIL + " intent sent with no data");
-                return;
-            }
-
-            if (!context.getPackageName().equals(
-                    mUri.getQueryParameter(VoicemailContract.PARAM_KEY_SOURCE_PACKAGE))) {
-                // Ignore if the fetch request is for a voicemail not from this package.
-                VvmLog.e(TAG,
-                        "ACTION_FETCH_VOICEMAIL from foreign pacakge " + context.getPackageName());
-                return;
-            }
-
-            Cursor cursor = mContentResolver.query(mUri, PROJECTION, null, null, null);
-            if (cursor == null) {
-                VvmLog.i(TAG, "ACTION_FETCH_VOICEMAIL query returned null");
-                return;
-            }
-            try {
-                if (cursor.moveToFirst()) {
-                    mUid = cursor.getString(SOURCE_DATA);
-                    String accountId = cursor.getString(PHONE_ACCOUNT_ID);
-                    if (TextUtils.isEmpty(accountId)) {
-                        TelephonyManager telephonyManager = (TelephonyManager)
-                                context.getSystemService(Context.TELEPHONY_SERVICE);
-                        accountId = telephonyManager.getSimSerialNumber();
-
-                        if (TextUtils.isEmpty(accountId)) {
-                            VvmLog.e(TAG, "Account null and no default sim found.");
-                            return;
-                        }
-                    }
-
-                    mPhoneAccount = new PhoneAccountHandle(
-                            ComponentName.unflattenFromString(
-                                    cursor.getString(PHONE_ACCOUNT_COMPONENT_NAME)),
-                            cursor.getString(PHONE_ACCOUNT_ID));
-                    if (!OmtpVvmSourceManager.getInstance(context)
-                            .isVvmSourceRegistered(mPhoneAccount)) {
-                        mPhoneAccount = getAccountFromMarshmallowAccount(context, mPhoneAccount);
-                        if (mPhoneAccount == null) {
-                            VvmLog.w(TAG, "Account not registered - cannot retrieve message.");
-                            return;
-                        }
-                        VvmLog.i(TAG, "Fetching voicemail with Marshmallow PhoneAccountHandle");
-                    }
-
-                    int subId = PhoneUtils.getSubIdForPhoneAccountHandle(mPhoneAccount);
-                    OmtpVvmCarrierConfigHelper carrierConfigHelper =
-                            new OmtpVvmCarrierConfigHelper(context, subId);
-                    VvmLog.i(TAG, "Requesting network to fetch voicemail");
-                    mNetworkCallback = new fetchVoicemailNetworkRequestCallback(context,
-                            mPhoneAccount);
-                    mNetworkCallback.requestNetwork();
-                }
-            } finally {
-                cursor.close();
-            }
-        }
-    }
-
-    /**
-     * In ag/930496 the format of PhoneAccountHandle has changed between Marshmallow and Nougat.
-     * This method attempts to search the account from the old database in registered sources using
-     * the old format. There's a chance of M phone account collisions on multi-SIM devices, but
-     * visual voicemail is not supported on M multi-SIM.
-     */
-    @Nullable
-    private static PhoneAccountHandle getAccountFromMarshmallowAccount(Context context,
-            PhoneAccountHandle oldAccount) {
-        for (PhoneAccountHandle handle : OmtpVvmSourceManager.getInstance(context)
-                .getOmtpVvmSources()) {
-            Phone phone = PhoneUtils.getPhoneForPhoneAccountHandle(handle);
-            if (phone == null) {
-                continue;
-            }
-            // getIccSerialNumber() is used for ID before N, and getFullIccSerialNumber() after.
-            if (phone.getIccSerialNumber().equals(oldAccount.getId())) {
-                return handle;
-            }
-        }
-        return null;
-    }
-
-    private class fetchVoicemailNetworkRequestCallback extends VvmNetworkRequestCallback {
-
-        public fetchVoicemailNetworkRequestCallback(Context context,
-                PhoneAccountHandle phoneAccount) {
-            super(context, phoneAccount, VoicemailStatus.edit(context, phoneAccount));
-        }
-
-        @Override
-        public void onAvailable(final Network network) {
-            super.onAvailable(network);
-            fetchVoicemail(network, getVoicemailStatusEditor());
-        }
-    }
-
-    private void fetchVoicemail(final Network network, final VoicemailStatus.Editor status) {
-        Executor executor = Executors.newCachedThreadPool();
-        executor.execute(new Runnable() {
-            @Override
-            public void run() {
-                try {
-                    while (mRetryCount > 0) {
-                        VvmLog.i(TAG, "fetching voicemail, retry count=" + mRetryCount);
-                        try (ImapHelper imapHelper = new ImapHelper(mContext, mPhoneAccount,
-                            network, status)) {
-                            boolean success = imapHelper.fetchVoicemailPayload(
-                                    new VoicemailFetchedCallback(mContext, mUri, mPhoneAccount),
-                                    mUid);
-                            if (!success && mRetryCount > 0) {
-                                VvmLog.i(TAG, "fetch voicemail failed, retrying");
-                                mRetryCount--;
-                            } else {
-                                return;
-                            }
-                        } catch (InitializingException e) {
-                          VvmLog.w(TAG, "Can't retrieve Imap credentials ", e);
-                            return;
-                        }
-                    }
-                } finally {
-                    if (mNetworkCallback != null) {
-                        mNetworkCallback.releaseNetwork();
-                    }
-                }
-            }
-        });
-    }
-}
diff --git a/src/com/android/phone/vvm/omtp/fetch/VoicemailFetchedCallback.java b/src/com/android/phone/vvm/omtp/fetch/VoicemailFetchedCallback.java
deleted file mode 100644
index e70ba49..0000000
--- a/src/com/android/phone/vvm/omtp/fetch/VoicemailFetchedCallback.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-package com.android.phone.vvm.omtp.fetch;
-
-import android.annotation.Nullable;
-import android.content.ContentResolver;
-import android.content.ContentValues;
-import android.content.Context;
-import android.net.Uri;
-import android.provider.VoicemailContract.Voicemails;
-import android.telecom.PhoneAccountHandle;
-import android.telecom.TelecomManager;
-import com.android.phone.R;
-import com.android.phone.vvm.omtp.VvmLog;
-import com.android.phone.vvm.omtp.imap.VoicemailPayload;
-import java.io.IOException;
-import java.io.OutputStream;
-import libcore.io.IoUtils;
-
-/**
- * Callback for when a voicemail payload is fetched. It copies the returned stream to the data
- * file corresponding to the voicemail.
- */
-public class VoicemailFetchedCallback {
-    private static final String TAG = "VoicemailFetchedCallback";
-
-    private final Context mContext;
-    private final ContentResolver mContentResolver;
-    private final Uri mUri;
-    private final PhoneAccountHandle mPhoneAccountHandle;
-
-    public VoicemailFetchedCallback(Context context, Uri uri,
-        PhoneAccountHandle phoneAccountHandle) {
-        mContext = context;
-        mContentResolver = context.getContentResolver();
-        mUri = uri;
-        mPhoneAccountHandle = phoneAccountHandle;
-    }
-
-    /**
-     * Saves the voicemail payload data into the voicemail provider then sets the "has_content" bit
-     * of the voicemail to "1".
-     *
-     * @param voicemailPayload The object containing the content data for the voicemail
-     */
-    public void setVoicemailContent(@Nullable VoicemailPayload voicemailPayload) {
-        if (voicemailPayload == null) {
-            VvmLog.i(TAG, "Payload not found, message has unsupported format");
-            ContentValues values = new ContentValues();
-            values.put(Voicemails.TRANSCRIPTION,
-                mContext.getString(R.string.vvm_unsupported_message_format,
-                    TelecomManager.from(mContext).getVoiceMailNumber(mPhoneAccountHandle)));
-            updateVoicemail(values);
-            return;
-        }
-
-        VvmLog.d(TAG, String.format("Writing new voicemail content: %s", mUri));
-        OutputStream outputStream = null;
-
-        try {
-            outputStream = mContentResolver.openOutputStream(mUri);
-            byte[] inputBytes = voicemailPayload.getBytes();
-            if (inputBytes != null) {
-                outputStream.write(inputBytes);
-            }
-        } catch (IOException e) {
-            VvmLog.w(TAG, String.format("File not found for %s", mUri));
-            return;
-        } finally {
-            IoUtils.closeQuietly(outputStream);
-        }
-
-        // Update mime_type & has_content after we are done with file update.
-        ContentValues values = new ContentValues();
-        values.put(Voicemails.MIME_TYPE, voicemailPayload.getMimeType());
-        values.put(Voicemails.HAS_CONTENT, true);
-        updateVoicemail(values);
-    }
-
-    private void updateVoicemail(ContentValues values) {
-        int updatedCount = mContentResolver.update(mUri, values, null, null);
-        if (updatedCount != 1) {
-            VvmLog
-                .e(TAG, "Updating voicemail should have updated 1 row, was: " + updatedCount);
-        }
-    }
-}
diff --git a/src/com/android/phone/vvm/omtp/imap/ImapHelper.java b/src/com/android/phone/vvm/omtp/imap/ImapHelper.java
deleted file mode 100644
index a03e421..0000000
--- a/src/com/android/phone/vvm/omtp/imap/ImapHelper.java
+++ /dev/null
@@ -1,705 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-package com.android.phone.vvm.omtp.imap;
-
-import android.content.Context;
-import android.net.ConnectivityManager;
-import android.net.Network;
-import android.net.NetworkInfo;
-import android.provider.VoicemailContract;
-import android.telecom.PhoneAccountHandle;
-import android.telecom.Voicemail;
-import android.util.Base64;
-import com.android.phone.PhoneUtils;
-import com.android.phone.VoicemailStatus;
-import com.android.phone.common.mail.Address;
-import com.android.phone.common.mail.Body;
-import com.android.phone.common.mail.BodyPart;
-import com.android.phone.common.mail.FetchProfile;
-import com.android.phone.common.mail.Flag;
-import com.android.phone.common.mail.Message;
-import com.android.phone.common.mail.MessagingException;
-import com.android.phone.common.mail.Multipart;
-import com.android.phone.common.mail.TempDirectory;
-import com.android.phone.common.mail.internet.MimeMessage;
-import com.android.phone.common.mail.store.ImapConnection;
-import com.android.phone.common.mail.store.ImapFolder;
-import com.android.phone.common.mail.store.ImapStore;
-import com.android.phone.common.mail.store.imap.ImapConstants;
-import com.android.phone.common.mail.store.imap.ImapResponse;
-import com.android.phone.common.mail.utils.LogUtils;
-import com.android.phone.vvm.omtp.OmtpConstants;
-import com.android.phone.vvm.omtp.OmtpConstants.ChangePinResult;
-import com.android.phone.vvm.omtp.OmtpEvents;
-import com.android.phone.vvm.omtp.OmtpVvmCarrierConfigHelper;
-import com.android.phone.vvm.omtp.VisualVoicemailPreferences;
-import com.android.phone.vvm.omtp.VvmLog;
-import com.android.phone.vvm.omtp.fetch.VoicemailFetchedCallback;
-import com.android.phone.vvm.omtp.sync.OmtpVvmSyncService.TranscriptionFetchedCallback;
-import java.io.BufferedOutputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.Closeable;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Locale;
-import libcore.io.IoUtils;
-
-/**
- * A helper interface to abstract commands sent across IMAP interface for a given account.
- */
-public class ImapHelper implements Closeable {
-
-    private static final String TAG = "ImapHelper";
-
-    private ImapFolder mFolder;
-    private ImapStore mImapStore;
-
-    private final Context mContext;
-    private final PhoneAccountHandle mPhoneAccount;
-    private final Network mNetwork;
-    private final VoicemailStatus.Editor mStatus;
-
-    VisualVoicemailPreferences mPrefs;
-    private static final String PREF_KEY_QUOTA_OCCUPIED = "quota_occupied_";
-    private static final String PREF_KEY_QUOTA_TOTAL = "quota_total_";
-
-    private int mQuotaOccupied;
-    private int mQuotaTotal;
-
-    private final OmtpVvmCarrierConfigHelper mConfig;
-
-    public class InitializingException extends Exception {
-
-        public InitializingException(String message) {
-            super(message);
-        }
-    }
-
-    public ImapHelper(Context context, PhoneAccountHandle phoneAccount, Network network,
-        VoicemailStatus.Editor status)
-        throws InitializingException {
-        this(context, new OmtpVvmCarrierConfigHelper(context,
-            PhoneUtils.getSubIdForPhoneAccountHandle(phoneAccount)), phoneAccount, network, status);
-    }
-
-    public ImapHelper(Context context, OmtpVvmCarrierConfigHelper config,
-        PhoneAccountHandle phoneAccount, Network network, VoicemailStatus.Editor status)
-        throws InitializingException {
-        mContext = context;
-        mPhoneAccount = phoneAccount;
-        mNetwork = network;
-        mStatus = status;
-        mConfig = config;
-        mPrefs = new VisualVoicemailPreferences(context,
-                phoneAccount);
-
-        try {
-            TempDirectory.setTempDirectory(context);
-
-            String username = mPrefs.getString(OmtpConstants.IMAP_USER_NAME, null);
-            String password = mPrefs.getString(OmtpConstants.IMAP_PASSWORD, null);
-            String serverName = mPrefs.getString(OmtpConstants.SERVER_ADDRESS, null);
-            int port = Integer.parseInt(
-                    mPrefs.getString(OmtpConstants.IMAP_PORT, null));
-            int auth = ImapStore.FLAG_NONE;
-
-            int sslPort = mConfig.getSslPort();
-            if (sslPort != 0) {
-                port = sslPort;
-                auth = ImapStore.FLAG_SSL;
-            }
-
-            mImapStore = new ImapStore(
-                    context, this, username, password, port, serverName, auth, network);
-        } catch (NumberFormatException e) {
-            handleEvent(OmtpEvents.DATA_INVALID_PORT);
-            LogUtils.w(TAG, "Could not parse port number");
-            throw new InitializingException("cannot initialize ImapHelper:" + e.toString());
-        }
-
-        mQuotaOccupied = mPrefs
-                .getInt(PREF_KEY_QUOTA_OCCUPIED, VoicemailContract.Status.QUOTA_UNAVAILABLE);
-        mQuotaTotal = mPrefs
-                .getInt(PREF_KEY_QUOTA_TOTAL, VoicemailContract.Status.QUOTA_UNAVAILABLE);
-    }
-
-    @Override
-    public void close() {
-        mImapStore.closeConnection();
-    }
-
-    public boolean isRoaming() {
-        ConnectivityManager connectivityManager = (ConnectivityManager) mContext.getSystemService(
-                Context.CONNECTIVITY_SERVICE);
-        NetworkInfo info = connectivityManager.getNetworkInfo(mNetwork);
-        if (info == null) {
-            return false;
-        }
-        return info.isRoaming();
-    }
-
-    public OmtpVvmCarrierConfigHelper getConfig() {
-        return mConfig;
-    }
-
-    public ImapConnection connect() {
-        return mImapStore.getConnection();
-    }
-
-    /**
-     * The caller thread will block until the method returns.
-     */
-    public boolean markMessagesAsRead(List<Voicemail> voicemails) {
-        return setFlags(voicemails, Flag.SEEN);
-    }
-
-    /**
-     * The caller thread will block until the method returns.
-     */
-    public boolean markMessagesAsDeleted(List<Voicemail> voicemails) {
-        return setFlags(voicemails, Flag.DELETED);
-    }
-
-    public void handleEvent(OmtpEvents event) {
-        mConfig.handleEvent(mStatus, event);
-    }
-
-    /**
-     * Set flags on the server for a given set of voicemails.
-     *
-     * @param voicemails The voicemails to set flags for.
-     * @param flags The flags to set on the voicemails.
-     * @return {@code true} if the operation completes successfully, {@code false} otherwise.
-     */
-    private boolean setFlags(List<Voicemail> voicemails, String... flags) {
-        if (voicemails.size() == 0) {
-            return false;
-        }
-        try {
-            mFolder = openImapFolder(ImapFolder.MODE_READ_WRITE);
-            if (mFolder != null) {
-                mFolder.setFlags(convertToImapMessages(voicemails), flags, true);
-                return true;
-            }
-            return false;
-        } catch (MessagingException e) {
-            LogUtils.e(TAG, e, "Messaging exception");
-            return false;
-        } finally {
-            closeImapFolder();
-        }
-    }
-
-    /**
-     * Fetch a list of voicemails from the server.
-     *
-     * @return A list of voicemail objects containing data about voicemails stored on the server.
-     */
-    public List<Voicemail> fetchAllVoicemails() {
-        List<Voicemail> result = new ArrayList<Voicemail>();
-        Message[] messages;
-        try {
-            mFolder = openImapFolder(ImapFolder.MODE_READ_WRITE);
-            if (mFolder == null) {
-                // This means we were unable to successfully open the folder.
-                return null;
-            }
-
-            // This method retrieves lightweight messages containing only the uid of the message.
-            messages = mFolder.getMessages(null);
-
-            for (Message message : messages) {
-                // Get the voicemail details (message structure).
-                MessageStructureWrapper messageStructureWrapper = fetchMessageStructure(message);
-                if (messageStructureWrapper != null) {
-                    result.add(getVoicemailFromMessageStructure(messageStructureWrapper));
-                }
-            }
-            return result;
-        } catch (MessagingException e) {
-            LogUtils.e(TAG, e, "Messaging Exception");
-            return null;
-        } finally {
-            closeImapFolder();
-        }
-    }
-
-    /**
-     * Extract voicemail details from the message structure. Also fetch transcription if a
-     * transcription exists.
-     */
-    private Voicemail getVoicemailFromMessageStructure(
-            MessageStructureWrapper messageStructureWrapper) throws MessagingException {
-        Message messageDetails = messageStructureWrapper.messageStructure;
-
-        TranscriptionFetchedListener listener = new TranscriptionFetchedListener();
-        if (messageStructureWrapper.transcriptionBodyPart != null) {
-            FetchProfile fetchProfile = new FetchProfile();
-            fetchProfile.add(messageStructureWrapper.transcriptionBodyPart);
-
-            mFolder.fetch(new Message[]{messageDetails}, fetchProfile, listener);
-        }
-
-        // Found an audio attachment, this is a valid voicemail.
-        long time = messageDetails.getSentDate().getTime();
-        String number = getNumber(messageDetails.getFrom());
-        boolean isRead = Arrays.asList(messageDetails.getFlags()).contains(Flag.SEEN);
-        return Voicemail.createForInsertion(time, number)
-                .setPhoneAccount(mPhoneAccount)
-                .setSourcePackage(mContext.getPackageName())
-                .setSourceData(messageDetails.getUid())
-                .setIsRead(isRead)
-                .setTranscription(listener.getVoicemailTranscription())
-                .build();
-    }
-
-    /**
-     * The "from" field of a visual voicemail IMAP message is the number of the caller who left the
-     * message. Extract this number from the list of "from" addresses.
-     *
-     * @param fromAddresses A list of addresses that comprise the "from" line.
-     * @return The number of the voicemail sender.
-     */
-    private String getNumber(Address[] fromAddresses) {
-        if (fromAddresses != null && fromAddresses.length > 0) {
-            if (fromAddresses.length != 1) {
-                LogUtils.w(TAG, "More than one from addresses found. Using the first one.");
-            }
-            String sender = fromAddresses[0].getAddress();
-            int atPos = sender.indexOf('@');
-            if (atPos != -1) {
-                // Strip domain part of the address.
-                sender = sender.substring(0, atPos);
-            }
-            return sender;
-        }
-        return null;
-    }
-
-    /**
-     * Fetches the structure of the given message and returns a wrapper containing the message
-     * structure and the transcription structure (if applicable).
-     *
-     * @throws MessagingException if fetching the structure of the message fails
-     */
-    private MessageStructureWrapper fetchMessageStructure(Message message)
-            throws MessagingException {
-        LogUtils.d(TAG, "Fetching message structure for " + message.getUid());
-
-        MessageStructureFetchedListener listener = new MessageStructureFetchedListener();
-
-        FetchProfile fetchProfile = new FetchProfile();
-        fetchProfile.addAll(Arrays.asList(FetchProfile.Item.FLAGS, FetchProfile.Item.ENVELOPE,
-                FetchProfile.Item.STRUCTURE));
-
-        // The IMAP folder fetch method will call "messageRetrieved" on the listener when the
-        // message is successfully retrieved.
-        mFolder.fetch(new Message[]{message}, fetchProfile, listener);
-        return listener.getMessageStructure();
-    }
-
-    public boolean fetchVoicemailPayload(VoicemailFetchedCallback callback, final String uid) {
-        try {
-            mFolder = openImapFolder(ImapFolder.MODE_READ_WRITE);
-            if (mFolder == null) {
-                // This means we were unable to successfully open the folder.
-                return false;
-            }
-            Message message = mFolder.getMessage(uid);
-            if (message == null) {
-                return false;
-            }
-            VoicemailPayload voicemailPayload = fetchVoicemailPayload(message);
-            callback.setVoicemailContent(voicemailPayload);
-            return true;
-        } catch (MessagingException e) {
-        } finally {
-            closeImapFolder();
-        }
-        return false;
-    }
-
-    /**
-     * Fetches the body of the given message and returns the parsed voicemail payload.
-     *
-     * @throws MessagingException if fetching the body of the message fails
-     */
-    private VoicemailPayload fetchVoicemailPayload(Message message)
-            throws MessagingException {
-        LogUtils.d(TAG, "Fetching message body for " + message.getUid());
-
-        MessageBodyFetchedListener listener = new MessageBodyFetchedListener();
-
-        FetchProfile fetchProfile = new FetchProfile();
-        fetchProfile.add(FetchProfile.Item.BODY);
-
-        mFolder.fetch(new Message[]{message}, fetchProfile, listener);
-        return listener.getVoicemailPayload();
-    }
-
-    public boolean fetchTranscription(TranscriptionFetchedCallback callback, String uid) {
-        try {
-            mFolder = openImapFolder(ImapFolder.MODE_READ_WRITE);
-            if (mFolder == null) {
-                // This means we were unable to successfully open the folder.
-                return false;
-            }
-
-            Message message = mFolder.getMessage(uid);
-            if (message == null) {
-                return false;
-            }
-
-            MessageStructureWrapper messageStructureWrapper = fetchMessageStructure(message);
-            if (messageStructureWrapper != null) {
-                TranscriptionFetchedListener listener = new TranscriptionFetchedListener();
-                if (messageStructureWrapper.transcriptionBodyPart != null) {
-                    FetchProfile fetchProfile = new FetchProfile();
-                    fetchProfile.add(messageStructureWrapper.transcriptionBodyPart);
-
-                    // This method is called synchronously so the transcription will be populated
-                    // in the listener once the next method is called.
-                    mFolder.fetch(new Message[]{message}, fetchProfile, listener);
-                    callback.setVoicemailTranscription(listener.getVoicemailTranscription());
-                }
-            }
-            return true;
-        } catch (MessagingException e) {
-            LogUtils.e(TAG, e, "Messaging Exception");
-            return false;
-        } finally {
-            closeImapFolder();
-        }
-    }
-
-
-    @ChangePinResult
-    public int changePin(String oldPin, String newPin)
-            throws MessagingException {
-        ImapConnection connection = mImapStore.getConnection();
-        try {
-            String command = getConfig().getProtocol()
-                    .getCommand(OmtpConstants.IMAP_CHANGE_TUI_PWD_FORMAT);
-            connection.sendCommand(
-                    String.format(Locale.US, command, newPin, oldPin), true);
-            return getChangePinResultFromImapResponse(connection.readResponse());
-        } catch (IOException ioe) {
-            VvmLog.e(TAG, "changePin: ", ioe);
-            return OmtpConstants.CHANGE_PIN_SYSTEM_ERROR;
-        } finally {
-            connection.destroyResponses();
-        }
-    }
-
-    public void changeVoicemailTuiLanguage(String languageCode)
-            throws MessagingException {
-        ImapConnection connection = mImapStore.getConnection();
-        try {
-            String command = getConfig().getProtocol()
-                    .getCommand(OmtpConstants.IMAP_CHANGE_VM_LANG_FORMAT);
-            connection.sendCommand(
-                    String.format(Locale.US, command, languageCode), true);
-        } catch (IOException ioe) {
-            LogUtils.e(TAG, ioe.toString());
-        } finally {
-            connection.destroyResponses();
-        }
-    }
-
-    public void closeNewUserTutorial() throws MessagingException {
-        ImapConnection connection = mImapStore.getConnection();
-        try {
-            String command = getConfig().getProtocol()
-                    .getCommand(OmtpConstants.IMAP_CLOSE_NUT);
-            connection.executeSimpleCommand(command, false);
-        } catch (IOException ioe) {
-            throw new MessagingException(MessagingException.SERVER_ERROR, ioe.toString());
-        } finally {
-            connection.destroyResponses();
-        }
-    }
-
-    @ChangePinResult
-    private static int getChangePinResultFromImapResponse(ImapResponse response)
-            throws MessagingException {
-        if (!response.isTagged()) {
-            throw new MessagingException(MessagingException.SERVER_ERROR,
-                    "tagged response expected");
-        }
-        if (!response.isOk()) {
-            String message = response.getStringOrEmpty(1).getString();
-            LogUtils.d(TAG, "change PIN failed: " + message);
-            if (OmtpConstants.RESPONSE_CHANGE_PIN_TOO_SHORT.equals(message)) {
-                return OmtpConstants.CHANGE_PIN_TOO_SHORT;
-            }
-            if (OmtpConstants.RESPONSE_CHANGE_PIN_TOO_LONG.equals(message)) {
-                return OmtpConstants.CHANGE_PIN_TOO_LONG;
-            }
-            if (OmtpConstants.RESPONSE_CHANGE_PIN_TOO_WEAK.equals(message)) {
-                return OmtpConstants.CHANGE_PIN_TOO_WEAK;
-            }
-            if (OmtpConstants.RESPONSE_CHANGE_PIN_MISMATCH.equals(message)) {
-                return OmtpConstants.CHANGE_PIN_MISMATCH;
-            }
-            if (OmtpConstants.RESPONSE_CHANGE_PIN_INVALID_CHARACTER.equals(message)) {
-                return OmtpConstants.CHANGE_PIN_INVALID_CHARACTER;
-            }
-            return OmtpConstants.CHANGE_PIN_SYSTEM_ERROR;
-        }
-        LogUtils.d(TAG, "change PIN succeeded");
-        return OmtpConstants.CHANGE_PIN_SUCCESS;
-    }
-
-    public void updateQuota() {
-        try {
-            mFolder = openImapFolder(ImapFolder.MODE_READ_WRITE);
-            if (mFolder == null) {
-                // This means we were unable to successfully open the folder.
-                return;
-            }
-            updateQuota(mFolder);
-        } catch (MessagingException e) {
-            LogUtils.e(TAG, e, "Messaging Exception");
-        } finally {
-            closeImapFolder();
-        }
-    }
-
-    private void updateQuota(ImapFolder folder) throws MessagingException {
-        setQuota(folder.getQuota());
-    }
-
-    private void setQuota(ImapFolder.Quota quota) {
-        if (quota == null) {
-            return;
-        }
-        if (quota.occupied == mQuotaOccupied && quota.total == mQuotaTotal) {
-            VvmLog.v(TAG, "Quota hasn't changed");
-            return;
-        }
-        mQuotaOccupied = quota.occupied;
-        mQuotaTotal = quota.total;
-        VoicemailStatus.edit(mContext, mPhoneAccount)
-                .setQuota(mQuotaOccupied, mQuotaTotal)
-                .apply();
-        mPrefs.edit()
-                .putInt(PREF_KEY_QUOTA_OCCUPIED, mQuotaOccupied)
-                .putInt(PREF_KEY_QUOTA_TOTAL, mQuotaTotal)
-                .apply();
-        VvmLog.v(TAG, "Quota changed to " + mQuotaOccupied + "/" + mQuotaTotal);
-    }
-
-    /**
-     * A wrapper to hold a message with its header details and the structure for transcriptions (so
-     * they can be fetched in the future).
-     */
-    public class MessageStructureWrapper {
-
-        public Message messageStructure;
-        public BodyPart transcriptionBodyPart;
-
-        public MessageStructureWrapper() {
-        }
-    }
-
-    /**
-     * Listener for the message structure being fetched.
-     */
-    private final class MessageStructureFetchedListener
-            implements ImapFolder.MessageRetrievalListener {
-
-        private MessageStructureWrapper mMessageStructure;
-
-        public MessageStructureFetchedListener() {
-        }
-
-        public MessageStructureWrapper getMessageStructure() {
-            return mMessageStructure;
-        }
-
-        @Override
-        public void messageRetrieved(Message message) {
-            LogUtils.d(TAG, "Fetched message structure for " + message.getUid());
-            LogUtils.d(TAG, "Message retrieved: " + message);
-            try {
-                mMessageStructure = getMessageOrNull(message);
-                if (mMessageStructure == null) {
-                    LogUtils.d(TAG, "This voicemail does not have an attachment...");
-                    return;
-                }
-            } catch (MessagingException e) {
-                LogUtils.e(TAG, e, "Messaging Exception");
-                closeImapFolder();
-            }
-        }
-
-        /**
-         * Check if this IMAP message is a valid voicemail and whether it contains a transcription.
-         *
-         * @param message The IMAP message.
-         * @return The MessageStructureWrapper object corresponding to an IMAP message and
-         * transcription.
-         */
-        private MessageStructureWrapper getMessageOrNull(Message message)
-                throws MessagingException {
-            if (!message.getMimeType().startsWith("multipart/")) {
-                LogUtils.w(TAG, "Ignored non multi-part message");
-                return null;
-            }
-
-            MessageStructureWrapper messageStructureWrapper = new MessageStructureWrapper();
-
-            Multipart multipart = (Multipart) message.getBody();
-            for (int i = 0; i < multipart.getCount(); ++i) {
-                BodyPart bodyPart = multipart.getBodyPart(i);
-                String bodyPartMimeType = bodyPart.getMimeType().toLowerCase();
-                LogUtils.d(TAG, "bodyPart mime type: " + bodyPartMimeType);
-
-                if (bodyPartMimeType.startsWith("audio/")) {
-                    messageStructureWrapper.messageStructure = message;
-                } else if (bodyPartMimeType.startsWith("text/")) {
-                    messageStructureWrapper.transcriptionBodyPart = bodyPart;
-                } else {
-                    VvmLog.v(TAG, "Unknown bodyPart MIME: " + bodyPartMimeType);
-                }
-            }
-
-            if (messageStructureWrapper.messageStructure != null) {
-                return messageStructureWrapper;
-            }
-
-            // No attachment found, this is not a voicemail.
-            return null;
-        }
-    }
-
-    /**
-     * Listener for the message body being fetched.
-     */
-    private final class MessageBodyFetchedListener implements ImapFolder.MessageRetrievalListener {
-
-        private VoicemailPayload mVoicemailPayload;
-
-        /**
-         * Returns the fetch voicemail payload.
-         */
-        public VoicemailPayload getVoicemailPayload() {
-            return mVoicemailPayload;
-        }
-
-        @Override
-        public void messageRetrieved(Message message) {
-            LogUtils.d(TAG, "Fetched message body for " + message.getUid());
-            LogUtils.d(TAG, "Message retrieved: " + message);
-            try {
-                mVoicemailPayload = getVoicemailPayloadFromMessage(message);
-            } catch (MessagingException e) {
-                LogUtils.e(TAG, "Messaging Exception:", e);
-            } catch (IOException e) {
-                LogUtils.e(TAG, "IO Exception:", e);
-            }
-        }
-
-        private VoicemailPayload getVoicemailPayloadFromMessage(Message message)
-                throws MessagingException, IOException {
-            Multipart multipart = (Multipart) message.getBody();
-            List<String> mimeTypes = new ArrayList<>();
-            for (int i = 0; i < multipart.getCount(); ++i) {
-                BodyPart bodyPart = multipart.getBodyPart(i);
-                String bodyPartMimeType = bodyPart.getMimeType().toLowerCase();
-                mimeTypes.add(bodyPartMimeType);
-                if (bodyPartMimeType.startsWith("audio/")) {
-                    byte[] bytes = getDataFromBody(bodyPart.getBody());
-                    LogUtils.d(TAG, String.format("Fetched %s bytes of data", bytes.length));
-                    return new VoicemailPayload(bodyPartMimeType, bytes);
-                }
-            }
-            LogUtils.e(TAG, "No audio attachment found on this voicemail, mimeTypes:" + mimeTypes);
-            return null;
-        }
-    }
-
-    /**
-     * Listener for the transcription being fetched.
-     */
-    private final class TranscriptionFetchedListener implements
-            ImapFolder.MessageRetrievalListener {
-
-        private String mVoicemailTranscription;
-
-        /**
-         * Returns the fetched voicemail transcription.
-         */
-        public String getVoicemailTranscription() {
-            return mVoicemailTranscription;
-        }
-
-        @Override
-        public void messageRetrieved(Message message) {
-            LogUtils.d(TAG, "Fetched transcription for " + message.getUid());
-            try {
-                mVoicemailTranscription = new String(getDataFromBody(message.getBody()));
-            } catch (MessagingException e) {
-                LogUtils.e(TAG, "Messaging Exception:", e);
-            } catch (IOException e) {
-                LogUtils.e(TAG, "IO Exception:", e);
-            }
-        }
-    }
-
-    private ImapFolder openImapFolder(String modeReadWrite) {
-        try {
-            if (mImapStore == null) {
-                return null;
-            }
-            ImapFolder folder = new ImapFolder(mImapStore, ImapConstants.INBOX);
-            folder.open(modeReadWrite);
-            return folder;
-        } catch (MessagingException e) {
-            LogUtils.e(TAG, e, "Messaging Exception");
-        }
-        return null;
-    }
-
-    private Message[] convertToImapMessages(List<Voicemail> voicemails) {
-        Message[] messages = new Message[voicemails.size()];
-        for (int i = 0; i < voicemails.size(); ++i) {
-            messages[i] = new MimeMessage();
-            messages[i].setUid(voicemails.get(i).getSourceData());
-        }
-        return messages;
-    }
-
-    private void closeImapFolder() {
-        if (mFolder != null) {
-            mFolder.close(true);
-        }
-    }
-
-    private byte[] getDataFromBody(Body body) throws IOException, MessagingException {
-        ByteArrayOutputStream out = new ByteArrayOutputStream();
-        BufferedOutputStream bufferedOut = new BufferedOutputStream(out);
-        try {
-            body.writeTo(bufferedOut);
-            return Base64.decode(out.toByteArray(), Base64.DEFAULT);
-        } finally {
-            IoUtils.closeQuietly(bufferedOut);
-            IoUtils.closeQuietly(out);
-        }
-    }
-}
\ No newline at end of file
diff --git a/src/com/android/phone/vvm/omtp/imap/VoicemailPayload.java b/src/com/android/phone/vvm/omtp/imap/VoicemailPayload.java
deleted file mode 100644
index 0ffa018..0000000
--- a/src/com/android/phone/vvm/omtp/imap/VoicemailPayload.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.phone.vvm.omtp.imap;
-
-/**
- * The payload for a voicemail, usually audio data.
- */
-public class VoicemailPayload {
-    private final String mMimeType;
-    private final byte[] mBytes;
-
-    public VoicemailPayload(String mimeType, byte[] bytes) {
-        mMimeType = mimeType;
-        mBytes = bytes;
-    }
-
-    public byte[] getBytes() {
-        return mBytes;
-    }
-
-    public String getMimeType() {
-        return mMimeType;
-    }
-}
\ No newline at end of file
diff --git a/src/com/android/phone/vvm/omtp/protocol/CvvmProtocol.java b/src/com/android/phone/vvm/omtp/protocol/CvvmProtocol.java
deleted file mode 100644
index 9960b18..0000000
--- a/src/com/android/phone/vvm/omtp/protocol/CvvmProtocol.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.phone.vvm.omtp.protocol;
-
-import android.telephony.SmsManager;
-
-import com.android.phone.vvm.omtp.OmtpConstants;
-import com.android.phone.vvm.omtp.sms.OmtpCvvmMessageSender;
-import com.android.phone.vvm.omtp.sms.OmtpMessageSender;
-
-/**
- * A flavor of OMTP protocol with a different mobile originated (MO) format
- *
- * Used by carriers such as T-Mobile
- */
-public class CvvmProtocol extends VisualVoicemailProtocol {
-
-    private static String IMAP_CHANGE_TUI_PWD_FORMAT = "CHANGE_TUI_PWD PWD=%1$s OLD_PWD=%2$s";
-    private static String IMAP_CHANGE_VM_LANG_FORMAT = "CHANGE_VM_LANG Lang=%1$s";
-    private static String IMAP_CLOSE_NUT = "CLOSE_NUT";
-
-    @Override
-    public OmtpMessageSender createMessageSender(SmsManager smsManager, short applicationPort,
-            String destinationNumber) {
-        return new OmtpCvvmMessageSender(smsManager, applicationPort, destinationNumber);
-    }
-
-    @Override
-    public String getCommand(String command) {
-        if (command == OmtpConstants.IMAP_CHANGE_TUI_PWD_FORMAT) {
-            return IMAP_CHANGE_TUI_PWD_FORMAT;
-        }
-        if (command == OmtpConstants.IMAP_CLOSE_NUT) {
-            return IMAP_CLOSE_NUT;
-        }
-        if (command == OmtpConstants.IMAP_CHANGE_VM_LANG_FORMAT) {
-            return IMAP_CHANGE_VM_LANG_FORMAT;
-        }
-        return super.getCommand(command);
-    }
-}
diff --git a/src/com/android/phone/vvm/omtp/protocol/OmtpProtocol.java b/src/com/android/phone/vvm/omtp/protocol/OmtpProtocol.java
deleted file mode 100644
index 7ec3dba..0000000
--- a/src/com/android/phone/vvm/omtp/protocol/OmtpProtocol.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.phone.vvm.omtp.protocol;
-
-import android.telephony.SmsManager;
-
-import com.android.phone.vvm.omtp.OmtpConstants;
-import com.android.phone.vvm.omtp.sms.OmtpMessageSender;
-import com.android.phone.vvm.omtp.sms.OmtpStandardMessageSender;
-
-public class OmtpProtocol extends VisualVoicemailProtocol {
-
-    @Override
-    public OmtpMessageSender createMessageSender(SmsManager smsManager, short applicationPort,
-            String destinationNumber) {
-        return new OmtpStandardMessageSender(smsManager, applicationPort, destinationNumber,
-                OmtpConstants.CLIENT_TYPE_GOOGLE_10, OmtpConstants.PROTOCOL_VERSION1_1,
-                null /*clientPrefix*/);
-    }
-}
diff --git a/src/com/android/phone/vvm/omtp/protocol/ProtocolHelper.java b/src/com/android/phone/vvm/omtp/protocol/ProtocolHelper.java
deleted file mode 100644
index 748fd39..0000000
--- a/src/com/android/phone/vvm/omtp/protocol/ProtocolHelper.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.phone.vvm.omtp.protocol;
-
-import android.telephony.SmsManager;
-import android.text.TextUtils;
-
-import com.android.phone.vvm.omtp.OmtpVvmCarrierConfigHelper;
-import com.android.phone.vvm.omtp.VvmLog;
-import com.android.phone.vvm.omtp.sms.OmtpMessageSender;
-
-public class ProtocolHelper {
-
-    private static final String TAG = "ProtocolHelper";
-
-    public static OmtpMessageSender getMessageSender(VisualVoicemailProtocol protocol,
-            OmtpVvmCarrierConfigHelper config) {
-
-        int applicationPort = config.getApplicationPort();
-        String destinationNumber = config.getDestinationNumber();
-        if (TextUtils.isEmpty(destinationNumber)) {
-            VvmLog.w(TAG, "No destination number for this carrier.");
-            return null;
-        }
-
-        SmsManager smsManager = SmsManager.getSmsManagerForSubscriptionId(config.getSubId());
-        return protocol.createMessageSender(smsManager, (short) applicationPort, destinationNumber);
-    }
-}
diff --git a/src/com/android/phone/vvm/omtp/protocol/VisualVoicemailProtocol.java b/src/com/android/phone/vvm/omtp/protocol/VisualVoicemailProtocol.java
deleted file mode 100644
index 6e6d6ef..0000000
--- a/src/com/android/phone/vvm/omtp/protocol/VisualVoicemailProtocol.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.phone.vvm.omtp.protocol;
-
-import android.annotation.Nullable;
-import android.app.PendingIntent;
-import android.content.Context;
-import android.os.Bundle;
-import android.telecom.PhoneAccountHandle;
-import android.telephony.SmsManager;
-import com.android.phone.VoicemailStatus;
-import com.android.phone.vvm.omtp.ActivationTask;
-import com.android.phone.vvm.omtp.DefaultOmtpEventHandler;
-import com.android.phone.vvm.omtp.OmtpEvents;
-import com.android.phone.vvm.omtp.OmtpVvmCarrierConfigHelper;
-import com.android.phone.vvm.omtp.sms.OmtpMessageSender;
-import com.android.phone.vvm.omtp.sms.StatusMessage;
-
-public abstract class VisualVoicemailProtocol {
-
-    /**
-     * Activation should cause the carrier to respond with a STATUS SMS.
-     */
-    public void startActivation(OmtpVvmCarrierConfigHelper config, PendingIntent sentIntent) {
-        OmtpMessageSender messageSender = ProtocolHelper.getMessageSender(this, config);
-        if (messageSender != null) {
-            messageSender.requestVvmActivation(sentIntent);
-        }
-    }
-
-    public void startDeactivation(OmtpVvmCarrierConfigHelper config) {
-        OmtpMessageSender messageSender = ProtocolHelper.getMessageSender(this, config);
-        if (messageSender != null) {
-            messageSender.requestVvmDeactivation(null);
-        }
-    }
-
-    public boolean supportsProvisioning() {
-        return false;
-    }
-
-    public void startProvisioning(ActivationTask task, PhoneAccountHandle handle,
-        OmtpVvmCarrierConfigHelper config, VoicemailStatus.Editor editor, StatusMessage message,
-        Bundle data) {
-        // Do nothing
-    }
-
-    public void requestStatus(OmtpVvmCarrierConfigHelper config,
-            @Nullable PendingIntent sentIntent) {
-        OmtpMessageSender messageSender = ProtocolHelper.getMessageSender(this, config);
-        if (messageSender != null) {
-            messageSender.requestVvmStatus(sentIntent);
-        }
-    }
-
-    public abstract OmtpMessageSender createMessageSender(SmsManager smsManager,
-            short applicationPort, String destinationNumber);
-
-    /**
-     * Translate an OMTP IMAP command to the protocol specific one. For example, changing the TUI
-     * password on OMTP is XCHANGE_TUI_PWD, but on CVVM and VVM3 it is CHANGE_TUI_PWD.
-     *
-     * @param command A String command in {@link com.android.phone.vvm.omtp.OmtpConstants}, the exact
-     * instance should be used instead of its' value.
-     * @returns Translated command, or {@code null} if not available in this protocol
-     */
-    public String getCommand(String command) {
-        return command;
-    }
-
-    public void handleEvent(Context context, OmtpVvmCarrierConfigHelper config,
-        VoicemailStatus.Editor status, OmtpEvents event) {
-        DefaultOmtpEventHandler.handleEvent(context, config, status, event);
-    }
-
-    /**
-     * Given an VVM SMS with an unknown {@code event}, let the protocol attempt to translate it into
-     * an equivalent STATUS SMS. Returns {@code null} if it cannot be translated.
-     */
-    @Nullable
-    public Bundle translateStatusSmsBundle(OmtpVvmCarrierConfigHelper config, String event,
-            Bundle data) {
-        return null;
-    }
-}
diff --git a/src/com/android/phone/vvm/omtp/protocol/VisualVoicemailProtocolFactory.java b/src/com/android/phone/vvm/omtp/protocol/VisualVoicemailProtocolFactory.java
deleted file mode 100644
index 4d39ae2..0000000
--- a/src/com/android/phone/vvm/omtp/protocol/VisualVoicemailProtocolFactory.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.phone.vvm.omtp.protocol;
-
-import android.annotation.Nullable;
-import android.content.res.Resources;
-import android.telephony.TelephonyManager;
-
-import com.android.phone.R;
-import com.android.phone.vvm.omtp.VvmLog;
-
-public class VisualVoicemailProtocolFactory {
-
-    private static final String TAG = "VvmProtocolFactory";
-
-    private static final String VVM_TYPE_VVM3 = "vvm_type_vvm3";
-
-    @Nullable
-    public static VisualVoicemailProtocol create(Resources resources, String type) {
-        if (type == null) {
-            return null;
-        }
-        switch (type) {
-            case TelephonyManager.VVM_TYPE_OMTP:
-                return new OmtpProtocol();
-            case TelephonyManager.VVM_TYPE_CVVM:
-                return new CvvmProtocol();
-            case VVM_TYPE_VVM3:
-                if (resources.getBoolean(R.bool.vvm3_enabled)) {
-                    return new Vvm3Protocol();
-                } else {
-                    VvmLog.e(TAG, "VVM3 is disabled");
-                    return null;
-                }
-            default:
-                VvmLog.e(TAG, "Unexpected visual voicemail type: " + type);
-        }
-        return null;
-    }
-}
diff --git a/src/com/android/phone/vvm/omtp/protocol/Vvm3EventHandler.java b/src/com/android/phone/vvm/omtp/protocol/Vvm3EventHandler.java
deleted file mode 100644
index 524c96d..0000000
--- a/src/com/android/phone/vvm/omtp/protocol/Vvm3EventHandler.java
+++ /dev/null
@@ -1,288 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.phone.vvm.omtp.protocol;
-
-import android.annotation.IntDef;
-import android.content.Context;
-import android.provider.VoicemailContract.Status;
-import android.telecom.PhoneAccountHandle;
-import android.util.Log;
-
-import com.android.phone.VoicemailStatus;
-import com.android.phone.settings.VoicemailChangePinActivity;
-import com.android.phone.vvm.omtp.DefaultOmtpEventHandler;
-import com.android.phone.vvm.omtp.OmtpEvents;
-import com.android.phone.vvm.omtp.OmtpEvents.Type;
-import com.android.phone.vvm.omtp.OmtpVvmCarrierConfigHelper;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * Handles {@link OmtpEvents} when {@link Vvm3Protocol} is being used. This handler writes custom
- * error codes into the voicemail status table so support on the dialer side is required.
- *
- * TODO(b/29577838) disable VVM3 by default so support on system dialer can be ensured.
- */
-public class Vvm3EventHandler {
-
-    private static final String TAG = "Vvm3EventHandler";
-
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef({VMS_DNS_FAILURE, VMG_DNS_FAILURE, SPG_DNS_FAILURE, VMS_NO_CELLULAR, VMG_NO_CELLULAR,
-            SPG_NO_CELLULAR, VMS_TIMEOUT, VMG_TIMEOUT, STATUS_SMS_TIMEOUT, SUBSCRIBER_BLOCKED,
-            UNKNOWN_USER, UNKNOWN_DEVICE, INVALID_PASSWORD, MAILBOX_NOT_INITIALIZED,
-            SERVICE_NOT_PROVISIONED, SERVICE_NOT_ACTIVATED, USER_BLOCKED, IMAP_GETQUOTA_ERROR,
-            IMAP_SELECT_ERROR, IMAP_ERROR, VMG_INTERNAL_ERROR, VMG_DB_ERROR,
-            VMG_COMMUNICATION_ERROR, SPG_URL_NOT_FOUND, VMG_UNKNOWN_ERROR, PIN_NOT_SET})
-    public @interface ErrorCode {
-
-    }
-
-    public static final int VMS_DNS_FAILURE = -9001;
-    public static final int VMG_DNS_FAILURE = -9002;
-    public static final int SPG_DNS_FAILURE = -9003;
-    public static final int VMS_NO_CELLULAR = -9004;
-    public static final int VMG_NO_CELLULAR = -9005;
-    public static final int SPG_NO_CELLULAR = -9006;
-    public static final int VMS_TIMEOUT = -9007;
-    public static final int VMG_TIMEOUT = -9008;
-    public static final int STATUS_SMS_TIMEOUT = -9009;
-
-    public static final int SUBSCRIBER_BLOCKED = -9990;
-    public static final int UNKNOWN_USER = -9991;
-    public static final int UNKNOWN_DEVICE = -9992;
-    public static final int INVALID_PASSWORD = -9993;
-    public static final int MAILBOX_NOT_INITIALIZED = -9994;
-    public static final int SERVICE_NOT_PROVISIONED = -9995;
-    public static final int SERVICE_NOT_ACTIVATED = -9996;
-    public static final int USER_BLOCKED = -9998;
-    public static final int IMAP_GETQUOTA_ERROR = -9997;
-    public static final int IMAP_SELECT_ERROR = -9989;
-    public static final int IMAP_ERROR = -9999;
-
-    public static final int VMG_INTERNAL_ERROR = -101;
-    public static final int VMG_DB_ERROR = -102;
-    public static final int VMG_COMMUNICATION_ERROR = -103;
-    public static final int SPG_URL_NOT_FOUND = -301;
-
-    // Non VVM3 codes:
-    public static final int VMG_UNKNOWN_ERROR = -1;
-    public static final int PIN_NOT_SET = -100;
-    // STATUS SMS returned st=U and rc!=2. The user cannot be provisioned and must contact customer
-    // support.
-    public static final int SUBSCRIBER_UNKNOWN = -99;
-
-
-    public static void handleEvent(Context context, OmtpVvmCarrierConfigHelper config,
-        VoicemailStatus.Editor status, OmtpEvents event) {
-        boolean handled = false;
-        switch (event.getType()) {
-            case Type.CONFIGURATION:
-                handled = handleConfigurationEvent(context, status, event);
-                break;
-            case Type.DATA_CHANNEL:
-                handled = handleDataChannelEvent(status, event);
-                break;
-            case Type.NOTIFICATION_CHANNEL:
-                handled = handleNotificationChannelEvent(status, event);
-                break;
-            case Type.OTHER:
-                handled = handleOtherEvent(status, event);
-                break;
-            default:
-                com.android.services.telephony.Log
-                        .wtf(TAG, "invalid event type " + event.getType() + " for " + event);
-        }
-        if (!handled) {
-            DefaultOmtpEventHandler.handleEvent(context, config, status, event);
-        }
-    }
-
-    private static boolean handleConfigurationEvent(Context context, VoicemailStatus.Editor status,
-        OmtpEvents event) {
-        switch (event) {
-            case CONFIG_REQUEST_STATUS_SUCCESS:
-                if (!isPinRandomized(context, status.getPhoneAccountHandle())) {
-                    return false;
-                } else {
-                    postError(status, PIN_NOT_SET);
-                }
-                break;
-            case CONFIG_ACTIVATING_SUBSEQUENT:
-                if (isPinRandomized(context, status.getPhoneAccountHandle())) {
-                    status.setConfigurationState(PIN_NOT_SET);
-                } else {
-                    status.setConfigurationState(Status.CONFIGURATION_STATE_OK);
-                }
-                status
-                        .setNotificationChannelState(Status.NOTIFICATION_CHANNEL_STATE_OK)
-                        .setDataChannelState(Status.DATA_CHANNEL_STATE_OK).apply();
-                break;
-            case CONFIG_DEFAULT_PIN_REPLACED:
-                postError(status, PIN_NOT_SET);
-                break;
-            case CONFIG_STATUS_SMS_TIME_OUT:
-                postError(status, STATUS_SMS_TIMEOUT);
-                break;
-            default:
-                return false;
-        }
-        return true;
-    }
-
-    private static boolean handleDataChannelEvent(VoicemailStatus.Editor status, OmtpEvents event) {
-        switch (event) {
-            case DATA_NO_CONNECTION:
-            case DATA_NO_CONNECTION_CELLULAR_REQUIRED:
-            case DATA_ALL_SOCKET_CONNECTION_FAILED:
-                postError(status, VMS_NO_CELLULAR);
-                break;
-            case DATA_SSL_INVALID_HOST_NAME:
-            case DATA_CANNOT_ESTABLISH_SSL_SESSION:
-            case DATA_IOE_ON_OPEN:
-                postError(status, VMS_TIMEOUT);
-                break;
-            case DATA_CANNOT_RESOLVE_HOST_ON_NETWORK:
-                postError(status, VMS_DNS_FAILURE);
-                break;
-            case DATA_BAD_IMAP_CREDENTIAL:
-                postError(status, IMAP_ERROR);
-                break;
-            case DATA_AUTH_UNKNOWN_USER:
-                postError(status, UNKNOWN_USER);
-                break;
-            case DATA_AUTH_UNKNOWN_DEVICE:
-                postError(status, UNKNOWN_DEVICE);
-                break;
-            case DATA_AUTH_INVALID_PASSWORD:
-                postError(status, INVALID_PASSWORD);
-                break;
-            case DATA_AUTH_MAILBOX_NOT_INITIALIZED:
-                postError(status, MAILBOX_NOT_INITIALIZED);
-                break;
-            case DATA_AUTH_SERVICE_NOT_PROVISIONED:
-                postError(status, SERVICE_NOT_PROVISIONED);
-                break;
-            case DATA_AUTH_SERVICE_NOT_ACTIVATED:
-                postError(status, SERVICE_NOT_ACTIVATED);
-                break;
-            case DATA_AUTH_USER_IS_BLOCKED:
-                postError(status, USER_BLOCKED);
-                break;
-            case DATA_REJECTED_SERVER_RESPONSE:
-            case DATA_INVALID_INITIAL_SERVER_RESPONSE:
-            case DATA_SSL_EXCEPTION:
-                postError(status, IMAP_ERROR);
-                break;
-            default:
-                return false;
-        }
-        return true;
-    }
-
-    private static boolean handleNotificationChannelEvent(VoicemailStatus.Editor status,
-        OmtpEvents event) {
-        return false;
-    }
-
-    private static boolean handleOtherEvent(VoicemailStatus.Editor status,
-            OmtpEvents event) {
-        switch (event) {
-            case VVM3_NEW_USER_SETUP_FAILED:
-                postError(status, MAILBOX_NOT_INITIALIZED);
-                break;
-            case VVM3_VMG_DNS_FAILURE:
-                postError(status, VMG_DNS_FAILURE);
-                break;
-            case VVM3_SPG_DNS_FAILURE:
-                postError(status, SPG_DNS_FAILURE);
-                break;
-            case VVM3_VMG_CONNECTION_FAILED:
-                postError(status, VMG_NO_CELLULAR);
-                break;
-            case VVM3_SPG_CONNECTION_FAILED:
-                postError(status, SPG_NO_CELLULAR);
-                break;
-            case VVM3_VMG_TIMEOUT:
-                postError(status, VMG_TIMEOUT);
-                break;
-            case VVM3_SUBSCRIBER_PROVISIONED:
-                postError(status, SERVICE_NOT_ACTIVATED);
-                break;
-            case VVM3_SUBSCRIBER_BLOCKED:
-                postError(status, SUBSCRIBER_BLOCKED);
-                break;
-            case VVM3_SUBSCRIBER_UNKNOWN:
-                postError(status, SUBSCRIBER_UNKNOWN);
-                break;
-            default:
-                return false;
-        }
-        return true;
-    }
-
-    private static void postError(VoicemailStatus.Editor editor, @ErrorCode int errorCode) {
-        switch (errorCode) {
-            case VMG_DNS_FAILURE:
-            case SPG_DNS_FAILURE:
-            case VMG_NO_CELLULAR:
-            case SPG_NO_CELLULAR:
-            case VMG_TIMEOUT:
-            case SUBSCRIBER_BLOCKED:
-            case UNKNOWN_USER:
-            case UNKNOWN_DEVICE:
-            case INVALID_PASSWORD:
-            case MAILBOX_NOT_INITIALIZED:
-            case SERVICE_NOT_PROVISIONED:
-            case SERVICE_NOT_ACTIVATED:
-            case USER_BLOCKED:
-            case VMG_UNKNOWN_ERROR:
-            case SPG_URL_NOT_FOUND:
-            case VMG_INTERNAL_ERROR:
-            case VMG_DB_ERROR:
-            case VMG_COMMUNICATION_ERROR:
-            case PIN_NOT_SET:
-            case SUBSCRIBER_UNKNOWN:
-                editor.setConfigurationState(errorCode);
-                break;
-            case VMS_NO_CELLULAR:
-            case VMS_DNS_FAILURE:
-            case VMS_TIMEOUT:
-            case IMAP_GETQUOTA_ERROR:
-            case IMAP_SELECT_ERROR:
-            case IMAP_ERROR:
-                editor.setDataChannelState(errorCode);
-                break;
-            case STATUS_SMS_TIMEOUT:
-                editor.setNotificationChannelState(errorCode);
-                break;
-            default:
-                Log.wtf(TAG, "unknown error code: " + errorCode);
-        }
-        editor.apply();
-    }
-
-    private static boolean isPinRandomized(Context context, PhoneAccountHandle phoneAccountHandle) {
-        if (phoneAccountHandle == null) {
-            // This should never happen.
-            Log.e(TAG, "status editor has null phone account handle");
-            return false;
-        }
-        return VoicemailChangePinActivity.isDefaultOldPinSet(context, phoneAccountHandle);
-    }
-}
diff --git a/src/com/android/phone/vvm/omtp/protocol/Vvm3Protocol.java b/src/com/android/phone/vvm/omtp/protocol/Vvm3Protocol.java
deleted file mode 100644
index 93e8fb9..0000000
--- a/src/com/android/phone/vvm/omtp/protocol/Vvm3Protocol.java
+++ /dev/null
@@ -1,306 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.phone.vvm.omtp.protocol;
-
-import android.annotation.Nullable;
-import android.app.PendingIntent;
-import android.content.Context;
-import android.net.Network;
-import android.os.Bundle;
-import android.telecom.PhoneAccountHandle;
-import android.telephony.SmsManager;
-import android.text.TextUtils;
-
-import com.android.phone.PhoneGlobals;
-import com.android.phone.VoicemailStatus;
-import com.android.phone.common.mail.MessagingException;
-import com.android.phone.settings.VisualVoicemailSettingsUtil;
-import com.android.phone.settings.VoicemailChangePinActivity;
-import com.android.phone.vvm.omtp.ActivationTask;
-import com.android.phone.vvm.omtp.OmtpConstants;
-import com.android.phone.vvm.omtp.OmtpEvents;
-import com.android.phone.vvm.omtp.OmtpVvmCarrierConfigHelper;
-import com.android.phone.vvm.omtp.VisualVoicemailPreferences;
-import com.android.phone.vvm.omtp.VvmLog;
-import com.android.phone.vvm.omtp.imap.ImapHelper;
-import com.android.phone.vvm.omtp.imap.ImapHelper.InitializingException;
-import com.android.phone.vvm.omtp.sms.OmtpMessageSender;
-import com.android.phone.vvm.omtp.sms.StatusMessage;
-import com.android.phone.vvm.omtp.sms.Vvm3MessageSender;
-import com.android.phone.vvm.omtp.sync.VvmNetworkRequest;
-import com.android.phone.vvm.omtp.sync.VvmNetworkRequest.NetworkWrapper;
-import com.android.phone.vvm.omtp.sync.VvmNetworkRequest.RequestFailedException;
-
-import java.io.IOException;
-import java.security.SecureRandom;
-import java.util.Locale;
-
-/**
- * A flavor of OMTP protocol with a different provisioning process
- *
- * Used by carriers such as Verizon Wireless
- */
-public class Vvm3Protocol extends VisualVoicemailProtocol {
-
-    private static final String TAG = "Vvm3Protocol";
-
-    private static final String SMS_EVENT_UNRECOGNIZED = "UNRECOGNIZED";
-    private static final String SMS_EVENT_UNRECOGNIZED_CMD = "cmd";
-    private static final String SMS_EVENT_UNRECOGNIZED_STATUS = "STATUS";
-    private static final String DEFAULT_VMG_URL_KEY = "default_vmg_url";
-
-    private static final String IMAP_CHANGE_TUI_PWD_FORMAT = "CHANGE_TUI_PWD PWD=%1$s OLD_PWD=%2$s";
-    private static final String IMAP_CHANGE_VM_LANG_FORMAT = "CHANGE_VM_LANG Lang=%1$s";
-    private static final String IMAP_CLOSE_NUT = "CLOSE_NUT";
-
-    private static final String ISO639_Spanish = "es";
-
-    /**
-     * For VVM3, if the STATUS SMS returns {@link StatusMessage#getProvisioningStatus()} of {@link
-     * OmtpConstants#SUBSCRIBER_UNKNOWN} and {@link StatusMessage#getReturnCode()} of this value,
-     * the user can self-provision visual voicemail service. For other response codes, the user must
-     * contact customer support to resolve the issue.
-     */
-    private static final String VVM3_UNKNOWN_SUBSCRIBER_CAN_SUBSCRIBE_RESPONSE_CODE = "2";
-
-    // Default prompt level when using the telephone user interface.
-    // Standard prompt when the user call into the voicemail, and no prompts when someone else is
-    // leaving a voicemail.
-    private static final String VVM3_VM_LANGUAGE_ENGLISH_STANDARD_NO_GUEST_PROMPTS = "5";
-    private static final String VVM3_VM_LANGUAGE_SPANISH_STANDARD_NO_GUEST_PROMPTS = "6";
-
-    private static final int DEFAULT_PIN_LENGTH = 6;
-
-    @Override
-    public void startActivation(OmtpVvmCarrierConfigHelper config,
-            @Nullable PendingIntent sentIntent) {
-        // VVM3 does not support activation SMS.
-        // Send a status request which will start the provisioning process if the user is not
-        // provisioned.
-        VvmLog.i(TAG, "Activating");
-        config.requestStatus(sentIntent);
-    }
-
-    @Override
-    public void startDeactivation(OmtpVvmCarrierConfigHelper config) {
-        // VVM3 does not support deactivation.
-        // do nothing.
-    }
-
-    @Override
-    public boolean supportsProvisioning() {
-        return true;
-    }
-
-    @Override
-    public void startProvisioning(ActivationTask task, PhoneAccountHandle phoneAccountHandle,
-            OmtpVvmCarrierConfigHelper config, VoicemailStatus.Editor status, StatusMessage message,
-            Bundle data) {
-        VvmLog.i(TAG, "start vvm3 provisioning");
-        if (OmtpConstants.SUBSCRIBER_UNKNOWN.equals(message.getProvisioningStatus())) {
-            VvmLog.i(TAG, "Provisioning status: Unknown");
-            if (VVM3_UNKNOWN_SUBSCRIBER_CAN_SUBSCRIBE_RESPONSE_CODE
-                    .equals(message.getReturnCode())) {
-                VvmLog.i(TAG, "Self provisioning available, subscribing");
-                new Vvm3Subscriber(task, phoneAccountHandle, config, status, data).subscribe();
-            } else {
-                config.handleEvent(status, OmtpEvents.VVM3_SUBSCRIBER_UNKNOWN);
-                PhoneGlobals.getInstance().setShouldCheckVisualVoicemailConfigurationForMwi(task.getSubId(),
-                        false);
-            }
-        } else if (OmtpConstants.SUBSCRIBER_NEW.equals(message.getProvisioningStatus())) {
-            VvmLog.i(TAG, "setting up new user");
-            // Save the IMAP credentials in preferences so they are persistent and can be retrieved.
-            VisualVoicemailPreferences prefs =
-                    new VisualVoicemailPreferences(config.getContext(), phoneAccountHandle);
-            message.putStatus(prefs.edit()).apply();
-
-            startProvisionNewUser(task, phoneAccountHandle, config, status, message);
-        } else if (OmtpConstants.SUBSCRIBER_PROVISIONED.equals(message.getProvisioningStatus())) {
-            VvmLog.i(TAG, "User provisioned but not activated, disabling VVM");
-            VisualVoicemailSettingsUtil
-                    .setEnabled(config.getContext(), phoneAccountHandle, false);
-            PhoneGlobals.getInstance().setShouldCheckVisualVoicemailConfigurationForMwi(task.getSubId(),
-                    false);
-        } else if (OmtpConstants.SUBSCRIBER_BLOCKED.equals(message.getProvisioningStatus())) {
-            VvmLog.i(TAG, "User blocked");
-            config.handleEvent(status, OmtpEvents.VVM3_SUBSCRIBER_BLOCKED);
-            PhoneGlobals.getInstance().setShouldCheckVisualVoicemailConfigurationForMwi(task.getSubId(),
-                    false);
-        }
-    }
-
-    @Override
-    public OmtpMessageSender createMessageSender(SmsManager smsManager, short applicationPort,
-            String destinationNumber) {
-        return new Vvm3MessageSender(smsManager, applicationPort, destinationNumber);
-    }
-
-    @Override
-    public void handleEvent(Context context, OmtpVvmCarrierConfigHelper config,
-            VoicemailStatus.Editor status, OmtpEvents event) {
-        Vvm3EventHandler.handleEvent(context, config, status, event);
-    }
-
-    @Override
-    public String getCommand(String command) {
-        if (command == OmtpConstants.IMAP_CHANGE_TUI_PWD_FORMAT) {
-            return IMAP_CHANGE_TUI_PWD_FORMAT;
-        }
-        if (command == OmtpConstants.IMAP_CLOSE_NUT) {
-            return IMAP_CLOSE_NUT;
-        }
-        if (command == OmtpConstants.IMAP_CHANGE_VM_LANG_FORMAT) {
-            return IMAP_CHANGE_VM_LANG_FORMAT;
-        }
-        return super.getCommand(command);
-    }
-
-    @Override
-    public Bundle translateStatusSmsBundle(OmtpVvmCarrierConfigHelper config, String event,
-            Bundle data) {
-        // UNRECOGNIZED?cmd=STATUS is the response of a STATUS request when the user is provisioned
-        // with iPhone visual voicemail without VoLTE. Translate it into an unprovisioned status
-        // so provisioning can be done.
-        if (!SMS_EVENT_UNRECOGNIZED.equals(event)) {
-            return null;
-        }
-        if (!SMS_EVENT_UNRECOGNIZED_STATUS.equals(data.getString(SMS_EVENT_UNRECOGNIZED_CMD))) {
-            return null;
-        }
-        Bundle bundle = new Bundle();
-        bundle.putString(OmtpConstants.PROVISIONING_STATUS, OmtpConstants.SUBSCRIBER_UNKNOWN);
-        bundle.putString(OmtpConstants.RETURN_CODE,
-                VVM3_UNKNOWN_SUBSCRIBER_CAN_SUBSCRIBE_RESPONSE_CODE);
-        String vmgUrl = config.getString(DEFAULT_VMG_URL_KEY);
-        if (TextUtils.isEmpty(vmgUrl)) {
-            VvmLog.e(TAG, "Unable to translate STATUS SMS: VMG URL is not set in config");
-            return null;
-        }
-        bundle.putString(Vvm3Subscriber.VMG_URL_KEY, vmgUrl);
-        VvmLog.i(TAG, "UNRECOGNIZED?cmd=STATUS translated into unprovisioned STATUS SMS");
-        return bundle;
-    }
-
-    private void startProvisionNewUser(ActivationTask task, PhoneAccountHandle phoneAccountHandle,
-            OmtpVvmCarrierConfigHelper config, VoicemailStatus.Editor status,
-            StatusMessage message) {
-        try (NetworkWrapper wrapper = VvmNetworkRequest
-                .getNetwork(config, phoneAccountHandle, status)) {
-            Network network = wrapper.get();
-
-            VvmLog.i(TAG, "new user: network available");
-            try (ImapHelper helper = new ImapHelper(config.getContext(), phoneAccountHandle,
-                    network, status)) {
-                // VVM3 has inconsistent error language code to OMTP. Just issue a raw command
-                // here.
-                // TODO(b/29082671): use LocaleList
-                if (Locale.getDefault().getLanguage()
-                        .equals(new Locale(ISO639_Spanish).getLanguage())) {
-                    // Spanish
-                    helper.changeVoicemailTuiLanguage(
-                            VVM3_VM_LANGUAGE_SPANISH_STANDARD_NO_GUEST_PROMPTS);
-                } else {
-                    // English
-                    helper.changeVoicemailTuiLanguage(
-                            VVM3_VM_LANGUAGE_ENGLISH_STANDARD_NO_GUEST_PROMPTS);
-                }
-                VvmLog.i(TAG, "new user: language set");
-
-                if (setPin(config.getContext(), phoneAccountHandle, helper, message)) {
-                    // Only close new user tutorial if the PIN has been changed.
-                    helper.closeNewUserTutorial();
-                    VvmLog.i(TAG, "new user: NUT closed");
-
-                    config.requestStatus(null);
-                }
-            } catch (InitializingException | MessagingException | IOException e) {
-                config.handleEvent(status, OmtpEvents.VVM3_NEW_USER_SETUP_FAILED);
-                task.fail();
-                VvmLog.e(TAG, e.toString());
-            }
-        } catch (RequestFailedException e) {
-            config.handleEvent(status, OmtpEvents.DATA_NO_CONNECTION_CELLULAR_REQUIRED);
-            task.fail();
-        }
-
-    }
-
-
-    private static boolean setPin(Context context, PhoneAccountHandle phoneAccountHandle,
-            ImapHelper helper, StatusMessage message)
-            throws IOException, MessagingException {
-        String defaultPin = getDefaultPin(message);
-        if (defaultPin == null) {
-            VvmLog.i(TAG, "cannot generate default PIN");
-            return false;
-        }
-
-        if (VoicemailChangePinActivity.isDefaultOldPinSet(context, phoneAccountHandle)) {
-            // The pin was already set
-            VvmLog.i(TAG, "PIN already set");
-            return true;
-        }
-        String newPin = generatePin(getMinimumPinLength(context, phoneAccountHandle));
-        if (helper.changePin(defaultPin, newPin) == OmtpConstants.CHANGE_PIN_SUCCESS) {
-            VoicemailChangePinActivity.setDefaultOldPIN(context, phoneAccountHandle, newPin);
-            helper.handleEvent(OmtpEvents.CONFIG_DEFAULT_PIN_REPLACED);
-        }
-        VvmLog.i(TAG, "new user: PIN set");
-        return true;
-    }
-
-    @Nullable
-    private static String getDefaultPin(StatusMessage message) {
-        // The IMAP username is [phone number]@example.com
-        String username = message.getImapUserName();
-        try {
-            String number = username.substring(0, username.indexOf('@'));
-            if (number.length() < 4) {
-                VvmLog.e(TAG, "unable to extract number from IMAP username");
-                return null;
-            }
-            return "1" + number.substring(number.length() - 4);
-        } catch (StringIndexOutOfBoundsException e) {
-            VvmLog.e(TAG, "unable to extract number from IMAP username");
-            return null;
-        }
-
-    }
-
-    private static int getMinimumPinLength(Context context, PhoneAccountHandle phoneAccountHandle) {
-        VisualVoicemailPreferences preferences = new VisualVoicemailPreferences(context,
-                phoneAccountHandle);
-        // The OMTP pin length format is {min}-{max}
-        String[] lengths = preferences.getString(OmtpConstants.TUI_PASSWORD_LENGTH, "").split("-");
-        if (lengths.length == 2) {
-            try {
-                return Integer.parseInt(lengths[0]);
-            } catch (NumberFormatException e) {
-                return DEFAULT_PIN_LENGTH;
-            }
-        }
-        return DEFAULT_PIN_LENGTH;
-    }
-
-    private static String generatePin(int length) {
-        SecureRandom random = new SecureRandom();
-        return String.format(Locale.US, "%010d", Math.abs(random.nextLong()))
-                .substring(0, length);
-
-    }
-}
diff --git a/src/com/android/phone/vvm/omtp/protocol/Vvm3Subscriber.java b/src/com/android/phone/vvm/omtp/protocol/Vvm3Subscriber.java
deleted file mode 100644
index ad00aa4..0000000
--- a/src/com/android/phone/vvm/omtp/protocol/Vvm3Subscriber.java
+++ /dev/null
@@ -1,323 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.phone.vvm.omtp.protocol;
-
-import android.annotation.WorkerThread;
-import android.net.Network;
-import android.os.Build;
-import android.os.Bundle;
-import android.telecom.PhoneAccountHandle;
-import android.telephony.TelephonyManager;
-import android.text.Html;
-import android.text.Spanned;
-import android.text.style.URLSpan;
-import android.util.ArrayMap;
-import com.android.phone.Assert;
-import com.android.phone.VoicemailStatus;
-import com.android.phone.vvm.omtp.ActivationTask;
-import com.android.phone.vvm.omtp.OmtpEvents;
-import com.android.phone.vvm.omtp.OmtpVvmCarrierConfigHelper;
-import com.android.phone.vvm.omtp.VvmLog;
-import com.android.phone.vvm.omtp.sync.VvmNetworkRequest;
-import com.android.phone.vvm.omtp.sync.VvmNetworkRequest.NetworkWrapper;
-import com.android.phone.vvm.omtp.sync.VvmNetworkRequest.RequestFailedException;
-import com.android.volley.AuthFailureError;
-import com.android.volley.Request;
-import com.android.volley.RequestQueue;
-import com.android.volley.toolbox.HurlStack;
-import com.android.volley.toolbox.RequestFuture;
-import com.android.volley.toolbox.StringRequest;
-import com.android.volley.toolbox.Volley;
-import java.io.IOException;
-import java.net.CookieHandler;
-import java.net.CookieManager;
-import java.net.HttpURLConnection;
-import java.net.URL;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Random;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * Class to subscribe to basic VVM3 visual voicemail, for example, Verizon. Subscription is required
- * when the user is unprovisioned. This could happen when the user is on a legacy service, or
- * switched over from devices that used other type of visual voicemail.
- *
- * The STATUS SMS will come with a URL to the voicemail management gateway. From it we can find the
- * self provisioning gateway URL that we can modify voicemail services.
- *
- * A request to the self provisioning gateway to activate basic visual voicemail will return us with
- * a web page. If the user hasn't subscribe to it yet it will contain a link to confirm the
- * subscription. This link should be clicked through cellular network, and have cookies enabled.
- *
- * After the process is completed, the carrier should send us another STATUS SMS with a new or ready
- * user.
- */
-public class Vvm3Subscriber {
-
-    private static final String TAG = "Vvm3Subscriber";
-
-    private static final String OPERATION_GET_SPG_URL = "retrieveSPGURL";
-    private static final String SPG_URL_TAG = "spgurl";
-    private static final String TRANSACTION_ID_TAG = "transactionid";
-    //language=XML
-    private static final String VMG_XML_REQUEST_FORMAT = ""
-            + "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
-            + "<VMGVVMRequest>"
-            + "  <MessageHeader>"
-            + "    <transactionid>%1$s</transactionid>"
-            + "  </MessageHeader>"
-            + "  <MessageBody>"
-            + "    <mdn>%2$s</mdn>"
-            + "    <operation>%3$s</operation>"
-            + "    <source>Device</source>"
-            + "    <devicemodel>%4$s</devicemodel>"
-            + "  </MessageBody>"
-            + "</VMGVVMRequest>";
-
-    static final String VMG_URL_KEY = "vmg_url";
-
-    // Self provisioning POST key/values. VVM3 API 2.1.0 12.3
-    private static final String SPG_VZW_MDN_PARAM = "VZW_MDN";
-    private static final String SPG_VZW_SERVICE_PARAM = "VZW_SERVICE";
-    private static final String SPG_VZW_SERVICE_BASIC = "BVVM";
-    private static final String SPG_DEVICE_MODEL_PARAM = "DEVICE_MODEL";
-    // Value for all android device
-    private static final String SPG_DEVICE_MODEL_ANDROID = "DROID_4G";
-    private static final String SPG_APP_TOKEN_PARAM = "APP_TOKEN";
-    private static final String SPG_APP_TOKEN = "q8e3t5u2o1";
-    private static final String SPG_LANGUAGE_PARAM = "SPG_LANGUAGE_PARAM";
-    private static final String SPG_LANGUAGE_EN = "ENGLISH";
-
-    private static final String BASIC_SUBSCRIBE_LINK_TEXT = "Subscribe to Basic Visual Voice Mail";
-
-    private static final int REQUEST_TIMEOUT_SECONDS = 30;
-
-    private final ActivationTask mTask;
-    private final PhoneAccountHandle mHandle;
-    private final OmtpVvmCarrierConfigHelper mHelper;
-    private final VoicemailStatus.Editor mStatus;
-    private final Bundle mData;
-
-    private final String mNumber;
-
-    private RequestQueue mRequestQueue;
-
-    private static class ProvisioningException extends Exception {
-
-        public ProvisioningException(String message) {
-            super(message);
-        }
-    }
-
-    static {
-        // Set the default cookie handler to retain session data for the self provisioning gateway.
-        // Note; this is not ideal as it is application-wide, and can easily get clobbered.
-        // But it seems to be the preferred way to manage cookie for HttpURLConnection, and manually
-        // managing cookies will greatly increase complexity.
-        CookieManager cookieManager = new CookieManager();
-        CookieHandler.setDefault(cookieManager);
-    }
-
-    @WorkerThread
-    public Vvm3Subscriber(ActivationTask task, PhoneAccountHandle handle,
-            OmtpVvmCarrierConfigHelper helper, VoicemailStatus.Editor status, Bundle data) {
-        Assert.isNotMainThread();
-        mTask = task;
-        mHandle = handle;
-        mHelper = helper;
-        mStatus = status;
-        mData = data;
-
-        // Assuming getLine1Number() will work with VVM3. For unprovisioned users the IMAP username
-        // is not included in the status SMS, thus no other way to get the current phone number.
-        mNumber = mHelper.getContext().getSystemService(TelephonyManager.class)
-                .getLine1Number(mHelper.getSubId());
-    }
-
-    @WorkerThread
-    public void subscribe() {
-        Assert.isNotMainThread();
-        // Cellular data is required to subscribe.
-        // processSubscription() is called after network is available.
-        VvmLog.i(TAG, "Subscribing");
-
-        try (NetworkWrapper wrapper = VvmNetworkRequest.getNetwork(mHelper, mHandle, mStatus)) {
-            Network network = wrapper.get();
-            VvmLog.d(TAG, "provisioning: network available");
-            mRequestQueue = Volley
-                    .newRequestQueue(mHelper.getContext(), new NetworkSpecifiedHurlStack(network));
-            processSubscription();
-        } catch (RequestFailedException e) {
-            mHelper.handleEvent(mStatus, OmtpEvents.VVM3_VMG_CONNECTION_FAILED);
-            mTask.fail();
-        }
-    }
-
-    private void processSubscription() {
-        try {
-            String gatewayUrl = getSelfProvisioningGateway();
-            String selfProvisionResponse = getSelfProvisionResponse(gatewayUrl);
-            String subscribeLink = findSubscribeLink(selfProvisionResponse);
-            clickSubscribeLink(subscribeLink);
-        } catch (ProvisioningException e) {
-            VvmLog.e(TAG, e.toString());
-            mTask.fail();
-        }
-    }
-
-    /**
-     * Get the URL to perform self-provisioning from the voicemail management gateway.
-     */
-    private String getSelfProvisioningGateway() throws ProvisioningException {
-        VvmLog.i(TAG, "retrieving SPG URL");
-        String response = vvm3XmlRequest(OPERATION_GET_SPG_URL);
-        return extractText(response, SPG_URL_TAG);
-    }
-
-    /**
-     * Sent a request to the self-provisioning gateway, which will return us with a webpage. The
-     * page might contain a "Subscribe to Basic Visual Voice Mail" link to complete the
-     * subscription. The cookie from this response and cellular data is required to click the link.
-     */
-    private String getSelfProvisionResponse(String url) throws ProvisioningException {
-        VvmLog.i(TAG, "Retrieving self provisioning response");
-
-        RequestFuture<String> future = RequestFuture.newFuture();
-
-        StringRequest stringRequest = new StringRequest(Request.Method.POST, url, future, future) {
-            @Override
-            protected Map<String, String> getParams() {
-                Map<String, String> params = new ArrayMap<>();
-                params.put(SPG_VZW_MDN_PARAM, mNumber);
-                params.put(SPG_VZW_SERVICE_PARAM, SPG_VZW_SERVICE_BASIC);
-                params.put(SPG_DEVICE_MODEL_PARAM, SPG_DEVICE_MODEL_ANDROID);
-                params.put(SPG_APP_TOKEN_PARAM, SPG_APP_TOKEN);
-                // Language to display the subscription page. The page is never shown to the user
-                // so just use English.
-                params.put(SPG_LANGUAGE_PARAM, SPG_LANGUAGE_EN);
-                return params;
-            }
-        };
-
-        mRequestQueue.add(stringRequest);
-        try {
-            return future.get(REQUEST_TIMEOUT_SECONDS, TimeUnit.SECONDS);
-        } catch (InterruptedException | ExecutionException | TimeoutException e) {
-            mHelper.handleEvent(mStatus, OmtpEvents.VVM3_SPG_CONNECTION_FAILED);
-            throw new ProvisioningException(e.toString());
-        }
-    }
-
-    private void clickSubscribeLink(String subscribeLink) throws ProvisioningException {
-        VvmLog.i(TAG, "Clicking subscribe link");
-        RequestFuture<String> future = RequestFuture.newFuture();
-
-        StringRequest stringRequest = new StringRequest(Request.Method.POST,
-                subscribeLink, future, future);
-        mRequestQueue.add(stringRequest);
-        try {
-            // A new STATUS SMS will be sent after this request.
-            future.get(REQUEST_TIMEOUT_SECONDS, TimeUnit.SECONDS);
-        } catch (TimeoutException | ExecutionException | InterruptedException e) {
-            mHelper.handleEvent(mStatus, OmtpEvents.VVM3_SPG_CONNECTION_FAILED);
-            throw new ProvisioningException(e.toString());
-        }
-        // It could take very long for the STATUS SMS to return. Waiting for it is unreliable.
-        // Just leave the CONFIG STATUS as CONFIGURING and end the task. The user can always
-        // manually retry if it took too long.
-    }
-
-    private String vvm3XmlRequest(String operation) throws ProvisioningException {
-        VvmLog.d(TAG, "Sending vvm3XmlRequest for " + operation);
-        String voicemailManagementGateway = mData.getString(VMG_URL_KEY);
-        if (voicemailManagementGateway == null) {
-            VvmLog.e(TAG, "voicemailManagementGateway url unknown");
-            return null;
-        }
-        String transactionId = createTransactionId();
-        String body = String.format(Locale.US, VMG_XML_REQUEST_FORMAT,
-                transactionId, mNumber, operation, Build.MODEL);
-
-        RequestFuture<String> future = RequestFuture.newFuture();
-        StringRequest stringRequest = new StringRequest(Request.Method.POST,
-                voicemailManagementGateway, future, future) {
-            @Override
-            public byte[] getBody() throws AuthFailureError {
-                return body.getBytes();
-            }
-        };
-        mRequestQueue.add(stringRequest);
-
-        try {
-            String response = future.get(REQUEST_TIMEOUT_SECONDS, TimeUnit.SECONDS);
-            if (!transactionId.equals(extractText(response, TRANSACTION_ID_TAG))) {
-                throw new ProvisioningException("transactionId mismatch");
-            }
-            return response;
-        } catch (InterruptedException | ExecutionException | TimeoutException e) {
-            mHelper.handleEvent(mStatus, OmtpEvents.VVM3_VMG_CONNECTION_FAILED);
-            throw new ProvisioningException(e.toString());
-        }
-    }
-
-    private String findSubscribeLink(String response) throws ProvisioningException {
-        Spanned doc = Html.fromHtml(response, Html.FROM_HTML_MODE_LEGACY);
-        URLSpan[] spans = doc.getSpans(0, doc.length(), URLSpan.class);
-        StringBuilder fulltext = new StringBuilder();
-        for (URLSpan span : spans) {
-            String text = doc.subSequence(doc.getSpanStart(span), doc.getSpanEnd(span)).toString();
-            if (BASIC_SUBSCRIBE_LINK_TEXT.equals(text)) {
-                return span.getURL();
-            }
-            fulltext.append(text);
-        }
-        throw new ProvisioningException("Subscribe link not found: " + fulltext);
-    }
-
-    private String createTransactionId() {
-        return String.valueOf(Math.abs(new Random().nextLong()));
-    }
-
-    private String extractText(String xml, String tag) throws ProvisioningException {
-        Pattern pattern = Pattern.compile("<" + tag + ">(.*)<\\/" + tag + ">");
-        Matcher matcher = pattern.matcher(xml);
-        if (matcher.find()) {
-            return matcher.group(1);
-        }
-        throw new ProvisioningException("Tag " + tag + " not found in xml response");
-    }
-
-    private static class NetworkSpecifiedHurlStack extends HurlStack {
-
-        private final Network mNetwork;
-
-        public NetworkSpecifiedHurlStack(Network network) {
-            mNetwork = network;
-        }
-
-        @Override
-        protected HttpURLConnection createConnection(URL url) throws IOException {
-            return (HttpURLConnection) mNetwork.openConnection(url);
-        }
-
-    }
-}
diff --git a/src/com/android/phone/vvm/omtp/scheduling/BaseTask.java b/src/com/android/phone/vvm/omtp/scheduling/BaseTask.java
deleted file mode 100644
index 76537fa..0000000
--- a/src/com/android/phone/vvm/omtp/scheduling/BaseTask.java
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.phone.vvm.omtp.scheduling;
-
-import android.annotation.CallSuper;
-import android.annotation.MainThread;
-import android.annotation.WorkerThread;
-import android.content.Context;
-import android.content.Intent;
-import android.os.SystemClock;
-import android.support.annotation.NonNull;
-import android.telephony.SubscriptionManager;
-import com.android.phone.Assert;
-import com.android.phone.NeededForTesting;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Provides common utilities for task implementations, such as execution time and managing {@link
- * Policy}
- */
-public abstract class BaseTask implements Task {
-
-    private static final String EXTRA_SUB_ID = "extra_sub_id";
-
-    private Context mContext;
-
-    private int mId;
-    private int mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
-
-    private boolean mHasStarted;
-    private volatile boolean mHasFailed;
-
-    @NonNull
-    private final List<Policy> mPolicies = new ArrayList<>();
-
-    private long mExecutionTime;
-
-    private static Clock sClock = new Clock();
-
-    protected BaseTask(int id) {
-        mId = id;
-        mExecutionTime = getTimeMillis();
-    }
-
-    /**
-     * Modify the task ID to prevent arbitrary task from executing. Can only be called before {@link
-     * #onCreate(Context, Intent, int, int)} returns.
-     */
-    @MainThread
-    public void setId(int id) {
-        Assert.isMainThread();
-        mId = id;
-    }
-
-    @MainThread
-    public boolean hasStarted() {
-        Assert.isMainThread();
-        return mHasStarted;
-    }
-
-    @MainThread
-    public boolean hasFailed() {
-        Assert.isMainThread();
-        return mHasFailed;
-    }
-
-    public Context getContext() {
-        return mContext;
-    }
-
-    public int getSubId() {
-        return mSubId;
-    }
-    /**
-     * Should be call in the constructor or {@link Policy#onCreate(BaseTask, Intent, int, int)} will
-     * be missed.
-     */
-    @MainThread
-    public BaseTask addPolicy(Policy policy) {
-        Assert.isMainThread();
-        mPolicies.add(policy);
-        return this;
-    }
-
-    /**
-     * Indicate the task has failed. {@link Policy#onFail()} will be triggered once the execution
-     * ends. This mechanism is used by policies for actions such as determining whether to schedule
-     * a retry. Must be call inside {@link #onExecuteInBackgroundThread()}
-     */
-    @WorkerThread
-    public void fail() {
-        Assert.isNotMainThread();
-        mHasFailed = true;
-    }
-
-    @MainThread
-    public void setExecutionTime(long timeMillis) {
-        Assert.isMainThread();
-        mExecutionTime = timeMillis;
-    }
-
-    public long getTimeMillis() {
-        return sClock.getTimeMillis();
-    }
-
-    /**
-     * Creates an intent that can be used to restart the current task. Derived class should build
-     * their intent upon this.
-     */
-    public Intent createRestartIntent() {
-        return createIntent(getContext(), this.getClass(), mSubId);
-    }
-
-    /**
-     * Creates an intent that can be used to start the {@link TaskSchedulerService}. Derived class
-     * should build their intent upon this.
-     */
-    public static Intent createIntent(Context context, Class<? extends BaseTask> task, int subId) {
-        Intent intent = TaskSchedulerService.createIntent(context, task);
-        intent.putExtra(EXTRA_SUB_ID, subId);
-        return intent;
-    }
-
-    @Override
-    public TaskId getId() {
-        return new TaskId(mId, mSubId);
-    }
-
-    @Override
-    @CallSuper
-    public void onCreate(Context context, Intent intent, int flags, int startId) {
-        mContext = context;
-        mSubId = intent.getIntExtra(EXTRA_SUB_ID, SubscriptionManager.INVALID_SUBSCRIPTION_ID);
-        for (Policy policy : mPolicies) {
-            policy.onCreate(this, intent, flags, startId);
-        }
-    }
-
-    @Override
-    public long getReadyInMilliSeconds() {
-        return mExecutionTime - getTimeMillis();
-    }
-
-    @Override
-    @CallSuper
-    public void onBeforeExecute() {
-        for (Policy policy : mPolicies) {
-            policy.onBeforeExecute();
-        }
-        mHasStarted = true;
-    }
-
-    @Override
-    @CallSuper
-    public void onCompleted() {
-        if (mHasFailed) {
-            for (Policy policy : mPolicies) {
-                policy.onFail();
-            }
-        }
-
-        for (Policy policy : mPolicies) {
-            policy.onCompleted();
-        }
-    }
-
-    @Override
-    public void onDuplicatedTaskAdded(Task task) {
-        for (Policy policy : mPolicies) {
-            policy.onDuplicatedTaskAdded();
-        }
-    }
-
-    @NeededForTesting
-    static class Clock {
-
-        public long getTimeMillis() {
-            return SystemClock.elapsedRealtime();
-        }
-    }
-
-    /**
-     * Used to replace the clock with an deterministic clock
-     */
-    @NeededForTesting
-    static void setClockForTesting(Clock clock) {
-        sClock = clock;
-    }
-}
diff --git a/src/com/android/phone/vvm/omtp/scheduling/BlockerTask.java b/src/com/android/phone/vvm/omtp/scheduling/BlockerTask.java
deleted file mode 100644
index 9d91828..0000000
--- a/src/com/android/phone/vvm/omtp/scheduling/BlockerTask.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.phone.vvm.omtp.scheduling;
-
-import android.content.Context;
-import android.content.Intent;
-
-import com.android.phone.vvm.omtp.VvmLog;
-
-/**
- * Task to block another task of the same ID from being queued for a certain amount of time.
- */
-public class BlockerTask extends BaseTask {
-
-    private static final String TAG = "BlockerTask";
-
-    public static final String EXTRA_TASK_ID = "extra_task_id";
-    public static final String EXTRA_BLOCK_FOR_MILLIS = "extra_block_for_millis";
-
-    public BlockerTask() {
-        super(TASK_INVALID);
-    }
-
-    @Override
-    public void onCreate(Context context, Intent intent, int flags, int startId) {
-        super.onCreate(context, intent, flags, startId);
-        setId(intent.getIntExtra(EXTRA_TASK_ID, TASK_INVALID));
-        setExecutionTime(getTimeMillis() + intent.getIntExtra(EXTRA_BLOCK_FOR_MILLIS, 0));
-    }
-
-    @Override
-    public void onExecuteInBackgroundThread() {
-        // Do nothing.
-    }
-
-    @Override
-    public void onDuplicatedTaskAdded(Task task) {
-        VvmLog
-            .v(TAG, task.toString() + "blocked, " + getReadyInMilliSeconds() + "millis remaining");
-    }
-}
diff --git a/src/com/android/phone/vvm/omtp/scheduling/MinimalIntervalPolicy.java b/src/com/android/phone/vvm/omtp/scheduling/MinimalIntervalPolicy.java
deleted file mode 100644
index 8bb22ca..0000000
--- a/src/com/android/phone/vvm/omtp/scheduling/MinimalIntervalPolicy.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.phone.vvm.omtp.scheduling;
-
-import android.content.Intent;
-
-import com.android.phone.vvm.omtp.scheduling.Task.TaskId;
-
-/**
- * If a task with this policy succeeds, a {@link BlockerTask} with the same {@link TaskId} of the
- * task will be queued immediately, preventing the same task from running for a certain amount of
- * time.
- */
-public class MinimalIntervalPolicy implements Policy {
-
-    BaseTask mTask;
-    TaskId mId;
-    int mBlockForMillis;
-
-    public MinimalIntervalPolicy(int blockForMillis) {
-        mBlockForMillis = blockForMillis;
-    }
-
-    @Override
-    public void onCreate(BaseTask task, Intent intent, int flags, int startId) {
-        mTask = task;
-        mId = mTask.getId();
-    }
-
-    @Override
-    public void onBeforeExecute() {
-
-    }
-
-    @Override
-    public void onCompleted() {
-        if (!mTask.hasFailed()) {
-            Intent intent = mTask
-                    .createIntent(mTask.getContext(), BlockerTask.class, mId.subId);
-            intent.putExtra(BlockerTask.EXTRA_TASK_ID, mId.id);
-            intent.putExtra(BlockerTask.EXTRA_BLOCK_FOR_MILLIS, mBlockForMillis);
-            mTask.getContext().startService(intent);
-        }
-    }
-
-    @Override
-    public void onFail() {
-
-    }
-
-    @Override
-    public void onDuplicatedTaskAdded() {
-
-    }
-}
diff --git a/src/com/android/phone/vvm/omtp/scheduling/Policy.java b/src/com/android/phone/vvm/omtp/scheduling/Policy.java
deleted file mode 100644
index fcb01b8..0000000
--- a/src/com/android/phone/vvm/omtp/scheduling/Policy.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.phone.vvm.omtp.scheduling;
-
-import android.content.Intent;
-
-/**
- * A set of listeners managed by {@link BaseTask} for common behaviors such as retrying. Call {@link
- * BaseTask#addPolicy(Policy)} to add a policy.
- */
-public interface Policy {
-
-    void onCreate(BaseTask task, Intent intent, int flags, int startId);
-
-    void onBeforeExecute();
-
-    void onCompleted();
-
-    void onFail();
-
-    void onDuplicatedTaskAdded();
-}
diff --git a/src/com/android/phone/vvm/omtp/scheduling/PostponePolicy.java b/src/com/android/phone/vvm/omtp/scheduling/PostponePolicy.java
deleted file mode 100644
index f23d7f7..0000000
--- a/src/com/android/phone/vvm/omtp/scheduling/PostponePolicy.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.phone.vvm.omtp.scheduling;
-
-import android.content.Intent;
-
-import com.android.phone.vvm.omtp.VvmLog;
-
-/**
- * A task with Postpone policy will not be executed immediately. It will wait for a while and if a
- * duplicated task is queued during the duration, the task will be postponed further. The task will
- * only be executed if no new task was added in postponeMillis. Useful to batch small tasks in quick
- * succession together.
- */
-public class PostponePolicy implements Policy {
-
-    private static final String TAG = "PostponePolicy";
-
-    private final int mPostponeMillis;
-    private BaseTask mTask;
-
-    public PostponePolicy(int postponeMillis) {
-        mPostponeMillis = postponeMillis;
-    }
-
-    @Override
-    public void onCreate(BaseTask task, Intent intent, int flags, int startId) {
-        mTask = task;
-        mTask.setExecutionTime(mTask.getTimeMillis() + mPostponeMillis);
-    }
-
-    @Override
-    public void onBeforeExecute() {
-        // Do nothing
-    }
-
-    @Override
-    public void onCompleted() {
-        // Do nothing
-    }
-
-    @Override
-    public void onFail() {
-        // Do nothing
-    }
-
-    @Override
-    public void onDuplicatedTaskAdded() {
-        if (mTask.hasStarted()) {
-            return;
-        }
-        VvmLog.d(TAG, "postponing " + mTask);
-        mTask.setExecutionTime(mTask.getTimeMillis() + mPostponeMillis);
-    }
-}
diff --git a/src/com/android/phone/vvm/omtp/scheduling/RetryPolicy.java b/src/com/android/phone/vvm/omtp/scheduling/RetryPolicy.java
deleted file mode 100644
index 4f4126a..0000000
--- a/src/com/android/phone/vvm/omtp/scheduling/RetryPolicy.java
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.phone.vvm.omtp.scheduling;
-
-import android.content.Intent;
-import android.telecom.PhoneAccountHandle;
-import com.android.phone.VoicemailStatus;
-import com.android.phone.vvm.omtp.VvmLog;
-import com.android.phone.vvm.omtp.utils.PhoneAccountHandleConverter;
-
-/**
- * A task with this policy will automatically re-queue itself if {@link BaseTask#fail()} has been
- * called during {@link BaseTask#onExecuteInBackgroundThread()}. A task will be retried at most
- * <code>retryLimit</code> times and with a <code>retryDelayMillis</code> interval in between.
- */
-public class RetryPolicy implements Policy {
-
-    private static final String TAG = "RetryPolicy";
-    private static final String EXTRA_RETRY_COUNT = "extra_retry_count";
-
-    private final int mRetryLimit;
-    private final int mRetryDelayMillis;
-
-    private BaseTask mTask;
-
-    private int mRetryCount;
-    private boolean mFailed;
-
-    private VoicemailStatus.DeferredEditor mVoicemailStatusEditor;
-
-    public RetryPolicy(int retryLimit, int retryDelayMillis) {
-        mRetryLimit = retryLimit;
-        mRetryDelayMillis = retryDelayMillis;
-    }
-
-    private boolean hasMoreRetries() {
-        return mRetryCount < mRetryLimit;
-    }
-
-    /**
-     * Error status should only be set if retries has exhausted or the task is successful. Status
-     * writes to this editor will be deferred until the task has ended, and will only be committed
-     * if the task is successful or there are no retries left.
-     */
-    public VoicemailStatus.Editor getVoicemailStatusEditor() {
-        return mVoicemailStatusEditor;
-    }
-
-    @Override
-    public void onCreate(BaseTask task, Intent intent, int flags, int startId) {
-        mTask = task;
-        mRetryCount = intent.getIntExtra(EXTRA_RETRY_COUNT, 0);
-        if (mRetryCount > 0) {
-            VvmLog.d(TAG, "retry #" + mRetryCount + " for " + mTask + " queued, executing in "
-                    + mRetryDelayMillis);
-            mTask.setExecutionTime(mTask.getTimeMillis() + mRetryDelayMillis);
-        }
-        PhoneAccountHandle phoneAccountHandle = PhoneAccountHandleConverter
-                .fromSubId(task.getSubId());
-        if (phoneAccountHandle == null) {
-            VvmLog.e(TAG, "null phone account for subId " + task.getSubId());
-            // This should never happen, but continue on if it does. The status write will be
-            // discarded.
-        }
-        mVoicemailStatusEditor = VoicemailStatus
-                .deferredEdit(task.getContext(), phoneAccountHandle);
-    }
-
-    @Override
-    public void onBeforeExecute() {
-
-    }
-
-    @Override
-    public void onCompleted() {
-        if (!mFailed || !hasMoreRetries()) {
-            if (!mFailed) {
-                VvmLog.d(TAG, mTask.toString() + " completed successfully");
-            }
-            if (!hasMoreRetries()) {
-                VvmLog.d(TAG, "Retry limit for " + mTask + " reached");
-            }
-            VvmLog.i(TAG, "committing deferred status: " + mVoicemailStatusEditor.getValues());
-            mVoicemailStatusEditor.deferredApply();
-            return;
-        }
-        VvmLog.i(TAG, "discarding deferred status: " + mVoicemailStatusEditor.getValues());
-        Intent intent = mTask.createRestartIntent();
-        intent.putExtra(EXTRA_RETRY_COUNT, mRetryCount + 1);
-
-        mTask.getContext().startService(intent);
-    }
-
-    @Override
-    public void onFail() {
-        mFailed = true;
-    }
-
-    @Override
-    public void onDuplicatedTaskAdded() {
-
-    }
-}
diff --git a/src/com/android/phone/vvm/omtp/scheduling/Task.java b/src/com/android/phone/vvm/omtp/scheduling/Task.java
deleted file mode 100644
index 05d86fd..0000000
--- a/src/com/android/phone/vvm/omtp/scheduling/Task.java
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.phone.vvm.omtp.scheduling;
-
-import android.annotation.MainThread;
-import android.annotation.WorkerThread;
-import android.content.Context;
-import android.content.Intent;
-import java.util.Objects;
-
-/**
- * A task for {@link TaskSchedulerService} to execute. Since the task is sent through a intent to
- * the scheduler, The task must be constructable with the intent. Specifically, It must have a
- * constructor with zero arguments, and have all relevant data packed inside the intent. Use {@link
- * TaskSchedulerService#createIntent(Context, Class)} to create a intent that will construct the
- * Task.
- *
- * <p>Only {@link #onExecuteInBackgroundThread()} is run on the worker thread.
- */
-public interface Task {
-
-    /**
-     * TaskId to indicate it has not be set. If a task does not provide a default TaskId it should
-     * be set before {@link Task#onCreate(Context, Intent, int, int) returns}
-     */
-    int TASK_INVALID = -1;
-
-    /**
-     * TaskId to indicate it should always be queued regardless of duplicates. {@link
-     * Task#onDuplicatedTaskAdded(Task)} will never be called on tasks with this TaskId.
-     */
-    int TASK_ALLOW_DUPLICATES = -2;
-
-    int TASK_UPLOAD = 1;
-    int TASK_SYNC = 2;
-    int TASK_ACTIVATION = 3;
-
-    /**
-     * Used to differentiate between types of tasks. If a task with the same TaskId is already in
-     * the queue the new task will be rejected.
-     */
-    class TaskId {
-
-        /**
-         * Indicates the operation type of the task.
-         */
-        public final int id;
-        /**
-         * Same operation for a different subId is allowed. subId is used to differentiate phone
-         * accounts in multi-SIM scenario. For example, each SIM can queue a sync task for their
-         * own.
-         */
-        public final int subId;
-
-        public TaskId(int id, int subId) {
-            this.id = id;
-            this.subId = subId;
-        }
-
-        @Override
-        public boolean equals(Object object) {
-            if (!(object instanceof TaskId)) {
-                return false;
-            }
-            TaskId other = (TaskId) object;
-            return id == other.id && subId == other.subId;
-        }
-
-        @Override
-        public int hashCode() {
-            return Objects.hash(id, subId);
-        }
-    }
-
-    TaskId getId();
-
-    @MainThread
-    void onCreate(Context context, Intent intent, int flags, int startId);
-
-    /**
-     * @return number of milliSeconds the scheduler should wait before running this task. A value
-     * less than {@link TaskSchedulerService#READY_TOLERANCE_MILLISECONDS} will be considered ready.
-     * If no tasks are ready, the scheduler will sleep for this amount of time before doing another
-     * check (it will still wake if a new task is added). The first task in the queue that is ready
-     * will be executed.
-     */
-    @MainThread
-    long getReadyInMilliSeconds();
-
-    /**
-     * Called on the main thread when the scheduler is about to send the task into the worker
-     * thread, calling {@link #onExecuteInBackgroundThread()}
-     */
-    @MainThread
-    void onBeforeExecute();
-
-    /**
-     * The actual payload of the task, executed on the worker thread.
-     */
-    @WorkerThread
-    void onExecuteInBackgroundThread();
-
-    /**
-     * Called on the main thread when {@link #onExecuteInBackgroundThread()} has finished or thrown
-     * an uncaught exception. The task is already removed from the queue at this point, and a same
-     * task can be queued again.
-     */
-    @MainThread
-    void onCompleted();
-
-    /**
-     * Another task with the same TaskId has been added. Necessary data can be retrieved from the
-     * other task, and after this returns the task will be discarded.
-     */
-    @MainThread
-    void onDuplicatedTaskAdded(Task task);
-}
diff --git a/src/com/android/phone/vvm/omtp/scheduling/TaskSchedulerService.java b/src/com/android/phone/vvm/omtp/scheduling/TaskSchedulerService.java
deleted file mode 100644
index 3d6fcdb..0000000
--- a/src/com/android/phone/vvm/omtp/scheduling/TaskSchedulerService.java
+++ /dev/null
@@ -1,392 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.phone.vvm.omtp.scheduling;
-
-import android.annotation.MainThread;
-import android.annotation.Nullable;
-import android.annotation.WorkerThread;
-import android.app.AlarmManager;
-import android.app.PendingIntent;
-import android.app.Service;
-import android.content.Context;
-import android.content.Intent;
-import android.os.Binder;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.IBinder;
-import android.os.Looper;
-import android.os.Message;
-import android.os.PowerManager;
-import android.os.PowerManager.WakeLock;
-import android.os.SystemClock;
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.phone.Assert;
-import com.android.phone.NeededForTesting;
-import com.android.phone.vvm.omtp.VvmLog;
-import com.android.phone.vvm.omtp.scheduling.Task.TaskId;
-import java.util.ArrayDeque;
-import java.util.Queue;
-
-/**
- * A service to queue and run {@link Task} on a worker thread. Only one task will be ran at a time,
- * and same task cannot exist in the queue at the same time. The service will be started when a
- * intent is received, and stopped when there are no more tasks in the queue.
- */
-public class TaskSchedulerService extends Service {
-
-    private static final String TAG = "VvmTaskScheduler";
-
-    private static final String ACTION_WAKEUP = "action_wakeup";
-
-    private static final int READY_TOLERANCE_MILLISECONDS = 100;
-
-    /**
-     * Threshold to determine whether to do a short or long sleep when a task is scheduled in the
-     * future.
-     *
-     * <p>A short sleep will continue to held the wake lock and use {@link
-     * Handler#postDelayed(Runnable, long)} to wait for the next task.
-     *
-     * <p>A long sleep will release the wake lock and set a {@link AlarmManager} alarm. The alarm is
-     * exact and will wake up the device. Note: as this service is run in the telephony process it
-     * does not seem to be restricted by doze or sleep, it will fire exactly at the moment. The
-     * unbundled version should take doze into account.
-     */
-    private static final int SHORT_SLEEP_THRESHOLD_MILLISECONDS = 60_000;
-    /**
-     * When there are no more tasks to be run the service should be stopped. But when all tasks has
-     * finished there might still be more tasks in the message queue waiting to be processed,
-     * especially the ones submitted in {@link Task#onCompleted()}. Wait for a while before stopping
-     * the service to make sure there are no pending messages.
-     */
-    private static final int STOP_DELAY_MILLISECONDS = 5_000;
-    private static final String EXTRA_CLASS_NAME = "extra_class_name";
-
-    private static final String WAKE_LOCK_TAG = "TaskSchedulerService_wakelock";
-
-    // The thread to run tasks on
-    private volatile WorkerThreadHandler mWorkerThreadHandler;
-
-    private Context mContext = this;
-    /**
-     * Used by tests to turn task handling into a single threaded process by calling {@link
-     * Handler#handleMessage(Message)} directly
-     */
-    private MessageSender mMessageSender = new MessageSender();
-
-    private MainThreadHandler mMainThreadHandler;
-
-    private WakeLock mWakeLock;
-
-    /**
-     * Main thread only, access through {@link #getTasks()}
-     */
-    private final Queue<Task> mTasks = new ArrayDeque<>();
-    private boolean mWorkerThreadIsBusy = false;
-
-    private final Runnable mStopServiceWithDelay = new Runnable() {
-        @Override
-        public void run() {
-            VvmLog.d(TAG, "Stopping service");
-            stopSelf();
-        }
-    };
-    /**
-     * Should attempt to run the next task when a task has finished or been added.
-     */
-    private boolean mTaskAutoRunDisabledForTesting = false;
-
-    @VisibleForTesting
-    final class WorkerThreadHandler extends Handler {
-
-        public WorkerThreadHandler(Looper looper) {
-            super(looper);
-        }
-
-        @Override
-        @WorkerThread
-        public void handleMessage(Message msg) {
-            Assert.isNotMainThread();
-            Task task = (Task) msg.obj;
-            try {
-                VvmLog.v(TAG, "executing task " + task);
-                task.onExecuteInBackgroundThread();
-            } catch (Throwable throwable) {
-                VvmLog.e(TAG, "Exception while executing task " + task + ":", throwable);
-            }
-
-            Message schedulerMessage = mMainThreadHandler.obtainMessage();
-            schedulerMessage.obj = task;
-            mMessageSender.send(schedulerMessage);
-        }
-    }
-
-    @VisibleForTesting
-    final class MainThreadHandler extends Handler {
-
-        public MainThreadHandler(Looper looper) {
-            super(looper);
-        }
-
-        @Override
-        @MainThread
-        public void handleMessage(Message msg) {
-            Assert.isMainThread();
-            Task task = (Task) msg.obj;
-            getTasks().remove(task);
-            task.onCompleted();
-            mWorkerThreadIsBusy = false;
-            maybeRunNextTask();
-        }
-    }
-
-    @Override
-    @MainThread
-    public void onCreate() {
-        super.onCreate();
-        mWakeLock = getSystemService(PowerManager.class)
-                .newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKE_LOCK_TAG);
-        mWakeLock.setReferenceCounted(false);
-        HandlerThread thread = new HandlerThread("VvmTaskSchedulerService");
-        thread.start();
-
-        mWorkerThreadHandler = new WorkerThreadHandler(thread.getLooper());
-        mMainThreadHandler = new MainThreadHandler(Looper.getMainLooper());
-    }
-
-    @Override
-    public void onDestroy() {
-        mWorkerThreadHandler.getLooper().quit();
-        mWakeLock.release();
-    }
-
-    @Override
-    @MainThread
-    public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
-        Assert.isMainThread();
-        // maybeRunNextTask() will release the wakelock either by entering a long sleep or stopping
-        // the service.
-        mWakeLock.acquire();
-        if (ACTION_WAKEUP.equals(intent.getAction())) {
-            VvmLog.d(TAG, "woke up by AlarmManager");
-        } else {
-            Task task = createTask(intent, flags, startId);
-            if (task == null) {
-                VvmLog.e(TAG, "cannot create task form intent");
-            } else {
-                addTask(task);
-            }
-        }
-        maybeRunNextTask();
-        // STICKY means the service will be automatically restarted will the last intent if it is
-        // killed.
-        return START_NOT_STICKY;
-    }
-
-    @MainThread
-    @VisibleForTesting
-    void addTask(Task task) {
-        Assert.isMainThread();
-        if (task.getId().id == Task.TASK_INVALID) {
-            throw new AssertionError("Task id was not set to a valid value before adding.");
-        }
-        if (task.getId().id != Task.TASK_ALLOW_DUPLICATES) {
-            Task oldTask = getTask(task.getId());
-            if (oldTask != null) {
-                oldTask.onDuplicatedTaskAdded(task);
-                return;
-            }
-        }
-        mMainThreadHandler.removeCallbacks(mStopServiceWithDelay);
-        getTasks().add(task);
-        maybeRunNextTask();
-    }
-
-    @MainThread
-    @Nullable
-    private Task getTask(TaskId taskId) {
-        Assert.isMainThread();
-        for (Task task : getTasks()) {
-            if (task.getId().equals(taskId)) {
-                return task;
-            }
-        }
-        return null;
-    }
-
-    @MainThread
-    private Queue<Task> getTasks() {
-        Assert.isMainThread();
-        return mTasks;
-    }
-
-    /**
-     * Create an intent that will queue the <code>task</code>
-     */
-    public static Intent createIntent(Context context, Class<? extends Task> task) {
-        Intent intent = new Intent(context, TaskSchedulerService.class);
-        intent.putExtra(EXTRA_CLASS_NAME, task.getName());
-        return intent;
-    }
-
-    @VisibleForTesting
-    @MainThread
-    @Nullable
-    Task createTask(@Nullable Intent intent, int flags, int startId) {
-        Assert.isMainThread();
-        if (intent == null) {
-            return null;
-        }
-        String className = intent.getStringExtra(EXTRA_CLASS_NAME);
-        VvmLog.d(TAG, "create task:" + className);
-        if (className == null) {
-            throw new IllegalArgumentException("EXTRA_CLASS_NAME expected");
-        }
-        try {
-            Task task = (Task) Class.forName(className).newInstance();
-            task.onCreate(mContext, intent, flags, startId);
-            return task;
-        } catch (ClassNotFoundException | IllegalAccessException | InstantiationException e) {
-            throw new IllegalArgumentException(e);
-        }
-    }
-
-    @MainThread
-    private void maybeRunNextTask() {
-        Assert.isMainThread();
-        if (mWorkerThreadIsBusy) {
-            return;
-        }
-        if (mTaskAutoRunDisabledForTesting) {
-            // If mTaskAutoRunDisabledForTesting is true, runNextTask() must be explicitly called
-            // to run the next task.
-            return;
-        }
-
-        runNextTask();
-    }
-
-    @VisibleForTesting
-    @MainThread
-    void runNextTask() {
-        Assert.isMainThread();
-        // The current alarm is no longer valid, a new one will be set up if required.
-        getSystemService(AlarmManager.class).cancel(getWakeupIntent());
-        if (getTasks().isEmpty()) {
-            prepareStop();
-            return;
-        }
-        Long minimalWaitTime = null;
-        for (Task task : getTasks()) {
-            long waitTime = task.getReadyInMilliSeconds();
-            if (waitTime < READY_TOLERANCE_MILLISECONDS) {
-                task.onBeforeExecute();
-                Message message = mWorkerThreadHandler.obtainMessage();
-                message.obj = task;
-                mWorkerThreadIsBusy = true;
-                mMessageSender.send(message);
-                return;
-            } else {
-                if (minimalWaitTime == null || waitTime < minimalWaitTime) {
-                    minimalWaitTime = waitTime;
-                }
-            }
-        }
-        VvmLog.d(TAG, "minimal wait time:" + minimalWaitTime);
-        if (!mTaskAutoRunDisabledForTesting && minimalWaitTime != null) {
-            // No tasks are currently ready. Sleep until the next one should be.
-            // If a new task is added during the sleep the service will wake immediately.
-            sleep(minimalWaitTime);
-        }
-    }
-
-    private void sleep(long timeMillis) {
-        if (timeMillis < SHORT_SLEEP_THRESHOLD_MILLISECONDS) {
-            mMainThreadHandler.postDelayed(new Runnable() {
-                @Override
-                public void run() {
-                    maybeRunNextTask();
-                }
-            }, timeMillis);
-            return;
-        }
-
-        // Tasks does not have a strict timing requirement, use AlarmManager.set() so the OS could
-        // optimize the battery usage. As this service currently run in the telephony process the
-        // OS give it privileges to behave the same as setExact(), but set() is the targeted
-        // behavior once this is unbundled.
-        getSystemService(AlarmManager.class).set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
-                SystemClock.elapsedRealtime() + timeMillis,
-                getWakeupIntent());
-        mWakeLock.release();
-        VvmLog.d(TAG, "Long sleep for " + timeMillis + " millis");
-    }
-
-    private PendingIntent getWakeupIntent() {
-        Intent intent = new Intent(ACTION_WAKEUP, null, this, getClass());
-        return PendingIntent.getService(this, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
-    }
-
-    private void prepareStop() {
-        VvmLog.d(TAG,
-                "No more tasks, stopping service if no task are added in "
-                        + STOP_DELAY_MILLISECONDS + " millis");
-        mMainThreadHandler.postDelayed(mStopServiceWithDelay, STOP_DELAY_MILLISECONDS);
-    }
-
-    static class MessageSender {
-
-        public void send(Message message) {
-            message.sendToTarget();
-        }
-    }
-
-    @NeededForTesting
-    void setContextForTest(Context context) {
-        mContext = context;
-    }
-
-    @NeededForTesting
-    void setTaskAutoRunDisabledForTest(boolean value) {
-        mTaskAutoRunDisabledForTesting = value;
-    }
-
-    @NeededForTesting
-    void setMessageSenderForTest(MessageSender sender) {
-        mMessageSender = sender;
-    }
-
-    @NeededForTesting
-    void clearTasksForTest() {
-        mTasks.clear();
-    }
-
-    @Override
-    @Nullable
-    public IBinder onBind(Intent intent) {
-        return new LocalBinder();
-    }
-
-    @NeededForTesting
-    class LocalBinder extends Binder {
-
-        @NeededForTesting
-        public TaskSchedulerService getService() {
-            return TaskSchedulerService.this;
-        }
-    }
-}
diff --git a/src/com/android/phone/vvm/omtp/sms/LegacyModeSmsHandler.java b/src/com/android/phone/vvm/omtp/sms/LegacyModeSmsHandler.java
deleted file mode 100644
index 6a5f349..0000000
--- a/src/com/android/phone/vvm/omtp/sms/LegacyModeSmsHandler.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2016 Google Inc. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.phone.vvm.omtp.sms;
-
-import android.content.Context;
-import android.os.Bundle;
-import android.telephony.VisualVoicemailSms;
-
-import com.android.internal.telephony.Phone;
-import com.android.phone.PhoneUtils;
-import com.android.phone.vvm.omtp.OmtpConstants;
-import com.android.phone.vvm.omtp.OmtpVvmCarrierConfigHelper;
-import com.android.phone.vvm.omtp.VvmLog;
-
-/**
- * Class ot handle voicemail SMS under legacy mode
- *
- * @see OmtpVvmCarrierConfigHelper#isLegacyModeEnabled()
- */
-public class LegacyModeSmsHandler {
-
-    private static final String TAG = "LegacyModeSmsHandler";
-
-    public static void handle(Context context, VisualVoicemailSms sms) {
-        VvmLog.v(TAG, "processing VVM SMS on legacy mode");
-        String eventType = sms.getPrefix();
-        Bundle data = sms.getFields();
-
-        if (eventType.equals(OmtpConstants.SYNC_SMS_PREFIX)) {
-            SyncMessage message = new SyncMessage(data);
-            VvmLog.v(TAG, "Received SYNC sms for " + sms.getPhoneAccountHandle() +
-                    " with event " + message.getSyncTriggerEvent());
-
-            switch (message.getSyncTriggerEvent()) {
-                case OmtpConstants.NEW_MESSAGE:
-                case OmtpConstants.MAILBOX_UPDATE:
-                    // The user has called into the voicemail and the new message count could
-                    // change.
-                    // For some carriers new message count could be set to 0 even if there are still
-                    // unread messages, to clear the message waiting indicator.
-                    VvmLog.v(TAG, "updating MWI");
-                    Phone phone = PhoneUtils.getPhoneForPhoneAccountHandle(
-                            sms.getPhoneAccountHandle());
-                    // Setting voicemail message count to non-zero will show the telephony voicemail
-                    // notification, and zero will clear it.
-                    phone.setVoiceMessageCount(message.getNewMessageCount());
-                    break;
-                default:
-                    break;
-            }
-        }
-    }
-}
diff --git a/src/com/android/phone/vvm/omtp/sms/OmtpCvvmMessageSender.java b/src/com/android/phone/vvm/omtp/sms/OmtpCvvmMessageSender.java
deleted file mode 100644
index 98d8594..0000000
--- a/src/com/android/phone/vvm/omtp/sms/OmtpCvvmMessageSender.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2015 Google Inc. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-package com.android.phone.vvm.omtp.sms;
-
-import android.annotation.Nullable;
-import android.app.PendingIntent;
-import android.telephony.SmsManager;
-
-import com.android.phone.vvm.omtp.OmtpConstants;
-
-/**
- * An implementation of the OmtpMessageSender for T-Mobile.
- */
-public class OmtpCvvmMessageSender extends OmtpMessageSender {
-    public OmtpCvvmMessageSender(SmsManager smsManager, short applicationPort,
-            String destinationNumber) {
-        super(smsManager, applicationPort, destinationNumber);
-    }
-
-    @Override
-    public void requestVvmActivation(@Nullable PendingIntent sentIntent) {
-        sendCvvmMessage(OmtpConstants.ACTIVATE_REQUEST, sentIntent);
-    }
-
-    @Override
-    public void requestVvmDeactivation(@Nullable PendingIntent sentIntent) {
-        sendCvvmMessage(OmtpConstants.DEACTIVATE_REQUEST, sentIntent);
-    }
-
-    @Override
-    public void requestVvmStatus(@Nullable PendingIntent sentIntent) {
-        sendCvvmMessage(OmtpConstants.STATUS_REQUEST, sentIntent);
-    }
-
-    private void sendCvvmMessage(String request, PendingIntent sentIntent) {
-        StringBuilder sb = new StringBuilder().append(request);
-        sb.append(OmtpConstants.SMS_PREFIX_SEPARATOR);
-        appendField(sb, "dt" /* device type */, "6" /* no VTT (transcription) support*/);
-        sendSms(sb.toString(), sentIntent);
-    }
-}
diff --git a/src/com/android/phone/vvm/omtp/sms/OmtpMessageReceiver.java b/src/com/android/phone/vvm/omtp/sms/OmtpMessageReceiver.java
deleted file mode 100644
index d42e70e..0000000
--- a/src/com/android/phone/vvm/omtp/sms/OmtpMessageReceiver.java
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-package com.android.phone.vvm.omtp.sms;
-
-import android.content.ContentUris;
-import android.content.Context;
-import android.content.Intent;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.UserManager;
-import android.provider.VoicemailContract;
-import android.telecom.PhoneAccountHandle;
-import android.telecom.Voicemail;
-import android.telephony.VisualVoicemailSms;
-
-import com.android.phone.settings.VisualVoicemailSettingsUtil;
-import com.android.phone.vvm.omtp.ActivationTask;
-import com.android.phone.vvm.omtp.OmtpConstants;
-import com.android.phone.vvm.omtp.OmtpVvmCarrierConfigHelper;
-import com.android.phone.vvm.omtp.VvmLog;
-import com.android.phone.vvm.omtp.protocol.VisualVoicemailProtocol;
-import com.android.phone.vvm.omtp.sync.OmtpVvmSyncService;
-import com.android.phone.vvm.omtp.sync.SyncOneTask;
-import com.android.phone.vvm.omtp.sync.SyncTask;
-import com.android.phone.vvm.omtp.sync.VoicemailsQueryHelper;
-import com.android.phone.vvm.omtp.utils.PhoneAccountHandleConverter;
-
-/**
- * Receive SMS messages and send for processing by the OMTP visual voicemail source.
- */
-public class OmtpMessageReceiver {
-
-    private static final String TAG = "OmtpMessageReceiver";
-
-    public static void onReceive(Context context, VisualVoicemailSms sms) {
-
-        PhoneAccountHandle phone = sms.getPhoneAccountHandle();
-        int subId = PhoneAccountHandleConverter.toSubId(phone);
-        if (!UserManager.get(context).isUserUnlocked()) {
-            VvmLog.i(TAG, "Received message on locked device");
-            // LegacyModeSmsHandler can handle new message notifications without storage access
-            LegacyModeSmsHandler.handle(context, sms);
-            // A full sync will happen after the device is unlocked, so nothing else need to be
-            // done.
-            return;
-        }
-
-        OmtpVvmCarrierConfigHelper helper = new OmtpVvmCarrierConfigHelper(context, subId);
-        if (!VisualVoicemailSettingsUtil.isEnabled(context, phone)) {
-            if (helper.isLegacyModeEnabled()) {
-                LegacyModeSmsHandler.handle(context, sms);
-            } else {
-                VvmLog.i(TAG, "Received vvm message for disabled vvm source.");
-            }
-            return;
-        }
-
-        String eventType = sms.getPrefix();
-        Bundle data = sms.getFields();
-
-        if (eventType == null || data == null) {
-            VvmLog.e(TAG, "Unparsable VVM SMS received, ignoring");
-            return;
-        }
-
-        if (eventType.equals(OmtpConstants.SYNC_SMS_PREFIX)) {
-            SyncMessage message = new SyncMessage(data);
-
-            VvmLog.v(TAG, "Received SYNC sms for " + subId +
-                    " with event " + message.getSyncTriggerEvent());
-            processSync(context, phone, message);
-        } else if (eventType.equals(OmtpConstants.STATUS_SMS_PREFIX)) {
-            VvmLog.v(TAG, "Received Status sms for " + subId);
-            // If the STATUS SMS is initiated by ActivationTask the TaskSchedulerService will reject
-            // the follow request. Providing the data will also prevent ActivationTask from
-            // requesting another STATUS SMS. The following task will only run if the carrier
-            // spontaneous send a STATUS SMS, in that case, the VVM service should be reactivated.
-            ActivationTask.start(context, subId, data);
-        } else {
-            VvmLog.w(TAG, "Unknown prefix: " + eventType);
-            VisualVoicemailProtocol protocol = helper.getProtocol();
-            if (protocol == null) {
-                return;
-            }
-            Bundle statusData = helper.getProtocol()
-                    .translateStatusSmsBundle(helper, eventType, data);
-            if (statusData != null) {
-                VvmLog.i(TAG, "Protocol recognized the SMS as STATUS, activating");
-                ActivationTask.start(context, subId, data);
-            }
-        }
-    }
-
-    /**
-     * A sync message has two purposes: to signal a new voicemail message, and to indicate the
-     * voicemails on the server have changed remotely (usually through the TUI). Save the new
-     * message to the voicemail provider if it is the former case and perform a full sync in the
-     * latter case.
-     *
-     * @param message The sync message to extract data from.
-     */
-    private static void processSync(Context context, PhoneAccountHandle phone,
-            SyncMessage message) {
-        Intent serviceIntent = null;
-        switch (message.getSyncTriggerEvent()) {
-            case OmtpConstants.NEW_MESSAGE:
-                if (!OmtpConstants.VOICE.equals(message.getContentType())) {
-                    VvmLog.i(TAG, "Non-voice message of type '" + message.getContentType()
-                        + "' received, ignoring");
-                    return;
-                }
-
-                Voicemail.Builder builder = Voicemail.createForInsertion(
-                        message.getTimestampMillis(), message.getSender())
-                        .setPhoneAccount(phone)
-                        .setSourceData(message.getId())
-                        .setDuration(message.getLength())
-                        .setSourcePackage(context.getPackageName());
-                Voicemail voicemail = builder.build();
-
-                VoicemailsQueryHelper queryHelper = new VoicemailsQueryHelper(context);
-                if (queryHelper.isVoicemailUnique(voicemail)) {
-                    Uri uri = VoicemailContract.Voicemails.insert(context, voicemail);
-                    voicemail = builder.setId(ContentUris.parseId(uri)).setUri(uri).build();
-                    SyncOneTask.start(context, phone, voicemail);
-                }
-                break;
-            case OmtpConstants.MAILBOX_UPDATE:
-                SyncTask.start(context, phone, OmtpVvmSyncService.SYNC_DOWNLOAD_ONLY);
-                break;
-            case OmtpConstants.GREETINGS_UPDATE:
-                // Not implemented in V1
-                break;
-            default:
-                VvmLog.e(TAG,
-                        "Unrecognized sync trigger event: " + message.getSyncTriggerEvent());
-                break;
-        }
-    }
-}
diff --git a/src/com/android/phone/vvm/omtp/sms/OmtpMessageSender.java b/src/com/android/phone/vvm/omtp/sms/OmtpMessageSender.java
deleted file mode 100644
index 9a775f0..0000000
--- a/src/com/android/phone/vvm/omtp/sms/OmtpMessageSender.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright (C) 2015 Google Inc. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-package com.android.phone.vvm.omtp.sms;
-
-import android.annotation.Nullable;
-import android.app.PendingIntent;
-import android.telephony.SmsManager;
-
-import com.android.phone.vvm.omtp.OmtpConstants;
-import com.android.phone.vvm.omtp.VvmLog;
-
-import java.io.UnsupportedEncodingException;
-import java.util.Locale;
-
-/**
- * Send client originated OMTP messages to the OMTP server.
- * <p>
- * Uses {@link PendingIntent} instead of a call back to notify when the message is
- * sent. This is primarily to keep the implementation simple and reuse what the underlying
- * {@link SmsManager} interface provides.
- * <p>
- * Provides simple APIs to send different types of mobile originated OMTP SMS to the VVM server.
- */
-public abstract class OmtpMessageSender {
-    protected static final String TAG = "OmtpMessageSender";
-    protected short mApplicationPort;
-    protected String mDestinationNumber;
-    protected SmsManager mSmsManager;
-
-    public OmtpMessageSender(SmsManager smsManager, short applicationPort,
-            String destinationNumber) {
-        mSmsManager = smsManager;
-        mApplicationPort = applicationPort;
-        mDestinationNumber = destinationNumber;
-    }
-
-    /**
-     * Sends a request to the VVM server to activate VVM for the current subscriber.
-     *
-     * @param sentIntent If not NULL this PendingIntent is broadcast when the message is
-     *            successfully sent, or failed.
-     */
-    public void requestVvmActivation(@Nullable PendingIntent sentIntent) {}
-
-    /**
-     * Sends a request to the VVM server to deactivate VVM for the current subscriber.
-     *
-     * @param sentIntent If not NULL this PendingIntent is broadcast when the message is
-     *            successfully sent, or failed.
-     */
-    public void requestVvmDeactivation(@Nullable PendingIntent sentIntent) {}
-
-    /**
-     * Send a request to the VVM server to get account status of the current subscriber.
-     *
-     * @param sentIntent If not NULL this PendingIntent is broadcast when the message is
-     *            successfully sent, or failed.
-     */
-    public void requestVvmStatus(@Nullable PendingIntent sentIntent) {}
-
-    protected void sendSms(String text, PendingIntent sentIntent) {
-        // If application port is set to 0 then send simple text message, else send data message.
-        if (mApplicationPort == 0) {
-            VvmLog
-                    .v(TAG, String.format("Sending TEXT sms '%s' to %s", text, mDestinationNumber));
-            mSmsManager.sendTextMessageWithSelfPermissions(mDestinationNumber, null, text,
-                    sentIntent, null, false);
-        } else {
-            byte[] data;
-            try {
-                data = text.getBytes("UTF-8");
-            } catch (UnsupportedEncodingException e) {
-                throw new IllegalStateException("Failed to encode: " + text);
-            }
-            VvmLog.v(TAG,
-                    String.format(Locale.US, "Sending BINARY sms '%s' to %s:%d", text,
-                            mDestinationNumber, mApplicationPort));
-            mSmsManager.sendDataMessageWithSelfPermissions(mDestinationNumber, null,
-                    mApplicationPort, data, sentIntent, null);
-        }
-    }
-
-    protected void appendField(StringBuilder sb, String field, Object value) {
-        sb.append(field).append(OmtpConstants.SMS_KEY_VALUE_SEPARATOR).append(value);
-    }
-}
diff --git a/src/com/android/phone/vvm/omtp/sms/OmtpStandardMessageSender.java b/src/com/android/phone/vvm/omtp/sms/OmtpStandardMessageSender.java
deleted file mode 100644
index 05276e1..0000000
--- a/src/com/android/phone/vvm/omtp/sms/OmtpStandardMessageSender.java
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Copyright (C) 2015 Google Inc. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-package com.android.phone.vvm.omtp.sms;
-
-import android.annotation.Nullable;
-import android.app.PendingIntent;
-import android.telephony.SmsManager;
-import android.text.TextUtils;
-
-import com.android.phone.vvm.omtp.OmtpConstants;
-
-/**
- * A implementation of the OmtpMessageSender using the standard OMTP sms protocol.
- */
-public class OmtpStandardMessageSender extends OmtpMessageSender {
-    private final String mClientType;
-    private final String mProtocolVersion;
-    private final String mClientPrefix;
-
-    /**
-     * Creates a new instance of OmtpStandardMessageSender.
-     *
-     * @param smsManager SMS sending library. There is a different SmsManager for each SIM.
-     * @param applicationPort If set to a value > 0 then a binary sms is sent to this port number.
-     *            Otherwise, a standard text SMS is sent.
-     * @param destinationNumber Destination number to be used.
-     * @param clientType The "ct" field to be set in the MO message. This is the value used by the
-     *            VVM server to identify the client. Certain VVM servers require a specific agreed
-     *            value for this field.
-     * @param protocolVersion OMTP protocol version.
-     * @param clientPrefix The client prefix requested to be used by the server in its MT messages.
-     */
-    public OmtpStandardMessageSender(SmsManager smsManager, short applicationPort,
-            String destinationNumber, String clientType, String protocolVersion,
-            String clientPrefix) {
-        super(smsManager, applicationPort, destinationNumber);
-        mClientType = clientType;
-        mProtocolVersion = protocolVersion;
-        mClientPrefix = clientPrefix;
-    }
-
-    // Activate message:
-    // V1.1: Activate:pv=<value>;ct=<value>
-    // V1.2: Activate:pv=<value>;ct=<value>;pt=<value>;<Clientprefix>
-    // V1.3: Activate:pv=<value>;ct=<value>;pt=<value>;<Clientprefix>
-    @Override
-    public void requestVvmActivation(@Nullable PendingIntent sentIntent) {
-        StringBuilder sb = new StringBuilder().append(OmtpConstants.ACTIVATE_REQUEST);
-
-        appendProtocolVersionAndClientType(sb);
-        if (TextUtils.equals(mProtocolVersion, OmtpConstants.PROTOCOL_VERSION1_2) ||
-                TextUtils.equals(mProtocolVersion, OmtpConstants.PROTOCOL_VERSION1_3)) {
-            appendApplicationPort(sb);
-            appendClientPrefix(sb);
-        }
-
-        sendSms(sb.toString(), sentIntent);
-    }
-
-    // Deactivate message:
-    // V1.1: Deactivate:pv=<value>;ct=<string>
-    // V1.2: Deactivate:pv=<value>;ct=<string>
-    // V1.3: Deactivate:pv=<value>;ct=<string>
-    @Override
-    public void requestVvmDeactivation(@Nullable PendingIntent sentIntent) {
-        StringBuilder sb = new StringBuilder().append(OmtpConstants.DEACTIVATE_REQUEST);
-        appendProtocolVersionAndClientType(sb);
-
-        sendSms(sb.toString(), sentIntent);
-    }
-
-    // Status message:
-    // V1.1: STATUS
-    // V1.2: STATUS
-    // V1.3: STATUS:pv=<value>;ct=<value>;pt=<value>;<Clientprefix>
-    @Override
-    public void requestVvmStatus(@Nullable PendingIntent sentIntent) {
-        StringBuilder sb = new StringBuilder().append(OmtpConstants.STATUS_REQUEST);
-
-        if (TextUtils.equals(mProtocolVersion, OmtpConstants.PROTOCOL_VERSION1_3)) {
-            appendProtocolVersionAndClientType(sb);
-            appendApplicationPort(sb);
-            appendClientPrefix(sb);
-        }
-
-        sendSms(sb.toString(), sentIntent);
-    }
-
-    private void appendProtocolVersionAndClientType(StringBuilder sb) {
-        sb.append(OmtpConstants.SMS_PREFIX_SEPARATOR);
-        appendField(sb, OmtpConstants.PROTOCOL_VERSION, mProtocolVersion);
-        sb.append(OmtpConstants.SMS_FIELD_SEPARATOR);
-        appendField(sb, OmtpConstants.CLIENT_TYPE, mClientType);
-    }
-
-    private void appendApplicationPort(StringBuilder sb) {
-        sb.append(OmtpConstants.SMS_FIELD_SEPARATOR);
-        appendField(sb, OmtpConstants.APPLICATION_PORT, mApplicationPort);
-    }
-
-    private void appendClientPrefix(StringBuilder sb) {
-        sb.append(OmtpConstants.SMS_FIELD_SEPARATOR);
-        sb.append(mClientPrefix);
-    }
-}
diff --git a/src/com/android/phone/vvm/omtp/sms/StatusMessage.java b/src/com/android/phone/vvm/omtp/sms/StatusMessage.java
deleted file mode 100644
index 65455d0..0000000
--- a/src/com/android/phone/vvm/omtp/sms/StatusMessage.java
+++ /dev/null
@@ -1,210 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-package com.android.phone.vvm.omtp.sms;
-
-import android.os.Bundle;
-import android.telecom.Log;
-
-import com.android.phone.NeededForTesting;
-import com.android.phone.vvm.omtp.OmtpConstants;
-import com.android.phone.vvm.omtp.VisualVoicemailPreferences;
-
-/**
- * Structured data representation of OMTP STATUS message.
- *
- * The getters will return null if the field was not set in the message body or it could not be
- * parsed.
- */
-public class StatusMessage {
-    // NOTE: Following Status SMS fields are not yet parsed, as they do not seem
-    // to be useful for initial omtp source implementation.
-    // lang, g_len, vs_len, pw_len, pm, gm, vtc, vt
-
-    private final String mProvisioningStatus;
-    private final String mStatusReturnCode;
-    private final String mSubscriptionUrl;
-    private final String mServerAddress;
-    private final String mTuiAccessNumber;
-    private final String mClientSmsDestinationNumber;
-    private final String mImapPort;
-    private final String mImapUserName;
-    private final String mImapPassword;
-    private final String mSmtpPort;
-    private final String mSmtpUserName;
-    private final String mSmtpPassword;
-    private final String mTuiPasswordLength;
-
-    @Override
-    public String toString() {
-        return "StatusMessage [mProvisioningStatus=" + mProvisioningStatus
-                + ", mStatusReturnCode=" + mStatusReturnCode
-                + ", mSubscriptionUrl=" + mSubscriptionUrl
-                + ", mServerAddress=" + mServerAddress
-                + ", mTuiAccessNumber=" + mTuiAccessNumber
-                + ", mClientSmsDestinationNumber=" + mClientSmsDestinationNumber
-                + ", mImapPort=" + mImapPort
-                + ", mImapUserName=" + mImapUserName
-                + ", mImapPassword=" + Log.pii(mImapPassword)
-                + ", mSmtpPort=" + mSmtpPort
-                + ", mSmtpUserName=" + mSmtpUserName
-                + ", mSmtpPassword=" + Log.pii(mSmtpPassword)
-                + ", mTuiPasswordLength=" + mTuiPasswordLength + "]";
-    }
-
-    public StatusMessage(Bundle wrappedData) {
-        mProvisioningStatus = unquote(getString(wrappedData, OmtpConstants.PROVISIONING_STATUS));
-        mStatusReturnCode = getString(wrappedData, OmtpConstants.RETURN_CODE);
-        mSubscriptionUrl = getString(wrappedData, OmtpConstants.SUBSCRIPTION_URL);
-        mServerAddress = getString(wrappedData, OmtpConstants.SERVER_ADDRESS);
-        mTuiAccessNumber = getString(wrappedData, OmtpConstants.TUI_ACCESS_NUMBER);
-        mClientSmsDestinationNumber = getString(wrappedData,
-                OmtpConstants.CLIENT_SMS_DESTINATION_NUMBER);
-        mImapPort = getString(wrappedData, OmtpConstants.IMAP_PORT);
-        mImapUserName = getString(wrappedData, OmtpConstants.IMAP_USER_NAME);
-        mImapPassword = getString(wrappedData, OmtpConstants.IMAP_PASSWORD);
-        mSmtpPort = getString(wrappedData, OmtpConstants.SMTP_PORT);
-        mSmtpUserName = getString(wrappedData, OmtpConstants.SMTP_USER_NAME);
-        mSmtpPassword = getString(wrappedData, OmtpConstants.SMTP_PASSWORD);
-        mTuiPasswordLength = getString(wrappedData, OmtpConstants.TUI_PASSWORD_LENGTH);
-    }
-
-    private static String unquote(String string) {
-        if (string.length() < 2) {
-            return string;
-        }
-        if (string.startsWith("\"") && string.endsWith("\"")) {
-            return string.substring(1, string.length() - 1);
-        }
-        return string;
-    }
-
-    /**
-     * @return the subscriber's VVM provisioning status.
-     */
-    public String getProvisioningStatus() {
-        return mProvisioningStatus;
-    }
-
-    /**
-     * @return the return-code of the status SMS.
-     */
-    public String getReturnCode() {
-        return mStatusReturnCode;
-    }
-
-    /**
-     * @return the URL of the voicemail server. This is the URL to send the users to for subscribing
-     * to the visual voicemail service.
-     */
-    @NeededForTesting
-    public String getSubscriptionUrl() {
-        return mSubscriptionUrl;
-    }
-
-    /**
-     * @return the voicemail server address. Either server IP address or fully qualified domain
-     * name.
-     */
-    public String getServerAddress() {
-        return mServerAddress;
-    }
-
-    /**
-     * @return the Telephony User Interface number to call to access voicemails directly from the
-     * IVR.
-     */
-    @NeededForTesting
-    public String getTuiAccessNumber() {
-        return mTuiAccessNumber;
-    }
-
-    /**
-     * @return the number to which client originated SMSes should be sent to.
-     */
-    @NeededForTesting
-    public String getClientSmsDestinationNumber() {
-        return mClientSmsDestinationNumber;
-    }
-
-    /**
-     * @return the IMAP server port to talk to.
-     */
-    public String getImapPort() {
-        return mImapPort;
-    }
-
-    /**
-     * @return the IMAP user name to be used for authentication.
-     */
-    public String getImapUserName() {
-        return mImapUserName;
-    }
-
-    /**
-     * @return the IMAP password to be used for authentication.
-     */
-    public String getImapPassword() {
-        return mImapPassword;
-    }
-
-    /**
-     * @return the SMTP server port to talk to.
-     */
-    @NeededForTesting
-    public String getSmtpPort() {
-        return mSmtpPort;
-    }
-
-    /**
-     * @return the SMTP user name to be used for SMTP authentication.
-     */
-    @NeededForTesting
-    public String getSmtpUserName() {
-        return mSmtpUserName;
-    }
-
-    /**
-     * @return the SMTP password to be used for SMTP authentication.
-     */
-    @NeededForTesting
-    public String getSmtpPassword() {
-        return mSmtpPassword;
-    }
-
-    public String getTuiPasswordLength() {
-        return mTuiPasswordLength;
-    }
-
-    private static String getString(Bundle bundle, String key) {
-        String value = bundle.getString(key);
-        if (value == null) {
-            return "";
-        }
-        return value;
-    }
-
-    /**
-     * Saves a StatusMessage to the {@link VisualVoicemailPreferences}. Not all fields are saved.
-     */
-    public VisualVoicemailPreferences.Editor putStatus(VisualVoicemailPreferences.Editor editor) {
-        return editor
-                .putString(OmtpConstants.IMAP_PORT, getImapPort())
-                .putString(OmtpConstants.SERVER_ADDRESS, getServerAddress())
-                .putString(OmtpConstants.IMAP_USER_NAME, getImapUserName())
-                .putString(OmtpConstants.IMAP_PASSWORD, getImapPassword())
-                .putString(OmtpConstants.TUI_PASSWORD_LENGTH, getTuiPasswordLength());
-    }
-}
\ No newline at end of file
diff --git a/src/com/android/phone/vvm/omtp/sms/StatusSmsFetcher.java b/src/com/android/phone/vvm/omtp/sms/StatusSmsFetcher.java
deleted file mode 100644
index adaa2f4..0000000
--- a/src/com/android/phone/vvm/omtp/sms/StatusSmsFetcher.java
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.phone.vvm.omtp.sms;
-
-import android.annotation.MainThread;
-import android.annotation.Nullable;
-import android.annotation.WorkerThread;
-import android.app.Activity;
-import android.app.PendingIntent;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.os.Bundle;
-import android.provider.VoicemailContract;
-import android.telecom.PhoneAccountHandle;
-import android.telephony.SmsManager;
-import android.telephony.VisualVoicemailSms;
-
-import com.android.phone.Assert;
-import com.android.phone.vvm.omtp.OmtpConstants;
-import com.android.phone.vvm.omtp.OmtpVvmCarrierConfigHelper;
-import com.android.phone.vvm.omtp.VvmLog;
-import com.android.phone.vvm.omtp.protocol.VisualVoicemailProtocol;
-import com.android.phone.vvm.omtp.utils.PhoneAccountHandleConverter;
-
-import java.io.Closeable;
-import java.io.IOException;
-import java.util.concurrent.CancellationException;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-
-/**
- * Intercepts a incoming STATUS SMS with a blocking call.
- */
-public class StatusSmsFetcher extends BroadcastReceiver implements Closeable {
-
-    private static final String TAG = "VvmStatusSmsFetcher";
-
-    private static final long STATUS_SMS_TIMEOUT_MILLIS = 60_000;
-    private static final String ACTION_REQUEST_SENT_INTENT
-            = "com.android.phone.vvm.omtp.sms.REQUEST_SENT";
-    private static final int ACTION_REQUEST_SENT_REQUEST_CODE = 0;
-
-    private CompletableFuture<Bundle> mFuture = new CompletableFuture<>();
-
-    private final Context mContext;
-    private final int mSubId;
-
-    public StatusSmsFetcher(Context context, int subId) {
-        mContext = context;
-        mSubId = subId;
-        IntentFilter filter = new IntentFilter(VoicemailContract.ACTION_VOICEMAIL_SMS_RECEIVED);
-        filter.addAction(ACTION_REQUEST_SENT_INTENT);
-        context.registerReceiver(this, filter);
-    }
-
-    @Override
-    public void close() throws IOException {
-        mContext.unregisterReceiver(this);
-    }
-
-    @WorkerThread
-    @Nullable
-    public Bundle get() throws InterruptedException, ExecutionException, TimeoutException,
-            CancellationException {
-        Assert.isNotMainThread();
-        return mFuture.get(STATUS_SMS_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
-    }
-
-    public PendingIntent getSentIntent() {
-        Intent intent = new Intent(ACTION_REQUEST_SENT_INTENT);
-        intent.setPackage(mContext.getPackageName());
-        // Because the receiver is registered dynamically, implicit intent must be used.
-        // There should only be a single status SMS request at a time.
-        return PendingIntent.getBroadcast(mContext, ACTION_REQUEST_SENT_REQUEST_CODE, intent,
-                PendingIntent.FLAG_CANCEL_CURRENT);
-    }
-
-    @Override
-    @MainThread
-    public void onReceive(Context context, Intent intent) {
-        Assert.isMainThread();
-        if (ACTION_REQUEST_SENT_INTENT.equals(intent.getAction())) {
-            int resultCode = getResultCode();
-
-            if (resultCode == Activity.RESULT_OK) {
-                VvmLog.d(TAG, "Request SMS successfully sent");
-                return;
-            }
-
-            VvmLog.e(TAG, "Request SMS send failed: " + sentSmsResultToString(resultCode));
-            mFuture.cancel(true);
-            return;
-        }
-
-        VisualVoicemailSms sms = intent.getExtras()
-                .getParcelable(VoicemailContract.EXTRA_VOICEMAIL_SMS);
-        PhoneAccountHandle phoneAccountHandle = sms.getPhoneAccountHandle();
-        int subId = PhoneAccountHandleConverter.toSubId(phoneAccountHandle);
-        if (mSubId != subId) {
-            return;
-        }
-        String eventType = sms.getPrefix();
-
-        if (eventType.equals(OmtpConstants.STATUS_SMS_PREFIX)) {
-            mFuture.complete(sms.getFields());
-            return;
-        }
-
-        if (eventType.equals(OmtpConstants.SYNC_SMS_PREFIX)) {
-            return;
-        }
-
-        VvmLog.i(TAG, "VVM SMS with event " + eventType
-                + " received, attempting to translate to STATUS SMS");
-        OmtpVvmCarrierConfigHelper helper = new OmtpVvmCarrierConfigHelper(context, subId);
-        VisualVoicemailProtocol protocol = helper.getProtocol();
-        if (protocol == null) {
-            return;
-        }
-        Bundle translatedBundle = protocol.translateStatusSmsBundle(helper, eventType,
-                sms.getFields());
-
-        if (translatedBundle != null) {
-            VvmLog.i(TAG, "Translated to STATUS SMS");
-            mFuture.complete(translatedBundle);
-        }
-    }
-
-    private static String sentSmsResultToString(int resultCode) {
-        switch (resultCode) {
-            case Activity.RESULT_OK:
-                return "OK";
-            case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
-                return "RESULT_ERROR_GENERIC_FAILURE";
-            case SmsManager.RESULT_ERROR_NO_SERVICE:
-                return "RESULT_ERROR_GENERIC_FAILURE";
-            case SmsManager.RESULT_ERROR_NULL_PDU:
-                return "RESULT_ERROR_GENERIC_FAILURE";
-            case SmsManager.RESULT_ERROR_RADIO_OFF:
-                return "RESULT_ERROR_GENERIC_FAILURE";
-            default:
-                return "UNKNOWN CODE: " + resultCode;
-        }
-    }
-}
diff --git a/src/com/android/phone/vvm/omtp/sms/SyncMessage.java b/src/com/android/phone/vvm/omtp/sms/SyncMessage.java
deleted file mode 100644
index 632ff9e..0000000
--- a/src/com/android/phone/vvm/omtp/sms/SyncMessage.java
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-package com.android.phone.vvm.omtp.sms;
-
-import android.annotation.Nullable;
-import android.os.Bundle;
-
-import com.android.phone.NeededForTesting;
-import com.android.phone.vvm.omtp.OmtpConstants;
-
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.Locale;
-
-/**
- * Structured data representation of an OMTP SYNC message.
- *
- * Getters will return null if the field was not set in the message body or it could not be parsed.
- */
-public class SyncMessage {
-    // Sync event that triggered this message.
-    private final String mSyncTriggerEvent;
-    // Total number of new messages on the server.
-    private final int mNewMessageCount;
-    // UID of the new message.
-    private final String mMessageId;
-    // Length of the message.
-    private final int mMessageLength;
-    // Content type (voice, video, fax...) of the new message.
-    private final String mContentType;
-    // Sender of the new message.
-    private final String mSender;
-    // Timestamp (in millis) of the new message.
-    private final long mMsgTimeMillis;
-
-    @Override
-    public String toString() {
-        return "SyncMessage [mSyncTriggerEvent=" + mSyncTriggerEvent
-                + ", mNewMessageCount=" + mNewMessageCount
-                + ", mMessageId=" + mMessageId
-                + ", mMessageLength=" + mMessageLength
-                + ", mContentType=" + mContentType
-                + ", mSender=" + mSender
-                + ", mMsgTimeMillis=" + mMsgTimeMillis + "]";
-    }
-
-    public SyncMessage(Bundle wrappedData) {
-        mSyncTriggerEvent = getString(wrappedData, OmtpConstants.SYNC_TRIGGER_EVENT);
-        mMessageId = getString(wrappedData, OmtpConstants.MESSAGE_UID);
-        mMessageLength = getInt(wrappedData, OmtpConstants.MESSAGE_LENGTH);
-        mContentType = getString(wrappedData, OmtpConstants.CONTENT_TYPE);
-        mSender = getString(wrappedData, OmtpConstants.SENDER);
-        mNewMessageCount = getInt(wrappedData, OmtpConstants.NUM_MESSAGE_COUNT);
-        mMsgTimeMillis = parseTime(wrappedData.getString(OmtpConstants.TIME));
-    }
-
-    private static long parseTime(@Nullable String value) {
-        if (value == null) {
-            return 0L;
-        }
-        try {
-            return new SimpleDateFormat(
-                    OmtpConstants.DATE_TIME_FORMAT, Locale.US)
-                    .parse(value).getTime();
-        } catch (ParseException e) {
-            return 0L;
-        }
-    }
-    /**
-     * @return the event that triggered the sync message. This is a mandatory field and must always
-     * be set.
-     */
-    public String getSyncTriggerEvent() {
-        return mSyncTriggerEvent;
-    }
-
-    /**
-     * @return the number of new messages stored on the voicemail server.
-     */
-    @NeededForTesting
-    public int getNewMessageCount() {
-        return mNewMessageCount;
-    }
-
-    /**
-     * @return the message ID of the new message.
-     * <p>
-     * Expected to be set only for
-     * {@link com.android.phone.vvm.omtp.OmtpConstants#NEW_MESSAGE}
-     */
-    public String getId() {
-        return mMessageId;
-    }
-
-    /**
-     * @return the content type of the new message.
-     * <p>
-     * Expected to be set only for
-     * {@link com.android.phone.vvm.omtp.OmtpConstants#NEW_MESSAGE}
-     */
-    @NeededForTesting
-    public String getContentType() {
-        return mContentType;
-    }
-
-    /**
-     * @return the message length of the new message.
-     * <p>
-     * Expected to be set only for
-     * {@link com.android.phone.vvm.omtp.OmtpConstants#NEW_MESSAGE}
-     */
-    public int getLength() {
-        return mMessageLength;
-    }
-
-    /**
-     * @return the sender's phone number of the new message specified as MSISDN.
-     * <p>
-     * Expected to be set only for
-     * {@link com.android.phone.vvm.omtp.OmtpConstants#NEW_MESSAGE}
-     */
-    public String getSender() {
-        return mSender;
-    }
-
-    /**
-     * @return the timestamp as milliseconds for the new message.
-     * <p>
-     * Expected to be set only for
-     * {@link com.android.phone.vvm.omtp.OmtpConstants#NEW_MESSAGE}
-     */
-    public long getTimestampMillis() {
-        return mMsgTimeMillis;
-    }
-
-    private static int getInt(Bundle wrappedData, String key) {
-        String value = wrappedData.getString(key);
-        if (value == null) {
-            return 0;
-        }
-        try {
-            return Integer.parseInt(value);
-        } catch (NumberFormatException e) {
-            return 0;
-        }
-    }
-
-    private static String getString(Bundle wrappedData, String key) {
-        String value = wrappedData.getString(key);
-        if (value == null) {
-            return "";
-        }
-        return value;
-    }
-}
\ No newline at end of file
diff --git a/src/com/android/phone/vvm/omtp/sms/Vvm3MessageSender.java b/src/com/android/phone/vvm/omtp/sms/Vvm3MessageSender.java
deleted file mode 100644
index dc2ea58..0000000
--- a/src/com/android/phone/vvm/omtp/sms/Vvm3MessageSender.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-package com.android.phone.vvm.omtp.sms;
-
-import android.annotation.Nullable;
-import android.app.PendingIntent;
-import android.telephony.SmsManager;
-
-public class Vvm3MessageSender extends OmtpMessageSender {
-
-    /**
-     * Creates a new instance of Vvm3MessageSender.
-     *
-     * @param smsManager SMS sending library. There is a different SmsManager for each SIM.
-     * @param applicationPort If set to a value > 0 then a binary sms is sent to this port number.
-     * Otherwise, a standard text SMS is sent.
-     */
-    public Vvm3MessageSender(SmsManager smsManager, short applicationPort,
-            String destinationNumber) {
-        super(smsManager, applicationPort, destinationNumber);
-    }
-
-    @Override
-    public void requestVvmActivation(@Nullable PendingIntent sentIntent) {
-        // Activation not supported for VVM3, send a status request instead.
-        requestVvmStatus(sentIntent);
-    }
-
-    @Override
-    public void requestVvmDeactivation(@Nullable PendingIntent sentIntent) {
-        // Deactivation not supported for VVM3, do nothing
-    }
-
-
-    @Override
-    public void requestVvmStatus(@Nullable PendingIntent sentIntent) {
-        // Status message:
-        // STATUS
-        StringBuilder sb = new StringBuilder().append("STATUS");
-        sendSms(sb.toString(), sentIntent);
-    }
-}
diff --git a/src/com/android/phone/vvm/omtp/sync/OmtpVvmSourceManager.java b/src/com/android/phone/vvm/omtp/sync/OmtpVvmSourceManager.java
deleted file mode 100644
index 9b06462..0000000
--- a/src/com/android/phone/vvm/omtp/sync/OmtpVvmSourceManager.java
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-package com.android.phone.vvm.omtp.sync;
-
-import android.content.Context;
-import android.telecom.PhoneAccountHandle;
-import android.telephony.PhoneStateListener;
-import android.telephony.SubscriptionManager;
-import android.telephony.TelephonyManager;
-import com.android.internal.telephony.Phone;
-import com.android.phone.PhoneUtils;
-import com.android.phone.VoicemailStatus;
-import com.android.phone.vvm.omtp.VvmPhoneStateListener;
-import java.util.Collections;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-
-/**
- * A singleton class designed to remember the active OMTP visual voicemail sources. Because a
- * voicemail source is tied 1:1 to a phone account, the phone account handle is used as the key
- * for each voicemail source and the associated data.
- */
-public class OmtpVvmSourceManager {
-    public static final String TAG = "OmtpVvmSourceManager";
-
-    private static OmtpVvmSourceManager sInstance = new OmtpVvmSourceManager();
-
-    private Context mContext;
-    private SubscriptionManager mSubscriptionManager;
-    private TelephonyManager mTelephonyManager;
-    // Each phone account is associated with a phone state listener for updates to whether the
-    // device is able to sync.
-    private Set<PhoneAccountHandle> mActiveVvmSources;
-    private Map<PhoneAccountHandle, PhoneStateListener> mPhoneStateListenerMap;
-
-    /**
-     * Private constructor. Instance should only be acquired through getInstance().
-     */
-    private OmtpVvmSourceManager() {}
-
-    public static OmtpVvmSourceManager getInstance(Context context) {
-        sInstance.setup(context);
-        return sInstance;
-    }
-
-    /**
-     * Set the context and system services so they do not need to be retrieved every time.
-     * @param context The context to get the subscription and telephony manager for.
-     */
-    private void setup(Context context) {
-        if (mContext == null) {
-            mContext = context;
-            mSubscriptionManager = SubscriptionManager.from(context);
-            mTelephonyManager = (TelephonyManager)
-                    mContext.getSystemService(Context.TELEPHONY_SERVICE);
-            mActiveVvmSources = Collections.newSetFromMap(
-                    new ConcurrentHashMap<PhoneAccountHandle, Boolean>(8, 0.9f, 1));
-            mPhoneStateListenerMap =
-                    new ConcurrentHashMap<PhoneAccountHandle, PhoneStateListener>(8, 0.9f, 1);
-        }
-    }
-
-    public void addSource(PhoneAccountHandle phoneAccount) {
-        mActiveVvmSources.add(phoneAccount);
-    }
-
-    /**
-     * When a voicemail source is removed, we don't always know which one was removed. Check the
-     * list of registered phone accounts against the active subscriptions list and remove the
-     * inactive sources.
-     */
-    public void removeInactiveSources() {
-        for (PhoneAccountHandle phoneAccount : mActiveVvmSources) {
-            if (!PhoneUtils.isPhoneAccountActive(mSubscriptionManager, phoneAccount)) {
-                removeSource(phoneAccount);
-            }
-        }
-
-        // Remove any orphaned phone state listeners as well.
-        for (PhoneAccountHandle phoneAccount : mPhoneStateListenerMap.keySet()) {
-            if (!PhoneUtils.isPhoneAccountActive(mSubscriptionManager, phoneAccount)) {
-                removePhoneStateListener(phoneAccount);
-            }
-        }
-    }
-
-    public void removeSource(Phone phone) {
-        removeSource(PhoneUtils.makePstnPhoneAccountHandle(phone));
-    }
-
-    public void removeSource(PhoneAccountHandle phoneAccount) {
-        // TODO: should use OmtpVvmCarrierConfigHelper to handle the event. But currently it
-        // couldn't handle events on removed SIMs
-        VoicemailStatus.disable(mContext, phoneAccount);
-        removePhoneStateListener(phoneAccount);
-        mActiveVvmSources.remove(phoneAccount);
-    }
-
-    public void addPhoneStateListener(Phone phone) {
-        addPhoneStateListener(PhoneUtils.makePstnPhoneAccountHandle(phone));
-    }
-
-    public void addPhoneStateListener(PhoneAccountHandle phoneAccount) {
-        if (!mPhoneStateListenerMap.containsKey(phoneAccount)) {
-            VvmPhoneStateListener phoneStateListener = new VvmPhoneStateListener(mContext,
-                    PhoneUtils.makePstnPhoneAccountHandle(phoneAccount.getId()));
-            mPhoneStateListenerMap.put(phoneAccount, phoneStateListener);
-            mTelephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_SERVICE_STATE);
-        }
-    }
-
-    public void removePhoneStateListener(PhoneAccountHandle phoneAccount) {
-        PhoneStateListener phoneStateListener =
-                mPhoneStateListenerMap.remove(phoneAccount);
-        mTelephonyManager.listen(phoneStateListener, 0);
-    }
-
-    public Set<PhoneAccountHandle> getOmtpVvmSources() {
-        return mActiveVvmSources;
-    }
-
-    /**
-     * Check if a certain account is registered.
-     *
-     * @param phoneAccount The account to look for.
-     * @return {@code true} if the account is in the list of registered OMTP voicemail sources.
-     * {@code false} otherwise.
-     */
-    public boolean isVvmSourceRegistered(PhoneAccountHandle phoneAccount) {
-        if (phoneAccount == null) {
-            return false;
-        }
-
-        return mActiveVvmSources.contains(phoneAccount);
-    }
-}
\ No newline at end of file
diff --git a/src/com/android/phone/vvm/omtp/sync/OmtpVvmSyncReceiver.java b/src/com/android/phone/vvm/omtp/sync/OmtpVvmSyncReceiver.java
deleted file mode 100644
index 41178eb..0000000
--- a/src/com/android/phone/vvm/omtp/sync/OmtpVvmSyncReceiver.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.phone.vvm.omtp.sync;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.provider.VoicemailContract;
-import android.telecom.PhoneAccountHandle;
-import android.telecom.TelecomManager;
-import com.android.phone.settings.VisualVoicemailSettingsUtil;
-import com.android.phone.vvm.omtp.ActivationTask;
-import com.android.phone.vvm.omtp.VvmLog;
-import com.android.phone.vvm.omtp.utils.PhoneAccountHandleConverter;
-import java.util.List;
-
-public class OmtpVvmSyncReceiver extends BroadcastReceiver {
-
-    private static final String TAG = "OmtpVvmSyncReceiver";
-
-    @Override
-    public void onReceive(final Context context, Intent intent) {
-        if (VoicemailContract.ACTION_SYNC_VOICEMAIL.equals(intent.getAction())) {
-            VvmLog.v(TAG, "Sync intent received");
-            for (PhoneAccountHandle source : OmtpVvmSourceManager.getInstance(context)
-                    .getOmtpVvmSources()) {
-                SyncTask.start(context, source, OmtpVvmSyncService.SYNC_FULL_SYNC);
-            }
-            activateUnactivatedAccounts(context);
-        }
-    }
-
-    private static void activateUnactivatedAccounts(Context context) {
-        List<PhoneAccountHandle> accounts =
-                context.getSystemService(TelecomManager.class).getCallCapablePhoneAccounts();
-        for (PhoneAccountHandle phoneAccount : accounts) {
-            if (!VisualVoicemailSettingsUtil.isEnabled(context, phoneAccount)) {
-                continue;
-            }
-            int subId = PhoneAccountHandleConverter.toSubId(phoneAccount);
-            if (!OmtpVvmSourceManager.getInstance(context).isVvmSourceRegistered(phoneAccount)) {
-                VvmLog.i(TAG, "Unactivated account " + phoneAccount + " found, activating");
-                ActivationTask.start(context, subId, null);
-            }
-        }
-    }
-}
diff --git a/src/com/android/phone/vvm/omtp/sync/OmtpVvmSyncService.java b/src/com/android/phone/vvm/omtp/sync/OmtpVvmSyncService.java
deleted file mode 100644
index 58797de..0000000
--- a/src/com/android/phone/vvm/omtp/sync/OmtpVvmSyncService.java
+++ /dev/null
@@ -1,280 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-package com.android.phone.vvm.omtp.sync;
-
-import android.content.Context;
-import android.net.Network;
-import android.net.Uri;
-import android.provider.VoicemailContract;
-import android.telecom.PhoneAccountHandle;
-import android.telecom.Voicemail;
-import android.text.TextUtils;
-import com.android.phone.Assert;
-import com.android.phone.PhoneUtils;
-import com.android.phone.VoicemailStatus;
-import com.android.phone.settings.VisualVoicemailSettingsUtil;
-import com.android.phone.vvm.omtp.ActivationTask;
-import com.android.phone.vvm.omtp.OmtpEvents;
-import com.android.phone.vvm.omtp.OmtpVvmCarrierConfigHelper;
-import com.android.phone.vvm.omtp.VvmLog;
-import com.android.phone.vvm.omtp.fetch.VoicemailFetchedCallback;
-import com.android.phone.vvm.omtp.imap.ImapHelper;
-import com.android.phone.vvm.omtp.imap.ImapHelper.InitializingException;
-import com.android.phone.vvm.omtp.scheduling.BaseTask;
-import com.android.phone.vvm.omtp.sync.VvmNetworkRequest.NetworkWrapper;
-import com.android.phone.vvm.omtp.sync.VvmNetworkRequest.RequestFailedException;
-import com.android.phone.vvm.omtp.utils.PhoneAccountHandleConverter;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Sync OMTP visual voicemail.
- */
-public class OmtpVvmSyncService {
-
-    private static final String TAG = OmtpVvmSyncService.class.getSimpleName();
-
-    /**
-     * Signifies a sync with both uploading to the server and downloading from the server.
-     */
-    public static final String SYNC_FULL_SYNC = "full_sync";
-    /**
-     * Only upload to the server.
-     */
-    public static final String SYNC_UPLOAD_ONLY = "upload_only";
-    /**
-     * Only download from the server.
-     */
-    public static final String SYNC_DOWNLOAD_ONLY = "download_only";
-    /**
-     * Only download single voicemail transcription.
-     */
-    public static final String SYNC_DOWNLOAD_ONE_TRANSCRIPTION =
-            "download_one_transcription";
-
-    private final Context mContext;
-
-    // Record the timestamp of the last full sync so that duplicate syncs can be reduced.
-    private static final String LAST_FULL_SYNC_TIMESTAMP = "last_full_sync_timestamp";
-    // Constant indicating that there has never been a full sync.
-    public static final long NO_PRIOR_FULL_SYNC = -1;
-
-    private VoicemailsQueryHelper mQueryHelper;
-
-    public OmtpVvmSyncService(Context context) {
-        mContext = context;
-        mQueryHelper = new VoicemailsQueryHelper(mContext);
-    }
-
-    public void sync(BaseTask task, String action, PhoneAccountHandle phoneAccount,
-            Voicemail voicemail, VoicemailStatus.Editor status) {
-        Assert.isTrue(phoneAccount != null);
-        VvmLog.v(TAG, "Sync requested: " + action + " - for account: " + phoneAccount);
-        setupAndSendRequest(task, phoneAccount, voicemail, action, status);
-    }
-
-    private void setupAndSendRequest(BaseTask task, PhoneAccountHandle phoneAccount,
-            Voicemail voicemail, String action, VoicemailStatus.Editor status) {
-        if (!VisualVoicemailSettingsUtil.isEnabled(mContext, phoneAccount)) {
-            VvmLog.v(TAG, "Sync requested for disabled account");
-            return;
-        }
-        int subId = PhoneAccountHandleConverter.toSubId(phoneAccount);
-        if (!OmtpVvmSourceManager.getInstance(mContext).isVvmSourceRegistered(phoneAccount)) {
-            ActivationTask.start(mContext, subId, null);
-            return;
-        }
-
-        OmtpVvmCarrierConfigHelper config = new OmtpVvmCarrierConfigHelper(mContext, subId);
-        // DATA_IMAP_OPERATION_STARTED posting should not be deferred. This event clears all data
-        // channel errors, which should happen when the task starts, not when it ends. It is the
-        // "Sync in progress..." status.
-        config.handleEvent(VoicemailStatus.edit(mContext, phoneAccount),
-                OmtpEvents.DATA_IMAP_OPERATION_STARTED);
-        try (NetworkWrapper network = VvmNetworkRequest.getNetwork(config, phoneAccount, status)) {
-            if (network == null) {
-                VvmLog.e(TAG, "unable to acquire network");
-                task.fail();
-                return;
-            }
-            doSync(task, network.get(), phoneAccount, voicemail, action, status);
-        } catch (RequestFailedException e) {
-            config.handleEvent(status, OmtpEvents.DATA_NO_CONNECTION_CELLULAR_REQUIRED);
-            task.fail();
-        }
-    }
-
-    private void doSync(BaseTask task, Network network, PhoneAccountHandle phoneAccount,
-            Voicemail voicemail, String action, VoicemailStatus.Editor status) {
-        try (ImapHelper imapHelper = new ImapHelper(mContext, phoneAccount, network, status)) {
-            boolean success;
-            if (voicemail == null) {
-                success = syncAll(action, imapHelper, phoneAccount);
-            } else {
-                success = syncOne(imapHelper, voicemail, phoneAccount);
-            }
-            if (success) {
-                // TODO: b/30569269 failure should interrupt all subsequent task via exceptions
-                imapHelper.updateQuota();
-                imapHelper.handleEvent(OmtpEvents.DATA_IMAP_OPERATION_COMPLETED);
-            } else {
-                task.fail();
-            }
-        } catch (InitializingException e) {
-            VvmLog.w(TAG, "Can't retrieve Imap credentials.", e);
-            return;
-        }
-    }
-
-    private boolean syncAll(String action, ImapHelper imapHelper, PhoneAccountHandle account) {
-        boolean uploadSuccess = true;
-        boolean downloadSuccess = true;
-
-        if (SYNC_FULL_SYNC.equals(action) || SYNC_UPLOAD_ONLY.equals(action)) {
-            uploadSuccess = upload(imapHelper);
-        }
-        if (SYNC_FULL_SYNC.equals(action) || SYNC_DOWNLOAD_ONLY.equals(action)) {
-            downloadSuccess = download(imapHelper, account);
-        }
-
-        VvmLog.v(TAG, "upload succeeded: [" + String.valueOf(uploadSuccess)
-                + "] download succeeded: [" + String.valueOf(downloadSuccess) + "]");
-
-        return uploadSuccess && downloadSuccess;
-    }
-
-    private boolean syncOne(ImapHelper imapHelper, Voicemail voicemail,
-            PhoneAccountHandle account) {
-        if (shouldPerformPrefetch(account, imapHelper)) {
-            VoicemailFetchedCallback callback = new VoicemailFetchedCallback(mContext,
-                    voicemail.getUri(), account);
-            imapHelper.fetchVoicemailPayload(callback, voicemail.getSourceData());
-        }
-
-        return imapHelper.fetchTranscription(
-                new TranscriptionFetchedCallback(mContext, voicemail),
-                voicemail.getSourceData());
-    }
-
-    private boolean upload(ImapHelper imapHelper) {
-        List<Voicemail> readVoicemails = mQueryHelper.getReadVoicemails();
-        List<Voicemail> deletedVoicemails = mQueryHelper.getDeletedVoicemails();
-
-        boolean success = true;
-
-        if (deletedVoicemails.size() > 0) {
-            if (imapHelper.markMessagesAsDeleted(deletedVoicemails)) {
-                // We want to delete selectively instead of all the voicemails for this provider
-                // in case the state changed since the IMAP query was completed.
-                mQueryHelper.deleteFromDatabase(deletedVoicemails);
-            } else {
-                success = false;
-            }
-        }
-
-        if (readVoicemails.size() > 0) {
-            if (imapHelper.markMessagesAsRead(readVoicemails)) {
-                mQueryHelper.markCleanInDatabase(readVoicemails);
-            } else {
-                success = false;
-            }
-        }
-
-        return success;
-    }
-
-    private boolean download(ImapHelper imapHelper, PhoneAccountHandle account) {
-        List<Voicemail> serverVoicemails = imapHelper.fetchAllVoicemails();
-        List<Voicemail> localVoicemails = mQueryHelper.getAllVoicemails();
-
-        if (localVoicemails == null || serverVoicemails == null) {
-            // Null value means the query failed.
-            return false;
-        }
-
-        Map<String, Voicemail> remoteMap = buildMap(serverVoicemails);
-
-        // Go through all the local voicemails and check if they are on the server.
-        // They may be read or deleted on the server but not locally. Perform the
-        // appropriate local operation if the status differs from the server. Remove
-        // the messages that exist both locally and on the server to know which server
-        // messages to insert locally.
-        for (int i = 0; i < localVoicemails.size(); i++) {
-            Voicemail localVoicemail = localVoicemails.get(i);
-            Voicemail remoteVoicemail = remoteMap.remove(localVoicemail.getSourceData());
-            if (remoteVoicemail == null) {
-                mQueryHelper.deleteFromDatabase(localVoicemail);
-            } else {
-                if (remoteVoicemail.isRead() != localVoicemail.isRead()) {
-                    mQueryHelper.markReadInDatabase(localVoicemail);
-                }
-
-                if (!TextUtils.isEmpty(remoteVoicemail.getTranscription()) &&
-                        TextUtils.isEmpty(localVoicemail.getTranscription())) {
-                    mQueryHelper.updateWithTranscription(localVoicemail,
-                            remoteVoicemail.getTranscription());
-                }
-            }
-        }
-
-        // The leftover messages are messages that exist on the server but not locally.
-        boolean prefetchEnabled = shouldPerformPrefetch(account, imapHelper);
-        for (Voicemail remoteVoicemail : remoteMap.values()) {
-            Uri uri = VoicemailContract.Voicemails.insert(mContext, remoteVoicemail);
-            if (prefetchEnabled) {
-                VoicemailFetchedCallback fetchedCallback =
-                        new VoicemailFetchedCallback(mContext, uri, account);
-                imapHelper.fetchVoicemailPayload(fetchedCallback, remoteVoicemail.getSourceData());
-            }
-        }
-
-        return true;
-    }
-
-    private boolean shouldPerformPrefetch(PhoneAccountHandle account, ImapHelper imapHelper) {
-        OmtpVvmCarrierConfigHelper carrierConfigHelper = new OmtpVvmCarrierConfigHelper(
-                mContext, PhoneUtils.getSubIdForPhoneAccountHandle(account));
-        return carrierConfigHelper.isPrefetchEnabled() && !imapHelper.isRoaming();
-    }
-
-    /**
-     * Builds a map from provider data to message for the given collection of voicemails.
-     */
-    private Map<String, Voicemail> buildMap(List<Voicemail> messages) {
-        Map<String, Voicemail> map = new HashMap<String, Voicemail>();
-        for (Voicemail message : messages) {
-            map.put(message.getSourceData(), message);
-        }
-        return map;
-    }
-
-    public class TranscriptionFetchedCallback {
-
-        private Context mContext;
-        private Voicemail mVoicemail;
-
-        public TranscriptionFetchedCallback(Context context, Voicemail voicemail) {
-            mContext = context;
-            mVoicemail = voicemail;
-        }
-
-        public void setVoicemailTranscription(String transcription) {
-            VoicemailsQueryHelper queryHelper = new VoicemailsQueryHelper(mContext);
-            queryHelper.updateWithTranscription(mVoicemail, transcription);
-        }
-    }
-}
diff --git a/src/com/android/phone/vvm/omtp/sync/SyncOneTask.java b/src/com/android/phone/vvm/omtp/sync/SyncOneTask.java
deleted file mode 100644
index 510efc7..0000000
--- a/src/com/android/phone/vvm/omtp/sync/SyncOneTask.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.phone.vvm.omtp.sync;
-
-import android.content.Context;
-import android.content.Intent;
-import android.telecom.PhoneAccountHandle;
-import android.telecom.Voicemail;
-import com.android.phone.VoicemailStatus;
-import com.android.phone.vvm.omtp.scheduling.BaseTask;
-import com.android.phone.vvm.omtp.scheduling.RetryPolicy;
-import com.android.phone.vvm.omtp.utils.PhoneAccountHandleConverter;
-
-/**
- * Task to download a single voicemail from the server. This task is initiated by a SMS notifying
- * the new voicemail arrival, and ignores the duplicated tasks constraint.
- */
-public class SyncOneTask extends BaseTask {
-
-    private static final int RETRY_TIMES = 2;
-    private static final int RETRY_INTERVAL_MILLIS = 5_000;
-
-    private static final String EXTRA_PHONE_ACCOUNT_HANDLE = "extra_phone_account_handle";
-    private static final String EXTRA_SYNC_TYPE = "extra_sync_type";
-    private static final String EXTRA_VOICEMAIL = "extra_voicemail";
-
-    private PhoneAccountHandle mPhone;
-    private String mSyncType;
-    private Voicemail mVoicemail;
-
-    public static void start(Context context, PhoneAccountHandle phone, Voicemail voicemail) {
-        Intent intent = BaseTask
-                .createIntent(context, SyncOneTask.class,
-                        PhoneAccountHandleConverter.toSubId(phone));
-        intent.putExtra(EXTRA_PHONE_ACCOUNT_HANDLE, phone);
-        intent.putExtra(EXTRA_SYNC_TYPE, OmtpVvmSyncService.SYNC_DOWNLOAD_ONE_TRANSCRIPTION);
-        intent.putExtra(EXTRA_VOICEMAIL, voicemail);
-        context.startService(intent);
-    }
-
-    public SyncOneTask() {
-        super(TASK_ALLOW_DUPLICATES);
-        addPolicy(new RetryPolicy(RETRY_TIMES, RETRY_INTERVAL_MILLIS));
-    }
-
-    public void onCreate(Context context, Intent intent, int flags, int startId) {
-        super.onCreate(context, intent, flags, startId);
-        mPhone = intent.getParcelableExtra(EXTRA_PHONE_ACCOUNT_HANDLE);
-        mSyncType = intent.getStringExtra(EXTRA_SYNC_TYPE);
-        mVoicemail = intent.getParcelableExtra(EXTRA_VOICEMAIL);
-    }
-
-    @Override
-    public void onExecuteInBackgroundThread() {
-        OmtpVvmSyncService service = new OmtpVvmSyncService(getContext());
-        service.sync(this, mSyncType, mPhone, mVoicemail,
-                VoicemailStatus.edit(getContext(), mPhone));
-    }
-
-    @Override
-    public Intent createRestartIntent() {
-        Intent intent = super.createRestartIntent();
-        intent.putExtra(EXTRA_PHONE_ACCOUNT_HANDLE, mPhone);
-        intent.putExtra(EXTRA_SYNC_TYPE, mSyncType);
-        intent.putExtra(EXTRA_VOICEMAIL, mVoicemail);
-        return intent;
-    }
-
-}
diff --git a/src/com/android/phone/vvm/omtp/sync/SyncTask.java b/src/com/android/phone/vvm/omtp/sync/SyncTask.java
deleted file mode 100644
index 7374ee6..0000000
--- a/src/com/android/phone/vvm/omtp/sync/SyncTask.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.phone.vvm.omtp.sync;
-
-import android.content.Context;
-import android.content.Intent;
-import android.telecom.PhoneAccountHandle;
-import com.android.phone.vvm.omtp.scheduling.BaseTask;
-import com.android.phone.vvm.omtp.scheduling.MinimalIntervalPolicy;
-import com.android.phone.vvm.omtp.scheduling.RetryPolicy;
-import com.android.phone.vvm.omtp.utils.PhoneAccountHandleConverter;
-
-/**
- * System initiated sync request.
- */
-public class SyncTask extends BaseTask {
-
-    // Try sync for a total of 5 times, should take around 5 minutes before finally giving up.
-    private static final int RETRY_TIMES = 4;
-    private static final int RETRY_INTERVAL_MILLIS = 5_000;
-    private static final int MINIMAL_INTERVAL_MILLIS = 60_000;
-
-    private static final String EXTRA_PHONE_ACCOUNT_HANDLE = "extra_phone_account_handle";
-    private static final String EXTRA_SYNC_TYPE = "extra_sync_type";
-
-    private final RetryPolicy mRetryPolicy;
-
-    private PhoneAccountHandle mPhone;
-    private String mSyncType;
-
-    public static void start(Context context, PhoneAccountHandle phone, String syncType) {
-        Intent intent = BaseTask
-                .createIntent(context, SyncTask.class, PhoneAccountHandleConverter.toSubId(phone));
-        intent.putExtra(EXTRA_PHONE_ACCOUNT_HANDLE, phone);
-        intent.putExtra(EXTRA_SYNC_TYPE, syncType);
-        context.startService(intent);
-    }
-
-    public SyncTask() {
-        super(TASK_SYNC);
-        mRetryPolicy = new RetryPolicy(RETRY_TIMES, RETRY_INTERVAL_MILLIS);
-        addPolicy(mRetryPolicy);
-        addPolicy(new MinimalIntervalPolicy(MINIMAL_INTERVAL_MILLIS));
-    }
-
-    public void onCreate(Context context, Intent intent, int flags, int startId) {
-        super.onCreate(context, intent, flags, startId);
-        mPhone = intent.getParcelableExtra(EXTRA_PHONE_ACCOUNT_HANDLE);
-        mSyncType = intent.getStringExtra(EXTRA_SYNC_TYPE);
-    }
-
-    @Override
-    public void onExecuteInBackgroundThread() {
-        OmtpVvmSyncService service = new OmtpVvmSyncService(getContext());
-        service.sync(this, mSyncType, mPhone, null, mRetryPolicy.getVoicemailStatusEditor());
-    }
-
-    @Override
-    public Intent createRestartIntent() {
-        Intent intent = super.createRestartIntent();
-        intent.putExtra(EXTRA_PHONE_ACCOUNT_HANDLE, mPhone);
-        intent.putExtra(EXTRA_SYNC_TYPE, mSyncType);
-        return intent;
-    }
-}
diff --git a/src/com/android/phone/vvm/omtp/sync/UploadTask.java b/src/com/android/phone/vvm/omtp/sync/UploadTask.java
deleted file mode 100644
index 87c0a46..0000000
--- a/src/com/android/phone/vvm/omtp/sync/UploadTask.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.phone.vvm.omtp.sync;
-
-import android.content.Context;
-import android.content.Intent;
-import android.telecom.PhoneAccountHandle;
-import com.android.phone.VoicemailStatus;
-import com.android.phone.vvm.omtp.VvmLog;
-import com.android.phone.vvm.omtp.scheduling.BaseTask;
-import com.android.phone.vvm.omtp.scheduling.PostponePolicy;
-import com.android.phone.vvm.omtp.utils.PhoneAccountHandleConverter;
-
-/**
- * Upload task triggered by database changes. Will wait until the database has been stable for
- * {@link #POSTPONE_MILLIS} to execute.
- */
-public class UploadTask extends BaseTask {
-
-    private static final String TAG = "VvmUploadTask";
-
-    private static final int POSTPONE_MILLIS = 5_000;
-
-    public UploadTask() {
-        super(TASK_UPLOAD);
-        addPolicy(new PostponePolicy(POSTPONE_MILLIS));
-    }
-
-    public static void start(Context context, PhoneAccountHandle phoneAccountHandle) {
-        Intent intent = BaseTask
-                .createIntent(context, UploadTask.class,
-                        PhoneAccountHandleConverter.toSubId(phoneAccountHandle));
-        context.startService(intent);
-    }
-
-    @Override
-    public void onCreate(Context context, Intent intent, int flags, int startId) {
-        super.onCreate(context, intent, flags, startId);
-    }
-
-    @Override
-    public void onExecuteInBackgroundThread() {
-        OmtpVvmSyncService service = new OmtpVvmSyncService(getContext());
-
-        PhoneAccountHandle phoneAccountHandle = PhoneAccountHandleConverter.fromSubId(getSubId());
-        if (phoneAccountHandle == null) {
-            // This should never happen
-            VvmLog.e(TAG, "null phone account for subId " + getSubId());
-            return;
-        }
-        service.sync(this, OmtpVvmSyncService.SYNC_UPLOAD_ONLY,
-                phoneAccountHandle, null,
-                VoicemailStatus.edit(getContext(), phoneAccountHandle));
-    }
-}
diff --git a/src/com/android/phone/vvm/omtp/sync/VoicemailProviderChangeReceiver.java b/src/com/android/phone/vvm/omtp/sync/VoicemailProviderChangeReceiver.java
deleted file mode 100644
index bc9e6e1..0000000
--- a/src/com/android/phone/vvm/omtp/sync/VoicemailProviderChangeReceiver.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-package com.android.phone.vvm.omtp.sync;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.provider.VoicemailContract;
-import android.telecom.PhoneAccountHandle;
-
-/**
- * Receives changes to the voicemail provider so they can be sent to the voicemail server.
- */
-public class VoicemailProviderChangeReceiver extends BroadcastReceiver {
-
-    @Override
-    public void onReceive(Context context, Intent intent) {
-        boolean isSelfChanged = intent.getBooleanExtra(VoicemailContract.EXTRA_SELF_CHANGE, false);
-        OmtpVvmSourceManager vvmSourceManager =
-                OmtpVvmSourceManager.getInstance(context);
-        if (vvmSourceManager.getOmtpVvmSources().size() > 0 && !isSelfChanged) {
-            for (PhoneAccountHandle source : OmtpVvmSourceManager.getInstance(context)
-                    .getOmtpVvmSources()) {
-                UploadTask.start(context, source);
-            }
-        }
-    }
-}
diff --git a/src/com/android/phone/vvm/omtp/sync/VoicemailStatusQueryHelper.java b/src/com/android/phone/vvm/omtp/sync/VoicemailStatusQueryHelper.java
deleted file mode 100644
index 66f3e9d..0000000
--- a/src/com/android/phone/vvm/omtp/sync/VoicemailStatusQueryHelper.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-package com.android.phone.vvm.omtp.sync;
-
-import android.content.ContentResolver;
-import android.content.Context;
-import android.database.Cursor;
-import android.net.Uri;
-import android.provider.VoicemailContract;
-import android.provider.VoicemailContract.Status;
-import android.telecom.PhoneAccountHandle;
-
-/**
- * Construct queries to interact with the voicemail status table.
- */
-public class VoicemailStatusQueryHelper {
-
-    final static String[] PROJECTION = new String[] {
-            Status._ID,                        // 0
-            Status.CONFIGURATION_STATE,        // 1
-            Status.NOTIFICATION_CHANNEL_STATE, // 2
-            Status.SOURCE_PACKAGE              // 3
-   };
-
-    public static final int _ID = 0;
-    public static final int CONFIGURATION_STATE = 1;
-    public static final int NOTIFICATION_CHANNEL_STATE = 2;
-    public static final int SOURCE_PACKAGE = 3;
-
-    private Context mContext;
-    private ContentResolver mContentResolver;
-    private Uri mSourceUri;
-
-    public VoicemailStatusQueryHelper(Context context) {
-        mContext = context;
-        mContentResolver = context.getContentResolver();
-        mSourceUri = VoicemailContract.Status.buildSourceUri(mContext.getPackageName());
-    }
-
-    /**
-     * Check if the configuration state for the voicemail source is "ok", meaning that the
-     * source is set up.
-     *
-     * @param phoneAccount The phone account for the voicemail source to check.
-     * @return {@code true} if the voicemail source is configured, {@code} false otherwise,
-     * including if the voicemail source is not registered in the table.
-     */
-    public boolean isVoicemailSourceConfigured(PhoneAccountHandle phoneAccount) {
-        return isFieldEqualTo(phoneAccount, CONFIGURATION_STATE, Status.CONFIGURATION_STATE_OK);
-    }
-
-    /**
-     * Check if the notifications channel of a voicemail source is active. That is, when a new
-     * voicemail is available, if the server able to notify the device.
-     *
-     * @return {@code true} if notifications channel is active, {@code false} otherwise.
-     */
-    public boolean isNotificationsChannelActive(PhoneAccountHandle phoneAccount) {
-        return isFieldEqualTo(phoneAccount, NOTIFICATION_CHANNEL_STATE,
-                Status.NOTIFICATION_CHANNEL_STATE_OK);
-    }
-
-    /**
-     * Check if a field for an entry in the status table is equal to a specific value.
-     *
-     * @param phoneAccount The phone account of the voicemail source to query for.
-     * @param columnIndex The column index of the field in the returned query.
-     * @param value The value to compare against.
-     * @return {@code true} if the stored value is equal to the provided value. {@code false}
-     * otherwise.
-     */
-    private boolean isFieldEqualTo(PhoneAccountHandle phoneAccount, int columnIndex, int value) {
-        Cursor cursor = null;
-        if (phoneAccount != null) {
-            String phoneAccountComponentName = phoneAccount.getComponentName().flattenToString();
-            String phoneAccountId = phoneAccount.getId();
-            if (phoneAccountComponentName == null || phoneAccountId == null) {
-                return false;
-            }
-            try {
-                String whereClause =
-                        Status.PHONE_ACCOUNT_COMPONENT_NAME + "=? AND " +
-                        Status.PHONE_ACCOUNT_ID + "=? AND " + Status.SOURCE_PACKAGE + "=?";
-                String[] whereArgs = { phoneAccountComponentName, phoneAccountId,
-                        mContext.getPackageName()};
-                cursor = mContentResolver.query(
-                        mSourceUri, PROJECTION, whereClause, whereArgs, null);
-                if (cursor != null && cursor.moveToFirst()) {
-                    return cursor.getInt(columnIndex) == value;
-                }
-            }
-            finally {
-                if (cursor != null) {
-                    cursor.close();
-                }
-            }
-        }
-        return false;
-    }
-}
diff --git a/src/com/android/phone/vvm/omtp/sync/VoicemailsQueryHelper.java b/src/com/android/phone/vvm/omtp/sync/VoicemailsQueryHelper.java
deleted file mode 100644
index 9906386..0000000
--- a/src/com/android/phone/vvm/omtp/sync/VoicemailsQueryHelper.java
+++ /dev/null
@@ -1,244 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-package com.android.phone.vvm.omtp.sync;
-
-import android.content.ContentResolver;
-import android.content.ContentUris;
-import android.content.ContentValues;
-import android.content.Context;
-import android.database.Cursor;
-import android.net.Uri;
-import android.provider.VoicemailContract;
-import android.provider.VoicemailContract.Voicemails;
-import android.telecom.PhoneAccountHandle;
-import android.telecom.Voicemail;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Construct queries to interact with the voicemails table.
- */
-public class VoicemailsQueryHelper {
-    final static String[] PROJECTION = new String[] {
-            Voicemails._ID,              // 0
-            Voicemails.SOURCE_DATA,      // 1
-            Voicemails.IS_READ,          // 2
-            Voicemails.DELETED,          // 3
-            Voicemails.TRANSCRIPTION     // 4
-    };
-
-    public static final int _ID = 0;
-    public static final int SOURCE_DATA = 1;
-    public static final int IS_READ = 2;
-    public static final int DELETED = 3;
-    public static final int TRANSCRIPTION = 4;
-
-    final static String READ_SELECTION = Voicemails.DIRTY + "=1 AND "
-                + Voicemails.DELETED + "!=1 AND " + Voicemails.IS_READ + "=1";
-    final static String DELETED_SELECTION = Voicemails.DELETED + "=1";
-
-    private Context mContext;
-    private ContentResolver mContentResolver;
-    private Uri mSourceUri;
-
-    public VoicemailsQueryHelper(Context context) {
-        mContext = context;
-        mContentResolver = context.getContentResolver();
-        mSourceUri = VoicemailContract.Voicemails.buildSourceUri(mContext.getPackageName());
-    }
-
-    /**
-     * Get all the local read voicemails that have not been synced to the server.
-     *
-     * @return A list of read voicemails.
-     */
-    public List<Voicemail> getReadVoicemails() {
-        return getLocalVoicemails(READ_SELECTION);
-    }
-
-    /**
-     * Get all the locally deleted voicemails that have not been synced to the server.
-     *
-     * @return A list of deleted voicemails.
-     */
-    public List<Voicemail> getDeletedVoicemails() {
-        return getLocalVoicemails(DELETED_SELECTION);
-    }
-
-    /**
-     * Get all voicemails locally stored.
-     *
-     * @return A list of all locally stored voicemails.
-     */
-    public List<Voicemail> getAllVoicemails() {
-        return getLocalVoicemails(null);
-    }
-
-    /**
-     * Utility method to make queries to the voicemail database.
-     *
-     * @param selection A filter declaring which rows to return. {@code null} returns all rows.
-     * @return A list of voicemails according to the selection statement.
-     */
-    private List<Voicemail> getLocalVoicemails(String selection) {
-        Cursor cursor = mContentResolver.query(mSourceUri, PROJECTION, selection, null, null);
-        if (cursor == null) {
-            return null;
-        }
-        try {
-            List<Voicemail> voicemails = new ArrayList<Voicemail>();
-            while (cursor.moveToNext()) {
-                final long id = cursor.getLong(_ID);
-                final String sourceData = cursor.getString(SOURCE_DATA);
-                final boolean isRead = cursor.getInt(IS_READ) == 1;
-                final String transcription = cursor.getString(TRANSCRIPTION);
-                Voicemail voicemail = Voicemail
-                        .createForUpdate(id, sourceData)
-                        .setIsRead(isRead)
-                        .setTranscription(transcription).build();
-                voicemails.add(voicemail);
-            }
-            return voicemails;
-        } finally {
-            cursor.close();
-        }
-    }
-
-    /**
-     * Deletes a list of voicemails from the voicemail content provider.
-     *
-     * @param voicemails The list of voicemails to delete
-     * @return The number of voicemails deleted
-     */
-    public int deleteFromDatabase(List<Voicemail> voicemails) {
-        int count = voicemails.size();
-        if (count == 0) {
-            return 0;
-        }
-
-        StringBuilder sb = new StringBuilder();
-        for (int i = 0; i < count; i++) {
-            if (i > 0) {
-                sb.append(",");
-            }
-            sb.append(voicemails.get(i).getId());
-        }
-
-        String selectionStatement = String.format(Voicemails._ID + " IN (%s)", sb.toString());
-        return mContentResolver.delete(Voicemails.CONTENT_URI, selectionStatement, null);
-    }
-
-    /**
-     * Utility method to delete a single voicemail.
-     */
-    public void deleteFromDatabase(Voicemail voicemail) {
-        mContentResolver.delete(Voicemails.CONTENT_URI, Voicemails._ID + "=?",
-                new String[] { Long.toString(voicemail.getId()) });
-    }
-
-    public int markReadInDatabase(List<Voicemail> voicemails) {
-        int count = voicemails.size();
-        for (int i = 0; i < count; i++) {
-            markReadInDatabase(voicemails.get(i));
-        }
-        return count;
-    }
-
-    /**
-     * Utility method to mark single message as read.
-     */
-    public void markReadInDatabase(Voicemail voicemail) {
-        Uri uri = ContentUris.withAppendedId(mSourceUri, voicemail.getId());
-        ContentValues contentValues = new ContentValues();
-        contentValues.put(Voicemails.IS_READ, "1");
-        mContentResolver.update(uri, contentValues, null, null);
-    }
-
-    /**
-     * Sends an update command to the voicemail content provider for a list of voicemails. From the
-     * view of the provider, since the updater is the owner of the entry, a blank "update" means
-     * that the voicemail source is indicating that the server has up-to-date information on the
-     * voicemail. This flips the "dirty" bit to "0".
-     *
-     * @param voicemails The list of voicemails to update
-     * @return The number of voicemails updated
-     */
-    public int markCleanInDatabase(List<Voicemail> voicemails) {
-        int count = voicemails.size();
-        for (int i = 0; i < count; i++) {
-            markCleanInDatabase(voicemails.get(i));
-        }
-        return count;
-    }
-
-    /**
-     * Utility method to mark single message as clean.
-     */
-    public void markCleanInDatabase(Voicemail voicemail) {
-        Uri uri = ContentUris.withAppendedId(mSourceUri, voicemail.getId());
-        ContentValues contentValues = new ContentValues();
-        mContentResolver.update(uri, contentValues, null, null);
-    }
-
-    /**
-     * Utility method to add a transcription to the voicemail.
-     */
-    public void updateWithTranscription(Voicemail voicemail, String transcription) {
-        Uri uri = ContentUris.withAppendedId(mSourceUri, voicemail.getId());
-        ContentValues contentValues = new ContentValues();
-        contentValues.put(Voicemails.TRANSCRIPTION, transcription);
-        mContentResolver.update(uri, contentValues, null, null);
-    }
-
-    /**
-     * Voicemail is unique if the tuple of (phone account component name, phone account id, source
-     * data) is unique. If the phone account is missing, we also consider this unique since it's
-     * simply an "unknown" account.
-     * @param voicemail The voicemail to check if it is unique.
-     * @return {@code true} if the voicemail is unique, {@code false} otherwise.
-     */
-    public boolean isVoicemailUnique(Voicemail voicemail) {
-        Cursor cursor = null;
-        PhoneAccountHandle phoneAccount = voicemail.getPhoneAccount();
-        if (phoneAccount != null) {
-            String phoneAccountComponentName = phoneAccount.getComponentName().flattenToString();
-            String phoneAccountId = phoneAccount.getId();
-            String sourceData = voicemail.getSourceData();
-            if (phoneAccountComponentName == null || phoneAccountId == null || sourceData == null) {
-                return true;
-            }
-            try {
-                String whereClause =
-                        Voicemails.PHONE_ACCOUNT_COMPONENT_NAME + "=? AND " +
-                        Voicemails.PHONE_ACCOUNT_ID + "=? AND " + Voicemails.SOURCE_DATA + "=?";
-                String[] whereArgs = { phoneAccountComponentName, phoneAccountId, sourceData };
-                cursor = mContentResolver.query(
-                        mSourceUri, PROJECTION, whereClause, whereArgs, null);
-                if (cursor.getCount() == 0) {
-                    return true;
-                } else {
-                    return false;
-                }
-            }
-            finally {
-                if (cursor != null) {
-                    cursor.close();
-                }
-            }
-        }
-        return true;
-    }
-}
diff --git a/src/com/android/phone/vvm/omtp/sync/VvmNetworkRequest.java b/src/com/android/phone/vvm/omtp/sync/VvmNetworkRequest.java
deleted file mode 100644
index 3bdb45b..0000000
--- a/src/com/android/phone/vvm/omtp/sync/VvmNetworkRequest.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.phone.vvm.omtp.sync;
-
-import android.net.Network;
-import android.support.annotation.NonNull;
-import android.telecom.PhoneAccountHandle;
-import com.android.phone.VoicemailStatus;
-import com.android.phone.vvm.omtp.OmtpVvmCarrierConfigHelper;
-import com.android.phone.vvm.omtp.VvmLog;
-import java.io.Closeable;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.Future;
-
-/**
- * Class to retrieve a {@link Network} synchronously. {@link #getNetwork(OmtpVvmCarrierConfigHelper,
- * PhoneAccountHandle)} will block until a suitable network is retrieved or it has failed.
- */
-public class VvmNetworkRequest {
-
-    private static final String TAG = "VvmNetworkRequest";
-
-    /**
-     * A wrapper around a Network returned by a {@link VvmNetworkRequestCallback}, which should be
-     * closed once not needed anymore.
-     */
-    public static class NetworkWrapper implements Closeable {
-
-        private final Network mNetwork;
-        private final VvmNetworkRequestCallback mCallback;
-
-        private NetworkWrapper(Network network, VvmNetworkRequestCallback callback) {
-            mNetwork = network;
-            mCallback = callback;
-        }
-
-        public Network get() {
-            return mNetwork;
-        }
-
-        @Override
-        public void close() {
-            mCallback.releaseNetwork();
-        }
-    }
-
-    public static class RequestFailedException extends Exception {
-
-        private RequestFailedException(Throwable cause) {
-            super(cause);
-        }
-    }
-
-    @NonNull
-    public static NetworkWrapper getNetwork(OmtpVvmCarrierConfigHelper config,
-        PhoneAccountHandle handle, VoicemailStatus.Editor status) throws RequestFailedException {
-        FutureNetworkRequestCallback callback = new FutureNetworkRequestCallback(config, handle,
-            status);
-        callback.requestNetwork();
-        try {
-            return callback.getFuture().get();
-        } catch (InterruptedException | ExecutionException e) {
-            callback.releaseNetwork();
-            VvmLog.e(TAG, "can't get future network", e);
-            throw new RequestFailedException(e);
-        }
-    }
-
-    private static class FutureNetworkRequestCallback extends VvmNetworkRequestCallback {
-
-        /**
-         * {@link CompletableFuture#get()} will block until {@link CompletableFuture#
-         * complete(Object) } has been called on the other thread.
-         */
-        private final CompletableFuture<NetworkWrapper> mFuture = new CompletableFuture<>();
-
-        public FutureNetworkRequestCallback(OmtpVvmCarrierConfigHelper config,
-            PhoneAccountHandle phoneAccount, VoicemailStatus.Editor status) {
-            super(config, phoneAccount, status);
-        }
-
-        public Future<NetworkWrapper> getFuture() {
-            return mFuture;
-        }
-
-        @Override
-        public void onAvailable(Network network) {
-            super.onAvailable(network);
-            mFuture.complete(new NetworkWrapper(network, this));
-        }
-
-        @Override
-        public void onFailed(String reason) {
-            super.onFailed(reason);
-            mFuture.complete(null);
-        }
-
-    }
-}
diff --git a/src/com/android/phone/vvm/omtp/sync/VvmNetworkRequestCallback.java b/src/com/android/phone/vvm/omtp/sync/VvmNetworkRequestCallback.java
deleted file mode 100644
index 787fdcd..0000000
--- a/src/com/android/phone/vvm/omtp/sync/VvmNetworkRequestCallback.java
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-package com.android.phone.vvm.omtp.sync;
-
-import android.annotation.CallSuper;
-import android.content.Context;
-import android.net.ConnectivityManager;
-import android.net.Network;
-import android.net.NetworkCapabilities;
-import android.net.NetworkRequest;
-import android.os.Handler;
-import android.os.Looper;
-import android.telecom.PhoneAccountHandle;
-import com.android.phone.PhoneUtils;
-import com.android.phone.VoicemailStatus;
-import com.android.phone.vvm.omtp.OmtpEvents;
-import com.android.phone.vvm.omtp.OmtpVvmCarrierConfigHelper;
-import com.android.phone.vvm.omtp.VvmLog;
-
-/**
- * Base class for network request call backs for visual voicemail syncing with the Imap server. This
- * handles retries and network requests.
- */
-public abstract class VvmNetworkRequestCallback extends ConnectivityManager.NetworkCallback {
-
-    private static final String TAG = "VvmNetworkRequest";
-
-    // Timeout used to call ConnectivityManager.requestNetwork
-    private static final int NETWORK_REQUEST_TIMEOUT_MILLIS = 60 * 1000;
-
-    public static final String NETWORK_REQUEST_FAILED_TIMEOUT = "timeout";
-    public static final String NETWORK_REQUEST_FAILED_LOST = "lost";
-
-    protected Context mContext;
-    protected PhoneAccountHandle mPhoneAccount;
-    protected NetworkRequest mNetworkRequest;
-    private ConnectivityManager mConnectivityManager;
-    private final OmtpVvmCarrierConfigHelper mCarrierConfigHelper;
-    private final int mSubId;
-    private final VoicemailStatus.Editor mStatus;
-    private boolean mRequestSent = false;
-    private boolean mResultReceived = false;
-
-    public VvmNetworkRequestCallback(Context context, PhoneAccountHandle phoneAccount,
-        VoicemailStatus.Editor status) {
-        mContext = context;
-        mPhoneAccount = phoneAccount;
-        mSubId = PhoneUtils.getSubIdForPhoneAccountHandle(phoneAccount);
-        mStatus = status;
-        mCarrierConfigHelper = new OmtpVvmCarrierConfigHelper(context, mSubId);
-        mNetworkRequest = createNetworkRequest();
-    }
-
-    public VvmNetworkRequestCallback(OmtpVvmCarrierConfigHelper config,
-        PhoneAccountHandle phoneAccount, VoicemailStatus.Editor status) {
-        mContext = config.getContext();
-        mPhoneAccount = phoneAccount;
-        mSubId = config.getSubId();
-        mStatus = status;
-        mCarrierConfigHelper = config;
-        mNetworkRequest = createNetworkRequest();
-    }
-
-    public VoicemailStatus.Editor getVoicemailStatusEditor() {
-        return mStatus;
-    }
-
-    /**
-     * @return NetworkRequest for a proper transport type. Use only cellular network if the carrier
-     * requires it. Otherwise use whatever available.
-     */
-    private NetworkRequest createNetworkRequest() {
-
-        NetworkRequest.Builder builder = new NetworkRequest.Builder()
-                .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
-
-        if (mCarrierConfigHelper.isCellularDataRequired()) {
-            VvmLog.d(TAG, "Transport type: CELLULAR");
-            builder.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
-                    .setNetworkSpecifier(Integer.toString(mSubId));
-        } else {
-            VvmLog.d(TAG, "Transport type: ANY");
-        }
-        return builder.build();
-    }
-
-    public NetworkRequest getNetworkRequest() {
-        return mNetworkRequest;
-    }
-
-    @Override
-    @CallSuper
-    public void onLost(Network network) {
-        VvmLog.d(TAG, "onLost");
-        mResultReceived = true;
-        onFailed(NETWORK_REQUEST_FAILED_LOST);
-    }
-
-    @Override
-    @CallSuper
-    public void onAvailable(Network network) {
-        super.onAvailable(network);
-        mResultReceived = true;
-    }
-
-    @Override
-    @CallSuper
-    public void onUnavailable() {
-        mResultReceived = true;
-        onFailed(NETWORK_REQUEST_FAILED_TIMEOUT);
-    }
-
-    public void requestNetwork() {
-        if (mRequestSent == true) {
-            VvmLog.e(TAG, "requestNetwork() called twice");
-            return;
-        }
-        mRequestSent = true;
-        getConnectivityManager().requestNetwork(getNetworkRequest(), this);
-        /**
-         * Somehow requestNetwork() with timeout doesn't work, and it's a hidden method.
-         * Implement our own timeout mechanism instead.
-         */
-        Handler handler = new Handler(Looper.getMainLooper());
-        handler.postDelayed(new Runnable() {
-            @Override
-            public void run() {
-                if (mResultReceived == false) {
-                    onFailed(NETWORK_REQUEST_FAILED_TIMEOUT);
-                }
-            }
-        }, NETWORK_REQUEST_TIMEOUT_MILLIS);
-    }
-
-    public void releaseNetwork() {
-        VvmLog.d(TAG, "releaseNetwork");
-        getConnectivityManager().unregisterNetworkCallback(this);
-    }
-
-    public ConnectivityManager getConnectivityManager() {
-        if (mConnectivityManager == null) {
-            mConnectivityManager = (ConnectivityManager) mContext.getSystemService(
-                    Context.CONNECTIVITY_SERVICE);
-        }
-        return mConnectivityManager;
-    }
-
-    @CallSuper
-    public void onFailed(String reason) {
-        VvmLog.d(TAG, "onFailed: " + reason);
-        if (mCarrierConfigHelper.isCellularDataRequired()) {
-            mCarrierConfigHelper
-                .handleEvent(mStatus, OmtpEvents.DATA_NO_CONNECTION_CELLULAR_REQUIRED);
-        } else {
-            mCarrierConfigHelper.handleEvent(mStatus, OmtpEvents.DATA_NO_CONNECTION);
-        }
-        releaseNetwork();
-    }
-}
diff --git a/src/com/android/phone/vvm/omtp/utils/XmlUtils.java b/src/com/android/phone/vvm/omtp/utils/XmlUtils.java
deleted file mode 100644
index 4eeb5ce..0000000
--- a/src/com/android/phone/vvm/omtp/utils/XmlUtils.java
+++ /dev/null
@@ -1,245 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.phone.vvm.omtp.utils;
-
-import android.util.ArrayMap;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-
-public class XmlUtils {
-
-    public static final ArrayMap<String, ?> readThisArrayMapXml(XmlPullParser parser, String endTag,
-            String[] name, ReadMapCallback callback)
-            throws XmlPullParserException, java.io.IOException {
-        ArrayMap<String, Object> map = new ArrayMap<>();
-
-        int eventType = parser.getEventType();
-        do {
-            if (eventType == XmlPullParser.START_TAG) {
-                Object val = readThisValueXml(parser, name, callback, true);
-                map.put(name[0], val);
-            } else if (eventType == XmlPullParser.END_TAG) {
-                if (parser.getName().equals(endTag)) {
-                    return map;
-                }
-                throw new XmlPullParserException(
-                        "Expected " + endTag + " end tag at: " + parser.getName());
-            }
-            eventType = parser.next();
-        } while (eventType != XmlPullParser.END_DOCUMENT);
-
-        throw new XmlPullParserException(
-                "Document ended before " + endTag + " end tag");
-    }
-
-    /**
-     * Read an ArrayList object from an XmlPullParser.  The XML data could previously have been
-     * generated by writeListXml().  The XmlPullParser must be positioned <em>after</em> the tag
-     * that begins the list.
-     *
-     * @param parser The XmlPullParser from which to read the list data.
-     * @param endTag Name of the tag that will end the list, usually "list".
-     * @param name An array of one string, used to return the name attribute of the list's tag.
-     * @return HashMap The newly generated list.
-     */
-    public static final ArrayList readThisListXml(XmlPullParser parser, String endTag,
-            String[] name, ReadMapCallback callback, boolean arrayMap)
-            throws XmlPullParserException, java.io.IOException {
-        ArrayList list = new ArrayList();
-
-        int eventType = parser.getEventType();
-        do {
-            if (eventType == XmlPullParser.START_TAG) {
-                Object val = readThisValueXml(parser, name, callback, arrayMap);
-                list.add(val);
-            } else if (eventType == XmlPullParser.END_TAG) {
-                if (parser.getName().equals(endTag)) {
-                    return list;
-                }
-                throw new XmlPullParserException(
-                        "Expected " + endTag + " end tag at: " + parser.getName());
-            }
-            eventType = parser.next();
-        } while (eventType != XmlPullParser.END_DOCUMENT);
-
-        throw new XmlPullParserException(
-                "Document ended before " + endTag + " end tag");
-    }
-
-    /**
-     * Read a String[] object from an XmlPullParser.  The XML data could previously have been
-     * generated by writeStringArrayXml().  The XmlPullParser must be positioned <em>after</em> the
-     * tag that begins the list.
-     *
-     * @param parser The XmlPullParser from which to read the list data.
-     * @param endTag Name of the tag that will end the list, usually "string-array".
-     * @param name An array of one string, used to return the name attribute of the list's tag.
-     * @return Returns a newly generated String[].
-     */
-    public static String[] readThisStringArrayXml(XmlPullParser parser, String endTag,
-            String[] name) throws XmlPullParserException, java.io.IOException {
-
-        parser.next();
-
-        List<String> array = new ArrayList<>();
-
-        int eventType = parser.getEventType();
-        do {
-            if (eventType == XmlPullParser.START_TAG) {
-                if (parser.getName().equals("item")) {
-                    try {
-                        array.add(parser.getAttributeValue(null, "value"));
-                    } catch (NullPointerException e) {
-                        throw new XmlPullParserException("Need value attribute in item");
-                    } catch (NumberFormatException e) {
-                        throw new XmlPullParserException("Not a number in value attribute in item");
-                    }
-                } else {
-                    throw new XmlPullParserException("Expected item tag at: " + parser.getName());
-                }
-            } else if (eventType == XmlPullParser.END_TAG) {
-                if (parser.getName().equals(endTag)) {
-                    return array.toArray(new String[0]);
-                } else if (parser.getName().equals("item")) {
-
-                } else {
-                    throw new XmlPullParserException("Expected " + endTag + " end tag at: " +
-                            parser.getName());
-                }
-            }
-            eventType = parser.next();
-        } while (eventType != XmlPullParser.END_DOCUMENT);
-
-        throw new XmlPullParserException("Document ended before " + endTag + " end tag");
-    }
-
-    private static Object readThisValueXml(XmlPullParser parser, String[] name,
-            ReadMapCallback callback, boolean arrayMap)
-            throws XmlPullParserException, java.io.IOException {
-        final String valueName = parser.getAttributeValue(null, "name");
-        final String tagName = parser.getName();
-
-        Object res;
-
-        if (tagName.equals("null")) {
-            res = null;
-        } else if (tagName.equals("string")) {
-            String value = "";
-            int eventType;
-            while ((eventType = parser.next()) != XmlPullParser.END_DOCUMENT) {
-                if (eventType == XmlPullParser.END_TAG) {
-                    if (parser.getName().equals("string")) {
-                        name[0] = valueName;
-                        return value;
-                    }
-                    throw new XmlPullParserException(
-                            "Unexpected end tag in <string>: " + parser.getName());
-                } else if (eventType == XmlPullParser.TEXT) {
-                    value += parser.getText();
-                } else if (eventType == XmlPullParser.START_TAG) {
-                    throw new XmlPullParserException(
-                            "Unexpected start tag in <string>: " + parser.getName());
-                }
-            }
-            throw new XmlPullParserException(
-                    "Unexpected end of document in <string>");
-        } else if ((res = readThisPrimitiveValueXml(parser, tagName)) != null) {
-            // all work already done by readThisPrimitiveValueXml
-        } else if (tagName.equals("string-array")) {
-            res = readThisStringArrayXml(parser, "string-array", name);
-            name[0] = valueName;
-            return res;
-        } else if (tagName.equals("list")) {
-            parser.next();
-            res = readThisListXml(parser, "list", name, callback, arrayMap);
-            name[0] = valueName;
-            return res;
-        } else if (callback != null) {
-            res = callback.readThisUnknownObjectXml(parser, tagName);
-            name[0] = valueName;
-            return res;
-        } else {
-            throw new XmlPullParserException("Unknown tag: " + tagName);
-        }
-
-        // Skip through to end tag.
-        int eventType;
-        while ((eventType = parser.next()) != XmlPullParser.END_DOCUMENT) {
-            if (eventType == XmlPullParser.END_TAG) {
-                if (parser.getName().equals(tagName)) {
-                    name[0] = valueName;
-                    return res;
-                }
-                throw new XmlPullParserException(
-                        "Unexpected end tag in <" + tagName + ">: " + parser.getName());
-            } else if (eventType == XmlPullParser.TEXT) {
-                throw new XmlPullParserException(
-                        "Unexpected text in <" + tagName + ">: " + parser.getName());
-            } else if (eventType == XmlPullParser.START_TAG) {
-                throw new XmlPullParserException(
-                        "Unexpected start tag in <" + tagName + ">: " + parser.getName());
-            }
-        }
-        throw new XmlPullParserException(
-                "Unexpected end of document in <" + tagName + ">");
-    }
-
-    private static final Object readThisPrimitiveValueXml(XmlPullParser parser, String tagName)
-            throws XmlPullParserException, java.io.IOException {
-        try {
-            if (tagName.equals("int")) {
-                return Integer.parseInt(parser.getAttributeValue(null, "value"));
-            } else if (tagName.equals("long")) {
-                return Long.valueOf(parser.getAttributeValue(null, "value"));
-            } else if (tagName.equals("float")) {
-                return Float.valueOf(parser.getAttributeValue(null, "value"));
-            } else if (tagName.equals("double")) {
-                return Double.valueOf(parser.getAttributeValue(null, "value"));
-            } else if (tagName.equals("boolean")) {
-                return Boolean.valueOf(parser.getAttributeValue(null, "value"));
-            } else {
-                return null;
-            }
-        } catch (NullPointerException e) {
-            throw new XmlPullParserException("Need value attribute in <" + tagName + ">");
-        } catch (NumberFormatException e) {
-            throw new XmlPullParserException(
-                    "Not a number in value attribute in <" + tagName + ">");
-        }
-    }
-
-    public interface ReadMapCallback {
-
-        /**
-         * Called from readThisMapXml when a START_TAG is not recognized. The input stream is
-         * positioned within the start tag so that attributes can be read using in.getAttribute.
-         *
-         * @param in the XML input stream
-         * @param tag the START_TAG that was not recognized.
-         * @return the Object parsed from the stream which will be put into the map.
-         * @throws XmlPullParserException if the START_TAG is not recognized.
-         * @throws IOException on XmlPullParser serialization errors.
-         */
-        Object readThisUnknownObjectXml(XmlPullParser in, String tag)
-                throws XmlPullParserException, IOException;
-    }
-}
\ No newline at end of file
diff --git a/src/org/apache/commons/io/IOUtils.java b/src/org/apache/commons/io/IOUtils.java
deleted file mode 100644
index b414507..0000000
--- a/src/org/apache/commons/io/IOUtils.java
+++ /dev/null
@@ -1,1202 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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 org.apache.commons.io;
-
-import java.io.BufferedInputStream;
-import java.io.BufferedReader;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.CharArrayWriter;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
-import java.io.PrintWriter;
-import java.io.Reader;
-import java.io.StringWriter;
-import java.io.Writer;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-
-/**
- * General IO stream manipulation utilities.
- * <p>
- * This class provides static utility methods for input/output operations.
- * <ul>
- * <li>closeQuietly - these methods close a stream ignoring nulls and exceptions
- * <li>toXxx/read - these methods read data from a stream
- * <li>write - these methods write data to a stream
- * <li>copy - these methods copy all the data from one stream to another
- * <li>contentEquals - these methods compare the content of two streams
- * </ul>
- * <p>
- * The byte-to-char methods and char-to-byte methods involve a conversion step.
- * Two methods are provided in each case, one that uses the platform default
- * encoding and the other which allows you to specify an encoding. You are
- * encouraged to always specify an encoding because relying on the platform
- * default can lead to unexpected results, for example when moving from
- * development to production.
- * <p>
- * All the methods in this class that read a stream are buffered internally.
- * This means that there is no cause to use a <code>BufferedInputStream</code>
- * or <code>BufferedReader</code>. The default buffer size of 4K has been shown
- * to be efficient in tests.
- * <p>
- * Wherever possible, the methods in this class do <em>not</em> flush or close
- * the stream. This is to avoid making non-portable assumptions about the
- * streams' origin and further use. Thus the caller is still responsible for
- * closing streams after use.
- * <p>
- * Origin of code: Excalibur.
- *
- * @author Peter Donald
- * @author Jeff Turner
- * @author Matthew Hawthorne
- * @author Stephen Colebourne
- * @author Gareth Davis
- * @author Ian Springer
- * @author Niall Pemberton
- * @author Sandy McArthur
- * @version $Id: IOUtils.java 481854 2006-12-03 18:30:07Z scolebourne $
- */
-public class IOUtils {
-    // NOTE: This class is focussed on InputStream, OutputStream, Reader and
-    // Writer. Each method should take at least one of these as a parameter,
-    // or return one of them.
-
-    /**
-     * The Unix directory separator character.
-     */
-    public static final char DIR_SEPARATOR_UNIX = '/';
-    /**
-     * The Windows directory separator character.
-     */
-    public static final char DIR_SEPARATOR_WINDOWS = '\\';
-    /**
-     * The system directory separator character.
-     */
-    public static final char DIR_SEPARATOR = File.separatorChar;
-    /**
-     * The Unix line separator string.
-     */
-    public static final String LINE_SEPARATOR_UNIX = "\n";
-    /**
-     * The Windows line separator string.
-     */
-    public static final String LINE_SEPARATOR_WINDOWS = "\r\n";
-    /**
-     * The system line separator string.
-     */
-    public static final String LINE_SEPARATOR;
-    static {
-        // avoid security issues
-        StringWriter buf = new StringWriter(4);
-        PrintWriter out = new PrintWriter(buf);
-        out.println();
-        LINE_SEPARATOR = buf.toString();
-    }
-
-    /**
-     * The default buffer size to use.
-     */
-    private static final int DEFAULT_BUFFER_SIZE = 1024 * 4;
-
-    /**
-     * Instances should NOT be constructed in standard programming.
-     */
-    public IOUtils() {
-        super();
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Unconditionally close an <code>Reader</code>.
-     * <p>
-     * Equivalent to {@link Reader#close()}, except any exceptions will be ignored.
-     * This is typically used in finally blocks.
-     *
-     * @param input  the Reader to close, may be null or already closed
-     */
-    public static void closeQuietly(Reader input) {
-        try {
-            if (input != null) {
-                input.close();
-            }
-        } catch (IOException ioe) {
-            // ignore
-        }
-    }
-
-    /**
-     * Unconditionally close a <code>Writer</code>.
-     * <p>
-     * Equivalent to {@link Writer#close()}, except any exceptions will be ignored.
-     * This is typically used in finally blocks.
-     *
-     * @param output  the Writer to close, may be null or already closed
-     */
-    public static void closeQuietly(Writer output) {
-        try {
-            if (output != null) {
-                output.close();
-            }
-        } catch (IOException ioe) {
-            // ignore
-        }
-    }
-
-    /**
-     * Unconditionally close an <code>InputStream</code>.
-     * <p>
-     * Equivalent to {@link InputStream#close()}, except any exceptions will be ignored.
-     * This is typically used in finally blocks.
-     *
-     * @param input  the InputStream to close, may be null or already closed
-     */
-    public static void closeQuietly(InputStream input) {
-        try {
-            if (input != null) {
-                input.close();
-            }
-        } catch (IOException ioe) {
-            // ignore
-        }
-    }
-
-    /**
-     * Unconditionally close an <code>OutputStream</code>.
-     * <p>
-     * Equivalent to {@link OutputStream#close()}, except any exceptions will be ignored.
-     * This is typically used in finally blocks.
-     *
-     * @param output  the OutputStream to close, may be null or already closed
-     */
-    public static void closeQuietly(OutputStream output) {
-        try {
-            if (output != null) {
-                output.close();
-            }
-        } catch (IOException ioe) {
-            // ignore
-        }
-    }
-
-    // read toByteArray
-    //-----------------------------------------------------------------------
-    /**
-     * Get the contents of an <code>InputStream</code> as a <code>byte[]</code>.
-     * <p>
-     * This method buffers the input internally, so there is no need to use a
-     * <code>BufferedInputStream</code>.
-     *
-     * @param input  the <code>InputStream</code> to read from
-     * @return the requested byte array
-     * @throws NullPointerException if the input is null
-     * @throws IOException if an I/O error occurs
-     */
-    public static byte[] toByteArray(InputStream input) throws IOException {
-        ByteArrayOutputStream output = new ByteArrayOutputStream();
-        copy(input, output);
-        return output.toByteArray();
-    }
-
-    /**
-     * Get the contents of a <code>Reader</code> as a <code>byte[]</code>
-     * using the default character encoding of the platform.
-     * <p>
-     * This method buffers the input internally, so there is no need to use a
-     * <code>BufferedReader</code>.
-     *
-     * @param input  the <code>Reader</code> to read from
-     * @return the requested byte array
-     * @throws NullPointerException if the input is null
-     * @throws IOException if an I/O error occurs
-     */
-    public static byte[] toByteArray(Reader input) throws IOException {
-        ByteArrayOutputStream output = new ByteArrayOutputStream();
-        copy(input, output);
-        return output.toByteArray();
-    }
-
-    /**
-     * Get the contents of a <code>Reader</code> as a <code>byte[]</code>
-     * using the specified character encoding.
-     * <p>
-     * Character encoding names can be found at
-     * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
-     * <p>
-     * This method buffers the input internally, so there is no need to use a
-     * <code>BufferedReader</code>.
-     *
-     * @param input  the <code>Reader</code> to read from
-     * @param encoding  the encoding to use, null means platform default
-     * @return the requested byte array
-     * @throws NullPointerException if the input is null
-     * @throws IOException if an I/O error occurs
-     * @since Commons IO 1.1
-     */
-    public static byte[] toByteArray(Reader input, String encoding)
-            throws IOException {
-        ByteArrayOutputStream output = new ByteArrayOutputStream();
-        copy(input, output, encoding);
-        return output.toByteArray();
-    }
-
-    /**
-     * Get the contents of a <code>String</code> as a <code>byte[]</code>
-     * using the default character encoding of the platform.
-     * <p>
-     * This is the same as {@link String#getBytes()}.
-     *
-     * @param input  the <code>String</code> to convert
-     * @return the requested byte array
-     * @throws NullPointerException if the input is null
-     * @throws IOException if an I/O error occurs (never occurs)
-     * @deprecated Use {@link String#getBytes()}
-     */
-    @Deprecated
-    public static byte[] toByteArray(String input) throws IOException {
-        return input.getBytes();
-    }
-
-    // read char[]
-    //-----------------------------------------------------------------------
-    /**
-     * Get the contents of an <code>InputStream</code> as a character array
-     * using the default character encoding of the platform.
-     * <p>
-     * This method buffers the input internally, so there is no need to use a
-     * <code>BufferedInputStream</code>.
-     *
-     * @param is  the <code>InputStream</code> to read from
-     * @return the requested character array
-     * @throws NullPointerException if the input is null
-     * @throws IOException if an I/O error occurs
-     * @since Commons IO 1.1
-     */
-    public static char[] toCharArray(InputStream is) throws IOException {
-        CharArrayWriter output = new CharArrayWriter();
-        copy(is, output);
-        return output.toCharArray();
-    }
-
-    /**
-     * Get the contents of an <code>InputStream</code> as a character array
-     * using the specified character encoding.
-     * <p>
-     * Character encoding names can be found at
-     * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
-     * <p>
-     * This method buffers the input internally, so there is no need to use a
-     * <code>BufferedInputStream</code>.
-     *
-     * @param is  the <code>InputStream</code> to read from
-     * @param encoding  the encoding to use, null means platform default
-     * @return the requested character array
-     * @throws NullPointerException if the input is null
-     * @throws IOException if an I/O error occurs
-     * @since Commons IO 1.1
-     */
-    public static char[] toCharArray(InputStream is, String encoding)
-            throws IOException {
-        CharArrayWriter output = new CharArrayWriter();
-        copy(is, output, encoding);
-        return output.toCharArray();
-    }
-
-    /**
-     * Get the contents of a <code>Reader</code> as a character array.
-     * <p>
-     * This method buffers the input internally, so there is no need to use a
-     * <code>BufferedReader</code>.
-     *
-     * @param input  the <code>Reader</code> to read from
-     * @return the requested character array
-     * @throws NullPointerException if the input is null
-     * @throws IOException if an I/O error occurs
-     * @since Commons IO 1.1
-     */
-    public static char[] toCharArray(Reader input) throws IOException {
-        CharArrayWriter sw = new CharArrayWriter();
-        copy(input, sw);
-        return sw.toCharArray();
-    }
-
-    // read toString
-    //-----------------------------------------------------------------------
-    /**
-     * Get the contents of an <code>InputStream</code> as a String
-     * using the default character encoding of the platform.
-     * <p>
-     * This method buffers the input internally, so there is no need to use a
-     * <code>BufferedInputStream</code>.
-     *
-     * @param input  the <code>InputStream</code> to read from
-     * @return the requested String
-     * @throws NullPointerException if the input is null
-     * @throws IOException if an I/O error occurs
-     */
-    public static String toString(InputStream input) throws IOException {
-        StringWriter sw = new StringWriter();
-        copy(input, sw);
-        return sw.toString();
-    }
-
-    /**
-     * Get the contents of an <code>InputStream</code> as a String
-     * using the specified character encoding.
-     * <p>
-     * Character encoding names can be found at
-     * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
-     * <p>
-     * This method buffers the input internally, so there is no need to use a
-     * <code>BufferedInputStream</code>.
-     *
-     * @param input  the <code>InputStream</code> to read from
-     * @param encoding  the encoding to use, null means platform default
-     * @return the requested String
-     * @throws NullPointerException if the input is null
-     * @throws IOException if an I/O error occurs
-     */
-    public static String toString(InputStream input, String encoding)
-            throws IOException {
-        StringWriter sw = new StringWriter();
-        copy(input, sw, encoding);
-        return sw.toString();
-    }
-
-    /**
-     * Get the contents of a <code>Reader</code> as a String.
-     * <p>
-     * This method buffers the input internally, so there is no need to use a
-     * <code>BufferedReader</code>.
-     *
-     * @param input  the <code>Reader</code> to read from
-     * @return the requested String
-     * @throws NullPointerException if the input is null
-     * @throws IOException if an I/O error occurs
-     */
-    public static String toString(Reader input) throws IOException {
-        StringWriter sw = new StringWriter();
-        copy(input, sw);
-        return sw.toString();
-    }
-
-    /**
-     * Get the contents of a <code>byte[]</code> as a String
-     * using the default character encoding of the platform.
-     *
-     * @param input the byte array to read from
-     * @return the requested String
-     * @throws NullPointerException if the input is null
-     * @throws IOException if an I/O error occurs (never occurs)
-     * @deprecated Use {@link String#String(byte[])}
-     */
-    @Deprecated
-    public static String toString(byte[] input) throws IOException {
-        return new String(input);
-    }
-
-    /**
-     * Get the contents of a <code>byte[]</code> as a String
-     * using the specified character encoding.
-     * <p>
-     * Character encoding names can be found at
-     * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
-     *
-     * @param input the byte array to read from
-     * @param encoding  the encoding to use, null means platform default
-     * @return the requested String
-     * @throws NullPointerException if the input is null
-     * @throws IOException if an I/O error occurs (never occurs)
-     * @deprecated Use {@link String#String(byte[],String)}
-     */
-    @Deprecated
-    public static String toString(byte[] input, String encoding)
-            throws IOException {
-        if (encoding == null) {
-            return new String(input);
-        } else {
-            return new String(input, encoding);
-        }
-    }
-
-    // readLines
-    //-----------------------------------------------------------------------
-    /**
-     * Get the contents of an <code>InputStream</code> as a list of Strings,
-     * one entry per line, using the default character encoding of the platform.
-     * <p>
-     * This method buffers the input internally, so there is no need to use a
-     * <code>BufferedInputStream</code>.
-     *
-     * @param input  the <code>InputStream</code> to read from, not null
-     * @return the list of Strings, never null
-     * @throws NullPointerException if the input is null
-     * @throws IOException if an I/O error occurs
-     * @since Commons IO 1.1
-     */
-    public static List<String> readLines(InputStream input) throws IOException {
-        InputStreamReader reader = new InputStreamReader(input);
-        return readLines(reader);
-    }
-
-    /**
-     * Get the contents of an <code>InputStream</code> as a list of Strings,
-     * one entry per line, using the specified character encoding.
-     * <p>
-     * Character encoding names can be found at
-     * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
-     * <p>
-     * This method buffers the input internally, so there is no need to use a
-     * <code>BufferedInputStream</code>.
-     *
-     * @param input  the <code>InputStream</code> to read from, not null
-     * @param encoding  the encoding to use, null means platform default
-     * @return the list of Strings, never null
-     * @throws NullPointerException if the input is null
-     * @throws IOException if an I/O error occurs
-     * @since Commons IO 1.1
-     */
-    public static List<String> readLines(InputStream input, String encoding) throws IOException {
-        if (encoding == null) {
-            return readLines(input);
-        } else {
-            InputStreamReader reader = new InputStreamReader(input, encoding);
-            return readLines(reader);
-        }
-    }
-
-    /**
-     * Get the contents of a <code>Reader</code> as a list of Strings,
-     * one entry per line.
-     * <p>
-     * This method buffers the input internally, so there is no need to use a
-     * <code>BufferedReader</code>.
-     *
-     * @param input  the <code>Reader</code> to read from, not null
-     * @return the list of Strings, never null
-     * @throws NullPointerException if the input is null
-     * @throws IOException if an I/O error occurs
-     * @since Commons IO 1.1
-     */
-    public static List<String> readLines(Reader input) throws IOException {
-        BufferedReader reader = new BufferedReader(input);
-        List<String> list = new ArrayList<String>();
-        String line = reader.readLine();
-        while (line != null) {
-            list.add(line);
-            line = reader.readLine();
-        }
-        return list;
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Convert the specified string to an input stream, encoded as bytes
-     * using the default character encoding of the platform.
-     *
-     * @param input the string to convert
-     * @return an input stream
-     * @since Commons IO 1.1
-     */
-    public static InputStream toInputStream(String input) {
-        byte[] bytes = input.getBytes();
-        return new ByteArrayInputStream(bytes);
-    }
-
-    /**
-     * Convert the specified string to an input stream, encoded as bytes
-     * using the specified character encoding.
-     * <p>
-     * Character encoding names can be found at
-     * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
-     *
-     * @param input the string to convert
-     * @param encoding the encoding to use, null means platform default
-     * @throws IOException if the encoding is invalid
-     * @return an input stream
-     * @since Commons IO 1.1
-     */
-    public static InputStream toInputStream(String input, String encoding) throws IOException {
-        byte[] bytes = encoding != null ? input.getBytes(encoding) : input.getBytes();
-        return new ByteArrayInputStream(bytes);
-    }
-
-    // write byte[]
-    //-----------------------------------------------------------------------
-    /**
-     * Writes bytes from a <code>byte[]</code> to an <code>OutputStream</code>.
-     *
-     * @param data  the byte array to write, do not modify during output,
-     * null ignored
-     * @param output  the <code>OutputStream</code> to write to
-     * @throws NullPointerException if output is null
-     * @throws IOException if an I/O error occurs
-     * @since Commons IO 1.1
-     */
-    public static void write(byte[] data, OutputStream output)
-            throws IOException {
-        if (data != null) {
-            output.write(data);
-        }
-    }
-
-    /**
-     * Writes bytes from a <code>byte[]</code> to chars on a <code>Writer</code>
-     * using the default character encoding of the platform.
-     * <p>
-     * This method uses {@link String#String(byte[])}.
-     *
-     * @param data  the byte array to write, do not modify during output,
-     * null ignored
-     * @param output  the <code>Writer</code> to write to
-     * @throws NullPointerException if output is null
-     * @throws IOException if an I/O error occurs
-     * @since Commons IO 1.1
-     */
-    public static void write(byte[] data, Writer output) throws IOException {
-        if (data != null) {
-            output.write(new String(data));
-        }
-    }
-
-    /**
-     * Writes bytes from a <code>byte[]</code> to chars on a <code>Writer</code>
-     * using the specified character encoding.
-     * <p>
-     * Character encoding names can be found at
-     * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
-     * <p>
-     * This method uses {@link String#String(byte[], String)}.
-     *
-     * @param data  the byte array to write, do not modify during output,
-     * null ignored
-     * @param output  the <code>Writer</code> to write to
-     * @param encoding  the encoding to use, null means platform default
-     * @throws NullPointerException if output is null
-     * @throws IOException if an I/O error occurs
-     * @since Commons IO 1.1
-     */
-    public static void write(byte[] data, Writer output, String encoding)
-            throws IOException {
-        if (data != null) {
-            if (encoding == null) {
-                write(data, output);
-            } else {
-                output.write(new String(data, encoding));
-            }
-        }
-    }
-
-    // write char[]
-    //-----------------------------------------------------------------------
-    /**
-     * Writes chars from a <code>char[]</code> to a <code>Writer</code>
-     * using the default character encoding of the platform.
-     *
-     * @param data  the char array to write, do not modify during output,
-     * null ignored
-     * @param output  the <code>Writer</code> to write to
-     * @throws NullPointerException if output is null
-     * @throws IOException if an I/O error occurs
-     * @since Commons IO 1.1
-     */
-    public static void write(char[] data, Writer output) throws IOException {
-        if (data != null) {
-            output.write(data);
-        }
-    }
-
-    /**
-     * Writes chars from a <code>char[]</code> to bytes on an
-     * <code>OutputStream</code>.
-     * <p>
-     * This method uses {@link String#String(char[])} and
-     * {@link String#getBytes()}.
-     *
-     * @param data  the char array to write, do not modify during output,
-     * null ignored
-     * @param output  the <code>OutputStream</code> to write to
-     * @throws NullPointerException if output is null
-     * @throws IOException if an I/O error occurs
-     * @since Commons IO 1.1
-     */
-    public static void write(char[] data, OutputStream output)
-            throws IOException {
-        if (data != null) {
-            output.write(new String(data).getBytes());
-        }
-    }
-
-    /**
-     * Writes chars from a <code>char[]</code> to bytes on an
-     * <code>OutputStream</code> using the specified character encoding.
-     * <p>
-     * Character encoding names can be found at
-     * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
-     * <p>
-     * This method uses {@link String#String(char[])} and
-     * {@link String#getBytes(String)}.
-     *
-     * @param data  the char array to write, do not modify during output,
-     * null ignored
-     * @param output  the <code>OutputStream</code> to write to
-     * @param encoding  the encoding to use, null means platform default
-     * @throws NullPointerException if output is null
-     * @throws IOException if an I/O error occurs
-     * @since Commons IO 1.1
-     */
-    public static void write(char[] data, OutputStream output, String encoding)
-            throws IOException {
-        if (data != null) {
-            if (encoding == null) {
-                write(data, output);
-            } else {
-                output.write(new String(data).getBytes(encoding));
-            }
-        }
-    }
-
-    // write String
-    //-----------------------------------------------------------------------
-    /**
-     * Writes chars from a <code>String</code> to a <code>Writer</code>.
-     *
-     * @param data  the <code>String</code> to write, null ignored
-     * @param output  the <code>Writer</code> to write to
-     * @throws NullPointerException if output is null
-     * @throws IOException if an I/O error occurs
-     * @since Commons IO 1.1
-     */
-    public static void write(String data, Writer output) throws IOException {
-        if (data != null) {
-            output.write(data);
-        }
-    }
-
-    /**
-     * Writes chars from a <code>String</code> to bytes on an
-     * <code>OutputStream</code> using the default character encoding of the
-     * platform.
-     * <p>
-     * This method uses {@link String#getBytes()}.
-     *
-     * @param data  the <code>String</code> to write, null ignored
-     * @param output  the <code>OutputStream</code> to write to
-     * @throws NullPointerException if output is null
-     * @throws IOException if an I/O error occurs
-     * @since Commons IO 1.1
-     */
-    public static void write(String data, OutputStream output)
-            throws IOException {
-        if (data != null) {
-            output.write(data.getBytes());
-        }
-    }
-
-    /**
-     * Writes chars from a <code>String</code> to bytes on an
-     * <code>OutputStream</code> using the specified character encoding.
-     * <p>
-     * Character encoding names can be found at
-     * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
-     * <p>
-     * This method uses {@link String#getBytes(String)}.
-     *
-     * @param data  the <code>String</code> to write, null ignored
-     * @param output  the <code>OutputStream</code> to write to
-     * @param encoding  the encoding to use, null means platform default
-     * @throws NullPointerException if output is null
-     * @throws IOException if an I/O error occurs
-     * @since Commons IO 1.1
-     */
-    public static void write(String data, OutputStream output, String encoding)
-            throws IOException {
-        if (data != null) {
-            if (encoding == null) {
-                write(data, output);
-            } else {
-                output.write(data.getBytes(encoding));
-            }
-        }
-    }
-
-    // write StringBuffer
-    //-----------------------------------------------------------------------
-    /**
-     * Writes chars from a <code>StringBuffer</code> to a <code>Writer</code>.
-     *
-     * @param data  the <code>StringBuffer</code> to write, null ignored
-     * @param output  the <code>Writer</code> to write to
-     * @throws NullPointerException if output is null
-     * @throws IOException if an I/O error occurs
-     * @since Commons IO 1.1
-     */
-    public static void write(StringBuffer data, Writer output)
-            throws IOException {
-        if (data != null) {
-            output.write(data.toString());
-        }
-    }
-
-    /**
-     * Writes chars from a <code>StringBuffer</code> to bytes on an
-     * <code>OutputStream</code> using the default character encoding of the
-     * platform.
-     * <p>
-     * This method uses {@link String#getBytes()}.
-     *
-     * @param data  the <code>StringBuffer</code> to write, null ignored
-     * @param output  the <code>OutputStream</code> to write to
-     * @throws NullPointerException if output is null
-     * @throws IOException if an I/O error occurs
-     * @since Commons IO 1.1
-     */
-    public static void write(StringBuffer data, OutputStream output)
-            throws IOException {
-        if (data != null) {
-            output.write(data.toString().getBytes());
-        }
-    }
-
-    /**
-     * Writes chars from a <code>StringBuffer</code> to bytes on an
-     * <code>OutputStream</code> using the specified character encoding.
-     * <p>
-     * Character encoding names can be found at
-     * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
-     * <p>
-     * This method uses {@link String#getBytes(String)}.
-     *
-     * @param data  the <code>StringBuffer</code> to write, null ignored
-     * @param output  the <code>OutputStream</code> to write to
-     * @param encoding  the encoding to use, null means platform default
-     * @throws NullPointerException if output is null
-     * @throws IOException if an I/O error occurs
-     * @since Commons IO 1.1
-     */
-    public static void write(StringBuffer data, OutputStream output,
-            String encoding) throws IOException {
-        if (data != null) {
-            if (encoding == null) {
-                write(data, output);
-            } else {
-                output.write(data.toString().getBytes(encoding));
-            }
-        }
-    }
-
-    // writeLines
-    //-----------------------------------------------------------------------
-    /**
-     * Writes the <code>toString()</code> value of each item in a collection to
-     * an <code>OutputStream</code> line by line, using the default character
-     * encoding of the platform and the specified line ending.
-     *
-     * @param lines  the lines to write, null entries produce blank lines
-     * @param lineEnding  the line separator to use, null is system default
-     * @param output  the <code>OutputStream</code> to write to, not null, not closed
-     * @throws NullPointerException if the output is null
-     * @throws IOException if an I/O error occurs
-     * @since Commons IO 1.1
-     */
-    public static void writeLines(Collection<Object> lines, String lineEnding,
-            OutputStream output) throws IOException {
-        if (lines == null) {
-            return;
-        }
-        if (lineEnding == null) {
-            lineEnding = LINE_SEPARATOR;
-        }
-        for (Iterator<Object> it = lines.iterator(); it.hasNext(); ) {
-            Object line = it.next();
-            if (line != null) {
-                output.write(line.toString().getBytes());
-            }
-            output.write(lineEnding.getBytes());
-        }
-    }
-
-    /**
-     * Writes the <code>toString()</code> value of each item in a collection to
-     * an <code>OutputStream</code> line by line, using the specified character
-     * encoding and the specified line ending.
-     * <p>
-     * Character encoding names can be found at
-     * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
-     *
-     * @param lines  the lines to write, null entries produce blank lines
-     * @param lineEnding  the line separator to use, null is system default
-     * @param output  the <code>OutputStream</code> to write to, not null, not closed
-     * @param encoding  the encoding to use, null means platform default
-     * @throws NullPointerException if the output is null
-     * @throws IOException if an I/O error occurs
-     * @since Commons IO 1.1
-     */
-    public static void writeLines(Collection<Object> lines, String lineEnding,
-            OutputStream output, String encoding) throws IOException {
-        if (encoding == null) {
-            writeLines(lines, lineEnding, output);
-        } else {
-            if (lines == null) {
-                return;
-            }
-            if (lineEnding == null) {
-                lineEnding = LINE_SEPARATOR;
-            }
-            for (Iterator<Object> it = lines.iterator(); it.hasNext(); ) {
-                Object line = it.next();
-                if (line != null) {
-                    output.write(line.toString().getBytes(encoding));
-                }
-                output.write(lineEnding.getBytes(encoding));
-            }
-        }
-    }
-
-    /**
-     * Writes the <code>toString()</code> value of each item in a collection to
-     * a <code>Writer</code> line by line, using the specified line ending.
-     *
-     * @param lines  the lines to write, null entries produce blank lines
-     * @param lineEnding  the line separator to use, null is system default
-     * @param writer  the <code>Writer</code> to write to, not null, not closed
-     * @throws NullPointerException if the input is null
-     * @throws IOException if an I/O error occurs
-     * @since Commons IO 1.1
-     */
-    public static void writeLines(Collection<Object> lines, String lineEnding,
-            Writer writer) throws IOException {
-        if (lines == null) {
-            return;
-        }
-        if (lineEnding == null) {
-            lineEnding = LINE_SEPARATOR;
-        }
-        for (Iterator<Object> it = lines.iterator(); it.hasNext(); ) {
-            Object line = it.next();
-            if (line != null) {
-                writer.write(line.toString());
-            }
-            writer.write(lineEnding);
-        }
-    }
-
-    // copy from InputStream
-    //-----------------------------------------------------------------------
-    /**
-     * Copy bytes from an <code>InputStream</code> to an
-     * <code>OutputStream</code>.
-     * <p>
-     * This method buffers the input internally, so there is no need to use a
-     * <code>BufferedInputStream</code>.
-     * <p>
-     * Large streams (over 2GB) will return a bytes copied value of
-     * <code>-1</code> after the copy has completed since the correct
-     * number of bytes cannot be returned as an int. For large streams
-     * use the <code>copyLarge(InputStream, OutputStream)</code> method.
-     *
-     * @param input  the <code>InputStream</code> to read from
-     * @param output  the <code>OutputStream</code> to write to
-     * @return the number of bytes copied
-     * @throws NullPointerException if the input or output is null
-     * @throws IOException if an I/O error occurs
-     * @throws ArithmeticException if the byte count is too large
-     * @since Commons IO 1.1
-     */
-    public static int copy(InputStream input, OutputStream output) throws IOException {
-        long count = copyLarge(input, output);
-        if (count > Integer.MAX_VALUE) {
-            return -1;
-        }
-        return (int) count;
-    }
-
-    /**
-     * Copy bytes from a large (over 2GB) <code>InputStream</code> to an
-     * <code>OutputStream</code>.
-     * <p>
-     * This method buffers the input internally, so there is no need to use a
-     * <code>BufferedInputStream</code>.
-     *
-     * @param input  the <code>InputStream</code> to read from
-     * @param output  the <code>OutputStream</code> to write to
-     * @return the number of bytes copied
-     * @throws NullPointerException if the input or output is null
-     * @throws IOException if an I/O error occurs
-     * @since Commons IO 1.3
-     */
-    public static long copyLarge(InputStream input, OutputStream output)
-            throws IOException {
-        byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
-        long count = 0;
-        int n = 0;
-        while (-1 != (n = input.read(buffer))) {
-            output.write(buffer, 0, n);
-            count += n;
-        }
-        return count;
-    }
-
-    /**
-     * Copy bytes from an <code>InputStream</code> to chars on a
-     * <code>Writer</code> using the default character encoding of the platform.
-     * <p>
-     * This method buffers the input internally, so there is no need to use a
-     * <code>BufferedInputStream</code>.
-     * <p>
-     * This method uses {@link InputStreamReader}.
-     *
-     * @param input  the <code>InputStream</code> to read from
-     * @param output  the <code>Writer</code> to write to
-     * @throws NullPointerException if the input or output is null
-     * @throws IOException if an I/O error occurs
-     * @since Commons IO 1.1
-     */
-    public static void copy(InputStream input, Writer output)
-            throws IOException {
-        InputStreamReader in = new InputStreamReader(input);
-        copy(in, output);
-    }
-
-    /**
-     * Copy bytes from an <code>InputStream</code> to chars on a
-     * <code>Writer</code> using the specified character encoding.
-     * <p>
-     * This method buffers the input internally, so there is no need to use a
-     * <code>BufferedInputStream</code>.
-     * <p>
-     * Character encoding names can be found at
-     * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
-     * <p>
-     * This method uses {@link InputStreamReader}.
-     *
-     * @param input  the <code>InputStream</code> to read from
-     * @param output  the <code>Writer</code> to write to
-     * @param encoding  the encoding to use, null means platform default
-     * @throws NullPointerException if the input or output is null
-     * @throws IOException if an I/O error occurs
-     * @since Commons IO 1.1
-     */
-    public static void copy(InputStream input, Writer output, String encoding)
-            throws IOException {
-        if (encoding == null) {
-            copy(input, output);
-        } else {
-            InputStreamReader in = new InputStreamReader(input, encoding);
-            copy(in, output);
-        }
-    }
-
-    // copy from Reader
-    //-----------------------------------------------------------------------
-    /**
-     * Copy chars from a <code>Reader</code> to a <code>Writer</code>.
-     * <p>
-     * This method buffers the input internally, so there is no need to use a
-     * <code>BufferedReader</code>.
-     * <p>
-     * Large streams (over 2GB) will return a chars copied value of
-     * <code>-1</code> after the copy has completed since the correct
-     * number of chars cannot be returned as an int. For large streams
-     * use the <code>copyLarge(Reader, Writer)</code> method.
-     *
-     * @param input  the <code>Reader</code> to read from
-     * @param output  the <code>Writer</code> to write to
-     * @return the number of characters copied
-     * @throws NullPointerException if the input or output is null
-     * @throws IOException if an I/O error occurs
-     * @throws ArithmeticException if the character count is too large
-     * @since Commons IO 1.1
-     */
-    public static int copy(Reader input, Writer output) throws IOException {
-        long count = copyLarge(input, output);
-        if (count > Integer.MAX_VALUE) {
-            return -1;
-        }
-        return (int) count;
-    }
-
-    /**
-     * Copy chars from a large (over 2GB) <code>Reader</code> to a <code>Writer</code>.
-     * <p>
-     * This method buffers the input internally, so there is no need to use a
-     * <code>BufferedReader</code>.
-     *
-     * @param input  the <code>Reader</code> to read from
-     * @param output  the <code>Writer</code> to write to
-     * @return the number of characters copied
-     * @throws NullPointerException if the input or output is null
-     * @throws IOException if an I/O error occurs
-     * @since Commons IO 1.3
-     */
-    public static long copyLarge(Reader input, Writer output) throws IOException {
-        char[] buffer = new char[DEFAULT_BUFFER_SIZE];
-        long count = 0;
-        int n = 0;
-        while (-1 != (n = input.read(buffer))) {
-            output.write(buffer, 0, n);
-            count += n;
-        }
-        return count;
-    }
-
-    /**
-     * Copy chars from a <code>Reader</code> to bytes on an
-     * <code>OutputStream</code> using the default character encoding of the
-     * platform, and calling flush.
-     * <p>
-     * This method buffers the input internally, so there is no need to use a
-     * <code>BufferedReader</code>.
-     * <p>
-     * Due to the implementation of OutputStreamWriter, this method performs a
-     * flush.
-     * <p>
-     * This method uses {@link OutputStreamWriter}.
-     *
-     * @param input  the <code>Reader</code> to read from
-     * @param output  the <code>OutputStream</code> to write to
-     * @throws NullPointerException if the input or output is null
-     * @throws IOException if an I/O error occurs
-     * @since Commons IO 1.1
-     */
-    public static void copy(Reader input, OutputStream output)
-            throws IOException {
-        OutputStreamWriter out = new OutputStreamWriter(output);
-        copy(input, out);
-        // XXX Unless anyone is planning on rewriting OutputStreamWriter, we
-        // have to flush here.
-        out.flush();
-    }
-
-    /**
-     * Copy chars from a <code>Reader</code> to bytes on an
-     * <code>OutputStream</code> using the specified character encoding, and
-     * calling flush.
-     * <p>
-     * This method buffers the input internally, so there is no need to use a
-     * <code>BufferedReader</code>.
-     * <p>
-     * Character encoding names can be found at
-     * <a href="http://www.iana.org/assignments/character-sets">IANA</a>.
-     * <p>
-     * Due to the implementation of OutputStreamWriter, this method performs a
-     * flush.
-     * <p>
-     * This method uses {@link OutputStreamWriter}.
-     *
-     * @param input  the <code>Reader</code> to read from
-     * @param output  the <code>OutputStream</code> to write to
-     * @param encoding  the encoding to use, null means platform default
-     * @throws NullPointerException if the input or output is null
-     * @throws IOException if an I/O error occurs
-     * @since Commons IO 1.1
-     */
-    public static void copy(Reader input, OutputStream output, String encoding)
-            throws IOException {
-        if (encoding == null) {
-            copy(input, output);
-        } else {
-            OutputStreamWriter out = new OutputStreamWriter(output, encoding);
-            copy(input, out);
-            // XXX Unless anyone is planning on rewriting OutputStreamWriter,
-            // we have to flush here.
-            out.flush();
-        }
-    }
-
-    // content equals
-    //-----------------------------------------------------------------------
-    /**
-     * Compare the contents of two Streams to determine if they are equal or
-     * not.
-     * <p>
-     * This method buffers the input internally using
-     * <code>BufferedInputStream</code> if they are not already buffered.
-     *
-     * @param input1  the first stream
-     * @param input2  the second stream
-     * @return true if the content of the streams are equal or they both don't
-     * exist, false otherwise
-     * @throws NullPointerException if either input is null
-     * @throws IOException if an I/O error occurs
-     */
-    public static boolean contentEquals(InputStream input1, InputStream input2)
-            throws IOException {
-        if (!(input1 instanceof BufferedInputStream)) {
-            input1 = new BufferedInputStream(input1);
-        }
-        if (!(input2 instanceof BufferedInputStream)) {
-            input2 = new BufferedInputStream(input2);
-        }
-
-        int ch = input1.read();
-        while (-1 != ch) {
-            int ch2 = input2.read();
-            if (ch != ch2) {
-                return false;
-            }
-            ch = input1.read();
-        }
-
-        int ch2 = input2.read();
-        return (ch2 == -1);
-    }
-
-    /**
-     * Compare the contents of two Readers to determine if they are equal or
-     * not.
-     * <p>
-     * This method buffers the input internally using
-     * <code>BufferedReader</code> if they are not already buffered.
-     *
-     * @param input1  the first reader
-     * @param input2  the second reader
-     * @return true if the content of the readers are equal or they both don't
-     * exist, false otherwise
-     * @throws NullPointerException if either input is null
-     * @throws IOException if an I/O error occurs
-     * @since Commons IO 1.1
-     */
-    public static boolean contentEquals(Reader input1, Reader input2)
-            throws IOException {
-        if (!(input1 instanceof BufferedReader)) {
-            input1 = new BufferedReader(input1);
-        }
-        if (!(input2 instanceof BufferedReader)) {
-            input2 = new BufferedReader(input2);
-        }
-
-        int ch = input1.read();
-        while (-1 != ch) {
-            int ch2 = input2.read();
-            if (ch != ch2) {
-                return false;
-            }
-            ch = input1.read();
-        }
-
-        int ch2 = input2.read();
-        return (ch2 == -1);
-    }
-
-}
diff --git a/src/org/apache/james/mime4j/BodyDescriptor.java b/src/org/apache/james/mime4j/BodyDescriptor.java
deleted file mode 100644
index 867c43d..0000000
--- a/src/org/apache/james/mime4j/BodyDescriptor.java
+++ /dev/null
@@ -1,392 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one   *
- * or more contributor license agreements.  See the NOTICE file *
- * distributed with this work for additional information        *
- * regarding copyright ownership.  The ASF licenses this file   *
- * to you 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 org.apache.james.mime4j;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Encapsulates the values of the MIME-specific header fields
- * (which starts with <code>Content-</code>).
- *
- *
- * @version $Id: BodyDescriptor.java,v 1.4 2005/02/11 10:08:37 ntherning Exp $
- */
-public class BodyDescriptor {
-    private static Log log = LogFactory.getLog(BodyDescriptor.class);
-
-    private String mimeType = "text/plain";
-    private String boundary = null;
-    private String charset = "us-ascii";
-    private String transferEncoding = "7bit";
-    private Map<String, String> parameters = new HashMap<String, String>();
-    private boolean contentTypeSet = false;
-    private boolean contentTransferEncSet = false;
-
-    /**
-     * Creates a new root <code>BodyDescriptor</code> instance.
-     */
-    public BodyDescriptor() {
-        this(null);
-    }
-
-    /**
-     * Creates a new <code>BodyDescriptor</code> instance.
-     *
-     * @param parent the descriptor of the parent or <code>null</code> if this
-     *        is the root descriptor.
-     */
-    public BodyDescriptor(BodyDescriptor parent) {
-        if (parent != null && parent.isMimeType("multipart/digest")) {
-            mimeType = "message/rfc822";
-        } else {
-            mimeType = "text/plain";
-        }
-    }
-
-    /**
-     * Should be called for each <code>Content-</code> header field of
-     * a MIME message or part.
-     *
-     * @param name the field name.
-     * @param value the field value.
-     */
-    public void addField(String name, String value) {
-
-        name = name.trim().toLowerCase();
-
-        if (name.equals("content-transfer-encoding") && !contentTransferEncSet) {
-            contentTransferEncSet = true;
-
-            value = value.trim().toLowerCase();
-            if (value.length() > 0) {
-                transferEncoding = value;
-            }
-
-        } else if (name.equals("content-type") && !contentTypeSet) {
-            contentTypeSet = true;
-
-            value = value.trim();
-
-            /*
-             * Unfold Content-Type value
-             */
-            StringBuffer sb = new StringBuffer();
-            for (int i = 0; i < value.length(); i++) {
-                char c = value.charAt(i);
-                if (c == '\r' || c == '\n') {
-                    continue;
-                }
-                sb.append(c);
-            }
-
-            Map<String, String> params = getHeaderParams(sb.toString());
-
-            String main = params.get("");
-            if (main != null) {
-                main = main.toLowerCase().trim();
-                int index = main.indexOf('/');
-                boolean valid = false;
-                if (index != -1) {
-                    String type = main.substring(0, index).trim();
-                    String subtype = main.substring(index + 1).trim();
-                    if (type.length() > 0 && subtype.length() > 0) {
-                        main = type + "/" + subtype;
-                        valid = true;
-                    }
-                }
-
-                if (!valid) {
-                    main = null;
-                }
-            }
-            String b = params.get("boundary");
-
-            if (main != null
-                    && ((main.startsWith("multipart/") && b != null)
-                            || !main.startsWith("multipart/"))) {
-
-                mimeType = main;
-            }
-
-            if (isMultipart()) {
-                boundary = b;
-            }
-
-            String c = params.get("charset");
-            if (c != null) {
-                c = c.trim();
-                if (c.length() > 0) {
-                    charset = c.toLowerCase();
-                }
-            }
-
-            /*
-             * Add all other parameters to parameters.
-             */
-            parameters.putAll(params);
-            parameters.remove("");
-            parameters.remove("boundary");
-            parameters.remove("charset");
-        }
-    }
-
-    private Map<String, String> getHeaderParams(String headerValue) {
-        Map<String, String> result = new HashMap<String, String>();
-
-        // split main value and parameters
-        String main;
-        String rest;
-        if (headerValue.indexOf(";") == -1) {
-            main = headerValue;
-            rest = null;
-        } else {
-            main = headerValue.substring(0, headerValue.indexOf(";"));
-            rest = headerValue.substring(main.length() + 1);
-        }
-
-        result.put("", main);
-        if (rest != null) {
-            char[] chars = rest.toCharArray();
-            StringBuffer paramName = new StringBuffer();
-            StringBuffer paramValue = new StringBuffer();
-
-            final byte READY_FOR_NAME = 0;
-            final byte IN_NAME = 1;
-            final byte READY_FOR_VALUE = 2;
-            final byte IN_VALUE = 3;
-            final byte IN_QUOTED_VALUE = 4;
-            final byte VALUE_DONE = 5;
-            final byte ERROR = 99;
-
-            byte state = READY_FOR_NAME;
-            boolean escaped = false;
-            for (int i = 0; i < chars.length; i++) {
-                char c = chars[i];
-
-                switch (state) {
-                    case ERROR:
-                        if (c == ';')
-                            state = READY_FOR_NAME;
-                        break;
-
-                    case READY_FOR_NAME:
-                        if (c == '=') {
-                            log.error("Expected header param name, got '='");
-                            state = ERROR;
-                            break;
-                        }
-
-                        paramName = new StringBuffer();
-                        paramValue = new StringBuffer();
-
-                        state = IN_NAME;
-                        // $FALL-THROUGH$
-
-                    case IN_NAME:
-                        if (c == '=') {
-                            if (paramName.length() == 0)
-                                state = ERROR;
-                            else
-                                state = READY_FOR_VALUE;
-                            break;
-                        }
-
-                        // not '='... just add to name
-                        paramName.append(c);
-                        break;
-
-                    case READY_FOR_VALUE:
-                        boolean fallThrough = false;
-                        switch (c) {
-                            case ' ':
-                            case '\t':
-                                break;  // ignore spaces, especially before '"'
-
-                            case '"':
-                                state = IN_QUOTED_VALUE;
-                                break;
-
-                            default:
-                                state = IN_VALUE;
-                                fallThrough = true;
-                                break;
-                        }
-                        if (!fallThrough)
-                            break;
-
-                        // $FALL-THROUGH$
-
-                    case IN_VALUE:
-                        fallThrough = false;
-                        switch (c) {
-                            case ';':
-                            case ' ':
-                            case '\t':
-                                result.put(
-                                   paramName.toString().trim().toLowerCase(),
-                                   paramValue.toString().trim());
-                                state = VALUE_DONE;
-                                fallThrough = true;
-                                break;
-                            default:
-                                paramValue.append(c);
-                                break;
-                        }
-                        if (!fallThrough)
-                            break;
-
-                        // $FALL-THROUGH$
-
-                    case VALUE_DONE:
-                        switch (c) {
-                            case ';':
-                                state = READY_FOR_NAME;
-                                break;
-
-                            case ' ':
-                            case '\t':
-                                break;
-
-                            default:
-                                state = ERROR;
-                                break;
-                        }
-                        break;
-
-                    case IN_QUOTED_VALUE:
-                        switch (c) {
-                            case '"':
-                                if (!escaped) {
-                                    // don't trim quoted strings; the spaces could be intentional.
-                                    result.put(
-                                            paramName.toString().trim().toLowerCase(),
-                                            paramValue.toString());
-                                    state = VALUE_DONE;
-                                } else {
-                                    escaped = false;
-                                    paramValue.append(c);
-                                }
-                                break;
-
-                            case '\\':
-                                if (escaped) {
-                                    paramValue.append('\\');
-                                }
-                                escaped = !escaped;
-                                break;
-
-                            default:
-                                if (escaped) {
-                                    paramValue.append('\\');
-                                }
-                                escaped = false;
-                                paramValue.append(c);
-                                break;
-                        }
-                        break;
-
-                }
-            }
-
-            // done looping.  check if anything is left over.
-            if (state == IN_VALUE) {
-                result.put(
-                        paramName.toString().trim().toLowerCase(),
-                        paramValue.toString().trim());
-            }
-        }
-
-        return result;
-    }
-
-
-    public boolean isMimeType(String mimeType) {
-        return this.mimeType.equals(mimeType.toLowerCase());
-    }
-
-    /**
-     * Return true if the BodyDescriptor belongs to a message
-     */
-    public boolean isMessage() {
-        return mimeType.equals("message/rfc822");
-    }
-
-    /**
-     * Return true if the BodyDescripotro belongs to a multipart
-     */
-    public boolean isMultipart() {
-        return mimeType.startsWith("multipart/");
-    }
-
-    /**
-     * Return the MimeType
-     */
-    public String getMimeType() {
-        return mimeType;
-    }
-
-    /**
-     * Return the boundary
-     */
-    public String getBoundary() {
-        return boundary;
-    }
-
-    /**
-     * Return the charset
-     */
-    public String getCharset() {
-        return charset;
-    }
-
-    /**
-     * Return all parameters for the BodyDescriptor
-     */
-    public Map<String, String> getParameters() {
-        return parameters;
-    }
-
-    /**
-     * Return the TransferEncoding
-     */
-    public String getTransferEncoding() {
-        return transferEncoding;
-    }
-
-    /**
-     * Return true if it's base64 encoded
-     */
-    public boolean isBase64Encoded() {
-        return "base64".equals(transferEncoding);
-    }
-
-    /**
-     * Return true if it's quoted-printable
-     */
-    public boolean isQuotedPrintableEncoded() {
-        return "quoted-printable".equals(transferEncoding);
-    }
-
-    @Override
-    public String toString() {
-        return mimeType;
-    }
-}
\ No newline at end of file
diff --git a/src/org/apache/james/mime4j/CloseShieldInputStream.java b/src/org/apache/james/mime4j/CloseShieldInputStream.java
deleted file mode 100644
index d9f3b07..0000000
--- a/src/org/apache/james/mime4j/CloseShieldInputStream.java
+++ /dev/null
@@ -1,129 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one   *
- * or more contributor license agreements.  See the NOTICE file *
- * distributed with this work for additional information        *
- * regarding copyright ownership.  The ASF licenses this file   *
- * to you 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 org.apache.james.mime4j;
-
-import java.io.InputStream;
-import java.io.IOException;
-
-/**
- * InputStream that shields its underlying input stream from
- * being closed.
- *
- *
- * @version $Id: CloseShieldInputStream.java,v 1.2 2004/10/02 12:41:10 ntherning Exp $
- */
-public class CloseShieldInputStream extends InputStream {
-
-    /**
-     * Underlying InputStream
-     */
-    private InputStream is;
-
-    public CloseShieldInputStream(InputStream is) {
-        this.is = is;
-    }
-
-    public InputStream getUnderlyingStream() {
-        return is;
-    }
-
-    /**
-     * @see java.io.InputStream#read()
-     */
-    public int read() throws IOException {
-        checkIfClosed();
-        return is.read();
-    }
-
-    /**
-     * @see java.io.InputStream#available()
-     */
-    public int available() throws IOException {
-        checkIfClosed();
-        return is.available();
-    }
-
-
-    /**
-     * Set the underlying InputStream to null
-     */
-    public void close() throws IOException {
-        is = null;
-    }
-
-    /**
-     * @see java.io.FilterInputStream#reset()
-     */
-    public synchronized void reset() throws IOException {
-        checkIfClosed();
-        is.reset();
-    }
-
-    /**
-     * @see java.io.FilterInputStream#markSupported()
-     */
-    public boolean markSupported() {
-        if (is == null)
-            return false;
-        return is.markSupported();
-    }
-
-    /**
-     * @see java.io.FilterInputStream#mark(int)
-     */
-    public synchronized void mark(int readlimit) {
-        if (is != null)
-            is.mark(readlimit);
-    }
-
-    /**
-     * @see java.io.FilterInputStream#skip(long)
-     */
-    public long skip(long n) throws IOException {
-        checkIfClosed();
-        return is.skip(n);
-    }
-
-    /**
-     * @see java.io.FilterInputStream#read(byte[])
-     */
-    public int read(byte b[]) throws IOException {
-        checkIfClosed();
-        return is.read(b);
-    }
-
-    /**
-     * @see java.io.FilterInputStream#read(byte[], int, int)
-     */
-    public int read(byte b[], int off, int len) throws IOException {
-        checkIfClosed();
-        return is.read(b, off, len);
-    }
-
-    /**
-     * Check if the underlying InputStream is null. If so throw an Exception
-     *
-     * @throws IOException if the underlying InputStream is null
-     */
-    private void checkIfClosed() throws IOException {
-        if (is == null)
-            throw new IOException("Stream is closed");
-    }
-}
\ No newline at end of file
diff --git a/src/org/apache/james/mime4j/ContentHandler.java b/src/org/apache/james/mime4j/ContentHandler.java
deleted file mode 100644
index b437e73..0000000
--- a/src/org/apache/james/mime4j/ContentHandler.java
+++ /dev/null
@@ -1,177 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one   *
- * or more contributor license agreements.  See the NOTICE file *
- * distributed with this work for additional information        *
- * regarding copyright ownership.  The ASF licenses this file   *
- * to you 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 org.apache.james.mime4j;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-/**
- * <p>
- * Receives notifications of the content of a plain RFC822 or MIME message.
- * Implement this interface and register an instance of that implementation
- * with a <code>MimeStreamParser</code> instance using its
- * {@link org.apache.james.mime4j.MimeStreamParser#setContentHandler(ContentHandler)}
- * method. The parser uses the <code>ContentHandler</code> instance to report
- * basic message-related events like the start and end of the body of a
- * part in a multipart MIME entity.
- * </p>
- * <p>
- * Events will be generated in the order the corresponding elements occur in
- * the message stream parsed by the parser. E.g.:
- * <pre>
- *      startMessage()
- *          startHeader()
- *              field(...)
- *              field(...)
- *              ...
- *          endHeader()
- *          startMultipart()
- *              preamble(...)
- *              startBodyPart()
- *                  startHeader()
- *                      field(...)
- *                      field(...)
- *                      ...
- *                  endHeader()
- *                  body()
- *              endBodyPart()
- *              startBodyPart()
- *                  startHeader()
- *                      field(...)
- *                      field(...)
- *                      ...
- *                  endHeader()
- *                  body()
- *              endBodyPart()
- *              epilogue(...)
- *          endMultipart()
- *      endMessage()
- * </pre>
- * The above shows an example of a MIME message consisting of a multipart
- * body containing two body parts.
- * </p>
- * <p>
- * See MIME RFCs 2045-2049 for more information on the structure of MIME
- * messages and RFC 822 and 2822 for the general structure of Internet mail
- * messages.
- * </p>
- *
- *
- * @version $Id: ContentHandler.java,v 1.3 2004/10/02 12:41:10 ntherning Exp $
- */
-public interface ContentHandler {
-    /**
-     * Called when a new message starts (a top level message or an embedded
-     * rfc822 message).
-     */
-    void startMessage();
-
-    /**
-     * Called when a message ends.
-     */
-    void endMessage();
-
-    /**
-     * Called when a new body part starts inside a
-     * <code>multipart/*</code> entity.
-     */
-    void startBodyPart();
-
-    /**
-     * Called when a body part ends.
-     */
-    void endBodyPart();
-
-    /**
-     * Called when a header (of a message or body part) is about to be parsed.
-     */
-    void startHeader();
-
-    /**
-     * Called for each field of a header.
-     *
-     * @param fieldData the raw contents of the field
-     *        (<code>Field-Name: field value</code>). The value will not be
-     *        unfolded.
-     */
-    void field(String fieldData);
-
-    /**
-     * Called when there are no more header fields in a message or body part.
-     */
-    void endHeader();
-
-    /**
-     * Called for the preamble (whatever comes before the first body part)
-     * of a <code>multipart/*</code> entity.
-     *
-     * @param is used to get the contents of the preamble.
-     * @throws IOException should be thrown on I/O errors.
-     */
-    void preamble(InputStream is) throws IOException;
-
-    /**
-     * Called for the epilogue (whatever comes after the final body part)
-     * of a <code>multipart/*</code> entity.
-     *
-     * @param is used to get the contents of the epilogue.
-     * @throws IOException should be thrown on I/O errors.
-     */
-    void epilogue(InputStream is) throws IOException;
-
-    /**
-     * Called when the body of a multipart entity is about to be parsed.
-     *
-     * @param bd encapsulates the values (either read from the
-     *        message stream or, if not present, determined implictly
-     *        as described in the
-     *        MIME rfc:s) of the <code>Content-Type</code> and
-     *        <code>Content-Transfer-Encoding</code> header fields.
-     */
-    void startMultipart(BodyDescriptor bd);
-
-    /**
-     * Called when the body of an entity has been parsed.
-     */
-    void endMultipart();
-
-    /**
-     * Called when the body of a discrete (non-multipart) entity is about to
-     * be parsed.
-     *
-     * @param bd see {@link #startMultipart(BodyDescriptor)}
-     * @param is the contents of the body. NOTE: this is the raw body contents
-     *           - it will not be decoded if encoded. The <code>bd</code>
-     *           parameter should be used to determine how the stream data
-     *           should be decoded.
-     * @throws IOException should be thrown on I/O errors.
-     */
-    void body(BodyDescriptor bd, InputStream is) throws IOException;
-
-    /**
-     * Called when a new entity (message or body part) starts and the
-     * parser is in <code>raw</code> mode.
-     *
-     * @param is the raw contents of the entity.
-     * @throws IOException should be thrown on I/O errors.
-     * @see MimeStreamParser#setRaw(boolean)
-     */
-    void raw(InputStream is) throws IOException;
-}
\ No newline at end of file
diff --git a/src/org/apache/james/mime4j/EOLConvertingInputStream.java b/src/org/apache/james/mime4j/EOLConvertingInputStream.java
deleted file mode 100644
index d6ef706..0000000
--- a/src/org/apache/james/mime4j/EOLConvertingInputStream.java
+++ /dev/null
@@ -1,139 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one   *
- * or more contributor license agreements.  See the NOTICE file *
- * distributed with this work for additional information        *
- * regarding copyright ownership.  The ASF licenses this file   *
- * to you 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 org.apache.james.mime4j;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.PushbackInputStream;
-
-/**
- * InputStream which converts <code>\r</code>
- * bytes not followed by <code>\n</code> and <code>\n</code> not
- * preceded by <code>\r</code> to <code>\r\n</code>.
- *
- *
- * @version $Id: EOLConvertingInputStream.java,v 1.4 2004/11/29 13:15:42 ntherning Exp $
- */
-public class EOLConvertingInputStream extends InputStream {
-    /** Converts single '\r' to '\r\n' */
-    public static final int CONVERT_CR   = 1;
-    /** Converts single '\n' to '\r\n' */
-    public static final int CONVERT_LF   = 2;
-    /** Converts single '\r' and '\n' to '\r\n' */
-    public static final int CONVERT_BOTH = 3;
-
-    private PushbackInputStream in = null;
-    private int previous = 0;
-    private int flags = CONVERT_BOTH;
-    private int size = 0;
-    private int pos = 0;
-    private int nextTenPctPos;
-    private int tenPctSize;
-    private Callback callback;
-
-    public interface Callback {
-        public void report(int bytesRead);
-    }
-
-    /**
-     * Creates a new <code>EOLConvertingInputStream</code>
-     * instance converting bytes in the given <code>InputStream</code>.
-     * The flag <code>CONVERT_BOTH</code> is the default.
-     *
-     * @param in the <code>InputStream</code> to read from.
-     */
-    public EOLConvertingInputStream(InputStream _in) {
-        super();
-        in = new PushbackInputStream(_in, 2);
-    }
-
-    /**
-     * Creates a new <code>EOLConvertingInputStream</code>
-     * instance converting bytes in the given <code>InputStream</code>.
-     *
-     * @param _in the <code>InputStream</code> to read from.
-     * @param _size the size of the input stream (need not be exact)
-     * @param _callback a callback reporting when each 10% of stream's size is reached
-     */
-    public EOLConvertingInputStream(InputStream _in, int _size, Callback _callback) {
-        this(_in);
-        size = _size;
-        tenPctSize = size / 10;
-        nextTenPctPos = tenPctSize;
-        callback = _callback;
-    }
-
-    /**
-     * Closes the underlying stream.
-     *
-     * @throws IOException on I/O errors.
-     */
-    public void close() throws IOException {
-        in.close();
-    }
-
-    private int readByte() throws IOException {
-        int b = in.read();
-        if (b != -1) {
-            if (callback != null && pos++ == nextTenPctPos) {
-                nextTenPctPos += tenPctSize;
-                if (callback != null) {
-                    callback.report(pos);
-                }
-            }
-        }
-        return b;
-    }
-
-    private void unreadByte(int c) throws IOException {
-        in.unread(c);
-        pos--;
-    }
-
-    /**
-     * @see java.io.InputStream#read()
-     */
-    public int read() throws IOException {
-        int b = readByte();
-
-        if (b == -1) {
-            pos = size;
-            return -1;
-        }
-
-        if ((flags & CONVERT_CR) != 0 && b == '\r') {
-            int c = readByte();
-            if (c != -1) {
-                unreadByte(c);
-            }
-            if (c != '\n') {
-                unreadByte('\n');
-            }
-        } else if ((flags & CONVERT_LF) != 0 && b == '\n' && previous != '\r') {
-            b = '\r';
-            unreadByte('\n');
-        }
-
-        previous = b;
-
-        return b;
-    }
-
-}
\ No newline at end of file
diff --git a/src/org/apache/james/mime4j/Log.java b/src/org/apache/james/mime4j/Log.java
deleted file mode 100644
index 5eeead5..0000000
--- a/src/org/apache/james/mime4j/Log.java
+++ /dev/null
@@ -1,114 +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 org.apache.james.mime4j;
-
-/**
- * Empty stub for the apache logging library.
- */
-public class Log {
-    private static final String LOG_TAG = "Email Log";
-
-    public Log(Class mClazz) {
-    }
-
-    public boolean isDebugEnabled() {
-        return false;
-    }
-
-    public boolean isErrorEnabled() {
-        return true;
-    }
-
-    public boolean isFatalEnabled() {
-        return true;
-    }
-
-    public boolean isInfoEnabled() {
-        return false;
-    }
-
-    public boolean isTraceEnabled() {
-        return false;
-    }
-
-    public boolean isWarnEnabled() {
-        return true;
-    }
-
-    public void trace(Object message) {
-        if (!isTraceEnabled()) return;
-        android.util.Log.v(LOG_TAG, toString(message, null));
-    }
-
-    public void trace(Object message, Throwable t) {
-        if (!isTraceEnabled()) return;
-        android.util.Log.v(LOG_TAG, toString(message, t));
-    }
-
-    public void debug(Object message) {
-        if (!isDebugEnabled()) return;
-        android.util.Log.d(LOG_TAG, toString(message, null));
-    }
-
-    public void debug(Object message, Throwable t) {
-        if (!isDebugEnabled()) return;
-        android.util.Log.d(LOG_TAG, toString(message, t));
-    }
-
-    public void info(Object message) {
-        if (!isInfoEnabled()) return;
-        android.util.Log.i(LOG_TAG, toString(message, null));
-    }
-
-    public void info(Object message, Throwable t) {
-        if (!isInfoEnabled()) return;
-        android.util.Log.i(LOG_TAG, toString(message, t));
-    }
-
-    public void warn(Object message) {
-        android.util.Log.w(LOG_TAG, toString(message, null));
-    }
-
-    public void warn(Object message, Throwable t) {
-        android.util.Log.w(LOG_TAG, toString(message, t));
-    }
-
-    public void error(Object message) {
-        android.util.Log.e(LOG_TAG, toString(message, null));
-    }
-
-    public void error(Object message, Throwable t) {
-        android.util.Log.e(LOG_TAG, toString(message, t));
-    }
-
-    public void fatal(Object message) {
-        android.util.Log.e(LOG_TAG, toString(message, null));
-    }
-
-    public void fatal(Object message, Throwable t) {
-        android.util.Log.e(LOG_TAG, toString(message, t));
-    }
-
-    private static String toString(Object o, Throwable t) {
-        String m = (o == null) ? "(null)" : o.toString();
-        if (t == null) {
-            return m;
-        } else {
-            return m + " " + t.getMessage();
-        }
-    }
-}
\ No newline at end of file
diff --git a/src/org/apache/james/mime4j/LogFactory.java b/src/org/apache/james/mime4j/LogFactory.java
deleted file mode 100644
index ed6e3de..0000000
--- a/src/org/apache/james/mime4j/LogFactory.java
+++ /dev/null
@@ -1,29 +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 org.apache.james.mime4j;
-
-/**
- * Empty stub for the apache logging library.
- */
-public final class LogFactory {
-    private LogFactory() {
-    }
-
-    public static Log getLog(Class clazz) {
-        return new Log(clazz);
-    }
-}
\ No newline at end of file
diff --git a/src/org/apache/james/mime4j/MimeBoundaryInputStream.java b/src/org/apache/james/mime4j/MimeBoundaryInputStream.java
deleted file mode 100644
index c6d6f24..0000000
--- a/src/org/apache/james/mime4j/MimeBoundaryInputStream.java
+++ /dev/null
@@ -1,184 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one   *
- * or more contributor license agreements.  See the NOTICE file *
- * distributed with this work for additional information        *
- * regarding copyright ownership.  The ASF licenses this file   *
- * to you 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 org.apache.james.mime4j;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.PushbackInputStream;
-
-/**
- * Stream that constrains itself to a single MIME body part.
- * After the stream ends (i.e. read() returns -1) {@link #hasMoreParts()}
- * can be used to determine if a final boundary has been seen or not.
- * If {@link #parentEOF()} is <code>true</code> an unexpected end of stream
- * has been detected in the parent stream.
- *
- *
- *
- * @version $Id: MimeBoundaryInputStream.java,v 1.2 2004/11/29 13:15:42 ntherning Exp $
- */
-public class MimeBoundaryInputStream extends InputStream {
-
-    private PushbackInputStream s = null;
-    private byte[] boundary = null;
-    private boolean first = true;
-    private boolean eof = false;
-    private boolean parenteof = false;
-    private boolean moreParts = true;
-
-    /**
-     * Creates a new MimeBoundaryInputStream.
-     * @param s The underlying stream.
-     * @param boundary Boundary string (not including leading hyphens).
-     */
-    public MimeBoundaryInputStream(InputStream s, String boundary)
-            throws IOException {
-
-        this.s = new PushbackInputStream(s, boundary.length() + 4);
-
-        boundary = "--" + boundary;
-        this.boundary = new byte[boundary.length()];
-        for (int i = 0; i < this.boundary.length; i++) {
-            this.boundary[i] = (byte) boundary.charAt(i);
-        }
-
-        /*
-         * By reading one byte we will update moreParts to be as expected
-         * before any bytes have been read.
-         */
-        int b = read();
-        if (b != -1) {
-            this.s.unread(b);
-        }
-    }
-
-    /**
-     * Closes the underlying stream.
-     *
-     * @throws IOException on I/O errors.
-     */
-    public void close() throws IOException {
-        s.close();
-    }
-
-    /**
-     * Determines if the underlying stream has more parts (this stream has
-     * not seen an end boundary).
-     *
-     * @return <code>true</code> if there are more parts in the underlying
-     *         stream, <code>false</code> otherwise.
-     */
-    public boolean hasMoreParts() {
-        return moreParts;
-    }
-
-    /**
-     * Determines if the parent stream has reached EOF
-     *
-     * @return <code>true</code>  if EOF has been reached for the parent stream,
-     *         <code>false</code> otherwise.
-     */
-    public boolean parentEOF() {
-        return parenteof;
-    }
-
-    /**
-     * Consumes all unread bytes of this stream. After a call to this method
-     * this stream will have reached EOF.
-     *
-     * @throws IOException on I/O errors.
-     */
-    public void consume() throws IOException {
-        while (read() != -1) {
-        }
-    }
-
-    /**
-     * @see java.io.InputStream#read()
-     */
-    public int read() throws IOException {
-        if (eof) {
-            return -1;
-        }
-
-        if (first) {
-            first = false;
-            if (matchBoundary()) {
-                return -1;
-            }
-        }
-
-        int b1 = s.read();
-        int b2 = s.read();
-
-        if (b1 == '\r' && b2 == '\n') {
-            if (matchBoundary()) {
-                return -1;
-            }
-        }
-
-        if (b2 != -1) {
-            s.unread(b2);
-        }
-
-        parenteof = b1 == -1;
-        eof = parenteof;
-
-        return b1;
-    }
-
-    private boolean matchBoundary() throws IOException {
-
-        for (int i = 0; i < boundary.length; i++) {
-            int b = s.read();
-            if (b != boundary[i]) {
-                if (b != -1) {
-                    s.unread(b);
-                }
-                for (int j = i - 1; j >= 0; j--) {
-                    s.unread(boundary[j]);
-                }
-                return false;
-            }
-        }
-
-        /*
-         * We have a match. Is it an end boundary?
-         */
-        int prev = s.read();
-        int curr = s.read();
-        moreParts = !(prev == '-' && curr == '-');
-        do {
-            if (curr == '\n' && prev == '\r') {
-                break;
-            }
-            prev = curr;
-        } while ((curr = s.read()) != -1);
-
-        if (curr == -1) {
-            moreParts = false;
-            parenteof = true;
-        }
-
-        eof = true;
-
-        return true;
-    }
-}
\ No newline at end of file
diff --git a/src/org/apache/james/mime4j/MimeStreamParser.java b/src/org/apache/james/mime4j/MimeStreamParser.java
deleted file mode 100644
index a8aad5a..0000000
--- a/src/org/apache/james/mime4j/MimeStreamParser.java
+++ /dev/null
@@ -1,324 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one   *
- * or more contributor license agreements.  See the NOTICE file *
- * distributed with this work for additional information        *
- * regarding copyright ownership.  The ASF licenses this file   *
- * to you 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 org.apache.james.mime4j;
-
-import org.apache.james.mime4j.decoder.Base64InputStream;
-import org.apache.james.mime4j.decoder.QuotedPrintableInputStream;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.BitSet;
-import java.util.LinkedList;
-
-/**
- * <p>
- * Parses MIME (or RFC822) message streams of bytes or characters and reports
- * parsing events to a <code>ContentHandler</code> instance.
- * </p>
- * <p>
- * Typical usage:<br/>
- * <pre>
- *      ContentHandler handler = new MyHandler();
- *      MimeStreamParser parser = new MimeStreamParser();
- *      parser.setContentHandler(handler);
- *      parser.parse(new BufferedInputStream(new FileInputStream("mime.msg")));
- * </pre>
- * <strong>NOTE:</strong> All lines must end with CRLF
- * (<code>\r\n</code>). If you are unsure of the line endings in your stream
- * you should wrap it in a {@link org.apache.james.mime4j.EOLConvertingInputStream} instance.
- *
- *
- * @version $Id: MimeStreamParser.java,v 1.8 2005/02/11 10:12:02 ntherning Exp $
- */
-public class MimeStreamParser {
-    private static final Log log = LogFactory.getLog(MimeStreamParser.class);
-
-    private static BitSet fieldChars = null;
-
-    private RootInputStream rootStream = null;
-    private LinkedList<BodyDescriptor> bodyDescriptors = new LinkedList<BodyDescriptor>();
-    private ContentHandler handler = null;
-    private boolean raw = false;
-    private boolean prematureEof = false;
-
-    static {
-        fieldChars = new BitSet();
-        for (int i = 0x21; i <= 0x39; i++) {
-            fieldChars.set(i);
-        }
-        for (int i = 0x3b; i <= 0x7e; i++) {
-            fieldChars.set(i);
-        }
-    }
-
-    /**
-     * Creates a new <code>MimeStreamParser</code> instance.
-     */
-    public MimeStreamParser() {
-    }
-
-    /**
-     * Parses a stream of bytes containing a MIME message.
-     *
-     * @param is the stream to parse.
-     * @throws IOException on I/O errors.
-     */
-    public void parse(InputStream is) throws IOException {
-        rootStream = new RootInputStream(is);
-        parseMessage(rootStream);
-    }
-
-    /**
-     * Determines if this parser is currently in raw mode.
-     *
-     * @return <code>true</code> if in raw mode, <code>false</code>
-     *         otherwise.
-     * @see #setRaw(boolean)
-     */
-    public boolean isRaw() {
-        return raw;
-    }
-
-    /**
-     * Enables or disables raw mode. In raw mode all future entities
-     * (messages or body parts) in the stream will be reported to the
-     * {@link ContentHandler#raw(InputStream)} handler method only.
-     * The stream will contain the entire unparsed entity contents
-     * including header fields and whatever is in the body.
-     *
-     * @param raw <code>true</code> enables raw mode, <code>false</code>
-     *        disables it.
-     */
-    public void setRaw(boolean raw) {
-        this.raw = raw;
-    }
-
-    /**
-     * Finishes the parsing and stops reading lines.
-     * NOTE: No more lines will be parsed but the parser
-     * will still call
-     * {@link ContentHandler#endMultipart()},
-     * {@link ContentHandler#endBodyPart()},
-     * {@link ContentHandler#endMessage()}, etc to match previous calls
-     * to
-     * {@link ContentHandler#startMultipart(BodyDescriptor)},
-     * {@link ContentHandler#startBodyPart()},
-     * {@link ContentHandler#startMessage()}, etc.
-     */
-    public void stop() {
-        rootStream.truncate();
-    }
-
-    /**
-     * Parses an entity which consists of a header followed by a body containing
-     * arbitrary data, body parts or an embedded message.
-     *
-     * @param is the stream to parse.
-     * @throws IOException on I/O errors.
-     */
-    private void parseEntity(InputStream is) throws IOException {
-        BodyDescriptor bd = parseHeader(is);
-
-        if (bd.isMultipart()) {
-            bodyDescriptors.addFirst(bd);
-
-            handler.startMultipart(bd);
-
-            MimeBoundaryInputStream tempIs =
-                new MimeBoundaryInputStream(is, bd.getBoundary());
-            handler.preamble(new CloseShieldInputStream(tempIs));
-            tempIs.consume();
-
-            while (tempIs.hasMoreParts()) {
-                tempIs = new MimeBoundaryInputStream(is, bd.getBoundary());
-                parseBodyPart(tempIs);
-                tempIs.consume();
-                if (tempIs.parentEOF()) {
-                    prematureEof = true;
-//                    if (log.isWarnEnabled()) {
-//                        log.warn("Line " + rootStream.getLineNumber()
-//                                + ": Body part ended prematurely. "
-//                                + "Higher level boundary detected or "
-//                                + "EOF reached.");
-//                    }
-                    break;
-                }
-            }
-
-            handler.epilogue(new CloseShieldInputStream(is));
-
-            handler.endMultipart();
-
-            bodyDescriptors.removeFirst();
-
-        } else if (bd.isMessage()) {
-            if (bd.isBase64Encoded()) {
-                log.warn("base64 encoded message/rfc822 detected");
-                is = new EOLConvertingInputStream(
-                        new Base64InputStream(is));
-            } else if (bd.isQuotedPrintableEncoded()) {
-                log.warn("quoted-printable encoded message/rfc822 detected");
-                is = new EOLConvertingInputStream(
-                        new QuotedPrintableInputStream(is));
-            }
-            bodyDescriptors.addFirst(bd);
-            parseMessage(is);
-            bodyDescriptors.removeFirst();
-        } else {
-            handler.body(bd, new CloseShieldInputStream(is));
-        }
-
-        /*
-         * Make sure the stream has been consumed.
-         */
-        while (is.read() != -1) {
-        }
-    }
-
-    private void parseMessage(InputStream is) throws IOException {
-        if (raw) {
-            handler.raw(new CloseShieldInputStream(is));
-        } else {
-            handler.startMessage();
-            parseEntity(is);
-            handler.endMessage();
-        }
-    }
-
-    public boolean getPrematureEof() {
-        return prematureEof;
-    }
-
-    private void parseBodyPart(InputStream is) throws IOException {
-        if (raw) {
-            handler.raw(new CloseShieldInputStream(is));
-        } else {
-            handler.startBodyPart();
-            parseEntity(is);
-            handler.endBodyPart();
-        }
-    }
-
-    /**
-     * Parses a header.
-     *
-     * @param is the stream to parse.
-     * @return a <code>BodyDescriptor</code> describing the body following
-     *         the header.
-     */
-    private BodyDescriptor parseHeader(InputStream is) throws IOException {
-        BodyDescriptor bd = new BodyDescriptor(bodyDescriptors.isEmpty()
-                        ? null : (BodyDescriptor) bodyDescriptors.getFirst());
-
-        handler.startHeader();
-
-        int lineNumber = rootStream.getLineNumber();
-
-        StringBuffer sb = new StringBuffer();
-        int curr = 0;
-        int prev = 0;
-        while ((curr = is.read()) != -1) {
-            if (curr == '\n' && (prev == '\n' || prev == 0)) {
-                /*
-                 * [\r]\n[\r]\n or an immediate \r\n have been seen.
-                 */
-                sb.deleteCharAt(sb.length() - 1);
-                break;
-            }
-            sb.append((char) curr);
-            prev = curr == '\r' ? prev : curr;
-        }
-
-//        if (curr == -1 && log.isWarnEnabled()) {
-//            log.warn("Line " + rootStream.getLineNumber()
-//                    + ": Unexpected end of headers detected. "
-//                    + "Boundary detected in header or EOF reached.");
-//        }
-
-        int start = 0;
-        int pos = 0;
-        int startLineNumber = lineNumber;
-        while (pos < sb.length()) {
-            while (pos < sb.length() && sb.charAt(pos) != '\r') {
-                pos++;
-            }
-            if (pos < sb.length() - 1 && sb.charAt(pos + 1) != '\n') {
-                pos++;
-                continue;
-            }
-
-            if (pos >= sb.length() - 2 || fieldChars.get(sb.charAt(pos + 2))) {
-
-                /*
-                 * field should be the complete field data excluding the
-                 * trailing \r\n.
-                 */
-                String field = sb.substring(start, pos);
-                start = pos + 2;
-
-                /*
-                 * Check for a valid field.
-                 */
-                int index = field.indexOf(':');
-                boolean valid = false;
-                if (index != -1 && fieldChars.get(field.charAt(0))) {
-                    valid = true;
-                    String fieldName = field.substring(0, index).trim();
-                    for (int i = 0; i < fieldName.length(); i++) {
-                        if (!fieldChars.get(fieldName.charAt(i))) {
-                            valid = false;
-                            break;
-                        }
-                    }
-
-                    if (valid) {
-                        handler.field(field);
-                        bd.addField(fieldName, field.substring(index + 1));
-                    }
-                }
-
-                if (!valid && log.isWarnEnabled()) {
-                    log.warn("Line " + startLineNumber
-                            + ": Ignoring invalid field: '" + field.trim() + "'");
-                }
-
-                startLineNumber = lineNumber;
-            }
-
-            pos += 2;
-            lineNumber++;
-        }
-
-        handler.endHeader();
-
-        return bd;
-    }
-
-    /**
-     * Sets the <code>ContentHandler</code> to use when reporting
-     * parsing events.
-     *
-     * @param h the <code>ContentHandler</code>.
-     */
-    public void setContentHandler(ContentHandler h) {
-        this.handler = h;
-    }
-
-}
\ No newline at end of file
diff --git a/src/org/apache/james/mime4j/RootInputStream.java b/src/org/apache/james/mime4j/RootInputStream.java
deleted file mode 100644
index cc8b241..0000000
--- a/src/org/apache/james/mime4j/RootInputStream.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one   *
- * or more contributor license agreements.  See the NOTICE file *
- * distributed with this work for additional information        *
- * regarding copyright ownership.  The ASF licenses this file   *
- * to you 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 org.apache.james.mime4j;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-/**
- * <code>InputStream</code> used by the parser to wrap the original user
- * supplied stream. This stream keeps track of the current line number and
- * can also be truncated. When truncated the stream will appear to have
- * reached end of file. This is used by the parser's
- * {@link org.apache.james.mime4j.MimeStreamParser#stop()} method.
- *
- *
- * @version $Id: RootInputStream.java,v 1.2 2004/10/02 12:41:10 ntherning Exp $
- */
-class RootInputStream extends InputStream {
-    private InputStream is = null;
-    private int lineNumber = 1;
-    private int prev = -1;
-    private boolean truncated = false;
-
-    /**
-     * Creates a new <code>RootInputStream</code>.
-     *
-     * @param in the stream to read from.
-     */
-    public RootInputStream(InputStream is) {
-        this.is = is;
-    }
-
-    /**
-     * Gets the current line number starting at 1
-     * (the number of <code>\r\n</code> read so far plus 1).
-     *
-     * @return the current line number.
-     */
-    public int getLineNumber() {
-        return lineNumber;
-    }
-
-    /**
-     * Truncates this <code>InputStream</code>. After this call any
-     * call to {@link #read()}, {@link #read(byte[]) or
-     * {@link #read(byte[], int, int)} will return
-     * -1 as if end-of-file had been reached.
-     */
-    public void truncate() {
-        this.truncated = true;
-    }
-
-    /**
-     * @see java.io.InputStream#read()
-     */
-    public int read() throws IOException {
-        if (truncated) {
-            return -1;
-        }
-
-        int b = is.read();
-        if (prev == '\r' && b == '\n') {
-            lineNumber++;
-        }
-        prev = b;
-        return b;
-    }
-
-    /**
-     *
-     * @see java.io.InputStream#read(byte[], int, int)
-     */
-    public int read(byte[] b, int off, int len) throws IOException {
-        if (truncated) {
-            return -1;
-        }
-
-        int n = is.read(b, off, len);
-        for (int i = off; i < off + n; i++) {
-            if (prev == '\r' && b[i] == '\n') {
-                lineNumber++;
-            }
-            prev = b[i];
-        }
-        return n;
-    }
-
-    /**
-     * @see java.io.InputStream#read(byte[])
-     */
-    public int read(byte[] b) throws IOException {
-        return read(b, 0, b.length);
-    }
-}
\ No newline at end of file
diff --git a/src/org/apache/james/mime4j/codec/EncoderUtil.java b/src/org/apache/james/mime4j/codec/EncoderUtil.java
deleted file mode 100644
index 6841bc9..0000000
--- a/src/org/apache/james/mime4j/codec/EncoderUtil.java
+++ /dev/null
@@ -1,630 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one   *
- * or more contributor license agreements.  See the NOTICE file *
- * distributed with this work for additional information        *
- * regarding copyright ownership.  The ASF licenses this file   *
- * to you 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 org.apache.james.mime4j.codec;
-
-import java.nio.ByteBuffer;
-import java.nio.charset.Charset;
-import java.util.BitSet;
-import java.util.Locale;
-
-import org.apache.james.mime4j.util.CharsetUtil;
-
-/**
- * ANDROID:  THIS CLASS IS COPIED FROM A NEWER VERSION OF MIME4J
- */
-
-/**
- * Static methods for encoding header field values. This includes encoded-words
- * as defined in <a href='http://www.faqs.org/rfcs/rfc2047.html'>RFC 2047</a>
- * or display-names of an e-mail address, for example.
- * 
- */
-public class EncoderUtil {
-
-    // This array is a lookup table that translates 6-bit positive integer index
-    // values into their "Base64 Alphabet" equivalents as specified in Table 1
-    // of RFC 2045.
-    // ANDROID:  THIS TABLE IS COPIED FROM BASE64OUTPUTSTREAM
-    static final byte[] BASE64_TABLE = { 'A', 'B', 'C', 'D', 'E', 'F',
-            'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
-            'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
-            'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's',
-            't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5',
-            '6', '7', '8', '9', '+', '/' };
-
-    // Byte used to pad output.
-    private static final byte BASE64_PAD = '=';
-
-    private static final BitSet Q_REGULAR_CHARS = initChars("=_?");
-
-    private static final BitSet Q_RESTRICTED_CHARS = initChars("=_?\"#$%&'(),.:;<>@[\\]^`{|}~");
-
-    private static final int MAX_USED_CHARACTERS = 50;
-
-    private static final String ENC_WORD_PREFIX = "=?";
-    private static final String ENC_WORD_SUFFIX = "?=";
-
-    private static final int ENCODED_WORD_MAX_LENGTH = 75; // RFC 2047
-
-    private static final BitSet TOKEN_CHARS = initChars("()<>@,;:\\\"/[]?=");
-
-    private static final BitSet ATEXT_CHARS = initChars("()<>@.,;:\\\"[]");
-
-    private static BitSet initChars(String specials) {
-        BitSet bs = new BitSet(128);
-        for (char ch = 33; ch < 127; ch++) {
-            if (specials.indexOf(ch) == -1) {
-                bs.set(ch);
-            }
-        }
-        return bs;
-    }
-
-    /**
-     * Selects one of the two encodings specified in RFC 2047.
-     */
-    public enum Encoding {
-        /** The B encoding (identical to base64 defined in RFC 2045). */
-        B,
-        /** The Q encoding (similar to quoted-printable defined in RFC 2045). */
-        Q
-    }
-
-    /**
-     * Indicates the intended usage of an encoded word.
-     */
-    public enum Usage {
-        /**
-         * Encoded word is used to replace a 'text' token in any Subject or
-         * Comments header field.
-         */
-        TEXT_TOKEN,
-        /**
-         * Encoded word is used to replace a 'word' entity within a 'phrase',
-         * for example, one that precedes an address in a From, To, or Cc
-         * header.
-         */
-        WORD_ENTITY
-    }
-
-    private EncoderUtil() {
-    }
-
-    /**
-     * Encodes the display-name portion of an address. See <a
-     * href='http://www.faqs.org/rfcs/rfc5322.html'>RFC 5322</a> section 3.4
-     * and <a href='http://www.faqs.org/rfcs/rfc2047.html'>RFC 2047</a> section
-     * 5.3. The specified string should not be folded.
-     * 
-     * @param displayName
-     *            display-name to encode.
-     * @return encoded display-name.
-     */
-    public static String encodeAddressDisplayName(String displayName) {
-        // display-name = phrase
-        // phrase = 1*( encoded-word / word )
-        // word = atom / quoted-string
-        // atom = [CFWS] 1*atext [CFWS]
-        // CFWS = comment or folding white space
-
-        if (isAtomPhrase(displayName)) {
-            return displayName;
-        } else if (hasToBeEncoded(displayName, 0)) {
-            return encodeEncodedWord(displayName, Usage.WORD_ENTITY);
-        } else {
-            return quote(displayName);
-        }
-    }
-
-    /**
-     * Encodes the local part of an address specification as described in RFC
-     * 5322 section 3.4.1. Leading and trailing CFWS should have been removed
-     * before calling this method. The specified string should not contain any
-     * illegal (control or non-ASCII) characters.
-     * 
-     * @param localPart
-     *            the local part to encode
-     * @return the encoded local part.
-     */
-    public static String encodeAddressLocalPart(String localPart) {
-        // local-part = dot-atom / quoted-string
-        // dot-atom = [CFWS] dot-atom-text [CFWS]
-        // CFWS = comment or folding white space
-
-        if (isDotAtomText(localPart)) {
-            return localPart;
-        } else {
-            return quote(localPart);
-        }
-    }
-
-    /**
-     * Encodes the specified strings into a header parameter as described in RFC
-     * 2045 section 5.1 and RFC 2183 section 2. The specified strings should not
-     * contain any illegal (control or non-ASCII) characters.
-     * 
-     * @param name
-     *            parameter name.
-     * @param value
-     *            parameter value.
-     * @return encoded result.
-     */
-    public static String encodeHeaderParameter(String name, String value) {
-        name = name.toLowerCase(Locale.US);
-
-        // value := token / quoted-string
-        if (isToken(value)) {
-            return name + "=" + value;
-        } else {
-            return name + "=" + quote(value);
-        }
-    }
-
-    /**
-     * Shortcut method that encodes the specified text into an encoded-word if
-     * the text has to be encoded.
-     * 
-     * @param text
-     *            text to encode.
-     * @param usage
-     *            whether the encoded-word is to be used to replace a text token
-     *            or a word entity (see RFC 822).
-     * @param usedCharacters
-     *            number of characters already used up (<code>0 <= usedCharacters <= 50</code>).
-     * @return the specified text if encoding is not necessary or an encoded
-     *         word or a sequence of encoded words otherwise.
-     */
-    public static String encodeIfNecessary(String text, Usage usage,
-            int usedCharacters) {
-        if (hasToBeEncoded(text, usedCharacters))
-            return encodeEncodedWord(text, usage, usedCharacters);
-        else
-            return text;
-    }
-
-    /**
-     * Determines if the specified string has to encoded into an encoded-word.
-     * Returns <code>true</code> if the text contains characters that don't
-     * fall into the printable ASCII character set or if the text contains a
-     * 'word' (sequence of non-whitespace characters) longer than 77 characters
-     * (including characters already used up in the line).
-     * 
-     * @param text
-     *            text to analyze.
-     * @param usedCharacters
-     *            number of characters already used up (<code>0 <= usedCharacters <= 50</code>).
-     * @return <code>true</code> if the specified text has to be encoded into
-     *         an encoded-word, <code>false</code> otherwise.
-     */
-    public static boolean hasToBeEncoded(String text, int usedCharacters) {
-        if (text == null)
-            throw new IllegalArgumentException();
-        if (usedCharacters < 0 || usedCharacters > MAX_USED_CHARACTERS)
-            throw new IllegalArgumentException();
-
-        int nonWhiteSpaceCount = usedCharacters;
-
-        for (int idx = 0; idx < text.length(); idx++) {
-            char ch = text.charAt(idx);
-            if (ch == '\t' || ch == ' ') {
-                nonWhiteSpaceCount = 0;
-            } else {
-                nonWhiteSpaceCount++;
-                if (nonWhiteSpaceCount > 77) {
-                    // Line cannot be folded into multiple lines with no more
-                    // than 78 characters each. Encoding as encoded-words makes
-                    // that possible. One character has to be reserved for
-                    // folding white space; that leaves 77 characters.
-                    return true;
-                }
-
-                if (ch < 32 || ch >= 127) {
-                    // non-printable ascii character has to be encoded
-                    return true;
-                }
-            }
-        }
-
-        return false;
-    }
-
-    /**
-     * Encodes the specified text into an encoded word or a sequence of encoded
-     * words separated by space. The text is separated into a sequence of
-     * encoded words if it does not fit in a single one.
-     * <p>
-     * The charset to encode the specified text into a byte array and the
-     * encoding to use for the encoded-word are detected automatically.
-     * <p>
-     * This method assumes that zero characters have already been used up in the
-     * current line.
-     * 
-     * @param text
-     *            text to encode.
-     * @param usage
-     *            whether the encoded-word is to be used to replace a text token
-     *            or a word entity (see RFC 822).
-     * @return the encoded word (or sequence of encoded words if the given text
-     *         does not fit in a single encoded word).
-     * @see #hasToBeEncoded(String, int)
-     */
-    public static String encodeEncodedWord(String text, Usage usage) {
-        return encodeEncodedWord(text, usage, 0, null, null);
-    }
-
-    /**
-     * Encodes the specified text into an encoded word or a sequence of encoded
-     * words separated by space. The text is separated into a sequence of
-     * encoded words if it does not fit in a single one.
-     * <p>
-     * The charset to encode the specified text into a byte array and the
-     * encoding to use for the encoded-word are detected automatically.
-     * 
-     * @param text
-     *            text to encode.
-     * @param usage
-     *            whether the encoded-word is to be used to replace a text token
-     *            or a word entity (see RFC 822).
-     * @param usedCharacters
-     *            number of characters already used up (<code>0 <= usedCharacters <= 50</code>).
-     * @return the encoded word (or sequence of encoded words if the given text
-     *         does not fit in a single encoded word).
-     * @see #hasToBeEncoded(String, int)
-     */
-    public static String encodeEncodedWord(String text, Usage usage,
-            int usedCharacters) {
-        return encodeEncodedWord(text, usage, usedCharacters, null, null);
-    }
-
-    /**
-     * Encodes the specified text into an encoded word or a sequence of encoded
-     * words separated by space. The text is separated into a sequence of
-     * encoded words if it does not fit in a single one.
-     * 
-     * @param text
-     *            text to encode.
-     * @param usage
-     *            whether the encoded-word is to be used to replace a text token
-     *            or a word entity (see RFC 822).
-     * @param usedCharacters
-     *            number of characters already used up (<code>0 <= usedCharacters <= 50</code>).
-     * @param charset
-     *            the Java charset that should be used to encode the specified
-     *            string into a byte array. A suitable charset is detected
-     *            automatically if this parameter is <code>null</code>.
-     * @param encoding
-     *            the encoding to use for the encoded-word (either B or Q). A
-     *            suitable encoding is automatically chosen if this parameter is
-     *            <code>null</code>.
-     * @return the encoded word (or sequence of encoded words if the given text
-     *         does not fit in a single encoded word).
-     * @see #hasToBeEncoded(String, int)
-     */
-    public static String encodeEncodedWord(String text, Usage usage,
-            int usedCharacters, Charset charset, Encoding encoding) {
-        if (text == null)
-            throw new IllegalArgumentException();
-        if (usedCharacters < 0 || usedCharacters > MAX_USED_CHARACTERS)
-            throw new IllegalArgumentException();
-
-        if (charset == null)
-            charset = determineCharset(text);
-
-        String mimeCharset = CharsetUtil.toMimeCharset(charset.name());
-        if (mimeCharset == null) {
-            // cannot happen if charset was originally null
-            throw new IllegalArgumentException("Unsupported charset");
-        }
-
-        byte[] bytes = encode(text, charset);
-
-        if (encoding == null)
-            encoding = determineEncoding(bytes, usage);
-
-        if (encoding == Encoding.B) {
-            String prefix = ENC_WORD_PREFIX + mimeCharset + "?B?";
-            return encodeB(prefix, text, usedCharacters, charset, bytes);
-        } else {
-            String prefix = ENC_WORD_PREFIX + mimeCharset + "?Q?";
-            return encodeQ(prefix, text, usage, usedCharacters, charset, bytes);
-        }
-    }
-
-    /**
-     * Encodes the specified byte array using the B encoding defined in RFC
-     * 2047.
-     * 
-     * @param bytes
-     *            byte array to encode.
-     * @return encoded string.
-     */
-    public static String encodeB(byte[] bytes) {
-        StringBuilder sb = new StringBuilder();
-
-        int idx = 0;
-        final int end = bytes.length;
-        for (; idx < end - 2; idx += 3) {
-            int data = (bytes[idx] & 0xff) << 16 | (bytes[idx + 1] & 0xff) << 8
-                    | bytes[idx + 2] & 0xff;
-            sb.append((char) BASE64_TABLE[data >> 18 & 0x3f]);
-            sb.append((char) BASE64_TABLE[data >> 12 & 0x3f]);
-            sb.append((char) BASE64_TABLE[data >> 6 & 0x3f]);
-            sb.append((char) BASE64_TABLE[data & 0x3f]);
-        }
-
-        if (idx == end - 2) {
-            int data = (bytes[idx] & 0xff) << 16 | (bytes[idx + 1] & 0xff) << 8;
-            sb.append((char) BASE64_TABLE[data >> 18 & 0x3f]);
-            sb.append((char) BASE64_TABLE[data >> 12 & 0x3f]);
-            sb.append((char) BASE64_TABLE[data >> 6 & 0x3f]);
-            sb.append((char) BASE64_PAD);
-
-        } else if (idx == end - 1) {
-            int data = (bytes[idx] & 0xff) << 16;
-            sb.append((char) BASE64_TABLE[data >> 18 & 0x3f]);
-            sb.append((char) BASE64_TABLE[data >> 12 & 0x3f]);
-            sb.append((char) BASE64_PAD);
-            sb.append((char) BASE64_PAD);
-        }
-
-        return sb.toString();
-    }
-
-    /**
-     * Encodes the specified byte array using the Q encoding defined in RFC
-     * 2047.
-     * 
-     * @param bytes
-     *            byte array to encode.
-     * @param usage
-     *            whether the encoded-word is to be used to replace a text token
-     *            or a word entity (see RFC 822).
-     * @return encoded string.
-     */
-    public static String encodeQ(byte[] bytes, Usage usage) {
-        BitSet qChars = usage == Usage.TEXT_TOKEN ? Q_REGULAR_CHARS
-                : Q_RESTRICTED_CHARS;
-
-        StringBuilder sb = new StringBuilder();
-
-        final int end = bytes.length;
-        for (int idx = 0; idx < end; idx++) {
-            int v = bytes[idx] & 0xff;
-            if (v == 32) {
-                sb.append('_');
-            } else if (!qChars.get(v)) {
-                sb.append('=');
-                sb.append(hexDigit(v >>> 4));
-                sb.append(hexDigit(v & 0xf));
-            } else {
-                sb.append((char) v);
-            }
-        }
-
-        return sb.toString();
-    }
-
-    /**
-     * Tests whether the specified string is a token as defined in RFC 2045
-     * section 5.1.
-     * 
-     * @param str
-     *            string to test.
-     * @return <code>true</code> if the specified string is a RFC 2045 token,
-     *         <code>false</code> otherwise.
-     */
-    public static boolean isToken(String str) {
-        // token := 1*<any (US-ASCII) CHAR except SPACE, CTLs, or tspecials>
-        // tspecials := "(" / ")" / "<" / ">" / "@" / "," / ";" / ":" / "\" /
-        // <"> / "/" / "[" / "]" / "?" / "="
-        // CTL := 0.- 31., 127.
-
-        final int length = str.length();
-        if (length == 0)
-            return false;
-
-        for (int idx = 0; idx < length; idx++) {
-            char ch = str.charAt(idx);
-            if (!TOKEN_CHARS.get(ch))
-                return false;
-        }
-
-        return true;
-    }
-
-    private static boolean isAtomPhrase(String str) {
-        // atom = [CFWS] 1*atext [CFWS]
-
-        boolean containsAText = false;
-
-        final int length = str.length();
-        for (int idx = 0; idx < length; idx++) {
-            char ch = str.charAt(idx);
-            if (ATEXT_CHARS.get(ch)) {
-                containsAText = true;
-            } else if (!CharsetUtil.isWhitespace(ch)) {
-                return false;
-            }
-        }
-
-        return containsAText;
-    }
-
-    // RFC 5322 section 3.2.3
-    private static boolean isDotAtomText(String str) {
-        // dot-atom-text = 1*atext *("." 1*atext)
-        // atext = ALPHA / DIGIT / "!" / "#" / "$" / "%" / "&" / "'" / "*" /
-        // "+" / "-" / "/" / "=" / "?" / "^" / "_" / "`" / "{" / "|" / "}" / "~"
-
-        char prev = '.';
-
-        final int length = str.length();
-        if (length == 0)
-            return false;
-
-        for (int idx = 0; idx < length; idx++) {
-            char ch = str.charAt(idx);
-
-            if (ch == '.') {
-                if (prev == '.' || idx == length - 1)
-                    return false;
-            } else {
-                if (!ATEXT_CHARS.get(ch))
-                    return false;
-            }
-
-            prev = ch;
-        }
-
-        return true;
-    }
-
-    // RFC 5322 section 3.2.4
-    private static String quote(String str) {
-        // quoted-string = [CFWS] DQUOTE *([FWS] qcontent) [FWS] DQUOTE [CFWS]
-        // qcontent = qtext / quoted-pair
-        // qtext = %d33 / %d35-91 / %d93-126
-        // quoted-pair = ("\" (VCHAR / WSP))
-        // VCHAR = %x21-7E
-        // DQUOTE = %x22
-
-        String escaped = str.replaceAll("[\\\\\"]", "\\\\$0");
-        return "\"" + escaped + "\"";
-    }
-
-    private static String encodeB(String prefix, String text,
-            int usedCharacters, Charset charset, byte[] bytes) {
-        int encodedLength = bEncodedLength(bytes);
-
-        int totalLength = prefix.length() + encodedLength
-                + ENC_WORD_SUFFIX.length();
-        if (totalLength <= ENCODED_WORD_MAX_LENGTH - usedCharacters) {
-            return prefix + encodeB(bytes) + ENC_WORD_SUFFIX;
-        } else {
-            int splitOffset = text.offsetByCodePoints(text.length() / 2, -1);
-                                                         
-            String part1 = text.substring(0, splitOffset);
-            byte[] bytes1 = encode(part1, charset);
-            String word1 = encodeB(prefix, part1, usedCharacters, charset,
-                    bytes1);
-
-            String part2 = text.substring(splitOffset);
-            byte[] bytes2 = encode(part2, charset);
-            String word2 = encodeB(prefix, part2, 0, charset, bytes2);
-
-            return word1 + " " + word2;
-        }
-    }
-
-    private static int bEncodedLength(byte[] bytes) {
-        return (bytes.length + 2) / 3 * 4;
-    }
-
-    private static String encodeQ(String prefix, String text, Usage usage,
-            int usedCharacters, Charset charset, byte[] bytes) {
-        int encodedLength = qEncodedLength(bytes, usage);
-
-        int totalLength = prefix.length() + encodedLength
-                + ENC_WORD_SUFFIX.length();
-        if (totalLength <= ENCODED_WORD_MAX_LENGTH - usedCharacters) {
-            return prefix + encodeQ(bytes, usage) + ENC_WORD_SUFFIX;
-        } else {
-            int splitOffset = text.offsetByCodePoints(text.length() / 2, -1);
-
-            String part1 = text.substring(0, splitOffset);
-            byte[] bytes1 = encode(part1, charset);
-            String word1 = encodeQ(prefix, part1, usage, usedCharacters,
-                    charset, bytes1);
-
-            String part2 = text.substring(splitOffset);
-            byte[] bytes2 = encode(part2, charset);
-            String word2 = encodeQ(prefix, part2, usage, 0, charset, bytes2);
-
-            return word1 + " " + word2;
-        }
-    }
-
-    private static int qEncodedLength(byte[] bytes, Usage usage) {
-        BitSet qChars = usage == Usage.TEXT_TOKEN ? Q_REGULAR_CHARS
-                : Q_RESTRICTED_CHARS;
-
-        int count = 0;
-
-        for (int idx = 0; idx < bytes.length; idx++) {
-            int v = bytes[idx] & 0xff;
-            if (v == 32) {
-                count++;
-            } else if (!qChars.get(v)) {
-                count += 3;
-            } else {
-                count++;
-            }
-        }
-
-        return count;
-    }
-
-    private static byte[] encode(String text, Charset charset) {
-        ByteBuffer buffer = charset.encode(text);
-        byte[] bytes = new byte[buffer.limit()];
-        buffer.get(bytes);
-        return bytes;
-    }
-
-    private static Charset determineCharset(String text) {
-        // it is an important property of iso-8859-1 that it directly maps
-        // unicode code points 0000 to 00ff to byte values 00 to ff.
-        boolean ascii = true;
-        final int len = text.length();
-        for (int index = 0; index < len; index++) {
-            char ch = text.charAt(index);
-            if (ch > 0xff) {
-                return CharsetUtil.UTF_8;
-            }
-            if (ch > 0x7f) {
-                ascii = false;
-            }
-        }
-        return ascii ? CharsetUtil.US_ASCII : CharsetUtil.ISO_8859_1;
-    }
-
-    private static Encoding determineEncoding(byte[] bytes, Usage usage) {
-        if (bytes.length == 0)
-            return Encoding.Q;
-
-        BitSet qChars = usage == Usage.TEXT_TOKEN ? Q_REGULAR_CHARS
-                : Q_RESTRICTED_CHARS;
-
-        int qEncoded = 0;
-        for (int i = 0; i < bytes.length; i++) {
-            int v = bytes[i] & 0xff;
-            if (v != 32 && !qChars.get(v)) {
-                qEncoded++;
-            }
-        }
-
-        int percentage = qEncoded * 100 / bytes.length;
-        return percentage > 30 ? Encoding.B : Encoding.Q;
-    }
-
-    private static char hexDigit(int i) {
-        return i < 10 ? (char) (i + '0') : (char) (i - 10 + 'A');
-    }
-}
diff --git a/src/org/apache/james/mime4j/decoder/Base64InputStream.java b/src/org/apache/james/mime4j/decoder/Base64InputStream.java
deleted file mode 100644
index 77f5d7d..0000000
--- a/src/org/apache/james/mime4j/decoder/Base64InputStream.java
+++ /dev/null
@@ -1,151 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one   *
- * or more contributor license agreements.  See the NOTICE file *
- * distributed with this work for additional information        *
- * regarding copyright ownership.  The ASF licenses this file   *
- * to you 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.                                           *
- ****************************************************************/
-
-/**
- * Modified to improve efficiency by Android   21-Aug-2009
- */
-
-package org.apache.james.mime4j.decoder;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-/**
- * Performs Base-64 decoding on an underlying stream.
- * 
- * 
- * @version $Id: Base64InputStream.java,v 1.3 2004/11/29 13:15:47 ntherning Exp $
- */
-public class Base64InputStream extends InputStream {
-    private final InputStream s;
-    private int outCount = 0;
-    private int outIndex = 0;
-    private final int[] outputBuffer = new int[3];
-    private final byte[] inputBuffer = new byte[4];
-    private boolean done = false;
-
-    public Base64InputStream(InputStream s) {
-        this.s = s;
-    }
-
-    /**
-     * Closes the underlying stream.
-     * 
-     * @throws IOException on I/O errors.
-     */
-    @Override
-    public void close() throws IOException {
-        s.close();
-    }
-    
-    @Override
-    public int read() throws IOException {
-        if (outIndex == outCount) {
-            fillBuffer();
-            if (outIndex == outCount) {
-                return -1;
-            }
-        }
-
-        return outputBuffer[outIndex++];
-    }
-
-    /**
-     * Retrieve data from the underlying stream, decode it,
-     * and put the results in the byteq.
-     * @throws IOException
-     */
-    private void fillBuffer() throws IOException {
-        outCount = 0;
-        outIndex = 0;
-        int inCount = 0;
-
-        int i;
-        // "done" is needed for the two successive '=' at the end
-        while (!done) {
-            switch (i = s.read()) {
-                case -1:
-                    // No more input - just return, let outputBuffer drain out, and be done
-                    return;
-                case '=':
-                    // once we meet the first '=', avoid reading the second '='
-                    done = true;
-                    decodeAndEnqueue(inCount);
-                    return;
-                default:
-                    byte sX = TRANSLATION[i];
-                    if (sX < 0) continue;
-                    inputBuffer[inCount++] = sX;
-                    if (inCount == 4) {
-                        decodeAndEnqueue(inCount);
-                        return;
-                    }
-                    break;
-            }
-        }
-    }
-
-    private void decodeAndEnqueue(int len) {
-        int accum = 0;
-        accum |= inputBuffer[0] << 18;
-        accum |= inputBuffer[1] << 12;
-        accum |= inputBuffer[2] << 6;
-        accum |= inputBuffer[3];
-
-        // There's a bit of duplicated code here because we want to have straight-through operation
-        // for the most common case of len==4
-        if (len == 4) {
-            outputBuffer[0] = (accum >> 16) & 0xFF;
-            outputBuffer[1] = (accum >> 8) & 0xFF;
-            outputBuffer[2] = (accum) & 0xFF;
-            outCount = 3;
-            return;
-        } else if (len == 3) {
-            outputBuffer[0] = (accum >> 16) & 0xFF;
-            outputBuffer[1] = (accum >> 8) & 0xFF;
-            outCount = 2;
-            return;
-        } else {    // len == 2
-            outputBuffer[0] = (accum >> 16) & 0xFF;
-            outCount = 1;
-            return;
-        }
-    }
-
-    private static byte[] TRANSLATION = {
-        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0x00 */
-        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0x10 */
-        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, /* 0x20 */
-        52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, /* 0x30 */
-        -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, /* 0x40 */
-        15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, /* 0x50 */
-        -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, /* 0x60 */
-        41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1, /* 0x70 */
-        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0x80 */
-        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0x90 */
-        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0xA0 */
-        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0xB0 */
-        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0xC0 */
-        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0xD0 */
-        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0xE0 */
-        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1     /* 0xF0 */
-    };
-
-
-}
diff --git a/src/org/apache/james/mime4j/decoder/ByteQueue.java b/src/org/apache/james/mime4j/decoder/ByteQueue.java
deleted file mode 100644
index 6d7ccef..0000000
--- a/src/org/apache/james/mime4j/decoder/ByteQueue.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one   *
- * or more contributor license agreements.  See the NOTICE file *
- * distributed with this work for additional information        *
- * regarding copyright ownership.  The ASF licenses this file   *
- * to you 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 org.apache.james.mime4j.decoder;
-
-import java.util.Iterator;
-
-public class ByteQueue {
-
-    private UnboundedFifoByteBuffer buf;
-    private int initialCapacity = -1;
-
-    public ByteQueue() {
-        buf = new UnboundedFifoByteBuffer();
-    }
-
-    public ByteQueue(int initialCapacity) {
-        buf = new UnboundedFifoByteBuffer(initialCapacity);
-        this.initialCapacity = initialCapacity;
-    }
-
-    public void enqueue(byte b) {
-        buf.add(b);
-    }
-
-    public byte dequeue() {
-        return buf.remove();
-    }
-
-    public int count() {
-        return buf.size();
-    }
-
-    public void clear() {
-        if (initialCapacity != -1)
-            buf = new UnboundedFifoByteBuffer(initialCapacity);
-        else
-            buf = new UnboundedFifoByteBuffer();
-    }
-
-    public Iterator iterator() {
-        return buf.iterator();
-    }
-
-
-}
diff --git a/src/org/apache/james/mime4j/decoder/DecoderUtil.java b/src/org/apache/james/mime4j/decoder/DecoderUtil.java
deleted file mode 100644
index 48fe07d..0000000
--- a/src/org/apache/james/mime4j/decoder/DecoderUtil.java
+++ /dev/null
@@ -1,284 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one   *
- * or more contributor license agreements.  See the NOTICE file *
- * distributed with this work for additional information        *
- * regarding copyright ownership.  The ASF licenses this file   *
- * to you 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 org.apache.james.mime4j.decoder;
-
-//BEGIN android-changed: Stubbing out logging
-import org.apache.james.mime4j.Log;
-import org.apache.james.mime4j.LogFactory;
-//END android-changed
-import org.apache.james.mime4j.util.CharsetUtil;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-
-/**
- * Static methods for decoding strings, byte arrays and encoded words.
- *
- * 
- * @version $Id: DecoderUtil.java,v 1.3 2005/02/07 15:33:59 ntherning Exp $
- */
-public class DecoderUtil {
-    private static Log log = LogFactory.getLog(DecoderUtil.class);
-    
-    /**
-     * Decodes a string containing quoted-printable encoded data. 
-     * 
-     * @param s the string to decode.
-     * @return the decoded bytes.
-     */
-    public static byte[] decodeBaseQuotedPrintable(String s) {
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        
-        try {
-            byte[] bytes = s.getBytes("US-ASCII");
-            
-            QuotedPrintableInputStream is = new QuotedPrintableInputStream(
-                                               new ByteArrayInputStream(bytes));
-            
-            int b = 0;
-            while ((b = is.read()) != -1) {
-                baos.write(b);
-            }
-        } catch (IOException e) {
-            /*
-             * This should never happen!
-             */
-            log.error(e);
-        }
-        
-        return baos.toByteArray();
-    }
-    
-    /**
-     * Decodes a string containing base64 encoded data. 
-     * 
-     * @param s the string to decode.
-     * @return the decoded bytes.
-     */
-    public static byte[] decodeBase64(String s) {
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        
-        try {
-            byte[] bytes = s.getBytes("US-ASCII");
-            
-            Base64InputStream is = new Base64InputStream(
-                                        new ByteArrayInputStream(bytes));
-            
-            int b = 0;
-            while ((b = is.read()) != -1) {
-                baos.write(b);
-            }
-        } catch (IOException e) {
-            /*
-             * This should never happen!
-             */
-            log.error(e);
-        }
-        
-        return baos.toByteArray();
-    }
-    
-    /**
-     * Decodes an encoded word encoded with the 'B' encoding (described in 
-     * RFC 2047) found in a header field body.
-     * 
-     * @param encodedWord the encoded word to decode.
-     * @param charset the Java charset to use.
-     * @return the decoded string.
-     * @throws UnsupportedEncodingException if the given Java charset isn't 
-     *         supported.
-     */
-    public static String decodeB(String encodedWord, String charset) 
-            throws UnsupportedEncodingException {
-        
-        return new String(decodeBase64(encodedWord), charset);
-    }
-    
-    /**
-     * Decodes an encoded word encoded with the 'Q' encoding (described in 
-     * RFC 2047) found in a header field body.
-     * 
-     * @param encodedWord the encoded word to decode.
-     * @param charset the Java charset to use.
-     * @return the decoded string.
-     * @throws UnsupportedEncodingException if the given Java charset isn't 
-     *         supported.
-     */
-    public static String decodeQ(String encodedWord, String charset)
-            throws UnsupportedEncodingException {
-           
-        /*
-         * Replace _ with =20
-         */
-        StringBuffer sb = new StringBuffer();
-        for (int i = 0; i < encodedWord.length(); i++) {
-            char c = encodedWord.charAt(i);
-            if (c == '_') {
-                sb.append("=20");
-            } else {
-                sb.append(c);
-            }
-        }
-        
-        return new String(decodeBaseQuotedPrintable(sb.toString()), charset);
-    }
-    
-    /**
-     * Decodes a string containing encoded words as defined by RFC 2047.
-     * Encoded words in have the form 
-     * =?charset?enc?Encoded word?= where enc is either 'Q' or 'q' for 
-     * quoted-printable and 'B' or 'b' for Base64.
-     * 
-     * ANDROID:  COPIED FROM A NEWER VERSION OF MIME4J
-     * 
-     * @param body the string to decode.
-     * @return the decoded string.
-     */
-    public static String decodeEncodedWords(String body) {
-        
-        // ANDROID:  Most strings will not include "=?" so a quick test can prevent unneeded
-        // object creation.  This could also be handled via lazy creation of the StringBuilder.
-        if (body.indexOf("=?") == -1) {
-            return body;
-        }
-
-        int previousEnd = 0;
-        boolean previousWasEncoded = false;
-
-        StringBuilder sb = new StringBuilder();
-
-        while (true) {
-            int begin = body.indexOf("=?", previousEnd);
-
-            // ANDROID:  The mime4j original version has an error here.  It gets confused if
-            // the encoded string begins with an '=' (just after "?Q?").  This patch seeks forward
-            // to find the two '?' in the "header", before looking for the final "?=".
-            if (begin == -1) {
-                break;
-            }
-            int qm1 = body.indexOf('?', begin + 2);
-            if (qm1 == -1) {
-                break;
-            }
-            int qm2 = body.indexOf('?', qm1 + 1);
-            if (qm2 == -1) {
-                break;
-            }
-            int end = body.indexOf("?=", qm2 + 1);
-            if (end == -1) {
-                break;
-            }
-            end += 2;
-
-            String sep = body.substring(previousEnd, begin);
-
-            String decoded = decodeEncodedWord(body, begin, end);
-            if (decoded == null) {
-                sb.append(sep);
-                sb.append(body.substring(begin, end));
-            } else {
-                if (!previousWasEncoded || !CharsetUtil.isWhitespace(sep)) {
-                    sb.append(sep);
-                }
-                sb.append(decoded);
-            }
-
-            previousEnd = end;
-            previousWasEncoded = decoded != null;
-        }
-
-        if (previousEnd == 0)
-            return body;
-
-        sb.append(body.substring(previousEnd));
-        return sb.toString();
-    }
-
-    // return null on error. Begin is index of '=?' in body.
-    public static String decodeEncodedWord(String body, int begin, int end) {
-        // Skip the '?=' chars in body and scan forward from there for next '?'
-        int qm1 = body.indexOf('?', begin + 2);
-        if (qm1 == -1 || qm1 == end - 2)
-            return null;
-
-        int qm2 = body.indexOf('?', qm1 + 1);
-        if (qm2 == -1 || qm2 == end - 2)
-            return null;
-
-        String mimeCharset = body.substring(begin + 2, qm1);
-        String encoding = body.substring(qm1 + 1, qm2);
-        String encodedText = body.substring(qm2 + 1, end - 2);
-
-        String charset = CharsetUtil.toJavaCharset(mimeCharset);
-        if (charset == null) {
-            if (log.isWarnEnabled()) {
-                log.warn("MIME charset '" + mimeCharset + "' in encoded word '"
-                        + body.substring(begin, end) + "' doesn't have a "
-                        + "corresponding Java charset");
-            }
-            return null;
-        } else if (!CharsetUtil.isDecodingSupported(charset)) {
-            if (log.isWarnEnabled()) {
-                log.warn("Current JDK doesn't support decoding of charset '"
-                        + charset + "' (MIME charset '" + mimeCharset
-                        + "' in encoded word '" + body.substring(begin, end)
-                        + "')");
-            }
-            return null;
-        }
-
-        if (encodedText.length() == 0) {
-            if (log.isWarnEnabled()) {
-                log.warn("Missing encoded text in encoded word: '"
-                        + body.substring(begin, end) + "'");
-            }
-            return null;
-        }
-
-        try {
-            if (encoding.equalsIgnoreCase("Q")) {
-                return DecoderUtil.decodeQ(encodedText, charset);
-            } else if (encoding.equalsIgnoreCase("B")) {
-                return DecoderUtil.decodeB(encodedText, charset);
-            } else {
-                if (log.isWarnEnabled()) {
-                    log.warn("Warning: Unknown encoding in encoded word '"
-                            + body.substring(begin, end) + "'");
-                }
-                return null;
-            }
-        } catch (UnsupportedEncodingException e) {
-            // should not happen because of isDecodingSupported check above
-            if (log.isWarnEnabled()) {
-                log.warn("Unsupported encoding in encoded word '"
-                        + body.substring(begin, end) + "'", e);
-            }
-            return null;
-        } catch (RuntimeException e) {
-            if (log.isWarnEnabled()) {
-                log.warn("Could not decode encoded word '"
-                        + body.substring(begin, end) + "'", e);
-            }
-            return null;
-        }
-    }
-}
diff --git a/src/org/apache/james/mime4j/decoder/QuotedPrintableInputStream.java b/src/org/apache/james/mime4j/decoder/QuotedPrintableInputStream.java
deleted file mode 100644
index e43f398..0000000
--- a/src/org/apache/james/mime4j/decoder/QuotedPrintableInputStream.java
+++ /dev/null
@@ -1,229 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one   *
- * or more contributor license agreements.  See the NOTICE file *
- * distributed with this work for additional information        *
- * regarding copyright ownership.  The ASF licenses this file   *
- * to you 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 org.apache.james.mime4j.decoder;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-//BEGIN android-changed: Stubbing out logging
-import org.apache.james.mime4j.Log;
-import org.apache.james.mime4j.LogFactory;
-//END android-changed
-
-/**
- * Performs Quoted-Printable decoding on an underlying stream.
- * 
- * 
- * 
- * @version $Id: QuotedPrintableInputStream.java,v 1.3 2004/11/29 13:15:47 ntherning Exp $
- */
-public class QuotedPrintableInputStream extends InputStream {
-    private static Log log = LogFactory.getLog(QuotedPrintableInputStream.class);
-    
-    private InputStream stream;
-    ByteQueue byteq = new ByteQueue();
-    ByteQueue pushbackq = new ByteQueue();
-    private byte state = 0;
-
-    public QuotedPrintableInputStream(InputStream stream) {
-        this.stream = stream;
-    }
-    
-    /**
-     * Closes the underlying stream.
-     * 
-     * @throws IOException on I/O errors.
-     */
-    public void close() throws IOException {
-        stream.close();
-    }
-
-    public int read() throws IOException {
-        fillBuffer();
-        if (byteq.count() == 0)
-            return -1;
-        else {
-            byte val = byteq.dequeue();
-            if (val >= 0)
-                return val;
-            else
-                return val & 0xFF;
-        }
-    }
-
-    /**
-     * Pulls bytes out of the underlying stream and places them in the
-     * pushback queue.  This is necessary (vs. reading from the
-     * underlying stream directly) to detect and filter out "transport
-     * padding" whitespace, i.e., all whitespace that appears immediately
-     * before a CRLF.
-     *
-     * @throws IOException Underlying stream threw IOException.
-     */
-    private void populatePushbackQueue() throws IOException {
-        //Debug.verify(pushbackq.count() == 0, "PopulatePushbackQueue called when pushback queue was not empty!");
-
-        if (pushbackq.count() != 0)
-            return;
-
-        while (true) {
-            int i = stream.read();
-            switch (i) {
-                case -1:
-                    // stream is done
-                    pushbackq.clear();  // discard any whitespace preceding EOF
-                    return;
-                case ' ':
-                case '\t':
-                    pushbackq.enqueue((byte)i);
-                    break;
-                case '\r':
-                case '\n':
-                    pushbackq.clear();  // discard any whitespace preceding EOL
-                    pushbackq.enqueue((byte)i);
-                    return;
-                default:
-                    pushbackq.enqueue((byte)i);
-                    return;
-            }
-        }
-    }
-
-    /**
-     * Causes the pushback queue to get populated if it is empty, then
-     * consumes and decodes bytes out of it until one or more bytes are
-     * in the byte queue.  This decoding step performs the actual QP
-     * decoding.
-     *
-     * @throws IOException Underlying stream threw IOException.
-     */
-    private void fillBuffer() throws IOException {
-        byte msdChar = 0;  // first digit of escaped num
-        while (byteq.count() == 0) {
-            if (pushbackq.count() == 0) {
-                populatePushbackQueue();
-                if (pushbackq.count() == 0)
-                    return;
-            }
-
-            byte b = (byte)pushbackq.dequeue();
-
-            switch (state) {
-                case 0:  // start state, no bytes pending
-                    if (b != '=') {
-                        byteq.enqueue(b);
-                        break;  // state remains 0
-                    } else {
-                        state = 1;
-                        break;
-                    }
-                case 1:  // encountered "=" so far
-                    if (b == '\r') {
-                        state = 2;
-                        break;
-                    } else if ((b >= '0' && b <= '9') || (b >= 'A' && b <= 'F') || (b >= 'a' && b <= 'f')) {
-                        state = 3;
-                        msdChar = b;  // save until next digit encountered
-                        break;
-                    } else if (b == '=') {
-                        /*
-                         * Special case when == is encountered.
-                         * Emit one = and stay in this state.
-                         */
-                        if (log.isWarnEnabled()) {
-                            log.warn("Malformed MIME; got ==");
-                        }
-                        byteq.enqueue((byte)'=');
-                        break;
-                    } else {
-                        if (log.isWarnEnabled()) {
-                            log.warn("Malformed MIME; expected \\r or "
-                                    + "[0-9A-Z], got " + b);
-                        }
-                        state = 0;
-                        byteq.enqueue((byte)'=');
-                        byteq.enqueue(b);
-                        break;
-                    }
-                case 2:  // encountered "=\r" so far
-                    if (b == '\n') {
-                        state = 0;
-                        break;
-                    } else {
-                        if (log.isWarnEnabled()) {
-                            log.warn("Malformed MIME; expected " 
-                                    + (int)'\n' + ", got " + b);
-                        }
-                        state = 0;
-                        byteq.enqueue((byte)'=');
-                        byteq.enqueue((byte)'\r');
-                        byteq.enqueue(b);
-                        break;
-                    }
-                case 3:  // encountered =<digit> so far; expecting another <digit> to complete the octet
-                    if ((b >= '0' && b <= '9') || (b >= 'A' && b <= 'F') || (b >= 'a' && b <= 'f')) {
-                        byte msd = asciiCharToNumericValue(msdChar);
-                        byte low = asciiCharToNumericValue(b);
-                        state = 0;
-                        byteq.enqueue((byte)((msd << 4) | low));
-                        break;
-                    } else {
-                        if (log.isWarnEnabled()) {
-                            log.warn("Malformed MIME; expected "
-                                     + "[0-9A-Z], got " + b);
-                        }
-                        state = 0;
-                        byteq.enqueue((byte)'=');
-                        byteq.enqueue(msdChar);
-                        byteq.enqueue(b);
-                        break;
-                    }
-                default:  // should never happen
-                    log.error("Illegal state: " + state);
-                    state = 0;
-                    byteq.enqueue(b);
-                    break;
-            }
-        }
-    }
-
-    /**
-     * Converts '0' => 0, 'A' => 10, etc.
-     * @param c ASCII character value.
-     * @return Numeric value of hexadecimal character.
-     */
-    private byte asciiCharToNumericValue(byte c) {
-        if (c >= '0' && c <= '9') {
-            return (byte)(c - '0');
-        } else if (c >= 'A' && c <= 'Z') {
-            return (byte)(0xA + (c - 'A'));
-        } else if (c >= 'a' && c <= 'z') {
-            return (byte)(0xA + (c - 'a'));
-        } else {
-            /*
-             * This should never happen since all calls to this method
-             * are preceded by a check that c is in [0-9A-Za-z]
-             */
-            throw new IllegalArgumentException((char) c 
-                    + " is not a hexadecimal digit");
-        }
-    }
-
-}
diff --git a/src/org/apache/james/mime4j/decoder/UnboundedFifoByteBuffer.java b/src/org/apache/james/mime4j/decoder/UnboundedFifoByteBuffer.java
deleted file mode 100644
index f01194f..0000000
--- a/src/org/apache/james/mime4j/decoder/UnboundedFifoByteBuffer.java
+++ /dev/null
@@ -1,272 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one   *
- * or more contributor license agreements.  See the NOTICE file *
- * distributed with this work for additional information        *
- * regarding copyright ownership.  The ASF licenses this file   *
- * to you 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 org.apache.james.mime4j.decoder;
-
-import java.util.Iterator;
-import java.util.NoSuchElementException;
-
-/**
- * UnboundedFifoByteBuffer is a very efficient buffer implementation.
- * According to performance testing, it exhibits a constant access time, but it
- * also outperforms ArrayList when used for the same purpose.
- * <p>
- * The removal order of an <code>UnboundedFifoByteBuffer</code> is based on the insertion
- * order; elements are removed in the same order in which they were added.
- * The iteration order is the same as the removal order.
- * <p>
- * The {@link #remove()} and {@link #get()} operations perform in constant time.
- * The {@link #add(Object)} operation performs in amortized constant time.  All
- * other operations perform in linear time or worse.
- * <p>
- * Note that this implementation is not synchronized.  The following can be
- * used to provide synchronized access to your <code>UnboundedFifoByteBuffer</code>:
- * <pre>
- *   Buffer fifo = BufferUtils.synchronizedBuffer(new UnboundedFifoByteBuffer());
- * </pre>
- * <p>
- * This buffer prevents null objects from being added.
- *
- * @since Commons Collections 3.0 (previously in main package v2.1)
- * @version $Revision: 1.1 $ $Date: 2004/08/24 06:52:02 $
- *
- * 
- * 
- * 
- * 
- * 
- */
-class UnboundedFifoByteBuffer {
-
-    protected byte[] buffer;
-    protected int head;
-    protected int tail;
-
-    /**
-     * Constructs an UnboundedFifoByteBuffer with the default number of elements.
-     * It is exactly the same as performing the following:
-     *
-     * <pre>
-     *   new UnboundedFifoByteBuffer(32);
-     * </pre>
-     */
-    public UnboundedFifoByteBuffer() {
-        this(32);
-    }
-
-    /**
-     * Constructs an UnboundedFifoByteBuffer with the specified number of elements.
-     * The integer must be a positive integer.
-     *
-     * @param initialSize  the initial size of the buffer
-     * @throws IllegalArgumentException  if the size is less than 1
-     */
-    public UnboundedFifoByteBuffer(int initialSize) {
-        if (initialSize <= 0) {
-            throw new IllegalArgumentException("The size must be greater than 0");
-        }
-        buffer = new byte[initialSize + 1];
-        head = 0;
-        tail = 0;
-    }
-
-    /**
-     * Returns the number of elements stored in the buffer.
-     *
-     * @return this buffer's size
-     */
-    public int size() {
-        int size = 0;
-
-        if (tail < head) {
-            size = buffer.length - head + tail;
-        } else {
-            size = tail - head;
-        }
-
-        return size;
-    }
-
-    /**
-     * Returns true if this buffer is empty; false otherwise.
-     *
-     * @return true if this buffer is empty
-     */
-    public boolean isEmpty() {
-        return (size() == 0);
-    }
-
-    /**
-     * Adds the given element to this buffer.
-     *
-     * @param b  the byte to add
-     * @return true, always
-     */
-    public boolean add(final byte b) {
-
-        if (size() + 1 >= buffer.length) {
-            byte[] tmp = new byte[((buffer.length - 1) * 2) + 1];
-
-            int j = 0;
-            for (int i = head; i != tail;) {
-                tmp[j] = buffer[i];
-                buffer[i] = 0;
-
-                j++;
-                i++;
-                if (i == buffer.length) {
-                    i = 0;
-                }
-            }
-
-            buffer = tmp;
-            head = 0;
-            tail = j;
-        }
-
-        buffer[tail] = b;
-        tail++;
-        if (tail >= buffer.length) {
-            tail = 0;
-        }
-        return true;
-    }
-
-    /**
-     * Returns the next object in the buffer.
-     *
-     * @return the next object in the buffer
-     * @throws BufferUnderflowException  if this buffer is empty
-     */
-    public byte get() {
-        if (isEmpty()) {
-            throw new IllegalStateException("The buffer is already empty");
-        }
-
-        return buffer[head];
-    }
-
-    /**
-     * Removes the next object from the buffer
-     *
-     * @return the removed object
-     * @throws BufferUnderflowException  if this buffer is empty
-     */
-    public byte remove() {
-        if (isEmpty()) {
-            throw new IllegalStateException("The buffer is already empty");
-        }
-
-        byte element = buffer[head];
-
-        head++;
-        if (head >= buffer.length) {
-            head = 0;
-        }
-
-        return element;
-    }
-
-    /**
-     * Increments the internal index.
-     *
-     * @param index  the index to increment
-     * @return the updated index
-     */
-    private int increment(int index) {
-        index++;
-        if (index >= buffer.length) {
-            index = 0;
-        }
-        return index;
-    }
-
-    /**
-     * Decrements the internal index.
-     *
-     * @param index  the index to decrement
-     * @return the updated index
-     */
-    private int decrement(int index) {
-        index--;
-        if (index < 0) {
-            index = buffer.length - 1;
-        }
-        return index;
-    }
-
-    /**
-     * Returns an iterator over this buffer's elements.
-     *
-     * @return an iterator over this buffer's elements
-     */
-    public Iterator iterator() {
-        return new Iterator() {
-
-            private int index = head;
-            private int lastReturnedIndex = -1;
-
-            public boolean hasNext() {
-                return index != tail;
-
-            }
-
-            public Object next() {
-                if (!hasNext()) {
-                    throw new NoSuchElementException();
-                }
-                lastReturnedIndex = index;
-                index = increment(index);
-                return new Byte(buffer[lastReturnedIndex]);
-            }
-
-            public void remove() {
-                if (lastReturnedIndex == -1) {
-                    throw new IllegalStateException();
-                }
-
-                // First element can be removed quickly
-                if (lastReturnedIndex == head) {
-                    UnboundedFifoByteBuffer.this.remove();
-                    lastReturnedIndex = -1;
-                    return;
-                }
-
-                // Other elements require us to shift the subsequent elements
-                int i = lastReturnedIndex + 1;
-                while (i != tail) {
-                    if (i >= buffer.length) {
-                        buffer[i - 1] = buffer[0];
-                        i = 0;
-                    } else {
-                        buffer[i - 1] = buffer[i];
-                        i++;
-                    }
-                }
-
-                lastReturnedIndex = -1;
-                tail = decrement(tail);
-                buffer[tail] = 0;
-                index = decrement(index);
-            }
-
-        };
-    }
-
-}
\ No newline at end of file
diff --git a/src/org/apache/james/mime4j/field/AddressListField.java b/src/org/apache/james/mime4j/field/AddressListField.java
deleted file mode 100644
index df9f398..0000000
--- a/src/org/apache/james/mime4j/field/AddressListField.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one   *
- * or more contributor license agreements.  See the NOTICE file *
- * distributed with this work for additional information        *
- * regarding copyright ownership.  The ASF licenses this file   *
- * to you 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 org.apache.james.mime4j.field;
-
-//BEGIN android-changed: Stubbing out logging
-import org.apache.james.mime4j.Log;
-import org.apache.james.mime4j.LogFactory;
-//END android-changed
-import org.apache.james.mime4j.field.address.AddressList;
-import org.apache.james.mime4j.field.address.parser.ParseException;
-
-public class AddressListField extends Field {
-    private AddressList addressList;
-    private ParseException parseException;
-
-    protected AddressListField(String name, String body, String raw, AddressList addressList, ParseException parseException) {
-        super(name, body, raw);
-        this.addressList = addressList;
-        this.parseException = parseException;
-    }
-
-    public AddressList getAddressList() {
-        return addressList;
-    }
-
-    public ParseException getParseException() {
-        return parseException;
-    }
-
-    public static class Parser implements FieldParser {
-        private static Log log = LogFactory.getLog(Parser.class);
-
-        public Field parse(final String name, final String body, final String raw) {
-            AddressList addressList = null;
-            ParseException parseException = null;
-            try {
-                addressList = AddressList.parse(body);
-            }
-            catch (ParseException e) {
-                if (log.isDebugEnabled()) {
-                    log.debug("Parsing value '" + body + "': "+ e.getMessage());
-                }
-                parseException = e;
-            }
-            return new AddressListField(name, body, raw, addressList, parseException);
-        }
-    }
-}
diff --git a/src/org/apache/james/mime4j/field/ContentTransferEncodingField.java b/src/org/apache/james/mime4j/field/ContentTransferEncodingField.java
deleted file mode 100644
index 73d8d23..0000000
--- a/src/org/apache/james/mime4j/field/ContentTransferEncodingField.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one   *
- * or more contributor license agreements.  See the NOTICE file *
- * distributed with this work for additional information        *
- * regarding copyright ownership.  The ASF licenses this file   *
- * to you 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 org.apache.james.mime4j.field;
-
-
-
-/**
- * Represents a <code>Content-Transfer-Encoding</code> field.
- *
- * 
- * @version $Id: ContentTransferEncodingField.java,v 1.2 2004/10/02 12:41:11 ntherning Exp $
- */
-public class ContentTransferEncodingField extends Field {
-    /**
-     * The <code>7bit</code> encoding.
-     */
-    public static final String ENC_7BIT = "7bit";
-    /**
-     * The <code>8bit</code> encoding.
-     */
-    public static final String ENC_8BIT = "8bit";
-    /**
-     * The <code>binary</code> encoding.
-     */
-    public static final String ENC_BINARY = "binary";
-    /**
-     * The <code>quoted-printable</code> encoding.
-     */
-    public static final String ENC_QUOTED_PRINTABLE = "quoted-printable";
-    /**
-     * The <code>base64</code> encoding.
-     */
-    public static final String ENC_BASE64 = "base64";
-    
-    private String encoding;
-    
-    protected ContentTransferEncodingField(String name, String body, String raw, String encoding) {
-        super(name, body, raw);
-        this.encoding = encoding;
-    }
-
-    /**
-     * Gets the encoding defined in this field.
-     * 
-     * @return the encoding or an empty string if not set.
-     */
-    public String getEncoding() {
-        return encoding;
-    }
-    
-    /**
-     * Gets the encoding of the given field if. Returns the default 
-     * <code>7bit</code> if not set or if
-     * <code>f</code> is <code>null</code>.
-     * 
-     * @return the encoding.
-     */
-    public static String getEncoding(ContentTransferEncodingField f) {
-        if (f != null && f.getEncoding().length() != 0) {
-            return f.getEncoding();
-        }
-        return ENC_7BIT;
-    }
-    
-    public static class Parser implements FieldParser {
-        public Field parse(final String name, final String body, final String raw) {
-            final String encoding = body.trim().toLowerCase();
-            return new ContentTransferEncodingField(name, body, raw, encoding);
-        }
-    }
-}
diff --git a/src/org/apache/james/mime4j/field/ContentTypeField.java b/src/org/apache/james/mime4j/field/ContentTypeField.java
deleted file mode 100644
index ad9f7f9..0000000
--- a/src/org/apache/james/mime4j/field/ContentTypeField.java
+++ /dev/null
@@ -1,259 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one   *
- * or more contributor license agreements.  See the NOTICE file *
- * distributed with this work for additional information        *
- * regarding copyright ownership.  The ASF licenses this file   *
- * to you 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 org.apache.james.mime4j.field;
-
-import java.io.StringReader;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-
-//BEGIN android-changed: Stubbing out logging
-import org.apache.james.mime4j.Log;
-import org.apache.james.mime4j.LogFactory;
-//END android-changed
-import org.apache.james.mime4j.field.contenttype.parser.ContentTypeParser;
-import org.apache.james.mime4j.field.contenttype.parser.ParseException;
-import org.apache.james.mime4j.field.contenttype.parser.TokenMgrError;
-
-/**
- * Represents a <code>Content-Type</code> field.
- *
- * <p>TODO: Remove dependency on Java 1.4 regexps</p>
- *
- *
- * @version $Id: ContentTypeField.java,v 1.6 2005/01/27 14:16:31 ntherning Exp $
- */
-public class ContentTypeField extends Field {
-
-    /**
-     * The prefix of all <code>multipart</code> MIME types.
-     */
-    public static final String TYPE_MULTIPART_PREFIX = "multipart/";
-    /**
-     * The <code>multipart/digest</code> MIME type.
-     */
-    public static final String TYPE_MULTIPART_DIGEST = "multipart/digest";
-    /**
-     * The <code>text/plain</code> MIME type.
-     */
-    public static final String TYPE_TEXT_PLAIN = "text/plain";
-    /**
-     * The <code>message/rfc822</code> MIME type.
-     */
-    public static final String TYPE_MESSAGE_RFC822 = "message/rfc822";
-    /**
-     * The name of the <code>boundary</code> parameter.
-     */
-    public static final String PARAM_BOUNDARY = "boundary";
-    /**
-     * The name of the <code>charset</code> parameter.
-     */
-    public static final String PARAM_CHARSET = "charset";
-
-    private String mimeType = "";
-    private Map<String, String> parameters = null;
-    private ParseException parseException;
-
-    protected ContentTypeField(String name, String body, String raw, String mimeType, Map<String, String> parameters, ParseException parseException) {
-        super(name, body, raw);
-        this.mimeType = mimeType;
-        this.parameters = parameters;
-        this.parseException = parseException;
-    }
-
-    /**
-     * Gets the exception that was raised during parsing of
-     * the field value, if any; otherwise, null.
-     */
-    public ParseException getParseException() {
-        return parseException;
-    }
-
-    /**
-     * Gets the MIME type defined in this Content-Type field.
-     *
-     * @return the MIME type or an empty string if not set.
-     */
-    public String getMimeType() {
-        return mimeType;
-    }
-
-    /**
-     * Gets the MIME type defined in the child's
-     * Content-Type field or derives a MIME type from the parent
-     * if child is <code>null</code> or hasn't got a MIME type value set.
-     * If child's MIME type is multipart but no boundary
-     * has been set the MIME type of child will be derived from
-     * the parent.
-     *
-     * @param child the child.
-     * @param parent the parent.
-     * @return the MIME type.
-     */
-    public static String getMimeType(ContentTypeField child,
-                                     ContentTypeField parent) {
-
-        if (child == null || child.getMimeType().length() == 0
-                || child.isMultipart() && child.getBoundary() == null) {
-
-            if (parent != null && parent.isMimeType(TYPE_MULTIPART_DIGEST)) {
-                return TYPE_MESSAGE_RFC822;
-            } else {
-                return TYPE_TEXT_PLAIN;
-            }
-        }
-
-        return child.getMimeType();
-    }
-
-    /**
-     * Gets the value of a parameter. Parameter names are case-insensitive.
-     *
-     * @param name the name of the parameter to get.
-     * @return the parameter value or <code>null</code> if not set.
-     */
-    public String getParameter(String name) {
-        return parameters != null
-                    ? parameters.get(name.toLowerCase())
-                    : null;
-    }
-
-    /**
-     * Gets all parameters.
-     *
-     * @return the parameters.
-     */
-    public Map<String, String> getParameters() {
-        if (parameters != null) {
-            return Collections.unmodifiableMap(parameters);
-        }
-        return Collections.emptyMap();
-    }
-
-    /**
-     * Gets the value of the <code>boundary</code> parameter if set.
-     *
-     * @return the <code>boundary</code> parameter value or <code>null</code>
-     *             if not set.
-     */
-    public String getBoundary() {
-        return getParameter(PARAM_BOUNDARY);
-    }
-
-    /**
-     * Gets the value of the <code>charset</code> parameter if set.
-     *
-     * @return the <code>charset</code> parameter value or <code>null</code>
-     *         if not set.
-     */
-    public String getCharset() {
-        return getParameter(PARAM_CHARSET);
-    }
-
-    /**
-     * Gets the value of the <code>charset</code> parameter if set for the
-     * given field. Returns the default <code>us-ascii</code> if not set or if
-     * <code>f</code> is <code>null</code>.
-     *
-     * @return the <code>charset</code> parameter value.
-     */
-    public static String getCharset(ContentTypeField f) {
-        if (f != null) {
-            if (f.getCharset() != null && f.getCharset().length() > 0) {
-                return f.getCharset();
-            }
-        }
-        return "us-ascii";
-    }
-
-    /**
-     * Determines if the MIME type of this field matches the given one.
-     *
-     * @param mimeType the MIME type to match against.
-     * @return <code>true</code> if the MIME type of this field matches,
-     *         <code>false</code> otherwise.
-     */
-    public boolean isMimeType(String mimeType) {
-        return this.mimeType.equalsIgnoreCase(mimeType);
-    }
-
-    /**
-     * Determines if the MIME type of this field is <code>multipart/*</code>.
-     *
-     * @return <code>true</code> if this field is has a <code>multipart/*</code>
-     *         MIME type, <code>false</code> otherwise.
-     */
-    public boolean isMultipart() {
-        return mimeType.startsWith(TYPE_MULTIPART_PREFIX);
-    }
-
-    public static class Parser implements FieldParser {
-        private static Log log = LogFactory.getLog(Parser.class);
-
-        public Field parse(final String name, final String body, final String raw) {
-            ParseException parseException = null;
-            String mimeType = "";
-            Map<String, String> parameters = null;
-
-            ContentTypeParser parser = new ContentTypeParser(new StringReader(body));
-            try {
-                parser.parseAll();
-            }
-            catch (ParseException e) {
-                if (log.isDebugEnabled()) {
-                    log.debug("Parsing value '" + body + "': "+ e.getMessage());
-                }
-                parseException = e;
-            }
-            catch (TokenMgrError e) {
-                if (log.isDebugEnabled()) {
-                    log.debug("Parsing value '" + body + "': "+ e.getMessage());
-                }
-                parseException = new ParseException(e.getMessage());
-            }
-
-            try {
-                final String type = parser.getType();
-                final String subType = parser.getSubType();
-
-                if (type != null && subType != null) {
-                    mimeType = (type + "/" + parser.getSubType()).toLowerCase();
-
-                    ArrayList<String> paramNames = parser.getParamNames();
-                    ArrayList<String> paramValues = parser.getParamValues();
-
-                    if (paramNames != null && paramValues != null) {
-                        for (int i = 0; i < paramNames.size() && i < paramValues.size(); i++) {
-                            if (parameters == null)
-                                parameters = new HashMap<String, String>((int)(paramNames.size() * 1.3 + 1));
-                            String paramName = paramNames.get(i).toLowerCase();
-                            String paramValue = paramValues.get(i);
-                            parameters.put(paramName, paramValue);
-                        }
-                    }
-                }
-            }
-            catch (NullPointerException npe) {
-            }
-            return new ContentTypeField(name, body, raw, mimeType, parameters, parseException);
-        }
-    }
-}
diff --git a/src/org/apache/james/mime4j/field/DateTimeField.java b/src/org/apache/james/mime4j/field/DateTimeField.java
deleted file mode 100644
index 5215534..0000000
--- a/src/org/apache/james/mime4j/field/DateTimeField.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one   *
- * or more contributor license agreements.  See the NOTICE file *
- * distributed with this work for additional information        *
- * regarding copyright ownership.  The ASF licenses this file   *
- * to you 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 org.apache.james.mime4j.field;
-
-//BEGIN android-changed: Stubbing out logging
-
-import com.android.phone.common.mail.utils.LogUtils;
-
-import org.apache.james.mime4j.Log;
-import org.apache.james.mime4j.LogFactory;
-//END
-import org.apache.james.mime4j.field.datetime.DateTime;
-import org.apache.james.mime4j.field.datetime.parser.ParseException;
-
-import java.util.Date;
-
-public class DateTimeField extends Field {
-    private Date date;
-    private ParseException parseException;
-
-    protected DateTimeField(String name, String body, String raw, Date date, ParseException parseException) {
-        super(name, body, raw);
-        this.date = date;
-        this.parseException = parseException;
-    }
-
-    public Date getDate() {
-        return date;
-    }
-
-    public ParseException getParseException() {
-        return parseException;
-    }
-
-    public static class Parser implements FieldParser {
-        private static Log log = LogFactory.getLog(Parser.class);
-
-        public Field parse(final String name, String body, final String raw) {
-            Date date = null;
-            ParseException parseException = null;
-            //BEGIN android-changed
-            body = LogUtils.cleanUpMimeDate(body);
-            //END android-changed
-            try {
-                date = DateTime.parse(body).getDate();
-            }
-            catch (ParseException e) {
-                if (log.isDebugEnabled()) {
-                    log.debug("Parsing value '" + body + "': "+ e.getMessage());
-                }
-                parseException = e;
-            }
-            return new DateTimeField(name, body, raw, date, parseException);
-        }
-    }
-}
diff --git a/src/org/apache/james/mime4j/field/DefaultFieldParser.java b/src/org/apache/james/mime4j/field/DefaultFieldParser.java
deleted file mode 100644
index 3695afe..0000000
--- a/src/org/apache/james/mime4j/field/DefaultFieldParser.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- *  Copyright 2006 the mime4j 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 org.apache.james.mime4j.field;
-
-public class DefaultFieldParser extends DelegatingFieldParser {
-    
-    public DefaultFieldParser() {
-        setFieldParser(Field.CONTENT_TRANSFER_ENCODING, new ContentTransferEncodingField.Parser());
-        setFieldParser(Field.CONTENT_TYPE, new ContentTypeField.Parser());
-        
-        final DateTimeField.Parser dateTimeParser = new DateTimeField.Parser();
-        setFieldParser(Field.DATE, dateTimeParser);
-        setFieldParser(Field.RESENT_DATE, dateTimeParser);
-        
-        final MailboxListField.Parser mailboxListParser = new MailboxListField.Parser();
-        setFieldParser(Field.FROM, mailboxListParser);
-        setFieldParser(Field.RESENT_FROM, mailboxListParser);
-        
-        final MailboxField.Parser mailboxParser = new MailboxField.Parser();
-        setFieldParser(Field.SENDER, mailboxParser);
-        setFieldParser(Field.RESENT_SENDER, mailboxParser);
-        
-        final AddressListField.Parser addressListParser = new AddressListField.Parser();
-        setFieldParser(Field.TO, addressListParser);
-        setFieldParser(Field.RESENT_TO, addressListParser);
-        setFieldParser(Field.CC, addressListParser);
-        setFieldParser(Field.RESENT_CC, addressListParser);
-        setFieldParser(Field.BCC, addressListParser);
-        setFieldParser(Field.RESENT_BCC, addressListParser);
-        setFieldParser(Field.REPLY_TO, addressListParser);
-    }
-}
diff --git a/src/org/apache/james/mime4j/field/DelegatingFieldParser.java b/src/org/apache/james/mime4j/field/DelegatingFieldParser.java
deleted file mode 100644
index 32b69ec..0000000
--- a/src/org/apache/james/mime4j/field/DelegatingFieldParser.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- *  Copyright 2006 the mime4j 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 org.apache.james.mime4j.field;
-
-import java.util.HashMap;
-import java.util.Map;
-
-public class DelegatingFieldParser implements FieldParser {
-
-    private Map<String, FieldParser> parsers = new HashMap<String, FieldParser>();
-    private FieldParser defaultParser = new UnstructuredField.Parser();
-
-    /**
-     * Sets the parser used for the field named <code>name</code>.
-     * @param name the name of the field
-     * @param parser the parser for fields named <code>name</code>
-     */
-    public void setFieldParser(final String name, final FieldParser parser) {
-        parsers.put(name.toLowerCase(), parser);
-    }
-
-    public FieldParser getParser(final String name) {
-        final FieldParser field = parsers.get(name.toLowerCase());
-        if(field==null) {
-            return defaultParser;
-        }
-        return field;
-    }
-
-    public Field parse(final String name, final String body, final String raw) {
-        final FieldParser parser = getParser(name);
-        return parser.parse(name, body, raw);
-    }
-}
diff --git a/src/org/apache/james/mime4j/field/Field.java b/src/org/apache/james/mime4j/field/Field.java
deleted file mode 100644
index 4dea5c5..0000000
--- a/src/org/apache/james/mime4j/field/Field.java
+++ /dev/null
@@ -1,192 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one   *
- * or more contributor license agreements.  See the NOTICE file *
- * distributed with this work for additional information        *
- * regarding copyright ownership.  The ASF licenses this file   *
- * to you 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 org.apache.james.mime4j.field;
-
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * The base class of all field classes.
- *
- * 
- * @version $Id: Field.java,v 1.6 2004/10/25 07:26:46 ntherning Exp $
- */
-public abstract class Field {
-    public static final String SENDER = "Sender";
-    public static final String FROM = "From";
-    public static final String TO = "To";
-    public static final String CC = "Cc";
-    public static final String BCC = "Bcc";
-    public static final String REPLY_TO = "Reply-To";
-    public static final String RESENT_SENDER = "Resent-Sender";
-    public static final String RESENT_FROM = "Resent-From";
-    public static final String RESENT_TO = "Resent-To";
-    public static final String RESENT_CC = "Resent-Cc";
-    public static final String RESENT_BCC = "Resent-Bcc";
-
-    public static final String DATE = "Date";
-    public static final String RESENT_DATE = "Resent-Date";
-
-    public static final String SUBJECT = "Subject";
-    public static final String CONTENT_TYPE = "Content-Type";
-    public static final String CONTENT_TRANSFER_ENCODING = 
-                                        "Content-Transfer-Encoding";
-    
-    private static final String FIELD_NAME_PATTERN = 
-        "^([\\x21-\\x39\\x3b-\\x7e]+)[ \t]*:";
-    private static final Pattern fieldNamePattern = 
-        Pattern.compile(FIELD_NAME_PATTERN);
-        
-    private static final DefaultFieldParser parser = new DefaultFieldParser();
-    
-    private final String name;
-    private final String body;
-    private final String raw;
-    
-    protected Field(final String name, final String body, final String raw) {
-        this.name = name;
-        this.body = body;
-        this.raw = raw;
-    }
-    
-    /**
-     * Parses the given string and returns an instance of the 
-     * <code>Field</code> class. The type of the class returned depends on
-     * the field name:
-     * <table>
-     *      <tr>
-     *          <td><em>Field name</em></td><td><em>Class returned</em></td>
-     *          <td>Content-Type</td><td>org.apache.james.mime4j.field.ContentTypeField</td>
-     *          <td>other</td><td>org.apache.james.mime4j.field.UnstructuredField</td>
-     *      </tr>
-     * </table>
-     * 
-     * @param s the string to parse.
-     * @return a <code>Field</code> instance.
-     * @throws IllegalArgumentException on parse errors.
-     */
-    public static Field parse(final String raw) {
-        
-        /*
-         * Unfold the field.
-         */
-        final String unfolded = raw.replaceAll("\r|\n", "");
-        
-        /*
-         * Split into name and value.
-         */
-        final Matcher fieldMatcher = fieldNamePattern.matcher(unfolded);
-        if (!fieldMatcher.find()) {
-            throw new IllegalArgumentException("Invalid field in string");
-        }
-        final String name = fieldMatcher.group(1);
-        
-        String body = unfolded.substring(fieldMatcher.end());
-        if (body.length() > 0 && body.charAt(0) == ' ') {
-            body = body.substring(1);
-        }
-        
-        return parser.parse(name, body, raw);
-    }
-    
-    /**
-     * Gets the default parser used to parse fields.
-     * @return the default field parser
-     */
-    public static DefaultFieldParser getParser() {
-        return parser;
-    }
-    
-    /**
-     * Gets the name of the field (<code>Subject</code>, 
-     * <code>From</code>, etc).
-     * 
-     * @return the field name.
-     */
-    public String getName() {
-        return name;
-    }
-    
-    /**
-     * Gets the original raw field string.
-     * 
-     * @return the original raw field string.
-     */
-    public String getRaw() {
-        return raw;
-    }
-    
-    /**
-     * Gets the unfolded, unparsed and possibly encoded (see RFC 2047) field 
-     * body string.
-     * 
-     * @return the unfolded unparsed field body string.
-     */
-    public String getBody() {
-        return body;
-    }
-    
-    /**
-     * Determines if this is a <code>Content-Type</code> field.
-     * 
-     * @return <code>true</code> if this is a <code>Content-Type</code> field,
-     *         <code>false</code> otherwise.
-     */
-    public boolean isContentType() {
-        return CONTENT_TYPE.equalsIgnoreCase(name);
-    }
-    
-    /**
-     * Determines if this is a <code>Subject</code> field.
-     * 
-     * @return <code>true</code> if this is a <code>Subject</code> field,
-     *         <code>false</code> otherwise.
-     */
-    public boolean isSubject() {
-        return SUBJECT.equalsIgnoreCase(name);
-    }
-    
-    /**
-     * Determines if this is a <code>From</code> field.
-     * 
-     * @return <code>true</code> if this is a <code>From</code> field,
-     *         <code>false</code> otherwise.
-     */
-    public boolean isFrom() {
-        return FROM.equalsIgnoreCase(name);
-    }
-    
-    /**
-     * Determines if this is a <code>To</code> field.
-     * 
-     * @return <code>true</code> if this is a <code>To</code> field,
-     *         <code>false</code> otherwise.
-     */
-    public boolean isTo() {
-        return TO.equalsIgnoreCase(name);
-    }
-    
-    /**
-     * @see #getRaw()
-     */
-    public String toString() {
-        return raw;
-    }
-}
diff --git a/src/org/apache/james/mime4j/field/FieldParser.java b/src/org/apache/james/mime4j/field/FieldParser.java
deleted file mode 100644
index 78aaf13..0000000
--- a/src/org/apache/james/mime4j/field/FieldParser.java
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- *  Copyright 2006 the mime4j 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 org.apache.james.mime4j.field;
-
-public interface FieldParser {
-    
-    Field parse(final String name, final String body, final String raw);
-}
diff --git a/src/org/apache/james/mime4j/field/MailboxField.java b/src/org/apache/james/mime4j/field/MailboxField.java
deleted file mode 100644
index f159800..0000000
--- a/src/org/apache/james/mime4j/field/MailboxField.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one   *
- * or more contributor license agreements.  See the NOTICE file *
- * distributed with this work for additional information        *
- * regarding copyright ownership.  The ASF licenses this file   *
- * to you 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 org.apache.james.mime4j.field;
-
-//BEGIN android-changed: Stubbing out logging
-import org.apache.james.mime4j.Log;
-import org.apache.james.mime4j.LogFactory;
-//END android-changed
-import org.apache.james.mime4j.field.address.AddressList;
-import org.apache.james.mime4j.field.address.Mailbox;
-import org.apache.james.mime4j.field.address.MailboxList;
-import org.apache.james.mime4j.field.address.parser.ParseException;
-
-public class MailboxField extends Field {
-    private final Mailbox mailbox;
-    private final ParseException parseException;
-
-    protected MailboxField(final String name, final String body, final String raw, final Mailbox mailbox, final ParseException parseException) {
-        super(name, body, raw);
-        this.mailbox = mailbox;
-        this.parseException = parseException;
-    }
-
-    public Mailbox getMailbox() {
-        return mailbox;
-    }
-
-    public ParseException getParseException() {
-        return parseException;
-    }
-    
-    public static class Parser implements FieldParser {
-        private static Log log = LogFactory.getLog(Parser.class);
-
-        public Field parse(final String name, final String body, final String raw) {
-            Mailbox mailbox = null;
-            ParseException parseException = null;
-            try {
-                MailboxList mailboxList = AddressList.parse(body).flatten();
-                if (mailboxList.size() > 0) {
-                    mailbox = mailboxList.get(0);
-                }
-            }
-            catch (ParseException e) {
-                if (log.isDebugEnabled()) {
-                    log.debug("Parsing value '" + body + "': "+ e.getMessage());
-                }
-                parseException = e;
-            }
-            return new MailboxField(name, body, raw, mailbox, parseException);
-        }
-    }
-}
diff --git a/src/org/apache/james/mime4j/field/MailboxListField.java b/src/org/apache/james/mime4j/field/MailboxListField.java
deleted file mode 100644
index 23378d4..0000000
--- a/src/org/apache/james/mime4j/field/MailboxListField.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one   *
- * or more contributor license agreements.  See the NOTICE file *
- * distributed with this work for additional information        *
- * regarding copyright ownership.  The ASF licenses this file   *
- * to you 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 org.apache.james.mime4j.field;
-
-//BEGIN android-changed: Stubbing out logging
-import org.apache.james.mime4j.Log;
-import org.apache.james.mime4j.LogFactory;
-//END android-changed
-import org.apache.james.mime4j.field.address.AddressList;
-import org.apache.james.mime4j.field.address.MailboxList;
-import org.apache.james.mime4j.field.address.parser.ParseException;
-
-public class MailboxListField extends Field {
-    
-    private MailboxList mailboxList;
-    private ParseException parseException;
-
-    protected MailboxListField(final String name, final String body, final String raw, final MailboxList mailboxList, final ParseException parseException) {
-        super(name, body, raw);
-        this.mailboxList = mailboxList;
-        this.parseException = parseException;
-    }
-
-    public MailboxList getMailboxList() {
-        return mailboxList;
-    }
-
-    public ParseException getParseException() {
-        return parseException;
-    }
-    
-    public static class Parser implements FieldParser {
-        private static Log log = LogFactory.getLog(Parser.class);
-
-        public Field parse(final String name, final String body, final String raw) {
-            MailboxList mailboxList = null;
-            ParseException parseException = null;
-            try {
-                mailboxList = AddressList.parse(body).flatten();
-            }
-            catch (ParseException e) {
-                if (log.isDebugEnabled()) {
-                    log.debug("Parsing value '" + body + "': "+ e.getMessage());
-                }
-                parseException = e;
-            }
-            return new MailboxListField(name, body, raw, mailboxList, parseException);
-        }
-    }
-}
diff --git a/src/org/apache/james/mime4j/field/UnstructuredField.java b/src/org/apache/james/mime4j/field/UnstructuredField.java
deleted file mode 100644
index 6084e44..0000000
--- a/src/org/apache/james/mime4j/field/UnstructuredField.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one   *
- * or more contributor license agreements.  See the NOTICE file *
- * distributed with this work for additional information        *
- * regarding copyright ownership.  The ASF licenses this file   *
- * to you 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 org.apache.james.mime4j.field;
-
-import org.apache.james.mime4j.decoder.DecoderUtil;
-
-
-/**
- * Simple unstructured field such as <code>Subject</code>.
- *
- * 
- * @version $Id: UnstructuredField.java,v 1.3 2004/10/25 07:26:46 ntherning Exp $
- */
-public class UnstructuredField extends Field {
-    private String value;
-    
-    protected UnstructuredField(String name, String body, String raw, String value) {
-        super(name, body, raw);
-        this.value = value;
-    }
-
-    public String getValue() {
-        return value;
-    }
-
-    public static class Parser implements FieldParser {
-        public Field parse(final String name, final String body, final String raw) {
-            final String value = DecoderUtil.decodeEncodedWords(body);
-            return new UnstructuredField(name, body, raw, value);
-        }
-    }
-}
diff --git a/src/org/apache/james/mime4j/field/address/Address.java b/src/org/apache/james/mime4j/field/address/Address.java
deleted file mode 100644
index 3e24e91..0000000
--- a/src/org/apache/james/mime4j/field/address/Address.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one   *
- * or more contributor license agreements.  See the NOTICE file *
- * distributed with this work for additional information        *
- * regarding copyright ownership.  The ASF licenses this file   *
- * to you 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 org.apache.james.mime4j.field.address;
-
-import java.util.ArrayList;
-
-/**
- * The abstract base for classes that represent RFC2822 addresses.
- * This includes groups and mailboxes.
- *
- * Currently, no public methods are introduced on this class.
- *
- *
- */
-public abstract class Address {
-
-	/**
-	 * Adds any mailboxes represented by this address
-	 * into the given ArrayList. Note that this method
-	 * has default (package) access, so a doAddMailboxesTo
-	 * method is needed to allow the behavior to be
-	 * overridden by subclasses.
-	 */
-	final void addMailboxesTo(ArrayList<Address> results) {
-		doAddMailboxesTo(results);
-	}
-
-	/**
-	 * Adds any mailboxes represented by this address
-	 * into the given ArrayList. Must be overridden by
-	 * concrete subclasses.
-	 */
-	protected abstract void doAddMailboxesTo(ArrayList<Address> results);
-
-}
diff --git a/src/org/apache/james/mime4j/field/address/AddressList.java b/src/org/apache/james/mime4j/field/address/AddressList.java
deleted file mode 100644
index 1829e79..0000000
--- a/src/org/apache/james/mime4j/field/address/AddressList.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one   *
- * or more contributor license agreements.  See the NOTICE file *
- * distributed with this work for additional information        *
- * regarding copyright ownership.  The ASF licenses this file   *
- * to you 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 org.apache.james.mime4j.field.address;
-
-import org.apache.james.mime4j.field.address.parser.AddressListParser;
-import org.apache.james.mime4j.field.address.parser.ParseException;
-
-import java.io.StringReader;
-import java.util.ArrayList;
-
-/**
- * An immutable, random-access list of Address objects.
- *
- *
- */
-public class AddressList {
-
-	private ArrayList<Address> addresses;
-
-	/**
-	 * @param addresses An ArrayList that contains only Address objects.
-	 * @param dontCopy true iff it is not possible for the addresses ArrayList to be modified by someone else.
-	 */
-	public AddressList(ArrayList<Address> addresses, boolean dontCopy) {
-		if (addresses != null)
-			this.addresses = (dontCopy ? addresses : new ArrayList<Address>(addresses));
-		else
-			this.addresses = new ArrayList<Address>(0);
-	}
-
-	/**
-	 * The number of elements in this list.
-	 */
-	public int size() {
-		return addresses.size();
-	}
-
-	/**
-	 * Gets an address.
-	 */
-	public Address get(int index) {
-		if (0 > index || size() <= index)
-			throw new IndexOutOfBoundsException();
-		return addresses.get(index);
-	}
-
-	/**
-	 * Returns a flat list of all mailboxes represented
-	 * in this address list. Use this if you don't care
-	 * about grouping.
-	 */
-	public MailboxList flatten() {
-		// in the common case, all addresses are mailboxes
-		boolean groupDetected = false;
-		for (int i = 0; i < size(); i++) {
-			if (!(get(i) instanceof Mailbox)) {
-				groupDetected = true;
-				break;
-			}
-		}
-
-		if (!groupDetected)
-			return new MailboxList(addresses, true);
-
-		ArrayList<Address> results = new ArrayList<Address>();
-		for (int i = 0; i < size(); i++) {
-			Address addr = get(i);
-			addr.addMailboxesTo(results);
-		}
-
-		// copy-on-construct this time, because subclasses
-		// could have held onto a reference to the results
-		return new MailboxList(results, false);
-	}
-
-	/**
-	 * Dumps a representation of this address list to
-	 * stdout, for debugging purposes.
-	 */
-	public void print() {
-		for (int i = 0; i < size(); i++) {
-			Address addr = get(i);
-			System.out.println(addr.toString());
-		}
-	}
-
-	/**
-	 * Parse the address list string, such as the value
-	 * of a From, To, Cc, Bcc, Sender, or Reply-To
-	 * header.
-	 *
-	 * The string MUST be unfolded already.
-	 */
-	public static AddressList parse(String rawAddressList) throws ParseException {
-		AddressListParser parser = new AddressListParser(new StringReader(rawAddressList));
-		return Builder.getInstance().buildAddressList(parser.parse());
-	}
-
-	/**
-	 * Test console.
-	 */
-	public static void main(String[] args) throws Exception {
-		java.io.BufferedReader reader = new java.io.BufferedReader(new java.io.InputStreamReader(System.in));
-		while (true) {
-			try {
-				System.out.print("> ");
-				String line = reader.readLine();
-				if (line.length() == 0 || line.toLowerCase().equals("exit") || line.toLowerCase().equals("quit")) {
-					System.out.println("Goodbye.");
-					return;
-				}
-				AddressList list = parse(line);
-				list.print();
-			}
-			catch(Exception e) {
-				e.printStackTrace();
-				Thread.sleep(300);
-			}
-		}
-	}
-}
diff --git a/src/org/apache/james/mime4j/field/address/Builder.java b/src/org/apache/james/mime4j/field/address/Builder.java
deleted file mode 100644
index 3bcd15b..0000000
--- a/src/org/apache/james/mime4j/field/address/Builder.java
+++ /dev/null
@@ -1,243 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one   *
- * or more contributor license agreements.  See the NOTICE file *
- * distributed with this work for additional information        *
- * regarding copyright ownership.  The ASF licenses this file   *
- * to you 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 org.apache.james.mime4j.field.address;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-
-import org.apache.james.mime4j.decoder.DecoderUtil;
-import org.apache.james.mime4j.field.address.parser.ASTaddr_spec;
-import org.apache.james.mime4j.field.address.parser.ASTaddress;
-import org.apache.james.mime4j.field.address.parser.ASTaddress_list;
-import org.apache.james.mime4j.field.address.parser.ASTangle_addr;
-import org.apache.james.mime4j.field.address.parser.ASTdomain;
-import org.apache.james.mime4j.field.address.parser.ASTgroup_body;
-import org.apache.james.mime4j.field.address.parser.ASTlocal_part;
-import org.apache.james.mime4j.field.address.parser.ASTmailbox;
-import org.apache.james.mime4j.field.address.parser.ASTname_addr;
-import org.apache.james.mime4j.field.address.parser.ASTphrase;
-import org.apache.james.mime4j.field.address.parser.ASTroute;
-import org.apache.james.mime4j.field.address.parser.Node;
-import org.apache.james.mime4j.field.address.parser.SimpleNode;
-import org.apache.james.mime4j.field.address.parser.Token;
-
-/**
- * Transforms the JJTree-generated abstract syntax tree
- * into a graph of org.apache.james.mime4j.field.address objects.
- *
- *
- */
-class Builder {
-
-	private static Builder singleton = new Builder();
-
-	public static Builder getInstance() {
-		return singleton;
-	}
-
-
-
-	public AddressList buildAddressList(ASTaddress_list node) {
-		ArrayList<Address> list = new ArrayList<Address>();
-		for (int i = 0; i < node.jjtGetNumChildren(); i++) {
-			ASTaddress childNode = (ASTaddress) node.jjtGetChild(i);
-			Address address = buildAddress(childNode);
-			list.add(address);
-		}
-		return new AddressList(list, true);
-	}
-
-	private Address buildAddress(ASTaddress node) {
-		ChildNodeIterator it = new ChildNodeIterator(node);
-		Node n = it.nextNode();
-		if (n instanceof ASTaddr_spec) {
-			return buildAddrSpec((ASTaddr_spec)n);
-		}
-		else if (n instanceof ASTangle_addr) {
-			return buildAngleAddr((ASTangle_addr)n);
-		}
-		else if (n instanceof ASTphrase) {
-			String name = buildString((ASTphrase)n, false);
-			Node n2 = it.nextNode();
-			if (n2 instanceof ASTgroup_body) {
-				return new Group(name, buildGroupBody((ASTgroup_body)n2));
-			}
-			else if (n2 instanceof ASTangle_addr) {
-                name = DecoderUtil.decodeEncodedWords(name);
-				return new NamedMailbox(name, buildAngleAddr((ASTangle_addr)n2));
-			}
-			else {
-				throw new IllegalStateException();
-			}
-		}
-		else {
-			throw new IllegalStateException();
-		}
-	}
-
-
-
-	private MailboxList buildGroupBody(ASTgroup_body node) {
-		ArrayList<Address> results = new ArrayList<Address>();
-		ChildNodeIterator it = new ChildNodeIterator(node);
-		while (it.hasNext()) {
-			Node n = it.nextNode();
-			if (n instanceof ASTmailbox)
-				results.add(buildMailbox((ASTmailbox)n));
-			else
-				throw new IllegalStateException();
-		}
-		return new MailboxList(results, true);
-	}
-
-	private Mailbox buildMailbox(ASTmailbox node) {
-		ChildNodeIterator it = new ChildNodeIterator(node);
-		Node n = it.nextNode();
-		if (n instanceof ASTaddr_spec) {
-			return buildAddrSpec((ASTaddr_spec)n);
-		}
-		else if (n instanceof ASTangle_addr) {
-			return buildAngleAddr((ASTangle_addr)n);
-		}
-		else if (n instanceof ASTname_addr) {
-			return buildNameAddr((ASTname_addr)n);
-		}
-		else {
-			throw new IllegalStateException();
-		}
-	}
-
-	private NamedMailbox buildNameAddr(ASTname_addr node) {
-		ChildNodeIterator it = new ChildNodeIterator(node);
-		Node n = it.nextNode();
-		String name;
-		if (n instanceof ASTphrase) {
-			name = buildString((ASTphrase)n, false);
-		}
-		else {
-			throw new IllegalStateException();
-		}
-
-		n = it.nextNode();
-		if (n instanceof ASTangle_addr) {
-            name = DecoderUtil.decodeEncodedWords(name);
-			return new NamedMailbox(name, buildAngleAddr((ASTangle_addr) n));
-		}
-		else {
-			throw new IllegalStateException();
-		}
-	}
-
-	private Mailbox buildAngleAddr(ASTangle_addr node) {
-		ChildNodeIterator it = new ChildNodeIterator(node);
-		DomainList route = null;
-		Node n = it.nextNode();
-		if (n instanceof ASTroute) {
-			route = buildRoute((ASTroute)n);
-			n = it.nextNode();
-		}
-		else if (n instanceof ASTaddr_spec)
-			; // do nothing
-		else
-			throw new IllegalStateException();
-
-		if (n instanceof ASTaddr_spec)
-			return buildAddrSpec(route, (ASTaddr_spec)n);
-		else
-			throw new IllegalStateException();
-	}
-
-	private DomainList buildRoute(ASTroute node) {
-		ArrayList<String> results = new ArrayList<String>(node.jjtGetNumChildren());
-		ChildNodeIterator it = new ChildNodeIterator(node);
-		while (it.hasNext()) {
-			Node n = it.nextNode();
-			if (n instanceof ASTdomain)
-				results.add(buildString((ASTdomain)n, true));
-			else
-				throw new IllegalStateException();
-		}
-		return new DomainList(results, true);
-	}
-
-	private Mailbox buildAddrSpec(ASTaddr_spec node) {
-		return buildAddrSpec(null, node);
-	}
-	private Mailbox buildAddrSpec(DomainList route, ASTaddr_spec node) {
-		ChildNodeIterator it = new ChildNodeIterator(node);
-		String localPart = buildString((ASTlocal_part)it.nextNode(), true);
-		String domain = buildString((ASTdomain)it.nextNode(), true);
-		return new Mailbox(route, localPart, domain);
-	}
-
-
-	private String buildString(SimpleNode node, boolean stripSpaces) {
-		Token head = node.firstToken;
-		Token tail = node.lastToken;
-		StringBuffer out = new StringBuffer();
-
-		while (head != tail) {
-			out.append(head.image);
-			head = head.next;
-			if (!stripSpaces)
-				addSpecials(out, head.specialToken);
-		}
-		out.append(tail.image);
-
-		return out.toString();
-	}
-
-	private void addSpecials(StringBuffer out, Token specialToken) {
-		if (specialToken != null) {
-			addSpecials(out, specialToken.specialToken);
-			out.append(specialToken.image);
-		}
-	}
-
-	private static class ChildNodeIterator implements Iterator<Node> {
-
-		private SimpleNode simpleNode;
-		private int index;
-		private int len;
-
-		public ChildNodeIterator(SimpleNode simpleNode) {
-			this.simpleNode = simpleNode;
-			this.len = simpleNode.jjtGetNumChildren();
-			this.index = 0;
-		}
-
-		public void remove() {
-			throw new UnsupportedOperationException();
-		}
-
-		public boolean hasNext() {
-			return index < len;
-		}
-
-		public Node next() {
-			return nextNode();
-		}
-
-		public Node nextNode() {
-			return simpleNode.jjtGetChild(index++);
-		}
-
-	}
-}
diff --git a/src/org/apache/james/mime4j/field/address/DomainList.java b/src/org/apache/james/mime4j/field/address/DomainList.java
deleted file mode 100644
index 49b0f3b..0000000
--- a/src/org/apache/james/mime4j/field/address/DomainList.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one   *
- * or more contributor license agreements.  See the NOTICE file *
- * distributed with this work for additional information        *
- * regarding copyright ownership.  The ASF licenses this file   *
- * to you 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 org.apache.james.mime4j.field.address;
-
-import java.util.ArrayList;
-
-/**
- * An immutable, random-access list of Strings (that
- * are supposedly domain names or domain literals).
- *
- *
- */
-public class DomainList {
-	private ArrayList<String> domains;
-
-	/**
-	 * @param domains An ArrayList that contains only String objects.
-	 * @param dontCopy true iff it is not possible for the domains ArrayList to be modified by someone else.
-	 */
-	public DomainList(ArrayList<String> domains, boolean dontCopy) {
-		if (domains != null)
-			this.domains = (dontCopy ? domains : new ArrayList<String>(domains));
-		else
-			this.domains = new ArrayList<String>(0);
-	}
-
-	/**
-	 * The number of elements in this list.
-	 */
-	public int size() {
-		return domains.size();
-	}
-
-	/**
-	 * Gets the domain name or domain literal at the
-	 * specified index.
-	 * @throws IndexOutOfBoundsException If index is &lt; 0 or &gt;= size().
-	 */
-	public String get(int index) {
-		if (0 > index || size() <= index)
-			throw new IndexOutOfBoundsException();
-		return domains.get(index);
-	}
-
-	/**
-	 * Returns the list of domains formatted as a route
-	 * string (not including the trailing ':').
-	 */
-	public String toRouteString() {
-		StringBuffer out = new StringBuffer();
-		for (int i = 0; i < domains.size(); i++) {
-			out.append("@");
-			out.append(get(i));
-			if (i + 1 < domains.size())
-				out.append(",");
-		}
-		return out.toString();
-	}
-}
diff --git a/src/org/apache/james/mime4j/field/address/Group.java b/src/org/apache/james/mime4j/field/address/Group.java
deleted file mode 100644
index c0ab7f7..0000000
--- a/src/org/apache/james/mime4j/field/address/Group.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one   *
- * or more contributor license agreements.  See the NOTICE file *
- * distributed with this work for additional information        *
- * regarding copyright ownership.  The ASF licenses this file   *
- * to you 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 org.apache.james.mime4j.field.address;
-
-import java.util.ArrayList;
-
-/**
- * A named group of zero or more mailboxes.
- *
- *
- */
-public class Group extends Address {
-	private String name;
-	private MailboxList mailboxList;
-
-	/**
-	 * @param name The group name.
-	 * @param mailboxes The mailboxes in this group.
-	 */
-	public Group(String name, MailboxList mailboxes) {
-		this.name = name;
-		this.mailboxList = mailboxes;
-	}
-
-	/**
-	 * Returns the group name.
-	 */
-	public String getName() {
-		return name;
-	}
-
-	/**
-	 * Returns the mailboxes in this group.
-	 */
-	public MailboxList getMailboxes() {
-		return mailboxList;
-	}
-
-	@Override
-	public String toString() {
-		StringBuffer buf = new StringBuffer();
-		buf.append(name);
-		buf.append(":");
-		for (int i = 0; i < mailboxList.size(); i++) {
-			buf.append(mailboxList.get(i).toString());
-			if (i + 1 < mailboxList.size())
-				buf.append(",");
-		}
-		buf.append(";");
-		return buf.toString();
-	}
-
-	@Override
-	protected void doAddMailboxesTo(ArrayList<Address> results) {
-		for (int i = 0; i < mailboxList.size(); i++)
-			results.add(mailboxList.get(i));
-	}
-}
diff --git a/src/org/apache/james/mime4j/field/address/Mailbox.java b/src/org/apache/james/mime4j/field/address/Mailbox.java
deleted file mode 100644
index 25f2548..0000000
--- a/src/org/apache/james/mime4j/field/address/Mailbox.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one   *
- * or more contributor license agreements.  See the NOTICE file *
- * distributed with this work for additional information        *
- * regarding copyright ownership.  The ASF licenses this file   *
- * to you 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 org.apache.james.mime4j.field.address;
-
-import java.util.ArrayList;
-
-/**
- * Represents a single e-mail address.
- *
- *
- */
-public class Mailbox extends Address {
-	private DomainList route;
-	private String localPart;
-	private String domain;
-
-	/**
-	 * Creates a mailbox without a route. Routes are obsolete.
-	 * @param localPart The part of the e-mail address to the left of the "@".
-	 * @param domain The part of the e-mail address to the right of the "@".
-	 */
-	public Mailbox(String localPart, String domain) {
-		this(null, localPart, domain);
-	}
-
-	/**
-	 * Creates a mailbox with a route. Routes are obsolete.
-	 * @param route The zero or more domains that make up the route. Can be null.
-	 * @param localPart The part of the e-mail address to the left of the "@".
-	 * @param domain The part of the e-mail address to the right of the "@".
-	 */
-	public Mailbox(DomainList route, String localPart, String domain) {
-		this.route = route;
-		this.localPart = localPart;
-		this.domain = domain;
-	}
-
-	/**
-	 * Returns the route list.
-	 */
-	public DomainList getRoute() {
-		return route;
-	}
-
-	/**
-	 * Returns the left part of the e-mail address
-	 * (before "@").
-	 */
-	public String getLocalPart() {
-		return localPart;
-	}
-
-	/**
-	 * Returns the right part of the e-mail address
-	 * (after "@").
-	 */
-	public String getDomain() {
-		return domain;
-	}
-
-	/**
-	 * Formats the address as a string, not including
-	 * the route.
-	 *
-	 * @see #getAddressString(boolean)
-	 */
-	public String getAddressString() {
-		return getAddressString(false);
-	}
-
-	/**
-	 * Note that this value may not be usable
-	 * for transport purposes, only display purposes.
-	 *
-	 * For example, if the unparsed address was
-	 *
-	 *   <"Joe Cheng"@joecheng.com>
-	 *
-	 * this method would return
-	 *
-	 *   <Joe Cheng@joecheng.com>
-	 *
-	 * which is not valid for transport; the local part
-	 * would need to be re-quoted.
-	 *
-	 * @param includeRoute true if the route should be included if it exists.
-	 */
-	public String getAddressString(boolean includeRoute) {
-		return "<" + (!includeRoute || route == null ? "" : route.toRouteString() + ":")
-			+ localPart
-			+ (domain == null ? "" : "@")
-			+ domain + ">";
-	}
-
-	@Override
-	protected final void doAddMailboxesTo(ArrayList<Address> results) {
-		results.add(this);
-	}
-
-	@Override
-	public String toString() {
-		return getAddressString();
-	}
-}
diff --git a/src/org/apache/james/mime4j/field/address/MailboxList.java b/src/org/apache/james/mime4j/field/address/MailboxList.java
deleted file mode 100644
index 2c9efb3..0000000
--- a/src/org/apache/james/mime4j/field/address/MailboxList.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one   *
- * or more contributor license agreements.  See the NOTICE file *
- * distributed with this work for additional information        *
- * regarding copyright ownership.  The ASF licenses this file   *
- * to you 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 org.apache.james.mime4j.field.address;
-
-import java.util.ArrayList;
-
-/**
- * An immutable, random-access list of Mailbox objects.
- *
- *
- */
-public class MailboxList {
-
-	private ArrayList<Address> mailboxes;
-
-	/**
-	 * @param mailboxes An ArrayList that contains only Mailbox objects.
-	 * @param dontCopy true iff it is not possible for the mailboxes ArrayList to be modified by someone else.
-	 */
-	public MailboxList(ArrayList<Address> mailboxes, boolean dontCopy) {
-		if (mailboxes != null)
-			this.mailboxes = (dontCopy ? mailboxes : new ArrayList<Address>(mailboxes));
-		else
-			this.mailboxes = new ArrayList<Address>(0);
-	}
-
-	/**
-	 * The number of elements in this list.
-	 */
-	public int size() {
-		return mailboxes.size();
-	}
-
-	/**
-	 * Gets an address.
-	 */
-	public Mailbox get(int index) {
-		if (0 > index || size() <= index)
-			throw new IndexOutOfBoundsException();
-		return (Mailbox)mailboxes.get(index);
-	}
-
-	/**
-	 * Dumps a representation of this mailbox list to
-	 * stdout, for debugging purposes.
-	 */
-	public void print() {
-		for (int i = 0; i < size(); i++) {
-			Mailbox mailbox = get(i);
-			System.out.println(mailbox.toString());
-		}
-	}
-
-}
diff --git a/src/org/apache/james/mime4j/field/address/NamedMailbox.java b/src/org/apache/james/mime4j/field/address/NamedMailbox.java
deleted file mode 100644
index 4b83060..0000000
--- a/src/org/apache/james/mime4j/field/address/NamedMailbox.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one   *
- * or more contributor license agreements.  See the NOTICE file *
- * distributed with this work for additional information        *
- * regarding copyright ownership.  The ASF licenses this file   *
- * to you 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 org.apache.james.mime4j.field.address;
-
-/**
- * A Mailbox that has a name/description.
- *
- *
- */
-public class NamedMailbox extends Mailbox {
-	private String name;
-
-	/**
-	 * @see Mailbox#Mailbox(String, String)
-	 */
-	public NamedMailbox(String name, String localPart, String domain) {
-		super(localPart, domain);
-		this.name = name;
-	}
-
-	/**
-	 * @see Mailbox#Mailbox(DomainList, String, String)
-	 */
-	public NamedMailbox(String name, DomainList route, String localPart, String domain) {
-		super(route, localPart, domain);
-		this.name = name;
-	}
-
-	/**
-	 * Creates a named mailbox based on an unnamed mailbox.
-	 */
-	public NamedMailbox(String name, Mailbox baseMailbox) {
-		super(baseMailbox.getRoute(), baseMailbox.getLocalPart(), baseMailbox.getDomain());
-		this.name = name;
-	}
-
-	/**
-	 * Returns the name of the mailbox.
-	 */
-	public String getName() {
-		return this.name;
-	}
-
-	/**
-	 * Same features (or problems) as Mailbox.getAddressString(boolean),
-	 * only more so.
-	 *
-	 * @see Mailbox#getAddressString(boolean)
-	 */
-	@Override
-	public String getAddressString(boolean includeRoute) {
-		return (name == null ? "" : name + " ") + super.getAddressString(includeRoute);
-	}
-}
diff --git a/src/org/apache/james/mime4j/field/address/parser/ASTaddr_spec.java b/src/org/apache/james/mime4j/field/address/parser/ASTaddr_spec.java
deleted file mode 100644
index 4d56d00..0000000
--- a/src/org/apache/james/mime4j/field/address/parser/ASTaddr_spec.java
+++ /dev/null
@@ -1,19 +0,0 @@
-/* Generated By:JJTree: Do not edit this line. ASTaddr_spec.java */
-
-package org.apache.james.mime4j.field.address.parser;
-
-public class ASTaddr_spec extends SimpleNode {
-  public ASTaddr_spec(int id) {
-    super(id);
-  }
-
-  public ASTaddr_spec(AddressListParser p, int id) {
-    super(p, id);
-  }
-
-
-  /** Accept the visitor. **/
-  public Object jjtAccept(AddressListParserVisitor visitor, Object data) {
-    return visitor.visit(this, data);
-  }
-}
diff --git a/src/org/apache/james/mime4j/field/address/parser/ASTaddress.java b/src/org/apache/james/mime4j/field/address/parser/ASTaddress.java
deleted file mode 100644
index 47bdeda..0000000
--- a/src/org/apache/james/mime4j/field/address/parser/ASTaddress.java
+++ /dev/null
@@ -1,19 +0,0 @@
-/* Generated By:JJTree: Do not edit this line. ASTaddress.java */
-
-package org.apache.james.mime4j.field.address.parser;
-
-public class ASTaddress extends SimpleNode {
-  public ASTaddress(int id) {
-    super(id);
-  }
-
-  public ASTaddress(AddressListParser p, int id) {
-    super(p, id);
-  }
-
-
-  /** Accept the visitor. **/
-  public Object jjtAccept(AddressListParserVisitor visitor, Object data) {
-    return visitor.visit(this, data);
-  }
-}
diff --git a/src/org/apache/james/mime4j/field/address/parser/ASTaddress_list.java b/src/org/apache/james/mime4j/field/address/parser/ASTaddress_list.java
deleted file mode 100644
index 737840e..0000000
--- a/src/org/apache/james/mime4j/field/address/parser/ASTaddress_list.java
+++ /dev/null
@@ -1,19 +0,0 @@
-/* Generated By:JJTree: Do not edit this line. ASTaddress_list.java */
-
-package org.apache.james.mime4j.field.address.parser;
-
-public class ASTaddress_list extends SimpleNode {
-  public ASTaddress_list(int id) {
-    super(id);
-  }
-
-  public ASTaddress_list(AddressListParser p, int id) {
-    super(p, id);
-  }
-
-
-  /** Accept the visitor. **/
-  public Object jjtAccept(AddressListParserVisitor visitor, Object data) {
-    return visitor.visit(this, data);
-  }
-}
diff --git a/src/org/apache/james/mime4j/field/address/parser/ASTangle_addr.java b/src/org/apache/james/mime4j/field/address/parser/ASTangle_addr.java
deleted file mode 100644
index 8cb8f42..0000000
--- a/src/org/apache/james/mime4j/field/address/parser/ASTangle_addr.java
+++ /dev/null
@@ -1,19 +0,0 @@
-/* Generated By:JJTree: Do not edit this line. ASTangle_addr.java */
-
-package org.apache.james.mime4j.field.address.parser;
-
-public class ASTangle_addr extends SimpleNode {
-  public ASTangle_addr(int id) {
-    super(id);
-  }
-
-  public ASTangle_addr(AddressListParser p, int id) {
-    super(p, id);
-  }
-
-
-  /** Accept the visitor. **/
-  public Object jjtAccept(AddressListParserVisitor visitor, Object data) {
-    return visitor.visit(this, data);
-  }
-}
diff --git a/src/org/apache/james/mime4j/field/address/parser/ASTdomain.java b/src/org/apache/james/mime4j/field/address/parser/ASTdomain.java
deleted file mode 100644
index b526643..0000000
--- a/src/org/apache/james/mime4j/field/address/parser/ASTdomain.java
+++ /dev/null
@@ -1,19 +0,0 @@
-/* Generated By:JJTree: Do not edit this line. ASTdomain.java */
-
-package org.apache.james.mime4j.field.address.parser;
-
-public class ASTdomain extends SimpleNode {
-  public ASTdomain(int id) {
-    super(id);
-  }
-
-  public ASTdomain(AddressListParser p, int id) {
-    super(p, id);
-  }
-
-
-  /** Accept the visitor. **/
-  public Object jjtAccept(AddressListParserVisitor visitor, Object data) {
-    return visitor.visit(this, data);
-  }
-}
diff --git a/src/org/apache/james/mime4j/field/address/parser/ASTgroup_body.java b/src/org/apache/james/mime4j/field/address/parser/ASTgroup_body.java
deleted file mode 100644
index f6017b9..0000000
--- a/src/org/apache/james/mime4j/field/address/parser/ASTgroup_body.java
+++ /dev/null
@@ -1,19 +0,0 @@
-/* Generated By:JJTree: Do not edit this line. ASTgroup_body.java */
-
-package org.apache.james.mime4j.field.address.parser;
-
-public class ASTgroup_body extends SimpleNode {
-  public ASTgroup_body(int id) {
-    super(id);
-  }
-
-  public ASTgroup_body(AddressListParser p, int id) {
-    super(p, id);
-  }
-
-
-  /** Accept the visitor. **/
-  public Object jjtAccept(AddressListParserVisitor visitor, Object data) {
-    return visitor.visit(this, data);
-  }
-}
diff --git a/src/org/apache/james/mime4j/field/address/parser/ASTlocal_part.java b/src/org/apache/james/mime4j/field/address/parser/ASTlocal_part.java
deleted file mode 100644
index 5c244fa..0000000
--- a/src/org/apache/james/mime4j/field/address/parser/ASTlocal_part.java
+++ /dev/null
@@ -1,19 +0,0 @@
-/* Generated By:JJTree: Do not edit this line. ASTlocal_part.java */
-
-package org.apache.james.mime4j.field.address.parser;
-
-public class ASTlocal_part extends SimpleNode {
-  public ASTlocal_part(int id) {
-    super(id);
-  }
-
-  public ASTlocal_part(AddressListParser p, int id) {
-    super(p, id);
-  }
-
-
-  /** Accept the visitor. **/
-  public Object jjtAccept(AddressListParserVisitor visitor, Object data) {
-    return visitor.visit(this, data);
-  }
-}
diff --git a/src/org/apache/james/mime4j/field/address/parser/ASTmailbox.java b/src/org/apache/james/mime4j/field/address/parser/ASTmailbox.java
deleted file mode 100644
index aeb469d..0000000
--- a/src/org/apache/james/mime4j/field/address/parser/ASTmailbox.java
+++ /dev/null
@@ -1,19 +0,0 @@
-/* Generated By:JJTree: Do not edit this line. ASTmailbox.java */
-
-package org.apache.james.mime4j.field.address.parser;
-
-public class ASTmailbox extends SimpleNode {
-  public ASTmailbox(int id) {
-    super(id);
-  }
-
-  public ASTmailbox(AddressListParser p, int id) {
-    super(p, id);
-  }
-
-
-  /** Accept the visitor. **/
-  public Object jjtAccept(AddressListParserVisitor visitor, Object data) {
-    return visitor.visit(this, data);
-  }
-}
diff --git a/src/org/apache/james/mime4j/field/address/parser/ASTname_addr.java b/src/org/apache/james/mime4j/field/address/parser/ASTname_addr.java
deleted file mode 100644
index 846c731..0000000
--- a/src/org/apache/james/mime4j/field/address/parser/ASTname_addr.java
+++ /dev/null
@@ -1,19 +0,0 @@
-/* Generated By:JJTree: Do not edit this line. ASTname_addr.java */
-
-package org.apache.james.mime4j.field.address.parser;
-
-public class ASTname_addr extends SimpleNode {
-  public ASTname_addr(int id) {
-    super(id);
-  }
-
-  public ASTname_addr(AddressListParser p, int id) {
-    super(p, id);
-  }
-
-
-  /** Accept the visitor. **/
-  public Object jjtAccept(AddressListParserVisitor visitor, Object data) {
-    return visitor.visit(this, data);
-  }
-}
diff --git a/src/org/apache/james/mime4j/field/address/parser/ASTphrase.java b/src/org/apache/james/mime4j/field/address/parser/ASTphrase.java
deleted file mode 100644
index 7d711c5..0000000
--- a/src/org/apache/james/mime4j/field/address/parser/ASTphrase.java
+++ /dev/null
@@ -1,19 +0,0 @@
-/* Generated By:JJTree: Do not edit this line. ASTphrase.java */
-
-package org.apache.james.mime4j.field.address.parser;
-
-public class ASTphrase extends SimpleNode {
-  public ASTphrase(int id) {
-    super(id);
-  }
-
-  public ASTphrase(AddressListParser p, int id) {
-    super(p, id);
-  }
-
-
-  /** Accept the visitor. **/
-  public Object jjtAccept(AddressListParserVisitor visitor, Object data) {
-    return visitor.visit(this, data);
-  }
-}
diff --git a/src/org/apache/james/mime4j/field/address/parser/ASTroute.java b/src/org/apache/james/mime4j/field/address/parser/ASTroute.java
deleted file mode 100644
index 54ea115..0000000
--- a/src/org/apache/james/mime4j/field/address/parser/ASTroute.java
+++ /dev/null
@@ -1,19 +0,0 @@
-/* Generated By:JJTree: Do not edit this line. ASTroute.java */
-
-package org.apache.james.mime4j.field.address.parser;
-
-public class ASTroute extends SimpleNode {
-  public ASTroute(int id) {
-    super(id);
-  }
-
-  public ASTroute(AddressListParser p, int id) {
-    super(p, id);
-  }
-
-
-  /** Accept the visitor. **/
-  public Object jjtAccept(AddressListParserVisitor visitor, Object data) {
-    return visitor.visit(this, data);
-  }
-}
diff --git a/src/org/apache/james/mime4j/field/address/parser/AddressListParser.java b/src/org/apache/james/mime4j/field/address/parser/AddressListParser.java
deleted file mode 100644
index 8094df0..0000000
--- a/src/org/apache/james/mime4j/field/address/parser/AddressListParser.java
+++ /dev/null
@@ -1,977 +0,0 @@
-/* Generated By:JJTree&JavaCC: Do not edit this line. AddressListParser.java */
-/*
- *  Copyright 2004 the mime4j 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 org.apache.james.mime4j.field.address.parser;
-
-public class AddressListParser/*@bgen(jjtree)*/implements AddressListParserTreeConstants, AddressListParserConstants {/*@bgen(jjtree)*/
-  protected JJTAddressListParserState jjtree = new JJTAddressListParserState();public static void main(String args[]) throws ParseException {
-                while (true) {
-                    try {
-                                AddressListParser parser = new AddressListParser(System.in);
-                        parser.parseLine();
-                        ((SimpleNode)parser.jjtree.rootNode()).dump("> ");
-                    } catch (Exception x) {
-                                x.printStackTrace();
-                                return;
-                    }
-                }
-    }
-
-    private static void log(String msg) {
-        System.out.print(msg);
-    }
-
-    public ASTaddress_list parse() throws ParseException {
-        try {
-            parseAll();
-            return (ASTaddress_list)jjtree.rootNode();
-        } catch (TokenMgrError tme) {
-            throw new ParseException(tme.getMessage());
-        }
-    }
-
-
-    void jjtreeOpenNodeScope(Node n) {
-        ((SimpleNode)n).firstToken = getToken(1);
-    }
-
-    void jjtreeCloseNodeScope(Node n) {
-        ((SimpleNode)n).lastToken = getToken(0);
-    }
-
-  final public void parseLine() throws ParseException {
-    address_list();
-    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-    case 1:
-      jj_consume_token(1);
-      break;
-    default:
-      jj_la1[0] = jj_gen;
-      ;
-    }
-    jj_consume_token(2);
-  }
-
-  final public void parseAll() throws ParseException {
-    address_list();
-    jj_consume_token(0);
-  }
-
-  final public void address_list() throws ParseException {
- /*@bgen(jjtree) address_list */
-  ASTaddress_list jjtn000 = new ASTaddress_list(JJTADDRESS_LIST);
-  boolean jjtc000 = true;
-  jjtree.openNodeScope(jjtn000);
-  jjtreeOpenNodeScope(jjtn000);
-    try {
-      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-      case 6:
-      case DOTATOM:
-      case QUOTEDSTRING:
-        address();
-        break;
-      default:
-        jj_la1[1] = jj_gen;
-        ;
-      }
-      label_1:
-      while (true) {
-        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-        case 3:
-          ;
-          break;
-        default:
-          jj_la1[2] = jj_gen;
-          break label_1;
-        }
-        jj_consume_token(3);
-        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-        case 6:
-        case DOTATOM:
-        case QUOTEDSTRING:
-          address();
-          break;
-        default:
-          jj_la1[3] = jj_gen;
-          ;
-        }
-      }
-    } catch (Throwable jjte000) {
-          if (jjtc000) {
-            jjtree.clearNodeScope(jjtn000);
-            jjtc000 = false;
-          } else {
-            jjtree.popNode();
-          }
-          if (jjte000 instanceof RuntimeException) {
-            {if (true) throw (RuntimeException)jjte000;}
-          }
-          if (jjte000 instanceof ParseException) {
-            {if (true) throw (ParseException)jjte000;}
-          }
-          {if (true) throw (Error)jjte000;}
-    } finally {
-          if (jjtc000) {
-            jjtree.closeNodeScope(jjtn000, true);
-            jjtreeCloseNodeScope(jjtn000);
-          }
-    }
-  }
-
-  final public void address() throws ParseException {
- /*@bgen(jjtree) address */
-  ASTaddress jjtn000 = new ASTaddress(JJTADDRESS);
-  boolean jjtc000 = true;
-  jjtree.openNodeScope(jjtn000);
-  jjtreeOpenNodeScope(jjtn000);
-    try {
-      if (jj_2_1(2147483647)) {
-        addr_spec();
-      } else {
-        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-        case 6:
-          angle_addr();
-          break;
-        case DOTATOM:
-        case QUOTEDSTRING:
-          phrase();
-          switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-          case 4:
-            group_body();
-            break;
-          case 6:
-            angle_addr();
-            break;
-          default:
-            jj_la1[4] = jj_gen;
-            jj_consume_token(-1);
-            throw new ParseException();
-          }
-          break;
-        default:
-          jj_la1[5] = jj_gen;
-          jj_consume_token(-1);
-          throw new ParseException();
-        }
-      }
-    } catch (Throwable jjte000) {
-          if (jjtc000) {
-            jjtree.clearNodeScope(jjtn000);
-            jjtc000 = false;
-          } else {
-            jjtree.popNode();
-          }
-          if (jjte000 instanceof RuntimeException) {
-            {if (true) throw (RuntimeException)jjte000;}
-          }
-          if (jjte000 instanceof ParseException) {
-            {if (true) throw (ParseException)jjte000;}
-          }
-          {if (true) throw (Error)jjte000;}
-    } finally {
-          if (jjtc000) {
-            jjtree.closeNodeScope(jjtn000, true);
-            jjtreeCloseNodeScope(jjtn000);
-          }
-    }
-  }
-
-  final public void mailbox() throws ParseException {
- /*@bgen(jjtree) mailbox */
-  ASTmailbox jjtn000 = new ASTmailbox(JJTMAILBOX);
-  boolean jjtc000 = true;
-  jjtree.openNodeScope(jjtn000);
-  jjtreeOpenNodeScope(jjtn000);
-    try {
-      if (jj_2_2(2147483647)) {
-        addr_spec();
-      } else {
-        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-        case 6:
-          angle_addr();
-          break;
-        case DOTATOM:
-        case QUOTEDSTRING:
-          name_addr();
-          break;
-        default:
-          jj_la1[6] = jj_gen;
-          jj_consume_token(-1);
-          throw new ParseException();
-        }
-      }
-    } catch (Throwable jjte000) {
-          if (jjtc000) {
-            jjtree.clearNodeScope(jjtn000);
-            jjtc000 = false;
-          } else {
-            jjtree.popNode();
-          }
-          if (jjte000 instanceof RuntimeException) {
-            {if (true) throw (RuntimeException)jjte000;}
-          }
-          if (jjte000 instanceof ParseException) {
-            {if (true) throw (ParseException)jjte000;}
-          }
-          {if (true) throw (Error)jjte000;}
-    } finally {
-          if (jjtc000) {
-            jjtree.closeNodeScope(jjtn000, true);
-            jjtreeCloseNodeScope(jjtn000);
-          }
-    }
-  }
-
-  final public void name_addr() throws ParseException {
- /*@bgen(jjtree) name_addr */
-  ASTname_addr jjtn000 = new ASTname_addr(JJTNAME_ADDR);
-  boolean jjtc000 = true;
-  jjtree.openNodeScope(jjtn000);
-  jjtreeOpenNodeScope(jjtn000);
-    try {
-      phrase();
-      angle_addr();
-    } catch (Throwable jjte000) {
-          if (jjtc000) {
-            jjtree.clearNodeScope(jjtn000);
-            jjtc000 = false;
-          } else {
-            jjtree.popNode();
-          }
-          if (jjte000 instanceof RuntimeException) {
-            {if (true) throw (RuntimeException)jjte000;}
-          }
-          if (jjte000 instanceof ParseException) {
-            {if (true) throw (ParseException)jjte000;}
-          }
-          {if (true) throw (Error)jjte000;}
-    } finally {
-          if (jjtc000) {
-            jjtree.closeNodeScope(jjtn000, true);
-            jjtreeCloseNodeScope(jjtn000);
-          }
-    }
-  }
-
-  final public void group_body() throws ParseException {
- /*@bgen(jjtree) group_body */
-  ASTgroup_body jjtn000 = new ASTgroup_body(JJTGROUP_BODY);
-  boolean jjtc000 = true;
-  jjtree.openNodeScope(jjtn000);
-  jjtreeOpenNodeScope(jjtn000);
-    try {
-      jj_consume_token(4);
-      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-      case 6:
-      case DOTATOM:
-      case QUOTEDSTRING:
-        mailbox();
-        break;
-      default:
-        jj_la1[7] = jj_gen;
-        ;
-      }
-      label_2:
-      while (true) {
-        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-        case 3:
-          ;
-          break;
-        default:
-          jj_la1[8] = jj_gen;
-          break label_2;
-        }
-        jj_consume_token(3);
-        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-        case 6:
-        case DOTATOM:
-        case QUOTEDSTRING:
-          mailbox();
-          break;
-        default:
-          jj_la1[9] = jj_gen;
-          ;
-        }
-      }
-      jj_consume_token(5);
-    } catch (Throwable jjte000) {
-          if (jjtc000) {
-            jjtree.clearNodeScope(jjtn000);
-            jjtc000 = false;
-          } else {
-            jjtree.popNode();
-          }
-          if (jjte000 instanceof RuntimeException) {
-            {if (true) throw (RuntimeException)jjte000;}
-          }
-          if (jjte000 instanceof ParseException) {
-            {if (true) throw (ParseException)jjte000;}
-          }
-          {if (true) throw (Error)jjte000;}
-    } finally {
-          if (jjtc000) {
-            jjtree.closeNodeScope(jjtn000, true);
-            jjtreeCloseNodeScope(jjtn000);
-          }
-    }
-  }
-
-  final public void angle_addr() throws ParseException {
- /*@bgen(jjtree) angle_addr */
-  ASTangle_addr jjtn000 = new ASTangle_addr(JJTANGLE_ADDR);
-  boolean jjtc000 = true;
-  jjtree.openNodeScope(jjtn000);
-  jjtreeOpenNodeScope(jjtn000);
-    try {
-      jj_consume_token(6);
-      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-      case 8:
-        route();
-        break;
-      default:
-        jj_la1[10] = jj_gen;
-        ;
-      }
-      addr_spec();
-      jj_consume_token(7);
-    } catch (Throwable jjte000) {
-          if (jjtc000) {
-            jjtree.clearNodeScope(jjtn000);
-            jjtc000 = false;
-          } else {
-            jjtree.popNode();
-          }
-          if (jjte000 instanceof RuntimeException) {
-            {if (true) throw (RuntimeException)jjte000;}
-          }
-          if (jjte000 instanceof ParseException) {
-            {if (true) throw (ParseException)jjte000;}
-          }
-          {if (true) throw (Error)jjte000;}
-    } finally {
-          if (jjtc000) {
-            jjtree.closeNodeScope(jjtn000, true);
-            jjtreeCloseNodeScope(jjtn000);
-          }
-    }
-  }
-
-  final public void route() throws ParseException {
- /*@bgen(jjtree) route */
-  ASTroute jjtn000 = new ASTroute(JJTROUTE);
-  boolean jjtc000 = true;
-  jjtree.openNodeScope(jjtn000);
-  jjtreeOpenNodeScope(jjtn000);
-    try {
-      jj_consume_token(8);
-      domain();
-      label_3:
-      while (true) {
-        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-        case 3:
-        case 8:
-          ;
-          break;
-        default:
-          jj_la1[11] = jj_gen;
-          break label_3;
-        }
-        label_4:
-        while (true) {
-          switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-          case 3:
-            ;
-            break;
-          default:
-            jj_la1[12] = jj_gen;
-            break label_4;
-          }
-          jj_consume_token(3);
-        }
-        jj_consume_token(8);
-        domain();
-      }
-      jj_consume_token(4);
-    } catch (Throwable jjte000) {
-          if (jjtc000) {
-            jjtree.clearNodeScope(jjtn000);
-            jjtc000 = false;
-          } else {
-            jjtree.popNode();
-          }
-          if (jjte000 instanceof RuntimeException) {
-            {if (true) throw (RuntimeException)jjte000;}
-          }
-          if (jjte000 instanceof ParseException) {
-            {if (true) throw (ParseException)jjte000;}
-          }
-          {if (true) throw (Error)jjte000;}
-    } finally {
-          if (jjtc000) {
-            jjtree.closeNodeScope(jjtn000, true);
-            jjtreeCloseNodeScope(jjtn000);
-          }
-    }
-  }
-
-  final public void phrase() throws ParseException {
- /*@bgen(jjtree) phrase */
-  ASTphrase jjtn000 = new ASTphrase(JJTPHRASE);
-  boolean jjtc000 = true;
-  jjtree.openNodeScope(jjtn000);
-  jjtreeOpenNodeScope(jjtn000);
-    try {
-      label_5:
-      while (true) {
-        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-        case DOTATOM:
-          jj_consume_token(DOTATOM);
-          break;
-        case QUOTEDSTRING:
-          jj_consume_token(QUOTEDSTRING);
-          break;
-        default:
-          jj_la1[13] = jj_gen;
-          jj_consume_token(-1);
-          throw new ParseException();
-        }
-        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-        case DOTATOM:
-        case QUOTEDSTRING:
-          ;
-          break;
-        default:
-          jj_la1[14] = jj_gen;
-          break label_5;
-        }
-      }
-    } finally {
-  if (jjtc000) {
-    jjtree.closeNodeScope(jjtn000, true);
-    jjtreeCloseNodeScope(jjtn000);
-  }
-    }
-  }
-
-  final public void addr_spec() throws ParseException {
- /*@bgen(jjtree) addr_spec */
-  ASTaddr_spec jjtn000 = new ASTaddr_spec(JJTADDR_SPEC);
-  boolean jjtc000 = true;
-  jjtree.openNodeScope(jjtn000);
-  jjtreeOpenNodeScope(jjtn000);
-    try {
-      local_part();
-      jj_consume_token(8);
-      domain();
-    } catch (Throwable jjte000) {
-          if (jjtc000) {
-            jjtree.clearNodeScope(jjtn000);
-            jjtc000 = false;
-          } else {
-            jjtree.popNode();
-          }
-          if (jjte000 instanceof RuntimeException) {
-            {if (true) throw (RuntimeException)jjte000;}
-          }
-          if (jjte000 instanceof ParseException) {
-            {if (true) throw (ParseException)jjte000;}
-          }
-          {if (true) throw (Error)jjte000;}
-    } finally {
-          if (jjtc000) {
-            jjtree.closeNodeScope(jjtn000, true);
-            jjtreeCloseNodeScope(jjtn000);
-          }
-    }
-  }
-
-  final public void local_part() throws ParseException {
- /*@bgen(jjtree) local_part */
-  ASTlocal_part jjtn000 = new ASTlocal_part(JJTLOCAL_PART);
-  boolean jjtc000 = true;
-  jjtree.openNodeScope(jjtn000);
-  jjtreeOpenNodeScope(jjtn000);Token t;
-    try {
-      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-      case DOTATOM:
-        t = jj_consume_token(DOTATOM);
-        break;
-      case QUOTEDSTRING:
-        t = jj_consume_token(QUOTEDSTRING);
-        break;
-      default:
-        jj_la1[15] = jj_gen;
-        jj_consume_token(-1);
-        throw new ParseException();
-      }
-      label_6:
-      while (true) {
-        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-        case 9:
-        case DOTATOM:
-        case QUOTEDSTRING:
-          ;
-          break;
-        default:
-          jj_la1[16] = jj_gen;
-          break label_6;
-        }
-        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-        case 9:
-          t = jj_consume_token(9);
-          break;
-        default:
-          jj_la1[17] = jj_gen;
-          ;
-        }
-                        if (t.image.charAt(t.image.length() - 1) != '.' || t.kind == AddressListParserConstants.QUOTEDSTRING)
-                                {if (true) throw new ParseException("Words in local part must be separated by '.'");}
-        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-        case DOTATOM:
-          t = jj_consume_token(DOTATOM);
-          break;
-        case QUOTEDSTRING:
-          t = jj_consume_token(QUOTEDSTRING);
-          break;
-        default:
-          jj_la1[18] = jj_gen;
-          jj_consume_token(-1);
-          throw new ParseException();
-        }
-      }
-    } finally {
-          if (jjtc000) {
-            jjtree.closeNodeScope(jjtn000, true);
-            jjtreeCloseNodeScope(jjtn000);
-          }
-    }
-  }
-
-  final public void domain() throws ParseException {
- /*@bgen(jjtree) domain */
-  ASTdomain jjtn000 = new ASTdomain(JJTDOMAIN);
-  boolean jjtc000 = true;
-  jjtree.openNodeScope(jjtn000);
-  jjtreeOpenNodeScope(jjtn000);Token t;
-    try {
-      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-      case DOTATOM:
-        t = jj_consume_token(DOTATOM);
-        label_7:
-        while (true) {
-          switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-          case 9:
-          case DOTATOM:
-            ;
-            break;
-          default:
-            jj_la1[19] = jj_gen;
-            break label_7;
-          }
-          switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-          case 9:
-            t = jj_consume_token(9);
-            break;
-          default:
-            jj_la1[20] = jj_gen;
-            ;
-          }
-                                if (t.image.charAt(t.image.length() - 1) != '.')
-                                        {if (true) throw new ParseException("Atoms in domain names must be separated by '.'");}
-          t = jj_consume_token(DOTATOM);
-        }
-        break;
-      case DOMAINLITERAL:
-        jj_consume_token(DOMAINLITERAL);
-        break;
-      default:
-        jj_la1[21] = jj_gen;
-        jj_consume_token(-1);
-        throw new ParseException();
-      }
-    } finally {
-          if (jjtc000) {
-            jjtree.closeNodeScope(jjtn000, true);
-            jjtreeCloseNodeScope(jjtn000);
-          }
-    }
-  }
-
-  final private boolean jj_2_1(int xla) {
-    jj_la = xla; jj_lastpos = jj_scanpos = token;
-    try { return !jj_3_1(); }
-    catch(LookaheadSuccess ls) { return true; }
-    finally { jj_save(0, xla); }
-  }
-
-  final private boolean jj_2_2(int xla) {
-    jj_la = xla; jj_lastpos = jj_scanpos = token;
-    try { return !jj_3_2(); }
-    catch(LookaheadSuccess ls) { return true; }
-    finally { jj_save(1, xla); }
-  }
-
-  final private boolean jj_3R_11() {
-    Token xsp;
-    xsp = jj_scanpos;
-    if (jj_scan_token(9)) jj_scanpos = xsp;
-    xsp = jj_scanpos;
-    if (jj_scan_token(14)) {
-    jj_scanpos = xsp;
-    if (jj_scan_token(31)) return true;
-    }
-    return false;
-  }
-
-  final private boolean jj_3R_13() {
-    Token xsp;
-    xsp = jj_scanpos;
-    if (jj_scan_token(9)) jj_scanpos = xsp;
-    if (jj_scan_token(DOTATOM)) return true;
-    return false;
-  }
-
-  final private boolean jj_3R_8() {
-    if (jj_3R_9()) return true;
-    if (jj_scan_token(8)) return true;
-    if (jj_3R_10()) return true;
-    return false;
-  }
-
-  final private boolean jj_3_1() {
-    if (jj_3R_8()) return true;
-    return false;
-  }
-
-  final private boolean jj_3R_12() {
-    if (jj_scan_token(DOTATOM)) return true;
-    Token xsp;
-    while (true) {
-      xsp = jj_scanpos;
-      if (jj_3R_13()) { jj_scanpos = xsp; break; }
-    }
-    return false;
-  }
-
-  final private boolean jj_3R_10() {
-    Token xsp;
-    xsp = jj_scanpos;
-    if (jj_3R_12()) {
-    jj_scanpos = xsp;
-    if (jj_scan_token(18)) return true;
-    }
-    return false;
-  }
-
-  final private boolean jj_3_2() {
-    if (jj_3R_8()) return true;
-    return false;
-  }
-
-  final private boolean jj_3R_9() {
-    Token xsp;
-    xsp = jj_scanpos;
-    if (jj_scan_token(14)) {
-    jj_scanpos = xsp;
-    if (jj_scan_token(31)) return true;
-    }
-    while (true) {
-      xsp = jj_scanpos;
-      if (jj_3R_11()) { jj_scanpos = xsp; break; }
-    }
-    return false;
-  }
-
-  public AddressListParserTokenManager token_source;
-  SimpleCharStream jj_input_stream;
-  public Token token, jj_nt;
-  private int jj_ntk;
-  private Token jj_scanpos, jj_lastpos;
-  private int jj_la;
-  public boolean lookingAhead = false;
-  private boolean jj_semLA;
-  private int jj_gen;
-  final private int[] jj_la1 = new int[22];
-  static private int[] jj_la1_0;
-  static private int[] jj_la1_1;
-  static {
-      jj_la1_0();
-      jj_la1_1();
-   }
-   private static void jj_la1_0() {
-      jj_la1_0 = new int[] {0x2,0x80004040,0x8,0x80004040,0x50,0x80004040,0x80004040,0x80004040,0x8,0x80004040,0x100,0x108,0x8,0x80004000,0x80004000,0x80004000,0x80004200,0x200,0x80004000,0x4200,0x200,0x44000,};
-   }
-   private static void jj_la1_1() {
-      jj_la1_1 = new int[] {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,};
-   }
-  final private JJCalls[] jj_2_rtns = new JJCalls[2];
-  private boolean jj_rescan = false;
-  private int jj_gc = 0;
-
-  public AddressListParser(java.io.InputStream stream) {
-     this(stream, null);
-  }
-  public AddressListParser(java.io.InputStream stream, String encoding) {
-    try { jj_input_stream = new SimpleCharStream(stream, encoding, 1, 1); } catch(java.io.UnsupportedEncodingException e) { throw new RuntimeException(e); }
-    token_source = new AddressListParserTokenManager(jj_input_stream);
-    token = new Token();
-    jj_ntk = -1;
-    jj_gen = 0;
-    for (int i = 0; i < 22; i++) jj_la1[i] = -1;
-    for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
-  }
-
-  public void ReInit(java.io.InputStream stream) {
-     ReInit(stream, null);
-  }
-  public void ReInit(java.io.InputStream stream, String encoding) {
-    try { jj_input_stream.ReInit(stream, encoding, 1, 1); } catch(java.io.UnsupportedEncodingException e) { throw new RuntimeException(e); }
-    token_source.ReInit(jj_input_stream);
-    token = new Token();
-    jj_ntk = -1;
-    jjtree.reset();
-    jj_gen = 0;
-    for (int i = 0; i < 22; i++) jj_la1[i] = -1;
-    for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
-  }
-
-  public AddressListParser(java.io.Reader stream) {
-    jj_input_stream = new SimpleCharStream(stream, 1, 1);
-    token_source = new AddressListParserTokenManager(jj_input_stream);
-    token = new Token();
-    jj_ntk = -1;
-    jj_gen = 0;
-    for (int i = 0; i < 22; i++) jj_la1[i] = -1;
-    for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
-  }
-
-  public void ReInit(java.io.Reader stream) {
-    jj_input_stream.ReInit(stream, 1, 1);
-    token_source.ReInit(jj_input_stream);
-    token = new Token();
-    jj_ntk = -1;
-    jjtree.reset();
-    jj_gen = 0;
-    for (int i = 0; i < 22; i++) jj_la1[i] = -1;
-    for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
-  }
-
-  public AddressListParser(AddressListParserTokenManager tm) {
-    token_source = tm;
-    token = new Token();
-    jj_ntk = -1;
-    jj_gen = 0;
-    for (int i = 0; i < 22; i++) jj_la1[i] = -1;
-    for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
-  }
-
-  public void ReInit(AddressListParserTokenManager tm) {
-    token_source = tm;
-    token = new Token();
-    jj_ntk = -1;
-    jjtree.reset();
-    jj_gen = 0;
-    for (int i = 0; i < 22; i++) jj_la1[i] = -1;
-    for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
-  }
-
-  final private Token jj_consume_token(int kind) throws ParseException {
-    Token oldToken;
-    if ((oldToken = token).next != null) token = token.next;
-    else token = token.next = token_source.getNextToken();
-    jj_ntk = -1;
-    if (token.kind == kind) {
-      jj_gen++;
-      if (++jj_gc > 100) {
-        jj_gc = 0;
-        for (int i = 0; i < jj_2_rtns.length; i++) {
-          JJCalls c = jj_2_rtns[i];
-          while (c != null) {
-            if (c.gen < jj_gen) c.first = null;
-            c = c.next;
-          }
-        }
-      }
-      return token;
-    }
-    token = oldToken;
-    jj_kind = kind;
-    throw generateParseException();
-  }
-
-  static private final class LookaheadSuccess extends java.lang.Error { }
-  final private LookaheadSuccess jj_ls = new LookaheadSuccess();
-  final private boolean jj_scan_token(int kind) {
-    if (jj_scanpos == jj_lastpos) {
-      jj_la--;
-      if (jj_scanpos.next == null) {
-        jj_lastpos = jj_scanpos = jj_scanpos.next = token_source.getNextToken();
-      } else {
-        jj_lastpos = jj_scanpos = jj_scanpos.next;
-      }
-    } else {
-      jj_scanpos = jj_scanpos.next;
-    }
-    if (jj_rescan) {
-      int i = 0; Token tok = token;
-      while (tok != null && tok != jj_scanpos) { i++; tok = tok.next; }
-      if (tok != null) jj_add_error_token(kind, i);
-    }
-    if (jj_scanpos.kind != kind) return true;
-    if (jj_la == 0 && jj_scanpos == jj_lastpos) throw jj_ls;
-    return false;
-  }
-
-  final public Token getNextToken() {
-    if (token.next != null) token = token.next;
-    else token = token.next = token_source.getNextToken();
-    jj_ntk = -1;
-    jj_gen++;
-    return token;
-  }
-
-  final public Token getToken(int index) {
-    Token t = lookingAhead ? jj_scanpos : token;
-    for (int i = 0; i < index; i++) {
-      if (t.next != null) t = t.next;
-      else t = t.next = token_source.getNextToken();
-    }
-    return t;
-  }
-
-  final private int jj_ntk() {
-    if ((jj_nt=token.next) == null)
-      return (jj_ntk = (token.next=token_source.getNextToken()).kind);
-    else
-      return (jj_ntk = jj_nt.kind);
-  }
-
-  private java.util.Vector<int[]> jj_expentries = new java.util.Vector<int[]>();
-  private int[] jj_expentry;
-  private int jj_kind = -1;
-  private int[] jj_lasttokens = new int[100];
-  private int jj_endpos;
-
-  private void jj_add_error_token(int kind, int pos) {
-    if (pos >= 100) return;
-    if (pos == jj_endpos + 1) {
-      jj_lasttokens[jj_endpos++] = kind;
-    } else if (jj_endpos != 0) {
-      jj_expentry = new int[jj_endpos];
-      for (int i = 0; i < jj_endpos; i++) {
-        jj_expentry[i] = jj_lasttokens[i];
-      }
-      boolean exists = false;
-      for (java.util.Enumeration<int[]> e = jj_expentries.elements(); e.hasMoreElements();) {
-        int[] oldentry = e.nextElement();
-        if (oldentry.length == jj_expentry.length) {
-          exists = true;
-          for (int i = 0; i < jj_expentry.length; i++) {
-            if (oldentry[i] != jj_expentry[i]) {
-              exists = false;
-              break;
-            }
-          }
-          if (exists) break;
-        }
-      }
-      if (!exists) jj_expentries.addElement(jj_expentry);
-      if (pos != 0) jj_lasttokens[(jj_endpos = pos) - 1] = kind;
-    }
-  }
-
-  public ParseException generateParseException() {
-    jj_expentries.removeAllElements();
-    boolean[] la1tokens = new boolean[34];
-    for (int i = 0; i < 34; i++) {
-      la1tokens[i] = false;
-    }
-    if (jj_kind >= 0) {
-      la1tokens[jj_kind] = true;
-      jj_kind = -1;
-    }
-    for (int i = 0; i < 22; i++) {
-      if (jj_la1[i] == jj_gen) {
-        for (int j = 0; j < 32; j++) {
-          if ((jj_la1_0[i] & (1<<j)) != 0) {
-            la1tokens[j] = true;
-          }
-          if ((jj_la1_1[i] & (1<<j)) != 0) {
-            la1tokens[32+j] = true;
-          }
-        }
-      }
-    }
-    for (int i = 0; i < 34; i++) {
-      if (la1tokens[i]) {
-        jj_expentry = new int[1];
-        jj_expentry[0] = i;
-        jj_expentries.addElement(jj_expentry);
-      }
-    }
-    jj_endpos = 0;
-    jj_rescan_token();
-    jj_add_error_token(0, 0);
-    int[][] exptokseq = new int[jj_expentries.size()][];
-    for (int i = 0; i < jj_expentries.size(); i++) {
-      exptokseq[i] = jj_expentries.elementAt(i);
-    }
-    return new ParseException(token, exptokseq, tokenImage);
-  }
-
-  final public void enable_tracing() {
-  }
-
-  final public void disable_tracing() {
-  }
-
-  final private void jj_rescan_token() {
-    jj_rescan = true;
-    for (int i = 0; i < 2; i++) {
-    try {
-      JJCalls p = jj_2_rtns[i];
-      do {
-        if (p.gen > jj_gen) {
-          jj_la = p.arg; jj_lastpos = jj_scanpos = p.first;
-          switch (i) {
-            case 0: jj_3_1(); break;
-            case 1: jj_3_2(); break;
-          }
-        }
-        p = p.next;
-      } while (p != null);
-      } catch(LookaheadSuccess ls) { }
-    }
-    jj_rescan = false;
-  }
-
-  final private void jj_save(int index, int xla) {
-    JJCalls p = jj_2_rtns[index];
-    while (p.gen > jj_gen) {
-      if (p.next == null) { p = p.next = new JJCalls(); break; }
-      p = p.next;
-    }
-    p.gen = jj_gen + xla - jj_la; p.first = token; p.arg = xla;
-  }
-
-  static final class JJCalls {
-    int gen;
-    Token first;
-    int arg;
-    JJCalls next;
-  }
-
-}
diff --git a/src/org/apache/james/mime4j/field/address/parser/AddressListParser.jj b/src/org/apache/james/mime4j/field/address/parser/AddressListParser.jj
deleted file mode 100644
index c14277b..0000000
--- a/src/org/apache/james/mime4j/field/address/parser/AddressListParser.jj
+++ /dev/null
@@ -1,595 +0,0 @@
-/*@bgen(jjtree) Generated By:JJTree: Do not edit this line. /Users/jason/Projects/apache-mime4j-0.3/target/generated-sources/jjtree/org/apache/james/mime4j/field/address/parser/AddressListParser.jj */
-/*@egen*//****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one   *
- * or more contributor license agreements.  See the NOTICE file *
- * distributed with this work for additional information        *
- * regarding copyright ownership.  The ASF licenses this file   *
- * to you 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.                                           *
- ****************************************************************/
-
-
-/**
- * RFC2822 address list parser.
- *
- * Created 9/17/2004
- * by Joe Cheng <code@joecheng.com>
- */
-
-options {
-	STATIC=false;
-	LOOKAHEAD=1;                                                                                                                               
-	//DEBUG_PARSER=true;
-	//DEBUG_TOKEN_MANAGER=true;
-}
-
-PARSER_BEGIN(AddressListParser)
-/*
- *  Copyright 2004 the mime4j 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 org.apache.james.mime4j.field.address.parser;
-
-public class AddressListParser/*@bgen(jjtree)*/implements AddressListParserTreeConstants/*@egen*/ {/*@bgen(jjtree)*/
-  protected JJTAddressListParserState jjtree = new JJTAddressListParserState();
-
-/*@egen*/
-    public static void main(String args[]) throws ParseException {
-		while (true) {
-		    try {
-				AddressListParser parser = new AddressListParser(System.in);
-		    	parser.parseLine();
-		    	((SimpleNode)parser.jjtree.rootNode()).dump("> ");
-		    } catch (Exception x) {
-				x.printStackTrace();
-				return;
-		    }
-		}
-    }
-    
-    private static void log(String msg) {
-    	System.out.print(msg);
-    }
-    
-    public ASTaddress_list parse() throws ParseException {
-        try {
-    	    parseAll();
-    	    return (ASTaddress_list)jjtree.rootNode();
-    	} catch (TokenMgrError tme) {
-    	    throw new ParseException(tme.getMessage());
-    	}
-    }
-    
-    
-    void jjtreeOpenNodeScope(Node n) {
-    	((SimpleNode)n).firstToken = getToken(1);
-    }
-    
-    void jjtreeCloseNodeScope(Node n) {
-    	((SimpleNode)n).lastToken = getToken(0);
-    }
-}
-
-PARSER_END(AddressListParser)
-
-void parseLine()       :
-{}
-{
-	address_list() ["\r"] "\n"
-}
-
-void parseAll()       :
-{}
-{
-	address_list() <EOF>
-}
-
-void address_list() :
-{/*@bgen(jjtree) address_list */
-  ASTaddress_list jjtn000 = new ASTaddress_list(JJTADDRESS_LIST);
-  boolean jjtc000 = true;
-  jjtree.openNodeScope(jjtn000);
-  jjtreeOpenNodeScope(jjtn000);
-/*@egen*/}
-{/*@bgen(jjtree) address_list */
-        try {
-/*@egen*/
-	[ address() ]
-	(
-		","
-		[ address() ]
-	)*/*@bgen(jjtree)*/
-        } catch (Throwable jjte000) {
-          if (jjtc000) {
-            jjtree.clearNodeScope(jjtn000);
-            jjtc000 = false;
-          } else {
-            jjtree.popNode();
-          }
-          if (jjte000 instanceof RuntimeException) {
-            throw (RuntimeException)jjte000;
-          }
-          if (jjte000 instanceof ParseException) {
-            throw (ParseException)jjte000;
-          }
-          throw (Error)jjte000;
-        } finally {
-          if (jjtc000) {
-            jjtree.closeNodeScope(jjtn000, true);
-            jjtreeCloseNodeScope(jjtn000);
-          }
-        }
-/*@egen*/
-}
-
-void address() :
-{/*@bgen(jjtree) address */
-  ASTaddress jjtn000 = new ASTaddress(JJTADDRESS);
-  boolean jjtc000 = true;
-  jjtree.openNodeScope(jjtn000);
-  jjtreeOpenNodeScope(jjtn000);
-/*@egen*/}
-{/*@bgen(jjtree) address */
-        try {
-/*@egen*/
-	LOOKAHEAD(2147483647)
-	addr_spec()
-|	angle_addr()
-|	( phrase() (group_body() | angle_addr()) )/*@bgen(jjtree)*/
-        } catch (Throwable jjte000) {
-          if (jjtc000) {
-            jjtree.clearNodeScope(jjtn000);
-            jjtc000 = false;
-          } else {
-            jjtree.popNode();
-          }
-          if (jjte000 instanceof RuntimeException) {
-            throw (RuntimeException)jjte000;
-          }
-          if (jjte000 instanceof ParseException) {
-            throw (ParseException)jjte000;
-          }
-          throw (Error)jjte000;
-        } finally {
-          if (jjtc000) {
-            jjtree.closeNodeScope(jjtn000, true);
-            jjtreeCloseNodeScope(jjtn000);
-          }
-        }
-/*@egen*/
-}
-
-void mailbox() :
-{/*@bgen(jjtree) mailbox */
-  ASTmailbox jjtn000 = new ASTmailbox(JJTMAILBOX);
-  boolean jjtc000 = true;
-  jjtree.openNodeScope(jjtn000);
-  jjtreeOpenNodeScope(jjtn000);
-/*@egen*/}
-{/*@bgen(jjtree) mailbox */
-        try {
-/*@egen*/
-	LOOKAHEAD(2147483647)
-	addr_spec()
-|	angle_addr()
-|	name_addr()/*@bgen(jjtree)*/
-        } catch (Throwable jjte000) {
-          if (jjtc000) {
-            jjtree.clearNodeScope(jjtn000);
-            jjtc000 = false;
-          } else {
-            jjtree.popNode();
-          }
-          if (jjte000 instanceof RuntimeException) {
-            throw (RuntimeException)jjte000;
-          }
-          if (jjte000 instanceof ParseException) {
-            throw (ParseException)jjte000;
-          }
-          throw (Error)jjte000;
-        } finally {
-          if (jjtc000) {
-            jjtree.closeNodeScope(jjtn000, true);
-            jjtreeCloseNodeScope(jjtn000);
-          }
-        }
-/*@egen*/
-}
-
-void name_addr() :
-{/*@bgen(jjtree) name_addr */
-  ASTname_addr jjtn000 = new ASTname_addr(JJTNAME_ADDR);
-  boolean jjtc000 = true;
-  jjtree.openNodeScope(jjtn000);
-  jjtreeOpenNodeScope(jjtn000);
-/*@egen*/}
-{/*@bgen(jjtree) name_addr */
-        try {
-/*@egen*/
-	phrase() angle_addr()/*@bgen(jjtree)*/
-        } catch (Throwable jjte000) {
-          if (jjtc000) {
-            jjtree.clearNodeScope(jjtn000);
-            jjtc000 = false;
-          } else {
-            jjtree.popNode();
-          }
-          if (jjte000 instanceof RuntimeException) {
-            throw (RuntimeException)jjte000;
-          }
-          if (jjte000 instanceof ParseException) {
-            throw (ParseException)jjte000;
-          }
-          throw (Error)jjte000;
-        } finally {
-          if (jjtc000) {
-            jjtree.closeNodeScope(jjtn000, true);
-            jjtreeCloseNodeScope(jjtn000);
-          }
-        }
-/*@egen*/
-}
-
-void group_body() :
-{/*@bgen(jjtree) group_body */
-  ASTgroup_body jjtn000 = new ASTgroup_body(JJTGROUP_BODY);
-  boolean jjtc000 = true;
-  jjtree.openNodeScope(jjtn000);
-  jjtreeOpenNodeScope(jjtn000);
-/*@egen*/}
-{/*@bgen(jjtree) group_body */
-        try {
-/*@egen*/
-	":"
-	[ mailbox() ]
-	(
-		","
-		[ mailbox() ]
-	)*
-	";"/*@bgen(jjtree)*/
-        } catch (Throwable jjte000) {
-          if (jjtc000) {
-            jjtree.clearNodeScope(jjtn000);
-            jjtc000 = false;
-          } else {
-            jjtree.popNode();
-          }
-          if (jjte000 instanceof RuntimeException) {
-            throw (RuntimeException)jjte000;
-          }
-          if (jjte000 instanceof ParseException) {
-            throw (ParseException)jjte000;
-          }
-          throw (Error)jjte000;
-        } finally {
-          if (jjtc000) {
-            jjtree.closeNodeScope(jjtn000, true);
-            jjtreeCloseNodeScope(jjtn000);
-          }
-        }
-/*@egen*/
-}
-
-void angle_addr() :
-{/*@bgen(jjtree) angle_addr */
-  ASTangle_addr jjtn000 = new ASTangle_addr(JJTANGLE_ADDR);
-  boolean jjtc000 = true;
-  jjtree.openNodeScope(jjtn000);
-  jjtreeOpenNodeScope(jjtn000);
-/*@egen*/}
-{/*@bgen(jjtree) angle_addr */
-        try {
-/*@egen*/
-	"<" [ route() ] addr_spec() ">"/*@bgen(jjtree)*/
-        } catch (Throwable jjte000) {
-          if (jjtc000) {
-            jjtree.clearNodeScope(jjtn000);
-            jjtc000 = false;
-          } else {
-            jjtree.popNode();
-          }
-          if (jjte000 instanceof RuntimeException) {
-            throw (RuntimeException)jjte000;
-          }
-          if (jjte000 instanceof ParseException) {
-            throw (ParseException)jjte000;
-          }
-          throw (Error)jjte000;
-        } finally {
-          if (jjtc000) {
-            jjtree.closeNodeScope(jjtn000, true);
-            jjtreeCloseNodeScope(jjtn000);
-          }
-        }
-/*@egen*/
-}
-
-void route() :
-{/*@bgen(jjtree) route */
-  ASTroute jjtn000 = new ASTroute(JJTROUTE);
-  boolean jjtc000 = true;
-  jjtree.openNodeScope(jjtn000);
-  jjtreeOpenNodeScope(jjtn000);
-/*@egen*/}
-{/*@bgen(jjtree) route */
-        try {
-/*@egen*/
-	"@" domain() ( (",")* "@" domain() )* ":"/*@bgen(jjtree)*/
-        } catch (Throwable jjte000) {
-          if (jjtc000) {
-            jjtree.clearNodeScope(jjtn000);
-            jjtc000 = false;
-          } else {
-            jjtree.popNode();
-          }
-          if (jjte000 instanceof RuntimeException) {
-            throw (RuntimeException)jjte000;
-          }
-          if (jjte000 instanceof ParseException) {
-            throw (ParseException)jjte000;
-          }
-          throw (Error)jjte000;
-        } finally {
-          if (jjtc000) {
-            jjtree.closeNodeScope(jjtn000, true);
-            jjtreeCloseNodeScope(jjtn000);
-          }
-        }
-/*@egen*/
-}
-
-void phrase() :
-{/*@bgen(jjtree) phrase */
-  ASTphrase jjtn000 = new ASTphrase(JJTPHRASE);
-  boolean jjtc000 = true;
-  jjtree.openNodeScope(jjtn000);
-  jjtreeOpenNodeScope(jjtn000);
-/*@egen*/}
-{/*@bgen(jjtree) phrase */
-try {
-/*@egen*/
-(	<DOTATOM>
-|	<QUOTEDSTRING>
-)+/*@bgen(jjtree)*/
-} finally {
-  if (jjtc000) {
-    jjtree.closeNodeScope(jjtn000, true);
-    jjtreeCloseNodeScope(jjtn000);
-  }
-}
-/*@egen*/
-}
-
-void addr_spec() :
-{/*@bgen(jjtree) addr_spec */
-  ASTaddr_spec jjtn000 = new ASTaddr_spec(JJTADDR_SPEC);
-  boolean jjtc000 = true;
-  jjtree.openNodeScope(jjtn000);
-  jjtreeOpenNodeScope(jjtn000);
-/*@egen*/}
-{/*@bgen(jjtree) addr_spec */
-        try {
-/*@egen*/
-	( local_part() "@" domain() )/*@bgen(jjtree)*/
-        } catch (Throwable jjte000) {
-          if (jjtc000) {
-            jjtree.clearNodeScope(jjtn000);
-            jjtc000 = false;
-          } else {
-            jjtree.popNode();
-          }
-          if (jjte000 instanceof RuntimeException) {
-            throw (RuntimeException)jjte000;
-          }
-          if (jjte000 instanceof ParseException) {
-            throw (ParseException)jjte000;
-          }
-          throw (Error)jjte000;
-        } finally {
-          if (jjtc000) {
-            jjtree.closeNodeScope(jjtn000, true);
-            jjtreeCloseNodeScope(jjtn000);
-          }
-        }
-/*@egen*/
-}
-
-void local_part() :
-{/*@bgen(jjtree) local_part */
-  ASTlocal_part jjtn000 = new ASTlocal_part(JJTLOCAL_PART);
-  boolean jjtc000 = true;
-  jjtree.openNodeScope(jjtn000);
-  jjtreeOpenNodeScope(jjtn000);
-/*@egen*/ Token t; }
-{/*@bgen(jjtree) local_part */
-        try {
-/*@egen*/
-	( t=<DOTATOM> | t=<QUOTEDSTRING> )
-	(	[t="."]
-		{
-			if (t.image.charAt(t.image.length() - 1) != '.' || t.kind == AddressListParserConstants.QUOTEDSTRING)
-				throw new ParseException("Words in local part must be separated by '.'");
-		}
-		(	t=<DOTATOM> | t=<QUOTEDSTRING> )
-	)*/*@bgen(jjtree)*/
-        } finally {
-          if (jjtc000) {
-            jjtree.closeNodeScope(jjtn000, true);
-            jjtreeCloseNodeScope(jjtn000);
-          }
-        }
-/*@egen*/
-}
-
-void domain() :
-{/*@bgen(jjtree) domain */
-  ASTdomain jjtn000 = new ASTdomain(JJTDOMAIN);
-  boolean jjtc000 = true;
-  jjtree.openNodeScope(jjtn000);
-  jjtreeOpenNodeScope(jjtn000);
-/*@egen*/ Token t; }
-{/*@bgen(jjtree) domain */
-        try {
-/*@egen*/
-	(	t=<DOTATOM>
-		(	[t="."]
-			{
-				if (t.image.charAt(t.image.length() - 1) != '.')
-					throw new ParseException("Atoms in domain names must be separated by '.'");
-			}
-			t=<DOTATOM>
-		)*
-	)
-|	<DOMAINLITERAL>/*@bgen(jjtree)*/
-        } finally {
-          if (jjtc000) {
-            jjtree.closeNodeScope(jjtn000, true);
-            jjtreeCloseNodeScope(jjtn000);
-          }
-        }
-/*@egen*/
-}
-
-SPECIAL_TOKEN :
-{
- 	< WS: ( [" ", "\t"] )+ >
-}
-
-TOKEN :
-{
-	< #ALPHA: ["a" - "z", "A" - "Z"] >
-|	< #DIGIT: ["0" - "9"] >
-|	< #ATEXT: ( <ALPHA> | <DIGIT>
-			  | "!" | "#" | "$" | "%"
-			  | "&" | "'" | "*" | "+"
-			  | "-" | "/" | "=" | "?"
-			  | "^" | "_" | "`" | "{"
-			  | "|" | "}" | "~"
-			  )>
-|	< DOTATOM: <ATEXT> ( <ATEXT> | "." )* >
-}
-
-TOKEN_MGR_DECLS :
-{
-	// Keeps track of how many levels of comment nesting
-	// we've encountered.  This is only used when the 2nd
-	// level is reached, for example ((this)), not (this).
-	// This is because the outermost level must be treated
-	// specially anyway, because the outermost ")" has a 
-	// different token type than inner ")" instances.
-	static int commentNest;
-}
-
-MORE :
-{
-	// domain literal
-	"[" : INDOMAINLITERAL
-}
-
-<INDOMAINLITERAL>
-MORE :
-{
-	< <QUOTEDPAIR>> { image.deleteCharAt(image.length() - 2); }
-|	< ~["[", "]", "\\"] >
-}
-
-<INDOMAINLITERAL>
-TOKEN :
-{
-	< DOMAINLITERAL: "]" > { matchedToken.image = image.toString(); }: DEFAULT
-}
-
-MORE :
-{
-	// starts a comment
-	"(" : INCOMMENT
-}
-
-<INCOMMENT>
-SKIP :
-{
-	// ends a comment
-	< COMMENT: ")" > : DEFAULT
-	// if this is ever changed to not be a SKIP, need
-	// to make sure matchedToken.token = token.toString()
-	// is called.
-}
-
-<INCOMMENT>
-MORE :
-{
-	< <QUOTEDPAIR>> { image.deleteCharAt(image.length() - 2); }
-|	"(" { commentNest = 1; } : NESTED_COMMENT
-|	< <ANY>>
-}
-
-<NESTED_COMMENT>
-MORE :
-{
-	< <QUOTEDPAIR>> { image.deleteCharAt(image.length() - 2); }
-|	"(" { ++commentNest; }
-|	")" { --commentNest; if (commentNest == 0) SwitchTo(INCOMMENT); }
-|	< <ANY>>
-}
-
-
-// QUOTED STRINGS
-
-MORE :
-{
-	"\"" { image.deleteCharAt(image.length() - 1); } : INQUOTEDSTRING
-}
-
-<INQUOTEDSTRING>
-MORE :
-{
-	< <QUOTEDPAIR>> { image.deleteCharAt(image.length() - 2); }
-|	< (~["\"", "\\"])+ >
-}
-
-<INQUOTEDSTRING>
-TOKEN :
-{
-	< QUOTEDSTRING: "\"" > { matchedToken.image = image.substring(0, image.length() - 1); } : DEFAULT
-}
-
-// GLOBALS
-
-<*>
-TOKEN :
-{
-	< #QUOTEDPAIR: "\\" <ANY> >
-|	< #ANY: ~[] >
-}
-
-// ERROR!
-/*
-
-<*>
-TOKEN :
-{
-	< UNEXPECTED_CHAR: <ANY> >
-}
-
-*/
\ No newline at end of file
diff --git a/src/org/apache/james/mime4j/field/address/parser/AddressListParserConstants.java b/src/org/apache/james/mime4j/field/address/parser/AddressListParserConstants.java
deleted file mode 100644
index 006a082..0000000
--- a/src/org/apache/james/mime4j/field/address/parser/AddressListParserConstants.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/* Generated By:JJTree&JavaCC: Do not edit this line. AddressListParserConstants.java */
-/*
- *  Copyright 2004 the mime4j 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 org.apache.james.mime4j.field.address.parser;
-
-public interface AddressListParserConstants {
-
-  int EOF = 0;
-  int WS = 10;
-  int ALPHA = 11;
-  int DIGIT = 12;
-  int ATEXT = 13;
-  int DOTATOM = 14;
-  int DOMAINLITERAL = 18;
-  int COMMENT = 20;
-  int QUOTEDSTRING = 31;
-  int QUOTEDPAIR = 32;
-  int ANY = 33;
-
-  int DEFAULT = 0;
-  int INDOMAINLITERAL = 1;
-  int INCOMMENT = 2;
-  int NESTED_COMMENT = 3;
-  int INQUOTEDSTRING = 4;
-
-  String[] tokenImage = {
-    "<EOF>",
-    "\"\\r\"",
-    "\"\\n\"",
-    "\",\"",
-    "\":\"",
-    "\";\"",
-    "\"<\"",
-    "\">\"",
-    "\"@\"",
-    "\".\"",
-    "<WS>",
-    "<ALPHA>",
-    "<DIGIT>",
-    "<ATEXT>",
-    "<DOTATOM>",
-    "\"[\"",
-    "<token of kind 16>",
-    "<token of kind 17>",
-    "\"]\"",
-    "\"(\"",
-    "\")\"",
-    "<token of kind 21>",
-    "\"(\"",
-    "<token of kind 23>",
-    "<token of kind 24>",
-    "\"(\"",
-    "\")\"",
-    "<token of kind 27>",
-    "\"\\\"\"",
-    "<token of kind 29>",
-    "<token of kind 30>",
-    "\"\\\"\"",
-    "<QUOTEDPAIR>",
-    "<ANY>",
-  };
-
-}
diff --git a/src/org/apache/james/mime4j/field/address/parser/AddressListParserTokenManager.java b/src/org/apache/james/mime4j/field/address/parser/AddressListParserTokenManager.java
deleted file mode 100644
index d2dd88d..0000000
--- a/src/org/apache/james/mime4j/field/address/parser/AddressListParserTokenManager.java
+++ /dev/null
@@ -1,1009 +0,0 @@
-/* Generated By:JJTree&JavaCC: Do not edit this line. AddressListParserTokenManager.java */
-/*
- *  Copyright 2004 the mime4j 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 org.apache.james.mime4j.field.address.parser;
-
-public class AddressListParserTokenManager implements AddressListParserConstants
-{
-        // Keeps track of how many levels of comment nesting
-        // we've encountered.  This is only used when the 2nd
-        // level is reached, for example ((this)), not (this).
-        // This is because the outermost level must be treated
-        // specially anyway, because the outermost ")" has a 
-        // different token type than inner ")" instances.
-        static int commentNest;
-  public  java.io.PrintStream debugStream = System.out;
-  public  void setDebugStream(java.io.PrintStream ds) { debugStream = ds; }
-private final int jjStopStringLiteralDfa_0(int pos, long active0)
-{
-   switch (pos)
-   {
-      default :
-         return -1;
-   }
-}
-private final int jjStartNfa_0(int pos, long active0)
-{
-   return jjMoveNfa_0(jjStopStringLiteralDfa_0(pos, active0), pos + 1);
-}
-private final int jjStopAtPos(int pos, int kind)
-{
-   jjmatchedKind = kind;
-   jjmatchedPos = pos;
-   return pos + 1;
-}
-private final int jjStartNfaWithStates_0(int pos, int kind, int state)
-{
-   jjmatchedKind = kind;
-   jjmatchedPos = pos;
-   try { curChar = input_stream.readChar(); }
-   catch(java.io.IOException e) { return pos + 1; }
-   return jjMoveNfa_0(state, pos + 1);
-}
-private final int jjMoveStringLiteralDfa0_0()
-{
-   switch(curChar)
-   {
-      case 10:
-         return jjStopAtPos(0, 2);
-      case 13:
-         return jjStopAtPos(0, 1);
-      case 34:
-         return jjStopAtPos(0, 28);
-      case 40:
-         return jjStopAtPos(0, 19);
-      case 44:
-         return jjStopAtPos(0, 3);
-      case 46:
-         return jjStopAtPos(0, 9);
-      case 58:
-         return jjStopAtPos(0, 4);
-      case 59:
-         return jjStopAtPos(0, 5);
-      case 60:
-         return jjStopAtPos(0, 6);
-      case 62:
-         return jjStopAtPos(0, 7);
-      case 64:
-         return jjStopAtPos(0, 8);
-      case 91:
-         return jjStopAtPos(0, 15);
-      default :
-         return jjMoveNfa_0(1, 0);
-   }
-}
-private final void jjCheckNAdd(int state)
-{
-   if (jjrounds[state] != jjround)
-   {
-      jjstateSet[jjnewStateCnt++] = state;
-      jjrounds[state] = jjround;
-   }
-}
-private final void jjAddStates(int start, int end)
-{
-   do {
-      jjstateSet[jjnewStateCnt++] = jjnextStates[start];
-   } while (start++ != end);
-}
-private final void jjCheckNAddTwoStates(int state1, int state2)
-{
-   jjCheckNAdd(state1);
-   jjCheckNAdd(state2);
-}
-private final void jjCheckNAddStates(int start, int end)
-{
-   do {
-      jjCheckNAdd(jjnextStates[start]);
-   } while (start++ != end);
-}
-private final void jjCheckNAddStates(int start)
-{
-   jjCheckNAdd(jjnextStates[start]);
-   jjCheckNAdd(jjnextStates[start + 1]);
-}
-private final int jjMoveNfa_0(int startState, int curPos)
-{
-   int[] nextStates;
-   int startsAt = 0;
-   jjnewStateCnt = 3;
-   int i = 1;
-   jjstateSet[0] = startState;
-   int j, kind = 0x7fffffff;
-   for (;;)
-   {
-      if (++jjround == 0x7fffffff)
-         ReInitRounds();
-      if (curChar < 64)
-      {
-         long l = 1L << curChar;
-         MatchLoop: do
-         {
-            switch(jjstateSet[--i])
-            {
-               case 1:
-                  if ((0xa3ffacfa00000000L & l) != 0L)
-                  {
-                     if (kind > 14)
-                        kind = 14;
-                     jjCheckNAdd(2);
-                  }
-                  else if ((0x100000200L & l) != 0L)
-                  {
-                     if (kind > 10)
-                        kind = 10;
-                     jjCheckNAdd(0);
-                  }
-                  break;
-               case 0:
-                  if ((0x100000200L & l) == 0L)
-                     break;
-                  kind = 10;
-                  jjCheckNAdd(0);
-                  break;
-               case 2:
-                  if ((0xa3ffecfa00000000L & l) == 0L)
-                     break;
-                  if (kind > 14)
-                     kind = 14;
-                  jjCheckNAdd(2);
-                  break;
-               default : break;
-            }
-         } while(i != startsAt);
-      }
-      else if (curChar < 128)
-      {
-         long l = 1L << (curChar & 077);
-         MatchLoop: do
-         {
-            switch(jjstateSet[--i])
-            {
-               case 1:
-               case 2:
-                  if ((0x7fffffffc7fffffeL & l) == 0L)
-                     break;
-                  if (kind > 14)
-                     kind = 14;
-                  jjCheckNAdd(2);
-                  break;
-               default : break;
-            }
-         } while(i != startsAt);
-      }
-      else
-      {
-         int i2 = (curChar & 0xff) >> 6;
-         long l2 = 1L << (curChar & 077);
-         MatchLoop: do
-         {
-            switch(jjstateSet[--i])
-            {
-               default : break;
-            }
-         } while(i != startsAt);
-      }
-      if (kind != 0x7fffffff)
-      {
-         jjmatchedKind = kind;
-         jjmatchedPos = curPos;
-         kind = 0x7fffffff;
-      }
-      ++curPos;
-      if ((i = jjnewStateCnt) == (startsAt = 3 - (jjnewStateCnt = startsAt)))
-         return curPos;
-      try { curChar = input_stream.readChar(); }
-      catch(java.io.IOException e) { return curPos; }
-   }
-}
-private final int jjStopStringLiteralDfa_2(int pos, long active0)
-{
-   switch (pos)
-   {
-      default :
-         return -1;
-   }
-}
-private final int jjStartNfa_2(int pos, long active0)
-{
-   return jjMoveNfa_2(jjStopStringLiteralDfa_2(pos, active0), pos + 1);
-}
-private final int jjStartNfaWithStates_2(int pos, int kind, int state)
-{
-   jjmatchedKind = kind;
-   jjmatchedPos = pos;
-   try { curChar = input_stream.readChar(); }
-   catch(java.io.IOException e) { return pos + 1; }
-   return jjMoveNfa_2(state, pos + 1);
-}
-private final int jjMoveStringLiteralDfa0_2()
-{
-   switch(curChar)
-   {
-      case 40:
-         return jjStopAtPos(0, 22);
-      case 41:
-         return jjStopAtPos(0, 20);
-      default :
-         return jjMoveNfa_2(0, 0);
-   }
-}
-static final long[] jjbitVec0 = {
-   0x0L, 0x0L, 0xffffffffffffffffL, 0xffffffffffffffffL
-};
-private final int jjMoveNfa_2(int startState, int curPos)
-{
-   int[] nextStates;
-   int startsAt = 0;
-   jjnewStateCnt = 3;
-   int i = 1;
-   jjstateSet[0] = startState;
-   int j, kind = 0x7fffffff;
-   for (;;)
-   {
-      if (++jjround == 0x7fffffff)
-         ReInitRounds();
-      if (curChar < 64)
-      {
-         long l = 1L << curChar;
-         MatchLoop: do
-         {
-            switch(jjstateSet[--i])
-            {
-               case 0:
-                  if (kind > 23)
-                     kind = 23;
-                  break;
-               case 1:
-                  if (kind > 21)
-                     kind = 21;
-                  break;
-               default : break;
-            }
-         } while(i != startsAt);
-      }
-      else if (curChar < 128)
-      {
-         long l = 1L << (curChar & 077);
-         MatchLoop: do
-         {
-            switch(jjstateSet[--i])
-            {
-               case 0:
-                  if (kind > 23)
-                     kind = 23;
-                  if (curChar == 92)
-                     jjstateSet[jjnewStateCnt++] = 1;
-                  break;
-               case 1:
-                  if (kind > 21)
-                     kind = 21;
-                  break;
-               case 2:
-                  if (kind > 23)
-                     kind = 23;
-                  break;
-               default : break;
-            }
-         } while(i != startsAt);
-      }
-      else
-      {
-         int i2 = (curChar & 0xff) >> 6;
-         long l2 = 1L << (curChar & 077);
-         MatchLoop: do
-         {
-            switch(jjstateSet[--i])
-            {
-               case 0:
-                  if ((jjbitVec0[i2] & l2) != 0L && kind > 23)
-                     kind = 23;
-                  break;
-               case 1:
-                  if ((jjbitVec0[i2] & l2) != 0L && kind > 21)
-                     kind = 21;
-                  break;
-               default : break;
-            }
-         } while(i != startsAt);
-      }
-      if (kind != 0x7fffffff)
-      {
-         jjmatchedKind = kind;
-         jjmatchedPos = curPos;
-         kind = 0x7fffffff;
-      }
-      ++curPos;
-      if ((i = jjnewStateCnt) == (startsAt = 3 - (jjnewStateCnt = startsAt)))
-         return curPos;
-      try { curChar = input_stream.readChar(); }
-      catch(java.io.IOException e) { return curPos; }
-   }
-}
-private final int jjStopStringLiteralDfa_4(int pos, long active0)
-{
-   switch (pos)
-   {
-      default :
-         return -1;
-   }
-}
-private final int jjStartNfa_4(int pos, long active0)
-{
-   return jjMoveNfa_4(jjStopStringLiteralDfa_4(pos, active0), pos + 1);
-}
-private final int jjStartNfaWithStates_4(int pos, int kind, int state)
-{
-   jjmatchedKind = kind;
-   jjmatchedPos = pos;
-   try { curChar = input_stream.readChar(); }
-   catch(java.io.IOException e) { return pos + 1; }
-   return jjMoveNfa_4(state, pos + 1);
-}
-private final int jjMoveStringLiteralDfa0_4()
-{
-   switch(curChar)
-   {
-      case 34:
-         return jjStopAtPos(0, 31);
-      default :
-         return jjMoveNfa_4(0, 0);
-   }
-}
-private final int jjMoveNfa_4(int startState, int curPos)
-{
-   int[] nextStates;
-   int startsAt = 0;
-   jjnewStateCnt = 3;
-   int i = 1;
-   jjstateSet[0] = startState;
-   int j, kind = 0x7fffffff;
-   for (;;)
-   {
-      if (++jjround == 0x7fffffff)
-         ReInitRounds();
-      if (curChar < 64)
-      {
-         long l = 1L << curChar;
-         MatchLoop: do
-         {
-            switch(jjstateSet[--i])
-            {
-               case 0:
-               case 2:
-                  if ((0xfffffffbffffffffL & l) == 0L)
-                     break;
-                  if (kind > 30)
-                     kind = 30;
-                  jjCheckNAdd(2);
-                  break;
-               case 1:
-                  if (kind > 29)
-                     kind = 29;
-                  break;
-               default : break;
-            }
-         } while(i != startsAt);
-      }
-      else if (curChar < 128)
-      {
-         long l = 1L << (curChar & 077);
-         MatchLoop: do
-         {
-            switch(jjstateSet[--i])
-            {
-               case 0:
-                  if ((0xffffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 30)
-                        kind = 30;
-                     jjCheckNAdd(2);
-                  }
-                  else if (curChar == 92)
-                     jjstateSet[jjnewStateCnt++] = 1;
-                  break;
-               case 1:
-                  if (kind > 29)
-                     kind = 29;
-                  break;
-               case 2:
-                  if ((0xffffffffefffffffL & l) == 0L)
-                     break;
-                  if (kind > 30)
-                     kind = 30;
-                  jjCheckNAdd(2);
-                  break;
-               default : break;
-            }
-         } while(i != startsAt);
-      }
-      else
-      {
-         int i2 = (curChar & 0xff) >> 6;
-         long l2 = 1L << (curChar & 077);
-         MatchLoop: do
-         {
-            switch(jjstateSet[--i])
-            {
-               case 0:
-               case 2:
-                  if ((jjbitVec0[i2] & l2) == 0L)
-                     break;
-                  if (kind > 30)
-                     kind = 30;
-                  jjCheckNAdd(2);
-                  break;
-               case 1:
-                  if ((jjbitVec0[i2] & l2) != 0L && kind > 29)
-                     kind = 29;
-                  break;
-               default : break;
-            }
-         } while(i != startsAt);
-      }
-      if (kind != 0x7fffffff)
-      {
-         jjmatchedKind = kind;
-         jjmatchedPos = curPos;
-         kind = 0x7fffffff;
-      }
-      ++curPos;
-      if ((i = jjnewStateCnt) == (startsAt = 3 - (jjnewStateCnt = startsAt)))
-         return curPos;
-      try { curChar = input_stream.readChar(); }
-      catch(java.io.IOException e) { return curPos; }
-   }
-}
-private final int jjStopStringLiteralDfa_3(int pos, long active0)
-{
-   switch (pos)
-   {
-      default :
-         return -1;
-   }
-}
-private final int jjStartNfa_3(int pos, long active0)
-{
-   return jjMoveNfa_3(jjStopStringLiteralDfa_3(pos, active0), pos + 1);
-}
-private final int jjStartNfaWithStates_3(int pos, int kind, int state)
-{
-   jjmatchedKind = kind;
-   jjmatchedPos = pos;
-   try { curChar = input_stream.readChar(); }
-   catch(java.io.IOException e) { return pos + 1; }
-   return jjMoveNfa_3(state, pos + 1);
-}
-private final int jjMoveStringLiteralDfa0_3()
-{
-   switch(curChar)
-   {
-      case 40:
-         return jjStopAtPos(0, 25);
-      case 41:
-         return jjStopAtPos(0, 26);
-      default :
-         return jjMoveNfa_3(0, 0);
-   }
-}
-private final int jjMoveNfa_3(int startState, int curPos)
-{
-   int[] nextStates;
-   int startsAt = 0;
-   jjnewStateCnt = 3;
-   int i = 1;
-   jjstateSet[0] = startState;
-   int j, kind = 0x7fffffff;
-   for (;;)
-   {
-      if (++jjround == 0x7fffffff)
-         ReInitRounds();
-      if (curChar < 64)
-      {
-         long l = 1L << curChar;
-         MatchLoop: do
-         {
-            switch(jjstateSet[--i])
-            {
-               case 0:
-                  if (kind > 27)
-                     kind = 27;
-                  break;
-               case 1:
-                  if (kind > 24)
-                     kind = 24;
-                  break;
-               default : break;
-            }
-         } while(i != startsAt);
-      }
-      else if (curChar < 128)
-      {
-         long l = 1L << (curChar & 077);
-         MatchLoop: do
-         {
-            switch(jjstateSet[--i])
-            {
-               case 0:
-                  if (kind > 27)
-                     kind = 27;
-                  if (curChar == 92)
-                     jjstateSet[jjnewStateCnt++] = 1;
-                  break;
-               case 1:
-                  if (kind > 24)
-                     kind = 24;
-                  break;
-               case 2:
-                  if (kind > 27)
-                     kind = 27;
-                  break;
-               default : break;
-            }
-         } while(i != startsAt);
-      }
-      else
-      {
-         int i2 = (curChar & 0xff) >> 6;
-         long l2 = 1L << (curChar & 077);
-         MatchLoop: do
-         {
-            switch(jjstateSet[--i])
-            {
-               case 0:
-                  if ((jjbitVec0[i2] & l2) != 0L && kind > 27)
-                     kind = 27;
-                  break;
-               case 1:
-                  if ((jjbitVec0[i2] & l2) != 0L && kind > 24)
-                     kind = 24;
-                  break;
-               default : break;
-            }
-         } while(i != startsAt);
-      }
-      if (kind != 0x7fffffff)
-      {
-         jjmatchedKind = kind;
-         jjmatchedPos = curPos;
-         kind = 0x7fffffff;
-      }
-      ++curPos;
-      if ((i = jjnewStateCnt) == (startsAt = 3 - (jjnewStateCnt = startsAt)))
-         return curPos;
-      try { curChar = input_stream.readChar(); }
-      catch(java.io.IOException e) { return curPos; }
-   }
-}
-private final int jjStopStringLiteralDfa_1(int pos, long active0)
-{
-   switch (pos)
-   {
-      default :
-         return -1;
-   }
-}
-private final int jjStartNfa_1(int pos, long active0)
-{
-   return jjMoveNfa_1(jjStopStringLiteralDfa_1(pos, active0), pos + 1);
-}
-private final int jjStartNfaWithStates_1(int pos, int kind, int state)
-{
-   jjmatchedKind = kind;
-   jjmatchedPos = pos;
-   try { curChar = input_stream.readChar(); }
-   catch(java.io.IOException e) { return pos + 1; }
-   return jjMoveNfa_1(state, pos + 1);
-}
-private final int jjMoveStringLiteralDfa0_1()
-{
-   switch(curChar)
-   {
-      case 93:
-         return jjStopAtPos(0, 18);
-      default :
-         return jjMoveNfa_1(0, 0);
-   }
-}
-private final int jjMoveNfa_1(int startState, int curPos)
-{
-   int[] nextStates;
-   int startsAt = 0;
-   jjnewStateCnt = 3;
-   int i = 1;
-   jjstateSet[0] = startState;
-   int j, kind = 0x7fffffff;
-   for (;;)
-   {
-      if (++jjround == 0x7fffffff)
-         ReInitRounds();
-      if (curChar < 64)
-      {
-         long l = 1L << curChar;
-         MatchLoop: do
-         {
-            switch(jjstateSet[--i])
-            {
-               case 0:
-                  if (kind > 17)
-                     kind = 17;
-                  break;
-               case 1:
-                  if (kind > 16)
-                     kind = 16;
-                  break;
-               default : break;
-            }
-         } while(i != startsAt);
-      }
-      else if (curChar < 128)
-      {
-         long l = 1L << (curChar & 077);
-         MatchLoop: do
-         {
-            switch(jjstateSet[--i])
-            {
-               case 0:
-                  if ((0xffffffffc7ffffffL & l) != 0L)
-                  {
-                     if (kind > 17)
-                        kind = 17;
-                  }
-                  else if (curChar == 92)
-                     jjstateSet[jjnewStateCnt++] = 1;
-                  break;
-               case 1:
-                  if (kind > 16)
-                     kind = 16;
-                  break;
-               case 2:
-                  if ((0xffffffffc7ffffffL & l) != 0L && kind > 17)
-                     kind = 17;
-                  break;
-               default : break;
-            }
-         } while(i != startsAt);
-      }
-      else
-      {
-         int i2 = (curChar & 0xff) >> 6;
-         long l2 = 1L << (curChar & 077);
-         MatchLoop: do
-         {
-            switch(jjstateSet[--i])
-            {
-               case 0:
-                  if ((jjbitVec0[i2] & l2) != 0L && kind > 17)
-                     kind = 17;
-                  break;
-               case 1:
-                  if ((jjbitVec0[i2] & l2) != 0L && kind > 16)
-                     kind = 16;
-                  break;
-               default : break;
-            }
-         } while(i != startsAt);
-      }
-      if (kind != 0x7fffffff)
-      {
-         jjmatchedKind = kind;
-         jjmatchedPos = curPos;
-         kind = 0x7fffffff;
-      }
-      ++curPos;
-      if ((i = jjnewStateCnt) == (startsAt = 3 - (jjnewStateCnt = startsAt)))
-         return curPos;
-      try { curChar = input_stream.readChar(); }
-      catch(java.io.IOException e) { return curPos; }
-   }
-}
-static final int[] jjnextStates = {
-};
-public static final String[] jjstrLiteralImages = {
-"", "\15", "\12", "\54", "\72", "\73", "\74", "\76", "\100", "\56", null, null, 
-null, null, null, null, null, null, null, null, null, null, null, null, null, null, 
-null, null, null, null, null, null, null, null, };
-public static final String[] lexStateNames = {
-   "DEFAULT", 
-   "INDOMAINLITERAL", 
-   "INCOMMENT", 
-   "NESTED_COMMENT", 
-   "INQUOTEDSTRING", 
-};
-public static final int[] jjnewLexState = {
-   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, 0, 2, 0, -1, 3, -1, -1, 
-   -1, -1, -1, 4, -1, -1, 0, -1, -1, 
-};
-static final long[] jjtoToken = {
-   0x800443ffL, 
-};
-static final long[] jjtoSkip = {
-   0x100400L, 
-};
-static final long[] jjtoSpecial = {
-   0x400L, 
-};
-static final long[] jjtoMore = {
-   0x7feb8000L, 
-};
-protected SimpleCharStream input_stream;
-private final int[] jjrounds = new int[3];
-private final int[] jjstateSet = new int[6];
-StringBuffer image;
-int jjimageLen;
-int lengthOfMatch;
-protected char curChar;
-public AddressListParserTokenManager(SimpleCharStream stream){
-   if (SimpleCharStream.staticFlag)
-      throw new Error("ERROR: Cannot use a static CharStream class with a non-static lexical analyzer.");
-   input_stream = stream;
-}
-public AddressListParserTokenManager(SimpleCharStream stream, int lexState){
-   this(stream);
-   SwitchTo(lexState);
-}
-public void ReInit(SimpleCharStream stream)
-{
-   jjmatchedPos = jjnewStateCnt = 0;
-   curLexState = defaultLexState;
-   input_stream = stream;
-   ReInitRounds();
-}
-private final void ReInitRounds()
-{
-   int i;
-   jjround = 0x80000001;
-   for (i = 3; i-- > 0;)
-      jjrounds[i] = 0x80000000;
-}
-public void ReInit(SimpleCharStream stream, int lexState)
-{
-   ReInit(stream);
-   SwitchTo(lexState);
-}
-public void SwitchTo(int lexState)
-{
-   if (lexState >= 5 || lexState < 0)
-      throw new TokenMgrError("Error: Ignoring invalid lexical state : " + lexState + ". State unchanged.", TokenMgrError.INVALID_LEXICAL_STATE);
-   else
-      curLexState = lexState;
-}
-
-protected Token jjFillToken()
-{
-   Token t = Token.newToken(jjmatchedKind);
-   t.kind = jjmatchedKind;
-   String im = jjstrLiteralImages[jjmatchedKind];
-   t.image = (im == null) ? input_stream.GetImage() : im;
-   t.beginLine = input_stream.getBeginLine();
-   t.beginColumn = input_stream.getBeginColumn();
-   t.endLine = input_stream.getEndLine();
-   t.endColumn = input_stream.getEndColumn();
-   return t;
-}
-
-int curLexState = 0;
-int defaultLexState = 0;
-int jjnewStateCnt;
-int jjround;
-int jjmatchedPos;
-int jjmatchedKind;
-
-public Token getNextToken() 
-{
-  int kind;
-  Token specialToken = null;
-  Token matchedToken;
-  int curPos = 0;
-
-  EOFLoop :
-  for (;;)
-  {   
-   try   
-   {     
-      curChar = input_stream.BeginToken();
-   }     
-   catch(java.io.IOException e)
-   {        
-      jjmatchedKind = 0;
-      matchedToken = jjFillToken();
-      matchedToken.specialToken = specialToken;
-      return matchedToken;
-   }
-   image = null;
-   jjimageLen = 0;
-
-   for (;;)
-   {
-     switch(curLexState)
-     {
-       case 0:
-         jjmatchedKind = 0x7fffffff;
-         jjmatchedPos = 0;
-         curPos = jjMoveStringLiteralDfa0_0();
-         break;
-       case 1:
-         jjmatchedKind = 0x7fffffff;
-         jjmatchedPos = 0;
-         curPos = jjMoveStringLiteralDfa0_1();
-         break;
-       case 2:
-         jjmatchedKind = 0x7fffffff;
-         jjmatchedPos = 0;
-         curPos = jjMoveStringLiteralDfa0_2();
-         break;
-       case 3:
-         jjmatchedKind = 0x7fffffff;
-         jjmatchedPos = 0;
-         curPos = jjMoveStringLiteralDfa0_3();
-         break;
-       case 4:
-         jjmatchedKind = 0x7fffffff;
-         jjmatchedPos = 0;
-         curPos = jjMoveStringLiteralDfa0_4();
-         break;
-     }
-     if (jjmatchedKind != 0x7fffffff)
-     {
-        if (jjmatchedPos + 1 < curPos)
-           input_stream.backup(curPos - jjmatchedPos - 1);
-        if ((jjtoToken[jjmatchedKind >> 6] & (1L << (jjmatchedKind & 077))) != 0L)
-        {
-           matchedToken = jjFillToken();
-           matchedToken.specialToken = specialToken;
-           TokenLexicalActions(matchedToken);
-       if (jjnewLexState[jjmatchedKind] != -1)
-         curLexState = jjnewLexState[jjmatchedKind];
-           return matchedToken;
-        }
-        else if ((jjtoSkip[jjmatchedKind >> 6] & (1L << (jjmatchedKind & 077))) != 0L)
-        {
-           if ((jjtoSpecial[jjmatchedKind >> 6] & (1L << (jjmatchedKind & 077))) != 0L)
-           {
-              matchedToken = jjFillToken();
-              if (specialToken == null)
-                 specialToken = matchedToken;
-              else
-              {
-                 matchedToken.specialToken = specialToken;
-                 specialToken = (specialToken.next = matchedToken);
-              }
-           }
-         if (jjnewLexState[jjmatchedKind] != -1)
-           curLexState = jjnewLexState[jjmatchedKind];
-           continue EOFLoop;
-        }
-        MoreLexicalActions();
-      if (jjnewLexState[jjmatchedKind] != -1)
-        curLexState = jjnewLexState[jjmatchedKind];
-        curPos = 0;
-        jjmatchedKind = 0x7fffffff;
-        try {
-           curChar = input_stream.readChar();
-           continue;
-        }
-        catch (java.io.IOException e1) { }
-     }
-     int error_line = input_stream.getEndLine();
-     int error_column = input_stream.getEndColumn();
-     String error_after = null;
-     boolean EOFSeen = false;
-     try { input_stream.readChar(); input_stream.backup(1); }
-     catch (java.io.IOException e1) {
-        EOFSeen = true;
-        error_after = curPos <= 1 ? "" : input_stream.GetImage();
-        if (curChar == '\n' || curChar == '\r') {
-           error_line++;
-           error_column = 0;
-        }
-        else
-           error_column++;
-     }
-     if (!EOFSeen) {
-        input_stream.backup(1);
-        error_after = curPos <= 1 ? "" : input_stream.GetImage();
-     }
-     throw new TokenMgrError(EOFSeen, curLexState, error_line, error_column, error_after, curChar, TokenMgrError.LEXICAL_ERROR);
-   }
-  }
-}
-
-void MoreLexicalActions()
-{
-   jjimageLen += (lengthOfMatch = jjmatchedPos + 1);
-   switch(jjmatchedKind)
-   {
-      case 16 :
-         if (image == null)
-            image = new StringBuffer();
-         image.append(input_stream.GetSuffix(jjimageLen));
-         jjimageLen = 0;
-                          image.deleteCharAt(image.length() - 2);
-         break;
-      case 21 :
-         if (image == null)
-            image = new StringBuffer();
-         image.append(input_stream.GetSuffix(jjimageLen));
-         jjimageLen = 0;
-                          image.deleteCharAt(image.length() - 2);
-         break;
-      case 22 :
-         if (image == null)
-            image = new StringBuffer();
-         image.append(input_stream.GetSuffix(jjimageLen));
-         jjimageLen = 0;
-              commentNest = 1;
-         break;
-      case 24 :
-         if (image == null)
-            image = new StringBuffer();
-         image.append(input_stream.GetSuffix(jjimageLen));
-         jjimageLen = 0;
-                          image.deleteCharAt(image.length() - 2);
-         break;
-      case 25 :
-         if (image == null)
-            image = new StringBuffer();
-         image.append(input_stream.GetSuffix(jjimageLen));
-         jjimageLen = 0;
-              ++commentNest;
-         break;
-      case 26 :
-         if (image == null)
-            image = new StringBuffer();
-         image.append(input_stream.GetSuffix(jjimageLen));
-         jjimageLen = 0;
-              --commentNest; if (commentNest == 0) SwitchTo(INCOMMENT);
-         break;
-      case 28 :
-         if (image == null)
-            image = new StringBuffer();
-         image.append(input_stream.GetSuffix(jjimageLen));
-         jjimageLen = 0;
-               image.deleteCharAt(image.length() - 1);
-         break;
-      case 29 :
-         if (image == null)
-            image = new StringBuffer();
-         image.append(input_stream.GetSuffix(jjimageLen));
-         jjimageLen = 0;
-                          image.deleteCharAt(image.length() - 2);
-         break;
-      default : 
-         break;
-   }
-}
-void TokenLexicalActions(Token matchedToken)
-{
-   switch(jjmatchedKind)
-   {
-      case 18 :
-        if (image == null)
-            image = new StringBuffer();
-            image.append(input_stream.GetSuffix(jjimageLen + (lengthOfMatch = jjmatchedPos + 1)));
-                                 matchedToken.image = image.toString();
-         break;
-      case 31 :
-        if (image == null)
-            image = new StringBuffer();
-            image.append(input_stream.GetSuffix(jjimageLen + (lengthOfMatch = jjmatchedPos + 1)));
-                                 matchedToken.image = image.substring(0, image.length() - 1);
-         break;
-      default : 
-         break;
-   }
-}
-}
diff --git a/src/org/apache/james/mime4j/field/address/parser/AddressListParserTreeConstants.java b/src/org/apache/james/mime4j/field/address/parser/AddressListParserTreeConstants.java
deleted file mode 100644
index 5987f19..0000000
--- a/src/org/apache/james/mime4j/field/address/parser/AddressListParserTreeConstants.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/* Generated By:JJTree: Do not edit this line. /Users/jason/Projects/apache-mime4j-0.3/target/generated-sources/jjtree/org/apache/james/mime4j/field/address/parser/AddressListParserTreeConstants.java */
-
-package org.apache.james.mime4j.field.address.parser;
-
-public interface AddressListParserTreeConstants
-{
-  public int JJTVOID = 0;
-  public int JJTADDRESS_LIST = 1;
-  public int JJTADDRESS = 2;
-  public int JJTMAILBOX = 3;
-  public int JJTNAME_ADDR = 4;
-  public int JJTGROUP_BODY = 5;
-  public int JJTANGLE_ADDR = 6;
-  public int JJTROUTE = 7;
-  public int JJTPHRASE = 8;
-  public int JJTADDR_SPEC = 9;
-  public int JJTLOCAL_PART = 10;
-  public int JJTDOMAIN = 11;
-
-
-  public String[] jjtNodeName = {
-    "void",
-    "address_list",
-    "address",
-    "mailbox",
-    "name_addr",
-    "group_body",
-    "angle_addr",
-    "route",
-    "phrase",
-    "addr_spec",
-    "local_part",
-    "domain",
-  };
-}
diff --git a/src/org/apache/james/mime4j/field/address/parser/AddressListParserVisitor.java b/src/org/apache/james/mime4j/field/address/parser/AddressListParserVisitor.java
deleted file mode 100644
index 8ec2fe7..0000000
--- a/src/org/apache/james/mime4j/field/address/parser/AddressListParserVisitor.java
+++ /dev/null
@@ -1,19 +0,0 @@
-/* Generated By:JJTree: Do not edit this line. /Users/jason/Projects/apache-mime4j-0.3/target/generated-sources/jjtree/org/apache/james/mime4j/field/address/parser/AddressListParserVisitor.java */
-
-package org.apache.james.mime4j.field.address.parser;
-
-public interface AddressListParserVisitor
-{
-  public Object visit(SimpleNode node, Object data);
-  public Object visit(ASTaddress_list node, Object data);
-  public Object visit(ASTaddress node, Object data);
-  public Object visit(ASTmailbox node, Object data);
-  public Object visit(ASTname_addr node, Object data);
-  public Object visit(ASTgroup_body node, Object data);
-  public Object visit(ASTangle_addr node, Object data);
-  public Object visit(ASTroute node, Object data);
-  public Object visit(ASTphrase node, Object data);
-  public Object visit(ASTaddr_spec node, Object data);
-  public Object visit(ASTlocal_part node, Object data);
-  public Object visit(ASTdomain node, Object data);
-}
diff --git a/src/org/apache/james/mime4j/field/address/parser/BaseNode.java b/src/org/apache/james/mime4j/field/address/parser/BaseNode.java
deleted file mode 100644
index 7809746..0000000
--- a/src/org/apache/james/mime4j/field/address/parser/BaseNode.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one   *
- * or more contributor license agreements.  See the NOTICE file *
- * distributed with this work for additional information        *
- * regarding copyright ownership.  The ASF licenses this file   *
- * to you 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 org.apache.james.mime4j.field.address.parser;
-
-import org.apache.james.mime4j.field.address.parser.Node;
-import org.apache.james.mime4j.field.address.parser.Token;
-
-public abstract class BaseNode implements Node {
-  
-  public Token firstToken;
-  public Token lastToken;
-
-}
\ No newline at end of file
diff --git a/src/org/apache/james/mime4j/field/address/parser/JJTAddressListParserState.java b/src/org/apache/james/mime4j/field/address/parser/JJTAddressListParserState.java
deleted file mode 100644
index 08b5c5b..0000000
--- a/src/org/apache/james/mime4j/field/address/parser/JJTAddressListParserState.java
+++ /dev/null
@@ -1,123 +0,0 @@
-/* Generated By:JJTree: Do not edit this line. /Users/jason/Projects/apache-mime4j-0.3/target/generated-sources/jjtree/org/apache/james/mime4j/field/address/parser/JJTAddressListParserState.java */
-
-package org.apache.james.mime4j.field.address.parser;
-
-class JJTAddressListParserState {
-  private java.util.Stack<Node> nodes;
-  private java.util.Stack<Integer> marks;
-
-  private int sp;		// number of nodes on stack
-  private int mk;		// current mark
-  private boolean node_created;
-
-  JJTAddressListParserState() {
-    nodes = new java.util.Stack<Node>();
-    marks = new java.util.Stack<Integer>();
-    sp = 0;
-    mk = 0;
-  }
-
-  /* Determines whether the current node was actually closed and
-     pushed.  This should only be called in the final user action of a
-     node scope.  */
-  boolean nodeCreated() {
-    return node_created;
-  }
-
-  /* Call this to reinitialize the node stack.  It is called
-     automatically by the parser's ReInit() method. */
-  void reset() {
-    nodes.removeAllElements();
-    marks.removeAllElements();
-    sp = 0;
-    mk = 0;
-  }
-
-  /* Returns the root node of the AST.  It only makes sense to call
-     this after a successful parse. */
-  Node rootNode() {
-    return nodes.elementAt(0);
-  }
-
-  /* Pushes a node on to the stack. */
-  void pushNode(Node n) {
-    nodes.push(n);
-    ++sp;
-  }
-
-  /* Returns the node on the top of the stack, and remove it from the
-     stack.  */
-  Node popNode() {
-    if (--sp < mk) {
-      mk = marks.pop().intValue();
-    }
-    return nodes.pop();
-  }
-
-  /* Returns the node currently on the top of the stack. */
-  Node peekNode() {
-    return nodes.peek();
-  }
-
-  /* Returns the number of children on the stack in the current node
-     scope. */
-  int nodeArity() {
-    return sp - mk;
-  }
-
-
-  void clearNodeScope(Node n) {
-    while (sp > mk) {
-      popNode();
-    }
-    mk = marks.pop().intValue();
-  }
-
-
-  void openNodeScope(Node n) {
-    marks.push(new Integer(mk));
-    mk = sp;
-    n.jjtOpen();
-  }
-
-
-  /* A definite node is constructed from a specified number of
-     children.  That number of nodes are popped from the stack and
-     made the children of the definite node.  Then the definite node
-     is pushed on to the stack. */
-  void closeNodeScope(Node n, int num) {
-    mk = marks.pop().intValue();
-    while (num-- > 0) {
-      Node c = popNode();
-      c.jjtSetParent(n);
-      n.jjtAddChild(c, num);
-    }
-    n.jjtClose();
-    pushNode(n);
-    node_created = true;
-  }
-
-
-  /* A conditional node is constructed if its condition is true.  All
-     the nodes that have been pushed since the node was opened are
-     made children of the the conditional node, which is then pushed
-     on to the stack.  If the condition is false the node is not
-     constructed and they are left on the stack. */
-  void closeNodeScope(Node n, boolean condition) {
-    if (condition) {
-      int a = nodeArity();
-      mk = marks.pop().intValue();
-      while (a-- > 0) {
-	Node c = popNode();
-	c.jjtSetParent(n);
-	n.jjtAddChild(c, a);
-      }
-      n.jjtClose();
-      pushNode(n);
-      node_created = true;
-    } else {
-      mk = marks.pop().intValue();
-      node_created = false;
-    }
-  }
-}
diff --git a/src/org/apache/james/mime4j/field/address/parser/Node.java b/src/org/apache/james/mime4j/field/address/parser/Node.java
deleted file mode 100644
index 1588920..0000000
--- a/src/org/apache/james/mime4j/field/address/parser/Node.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Generated By:JJTree: Do not edit this line. Node.java */
-
-package org.apache.james.mime4j.field.address.parser;
-
-/* All AST nodes must implement this interface.  It provides basic
-   machinery for constructing the parent and child relationships
-   between nodes. */
-
-public interface Node {
-
-  /** This method is called after the node has been made the current
-    node.  It indicates that child nodes can now be added to it. */
-  public void jjtOpen();
-
-  /** This method is called after all the child nodes have been
-    added. */
-  public void jjtClose();
-
-  /** This pair of methods are used to inform the node of its
-    parent. */
-  public void jjtSetParent(Node n);
-  public Node jjtGetParent();
-
-  /** This method tells the node to add its argument to the node's
-    list of children.  */
-  public void jjtAddChild(Node n, int i);
-
-  /** This method returns a child node.  The children are numbered
-     from zero, left to right. */
-  public Node jjtGetChild(int i);
-
-  /** Return the number of children the node has. */
-  public int jjtGetNumChildren();
-
-  /** Accept the visitor. **/
-  public Object jjtAccept(AddressListParserVisitor visitor, Object data);
-}
diff --git a/src/org/apache/james/mime4j/field/address/parser/ParseException.java b/src/org/apache/james/mime4j/field/address/parser/ParseException.java
deleted file mode 100644
index e20146f..0000000
--- a/src/org/apache/james/mime4j/field/address/parser/ParseException.java
+++ /dev/null
@@ -1,207 +0,0 @@
-/* Generated By:JavaCC: Do not edit this line. ParseException.java Version 3.0 */
-/*
- *  Copyright 2004 the mime4j 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 org.apache.james.mime4j.field.address.parser;
-
-/**
- * This exception is thrown when parse errors are encountered.
- * You can explicitly create objects of this exception type by
- * calling the method generateParseException in the generated
- * parser.
- *
- * You can modify this class to customize your error reporting
- * mechanisms so long as you retain the public fields.
- */
-public class ParseException extends Exception {
-
-  /**
-   * This constructor is used by the method "generateParseException"
-   * in the generated parser.  Calling this constructor generates
-   * a new object of this type with the fields "currentToken",
-   * "expectedTokenSequences", and "tokenImage" set.  The boolean
-   * flag "specialConstructor" is also set to true to indicate that
-   * this constructor was used to create this object.
-   * This constructor calls its super class with the empty string
-   * to force the "toString" method of parent class "Throwable" to
-   * print the error message in the form:
-   *     ParseException: <result of getMessage>
-   */
-  public ParseException(Token currentTokenVal,
-                        int[][] expectedTokenSequencesVal,
-                        String[] tokenImageVal
-                       )
-  {
-    super("");
-    specialConstructor = true;
-    currentToken = currentTokenVal;
-    expectedTokenSequences = expectedTokenSequencesVal;
-    tokenImage = tokenImageVal;
-  }
-
-  /**
-   * The following constructors are for use by you for whatever
-   * purpose you can think of.  Constructing the exception in this
-   * manner makes the exception behave in the normal way - i.e., as
-   * documented in the class "Throwable".  The fields "errorToken",
-   * "expectedTokenSequences", and "tokenImage" do not contain
-   * relevant information.  The JavaCC generated code does not use
-   * these constructors.
-   */
-
-  public ParseException() {
-    super();
-    specialConstructor = false;
-  }
-
-  public ParseException(String message) {
-    super(message);
-    specialConstructor = false;
-  }
-
-  /**
-   * This variable determines which constructor was used to create
-   * this object and thereby affects the semantics of the
-   * "getMessage" method (see below).
-   */
-  protected boolean specialConstructor;
-
-  /**
-   * This is the last token that has been consumed successfully.  If
-   * this object has been created due to a parse error, the token
-   * followng this token will (therefore) be the first error token.
-   */
-  public Token currentToken;
-
-  /**
-   * Each entry in this array is an array of integers.  Each array
-   * of integers represents a sequence of tokens (by their ordinal
-   * values) that is expected at this point of the parse.
-   */
-  public int[][] expectedTokenSequences;
-
-  /**
-   * This is a reference to the "tokenImage" array of the generated
-   * parser within which the parse error occurred.  This array is
-   * defined in the generated ...Constants interface.
-   */
-  public String[] tokenImage;
-
-  /**
-   * This method has the standard behavior when this object has been
-   * created using the standard constructors.  Otherwise, it uses
-   * "currentToken" and "expectedTokenSequences" to generate a parse
-   * error message and returns it.  If this object has been created
-   * due to a parse error, and you do not catch it (it gets thrown
-   * from the parser), then this method is called during the printing
-   * of the final stack trace, and hence the correct error message
-   * gets displayed.
-   */
-  public String getMessage() {
-    if (!specialConstructor) {
-      return super.getMessage();
-    }
-    StringBuffer expected = new StringBuffer();
-    int maxSize = 0;
-    for (int i = 0; i < expectedTokenSequences.length; i++) {
-      if (maxSize < expectedTokenSequences[i].length) {
-        maxSize = expectedTokenSequences[i].length;
-      }
-      for (int j = 0; j < expectedTokenSequences[i].length; j++) {
-        expected.append(tokenImage[expectedTokenSequences[i][j]]).append(" ");
-      }
-      if (expectedTokenSequences[i][expectedTokenSequences[i].length - 1] != 0) {
-        expected.append("...");
-      }
-      expected.append(eol).append("    ");
-    }
-    String retval = "Encountered \"";
-    Token tok = currentToken.next;
-    for (int i = 0; i < maxSize; i++) {
-      if (i != 0) retval += " ";
-      if (tok.kind == 0) {
-        retval += tokenImage[0];
-        break;
-      }
-      retval += add_escapes(tok.image);
-      tok = tok.next; 
-    }
-    retval += "\" at line " + currentToken.next.beginLine + ", column " + currentToken.next.beginColumn;
-    retval += "." + eol;
-    if (expectedTokenSequences.length == 1) {
-      retval += "Was expecting:" + eol + "    ";
-    } else {
-      retval += "Was expecting one of:" + eol + "    ";
-    }
-    retval += expected.toString();
-    return retval;
-  }
-
-  /**
-   * The end of line string for this machine.
-   */
-  protected String eol = System.getProperty("line.separator", "\n");
- 
-  /**
-   * Used to convert raw characters to their escaped version
-   * when these raw version cannot be used as part of an ASCII
-   * string literal.
-   */
-  protected String add_escapes(String str) {
-      StringBuffer retval = new StringBuffer();
-      char ch;
-      for (int i = 0; i < str.length(); i++) {
-        switch (str.charAt(i))
-        {
-           case 0 :
-              continue;
-           case '\b':
-              retval.append("\\b");
-              continue;
-           case '\t':
-              retval.append("\\t");
-              continue;
-           case '\n':
-              retval.append("\\n");
-              continue;
-           case '\f':
-              retval.append("\\f");
-              continue;
-           case '\r':
-              retval.append("\\r");
-              continue;
-           case '\"':
-              retval.append("\\\"");
-              continue;
-           case '\'':
-              retval.append("\\\'");
-              continue;
-           case '\\':
-              retval.append("\\\\");
-              continue;
-           default:
-              if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) {
-                 String s = "0000" + Integer.toString(ch, 16);
-                 retval.append("\\u" + s.substring(s.length() - 4, s.length()));
-              } else {
-                 retval.append(ch);
-              }
-              continue;
-        }
-      }
-      return retval.toString();
-   }
-
-}
diff --git a/src/org/apache/james/mime4j/field/address/parser/SimpleCharStream.java b/src/org/apache/james/mime4j/field/address/parser/SimpleCharStream.java
deleted file mode 100644
index c9ba0b4..0000000
--- a/src/org/apache/james/mime4j/field/address/parser/SimpleCharStream.java
+++ /dev/null
@@ -1,454 +0,0 @@
-/* Generated By:JavaCC: Do not edit this line. SimpleCharStream.java Version 4.0 */
-/*
- *  Copyright 2004 the mime4j 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 org.apache.james.mime4j.field.address.parser;
-
-/**
- * An implementation of interface CharStream, where the stream is assumed to
- * contain only ASCII characters (without unicode processing).
- */
-
-public class SimpleCharStream
-{
-  public static final boolean staticFlag = false;
-  int bufsize;
-  int available;
-  int tokenBegin;
-  public int bufpos = -1;
-  protected int bufline[];
-  protected int bufcolumn[];
-
-  protected int column = 0;
-  protected int line = 1;
-
-  protected boolean prevCharIsCR = false;
-  protected boolean prevCharIsLF = false;
-
-  protected java.io.Reader inputStream;
-
-  protected char[] buffer;
-  protected int maxNextCharInd = 0;
-  protected int inBuf = 0;
-  protected int tabSize = 8;
-
-  protected void setTabSize(int i) { tabSize = i; }
-  protected int getTabSize(int i) { return tabSize; }
-
-
-  protected void ExpandBuff(boolean wrapAround)
-  {
-     char[] newbuffer = new char[bufsize + 2048];
-     int newbufline[] = new int[bufsize + 2048];
-     int newbufcolumn[] = new int[bufsize + 2048];
-
-     try
-     {
-        if (wrapAround)
-        {
-           System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin);
-           System.arraycopy(buffer, 0, newbuffer,
-                                             bufsize - tokenBegin, bufpos);
-           buffer = newbuffer;
-
-           System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin);
-           System.arraycopy(bufline, 0, newbufline, bufsize - tokenBegin, bufpos);
-           bufline = newbufline;
-
-           System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin);
-           System.arraycopy(bufcolumn, 0, newbufcolumn, bufsize - tokenBegin, bufpos);
-           bufcolumn = newbufcolumn;
-
-           maxNextCharInd = (bufpos += (bufsize - tokenBegin));
-        }
-        else
-        {
-           System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin);
-           buffer = newbuffer;
-
-           System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin);
-           bufline = newbufline;
-
-           System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin);
-           bufcolumn = newbufcolumn;
-
-           maxNextCharInd = (bufpos -= tokenBegin);
-        }
-     }
-     catch (Throwable t)
-     {
-        throw new Error(t.getMessage());
-     }
-
-
-     bufsize += 2048;
-     available = bufsize;
-     tokenBegin = 0;
-  }
-
-  protected void FillBuff() throws java.io.IOException
-  {
-     if (maxNextCharInd == available)
-     {
-        if (available == bufsize)
-        {
-           if (tokenBegin > 2048)
-           {
-              bufpos = maxNextCharInd = 0;
-              available = tokenBegin;
-           }
-           else if (tokenBegin < 0)
-              bufpos = maxNextCharInd = 0;
-           else
-              ExpandBuff(false);
-        }
-        else if (available > tokenBegin)
-           available = bufsize;
-        else if ((tokenBegin - available) < 2048)
-           ExpandBuff(true);
-        else
-           available = tokenBegin;
-     }
-
-     int i;
-     try {
-        if ((i = inputStream.read(buffer, maxNextCharInd,
-                                    available - maxNextCharInd)) == -1)
-        {
-           inputStream.close();
-           throw new java.io.IOException();
-        }
-        else
-           maxNextCharInd += i;
-        return;
-     }
-     catch(java.io.IOException e) {
-        --bufpos;
-        backup(0);
-        if (tokenBegin == -1)
-           tokenBegin = bufpos;
-        throw e;
-     }
-  }
-
-  public char BeginToken() throws java.io.IOException
-  {
-     tokenBegin = -1;
-     char c = readChar();
-     tokenBegin = bufpos;
-
-     return c;
-  }
-
-  protected void UpdateLineColumn(char c)
-  {
-     column++;
-
-     if (prevCharIsLF)
-     {
-        prevCharIsLF = false;
-        line += (column = 1);
-     }
-     else if (prevCharIsCR)
-     {
-        prevCharIsCR = false;
-        if (c == '\n')
-        {
-           prevCharIsLF = true;
-        }
-        else
-           line += (column = 1);
-     }
-
-     switch (c)
-     {
-        case '\r' :
-           prevCharIsCR = true;
-           break;
-        case '\n' :
-           prevCharIsLF = true;
-           break;
-        case '\t' :
-           column--;
-           column += (tabSize - (column % tabSize));
-           break;
-        default :
-           break;
-     }
-
-     bufline[bufpos] = line;
-     bufcolumn[bufpos] = column;
-  }
-
-  public char readChar() throws java.io.IOException
-  {
-     if (inBuf > 0)
-     {
-        --inBuf;
-
-        if (++bufpos == bufsize)
-           bufpos = 0;
-
-        return buffer[bufpos];
-     }
-
-     if (++bufpos >= maxNextCharInd)
-        FillBuff();
-
-     char c = buffer[bufpos];
-
-     UpdateLineColumn(c);
-     return (c);
-  }
-
-  /**
-   * @deprecated 
-   * @see #getEndColumn
-   */
-  @Deprecated
-  public int getColumn() {
-     return bufcolumn[bufpos];
-  }
-
-  /**
-   * @deprecated 
-   * @see #getEndLine
-   */
-  @Deprecated
-  public int getLine() {
-     return bufline[bufpos];
-  }
-
-  public int getEndColumn() {
-     return bufcolumn[bufpos];
-  }
-
-  public int getEndLine() {
-     return bufline[bufpos];
-  }
-
-  public int getBeginColumn() {
-     return bufcolumn[tokenBegin];
-  }
-
-  public int getBeginLine() {
-     return bufline[tokenBegin];
-  }
-
-  public void backup(int amount) {
-
-    inBuf += amount;
-    if ((bufpos -= amount) < 0)
-       bufpos += bufsize;
-  }
-
-  public SimpleCharStream(java.io.Reader dstream, int startline,
-  int startcolumn, int buffersize)
-  {
-    inputStream = dstream;
-    line = startline;
-    column = startcolumn - 1;
-
-    available = bufsize = buffersize;
-    buffer = new char[buffersize];
-    bufline = new int[buffersize];
-    bufcolumn = new int[buffersize];
-  }
-
-  public SimpleCharStream(java.io.Reader dstream, int startline,
-                          int startcolumn)
-  {
-     this(dstream, startline, startcolumn, 4096);
-  }
-
-  public SimpleCharStream(java.io.Reader dstream)
-  {
-     this(dstream, 1, 1, 4096);
-  }
-  public void ReInit(java.io.Reader dstream, int startline,
-  int startcolumn, int buffersize)
-  {
-    inputStream = dstream;
-    line = startline;
-    column = startcolumn - 1;
-
-    if (buffer == null || buffersize != buffer.length)
-    {
-      available = bufsize = buffersize;
-      buffer = new char[buffersize];
-      bufline = new int[buffersize];
-      bufcolumn = new int[buffersize];
-    }
-    prevCharIsLF = prevCharIsCR = false;
-    tokenBegin = inBuf = maxNextCharInd = 0;
-    bufpos = -1;
-  }
-
-  public void ReInit(java.io.Reader dstream, int startline,
-                     int startcolumn)
-  {
-     ReInit(dstream, startline, startcolumn, 4096);
-  }
-
-  public void ReInit(java.io.Reader dstream)
-  {
-     ReInit(dstream, 1, 1, 4096);
-  }
-  public SimpleCharStream(java.io.InputStream dstream, String encoding, int startline,
-  int startcolumn, int buffersize) throws java.io.UnsupportedEncodingException
-  {
-     this(encoding == null ? new java.io.InputStreamReader(dstream) : new java.io.InputStreamReader(dstream, encoding), startline, startcolumn, buffersize);
-  }
-
-  public SimpleCharStream(java.io.InputStream dstream, int startline,
-  int startcolumn, int buffersize)
-  {
-     this(new java.io.InputStreamReader(dstream), startline, startcolumn, buffersize);
-  }
-
-  public SimpleCharStream(java.io.InputStream dstream, String encoding, int startline,
-                          int startcolumn) throws java.io.UnsupportedEncodingException
-  {
-     this(dstream, encoding, startline, startcolumn, 4096);
-  }
-
-  public SimpleCharStream(java.io.InputStream dstream, int startline,
-                          int startcolumn)
-  {
-     this(dstream, startline, startcolumn, 4096);
-  }
-
-  public SimpleCharStream(java.io.InputStream dstream, String encoding) throws java.io.UnsupportedEncodingException
-  {
-     this(dstream, encoding, 1, 1, 4096);
-  }
-
-  public SimpleCharStream(java.io.InputStream dstream)
-  {
-     this(dstream, 1, 1, 4096);
-  }
-
-  public void ReInit(java.io.InputStream dstream, String encoding, int startline,
-                          int startcolumn, int buffersize) throws java.io.UnsupportedEncodingException
-  {
-     ReInit(encoding == null ? new java.io.InputStreamReader(dstream) : new java.io.InputStreamReader(dstream, encoding), startline, startcolumn, buffersize);
-  }
-
-  public void ReInit(java.io.InputStream dstream, int startline,
-                          int startcolumn, int buffersize)
-  {
-     ReInit(new java.io.InputStreamReader(dstream), startline, startcolumn, buffersize);
-  }
-
-  public void ReInit(java.io.InputStream dstream, String encoding) throws java.io.UnsupportedEncodingException
-  {
-     ReInit(dstream, encoding, 1, 1, 4096);
-  }
-
-  public void ReInit(java.io.InputStream dstream)
-  {
-     ReInit(dstream, 1, 1, 4096);
-  }
-  public void ReInit(java.io.InputStream dstream, String encoding, int startline,
-                     int startcolumn) throws java.io.UnsupportedEncodingException
-  {
-     ReInit(dstream, encoding, startline, startcolumn, 4096);
-  }
-  public void ReInit(java.io.InputStream dstream, int startline,
-                     int startcolumn)
-  {
-     ReInit(dstream, startline, startcolumn, 4096);
-  }
-  public String GetImage()
-  {
-     if (bufpos >= tokenBegin)
-        return new String(buffer, tokenBegin, bufpos - tokenBegin + 1);
-     else
-        return new String(buffer, tokenBegin, bufsize - tokenBegin) +
-                              new String(buffer, 0, bufpos + 1);
-  }
-
-  public char[] GetSuffix(int len)
-  {
-     char[] ret = new char[len];
-
-     if ((bufpos + 1) >= len)
-        System.arraycopy(buffer, bufpos - len + 1, ret, 0, len);
-     else
-     {
-        System.arraycopy(buffer, bufsize - (len - bufpos - 1), ret, 0,
-                                                          len - bufpos - 1);
-        System.arraycopy(buffer, 0, ret, len - bufpos - 1, bufpos + 1);
-     }
-
-     return ret;
-  }
-
-  public void Done()
-  {
-     buffer = null;
-     bufline = null;
-     bufcolumn = null;
-  }
-
-  /**
-   * Method to adjust line and column numbers for the start of a token.
-   */
-  public void adjustBeginLineColumn(int newLine, int newCol)
-  {
-     int start = tokenBegin;
-     int len;
-
-     if (bufpos >= tokenBegin)
-     {
-        len = bufpos - tokenBegin + inBuf + 1;
-     }
-     else
-     {
-        len = bufsize - tokenBegin + bufpos + 1 + inBuf;
-     }
-
-     int i = 0, j = 0, k = 0;
-     int nextColDiff = 0, columnDiff = 0;
-
-     while (i < len &&
-            bufline[j = start % bufsize] == bufline[k = ++start % bufsize])
-     {
-        bufline[j] = newLine;
-        nextColDiff = columnDiff + bufcolumn[k] - bufcolumn[j];
-        bufcolumn[j] = newCol + columnDiff;
-        columnDiff = nextColDiff;
-        i++;
-     } 
-
-     if (i < len)
-     {
-        bufline[j] = newLine++;
-        bufcolumn[j] = newCol + columnDiff;
-
-        while (i++ < len)
-        {
-           if (bufline[j = start % bufsize] != bufline[++start % bufsize])
-              bufline[j] = newLine++;
-           else
-              bufline[j] = newLine;
-        }
-     }
-
-     line = bufline[j];
-     column = bufcolumn[j];
-  }
-
-}
diff --git a/src/org/apache/james/mime4j/field/address/parser/SimpleNode.java b/src/org/apache/james/mime4j/field/address/parser/SimpleNode.java
deleted file mode 100644
index 9bf537e..0000000
--- a/src/org/apache/james/mime4j/field/address/parser/SimpleNode.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/* Generated By:JJTree: Do not edit this line. SimpleNode.java */
-
-package org.apache.james.mime4j.field.address.parser;
-
-public class SimpleNode extends org.apache.james.mime4j.field.address.parser.BaseNode implements Node {
-  protected Node parent;
-  protected Node[] children;
-  protected int id;
-  protected AddressListParser parser;
-
-  public SimpleNode(int i) {
-    id = i;
-  }
-
-  public SimpleNode(AddressListParser p, int i) {
-    this(i);
-    parser = p;
-  }
-
-  public void jjtOpen() {
-  }
-
-  public void jjtClose() {
-  }
-  
-  public void jjtSetParent(Node n) { parent = n; }
-  public Node jjtGetParent() { return parent; }
-
-  public void jjtAddChild(Node n, int i) {
-    if (children == null) {
-      children = new Node[i + 1];
-    } else if (i >= children.length) {
-      Node c[] = new Node[i + 1];
-      System.arraycopy(children, 0, c, 0, children.length);
-      children = c;
-    }
-    children[i] = n;
-  }
-
-  public Node jjtGetChild(int i) {
-    return children[i];
-  }
-
-  public int jjtGetNumChildren() {
-    return (children == null) ? 0 : children.length;
-  }
-
-  /** Accept the visitor. **/
-  public Object jjtAccept(AddressListParserVisitor visitor, Object data) {
-    return visitor.visit(this, data);
-  }
-
-  /** Accept the visitor. **/
-  public Object childrenAccept(AddressListParserVisitor visitor, Object data) {
-    if (children != null) {
-      for (int i = 0; i < children.length; ++i) {
-        children[i].jjtAccept(visitor, data);
-      }
-    }
-    return data;
-  }
-
-  /* You can override these two methods in subclasses of SimpleNode to
-     customize the way the node appears when the tree is dumped.  If
-     your output uses more than one line you should override
-     toString(String), otherwise overriding toString() is probably all
-     you need to do. */
-
-  public String toString() { return AddressListParserTreeConstants.jjtNodeName[id]; }
-  public String toString(String prefix) { return prefix + toString(); }
-
-  /* Override this method if you want to customize how the node dumps
-     out its children. */
-
-  public void dump(String prefix) {
-    System.out.println(toString(prefix));
-    if (children != null) {
-      for (int i = 0; i < children.length; ++i) {
-	SimpleNode n = (SimpleNode)children[i];
-	if (n != null) {
-	  n.dump(prefix + " ");
-	}
-      }
-    }
-  }
-}
-
diff --git a/src/org/apache/james/mime4j/field/address/parser/Token.java b/src/org/apache/james/mime4j/field/address/parser/Token.java
deleted file mode 100644
index 2382e8e..0000000
--- a/src/org/apache/james/mime4j/field/address/parser/Token.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/* Generated By:JavaCC: Do not edit this line. Token.java Version 3.0 */
-/*
- *  Copyright 2004 the mime4j 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 org.apache.james.mime4j.field.address.parser;
-
-/**
- * Describes the input token stream.
- */
-
-public class Token {
-
-  /**
-   * An integer that describes the kind of this token.  This numbering
-   * system is determined by JavaCCParser, and a table of these numbers is
-   * stored in the file ...Constants.java.
-   */
-  public int kind;
-
-  /**
-   * beginLine and beginColumn describe the position of the first character
-   * of this token; endLine and endColumn describe the position of the
-   * last character of this token.
-   */
-  public int beginLine, beginColumn, endLine, endColumn;
-
-  /**
-   * The string image of the token.
-   */
-  public String image;
-
-  /**
-   * A reference to the next regular (non-special) token from the input
-   * stream.  If this is the last token from the input stream, or if the
-   * token manager has not read tokens beyond this one, this field is
-   * set to null.  This is true only if this token is also a regular
-   * token.  Otherwise, see below for a description of the contents of
-   * this field.
-   */
-  public Token next;
-
-  /**
-   * This field is used to access special tokens that occur prior to this
-   * token, but after the immediately preceding regular (non-special) token.
-   * If there are no such special tokens, this field is set to null.
-   * When there are more than one such special token, this field refers
-   * to the last of these special tokens, which in turn refers to the next
-   * previous special token through its specialToken field, and so on
-   * until the first special token (whose specialToken field is null).
-   * The next fields of special tokens refer to other special tokens that
-   * immediately follow it (without an intervening regular token).  If there
-   * is no such token, this field is null.
-   */
-  public Token specialToken;
-
-  /**
-   * Returns the image.
-   */
-  public String toString()
-  {
-     return image;
-  }
-
-  /**
-   * Returns a new Token object, by default. However, if you want, you
-   * can create and return subclass objects based on the value of ofKind.
-   * Simply add the cases to the switch for all those special cases.
-   * For example, if you have a subclass of Token called IDToken that
-   * you want to create if ofKind is ID, simlpy add something like :
-   *
-   *    case MyParserConstants.ID : return new IDToken();
-   *
-   * to the following switch statement. Then you can cast matchedToken
-   * variable to the appropriate type and use it in your lexical actions.
-   */
-  public static final Token newToken(int ofKind)
-  {
-     switch(ofKind)
-     {
-       default : return new Token();
-     }
-  }
-
-}
diff --git a/src/org/apache/james/mime4j/field/address/parser/TokenMgrError.java b/src/org/apache/james/mime4j/field/address/parser/TokenMgrError.java
deleted file mode 100644
index 0299c85..0000000
--- a/src/org/apache/james/mime4j/field/address/parser/TokenMgrError.java
+++ /dev/null
@@ -1,148 +0,0 @@
-/* Generated By:JavaCC: Do not edit this line. TokenMgrError.java Version 3.0 */
-/*
- *  Copyright 2004 the mime4j 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 org.apache.james.mime4j.field.address.parser;
-
-public class TokenMgrError extends Error
-{
-   /*
-    * Ordinals for various reasons why an Error of this type can be thrown.
-    */
-
-   /**
-    * Lexical error occured.
-    */
-   static final int LEXICAL_ERROR = 0;
-
-   /**
-    * An attempt wass made to create a second instance of a static token manager.
-    */
-   static final int STATIC_LEXER_ERROR = 1;
-
-   /**
-    * Tried to change to an invalid lexical state.
-    */
-   static final int INVALID_LEXICAL_STATE = 2;
-
-   /**
-    * Detected (and bailed out of) an infinite loop in the token manager.
-    */
-   static final int LOOP_DETECTED = 3;
-
-   /**
-    * Indicates the reason why the exception is thrown. It will have
-    * one of the above 4 values.
-    */
-   int errorCode;
-
-   /**
-    * Replaces unprintable characters by their espaced (or unicode escaped)
-    * equivalents in the given string
-    */
-   protected static final String addEscapes(String str) {
-      StringBuffer retval = new StringBuffer();
-      char ch;
-      for (int i = 0; i < str.length(); i++) {
-        switch (str.charAt(i))
-        {
-           case 0 :
-              continue;
-           case '\b':
-              retval.append("\\b");
-              continue;
-           case '\t':
-              retval.append("\\t");
-              continue;
-           case '\n':
-              retval.append("\\n");
-              continue;
-           case '\f':
-              retval.append("\\f");
-              continue;
-           case '\r':
-              retval.append("\\r");
-              continue;
-           case '\"':
-              retval.append("\\\"");
-              continue;
-           case '\'':
-              retval.append("\\\'");
-              continue;
-           case '\\':
-              retval.append("\\\\");
-              continue;
-           default:
-              if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) {
-                 String s = "0000" + Integer.toString(ch, 16);
-                 retval.append("\\u" + s.substring(s.length() - 4, s.length()));
-              } else {
-                 retval.append(ch);
-              }
-              continue;
-        }
-      }
-      return retval.toString();
-   }
-
-   /**
-    * Returns a detailed message for the Error when it is thrown by the
-    * token manager to indicate a lexical error.
-    * Parameters : 
-    *    EOFSeen     : indicates if EOF caused the lexicl error
-    *    curLexState : lexical state in which this error occured
-    *    errorLine   : line number when the error occured
-    *    errorColumn : column number when the error occured
-    *    errorAfter  : prefix that was seen before this error occured
-    *    curchar     : the offending character
-    * Note: You can customize the lexical error message by modifying this method.
-    */
-   protected static String LexicalError(boolean EOFSeen, int lexState, int errorLine, int errorColumn, String errorAfter, char curChar) {
-      return("Lexical error at line " +
-           errorLine + ", column " +
-           errorColumn + ".  Encountered: " +
-           (EOFSeen ? "<EOF> " : ("\"" + addEscapes(String.valueOf(curChar)) + "\"") + " (" + (int)curChar + "), ") +
-           "after : \"" + addEscapes(errorAfter) + "\"");
-   }
-
-   /**
-    * You can also modify the body of this method to customize your error messages.
-    * For example, cases like LOOP_DETECTED and INVALID_LEXICAL_STATE are not
-    * of end-users concern, so you can return something like : 
-    *
-    *     "Internal Error : Please file a bug report .... "
-    *
-    * from this method for such cases in the release version of your parser.
-    */
-   public String getMessage() {
-      return super.getMessage();
-   }
-
-   /*
-    * Constructors of various flavors follow.
-    */
-
-   public TokenMgrError() {
-   }
-
-   public TokenMgrError(String message, int reason) {
-      super(message);
-      errorCode = reason;
-   }
-
-   public TokenMgrError(boolean EOFSeen, int lexState, int errorLine, int errorColumn, String errorAfter, char curChar, int reason) {
-      this(LexicalError(EOFSeen, lexState, errorLine, errorColumn, errorAfter, curChar), reason);
-   }
-}
diff --git a/src/org/apache/james/mime4j/field/contenttype/parser/ContentTypeParser.java b/src/org/apache/james/mime4j/field/contenttype/parser/ContentTypeParser.java
deleted file mode 100644
index cacf3af..0000000
--- a/src/org/apache/james/mime4j/field/contenttype/parser/ContentTypeParser.java
+++ /dev/null
@@ -1,268 +0,0 @@
-/* Generated By:JavaCC: Do not edit this line. ContentTypeParser.java */
-/*
- *  Copyright 2004 the mime4j 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 org.apache.james.mime4j.field.contenttype.parser;
-
-import java.util.ArrayList;
-import java.util.Vector;
-
-public class ContentTypeParser implements ContentTypeParserConstants {
-
-        private String type;
-        private String subtype;
-        private ArrayList<String> paramNames = new ArrayList<String>();
-        private ArrayList<String> paramValues = new ArrayList<String>();
-
-        public String getType() { return type; }
-        public String getSubType() { return subtype; }
-        public ArrayList<String> getParamNames() { return paramNames; }
-        public ArrayList<String> getParamValues() { return paramValues; }
-
-    public static void main(String args[]) throws ParseException {
-        while (true) {
-            try {
-                ContentTypeParser parser = new ContentTypeParser(System.in);
-                parser.parseLine();
-            } catch (Exception x) {
-                x.printStackTrace();
-                return;
-            }
-        }
-    }
-
-  final public void parseLine() throws ParseException {
-    parse();
-    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-    case 1:
-      jj_consume_token(1);
-      break;
-    default:
-      jj_la1[0] = jj_gen;
-      ;
-    }
-    jj_consume_token(2);
-  }
-
-  final public void parseAll() throws ParseException {
-    parse();
-    jj_consume_token(0);
-  }
-
-  final public void parse() throws ParseException {
-        Token type;
-        Token subtype;
-    type = jj_consume_token(ATOKEN);
-    jj_consume_token(3);
-    subtype = jj_consume_token(ATOKEN);
-                this.type = type.image;
-                this.subtype = subtype.image;
-    label_1:
-    while (true) {
-      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-      case 4:
-        ;
-        break;
-      default:
-        jj_la1[1] = jj_gen;
-        break label_1;
-      }
-      jj_consume_token(4);
-      parameter();
-    }
-  }
-
-  final public void parameter() throws ParseException {
-        Token attrib;
-        String val;
-    attrib = jj_consume_token(ATOKEN);
-    jj_consume_token(5);
-    val = value();
-                paramNames.add(attrib.image);
-                paramValues.add(val);
-  }
-
-  final public String value() throws ParseException {
- Token t;
-    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-    case ATOKEN:
-      t = jj_consume_token(ATOKEN);
-      break;
-    case QUOTEDSTRING:
-      t = jj_consume_token(QUOTEDSTRING);
-      break;
-    default:
-      jj_la1[2] = jj_gen;
-      jj_consume_token(-1);
-      throw new ParseException();
-    }
-          {if (true) return t.image;}
-    throw new Error("Missing return statement in function");
-  }
-
-  public ContentTypeParserTokenManager token_source;
-  SimpleCharStream jj_input_stream;
-  public Token token, jj_nt;
-  private int jj_ntk;
-  private int jj_gen;
-  final private int[] jj_la1 = new int[3];
-  static private int[] jj_la1_0;
-  static {
-      jj_la1_0();
-   }
-   private static void jj_la1_0() {
-      jj_la1_0 = new int[] {0x2,0x10,0x280000,};
-   }
-
-  public ContentTypeParser(java.io.InputStream stream) {
-     this(stream, null);
-  }
-  public ContentTypeParser(java.io.InputStream stream, String encoding) {
-    try { jj_input_stream = new SimpleCharStream(stream, encoding, 1, 1); } catch(java.io.UnsupportedEncodingException e) { throw new RuntimeException(e); }
-    token_source = new ContentTypeParserTokenManager(jj_input_stream);
-    token = new Token();
-    jj_ntk = -1;
-    jj_gen = 0;
-    for (int i = 0; i < 3; i++) jj_la1[i] = -1;
-  }
-
-  public void ReInit(java.io.InputStream stream) {
-     ReInit(stream, null);
-  }
-  public void ReInit(java.io.InputStream stream, String encoding) {
-    try { jj_input_stream.ReInit(stream, encoding, 1, 1); } catch(java.io.UnsupportedEncodingException e) { throw new RuntimeException(e); }
-    token_source.ReInit(jj_input_stream);
-    token = new Token();
-    jj_ntk = -1;
-    jj_gen = 0;
-    for (int i = 0; i < 3; i++) jj_la1[i] = -1;
-  }
-
-  public ContentTypeParser(java.io.Reader stream) {
-    jj_input_stream = new SimpleCharStream(stream, 1, 1);
-    token_source = new ContentTypeParserTokenManager(jj_input_stream);
-    token = new Token();
-    jj_ntk = -1;
-    jj_gen = 0;
-    for (int i = 0; i < 3; i++) jj_la1[i] = -1;
-  }
-
-  public void ReInit(java.io.Reader stream) {
-    jj_input_stream.ReInit(stream, 1, 1);
-    token_source.ReInit(jj_input_stream);
-    token = new Token();
-    jj_ntk = -1;
-    jj_gen = 0;
-    for (int i = 0; i < 3; i++) jj_la1[i] = -1;
-  }
-
-  public ContentTypeParser(ContentTypeParserTokenManager tm) {
-    token_source = tm;
-    token = new Token();
-    jj_ntk = -1;
-    jj_gen = 0;
-    for (int i = 0; i < 3; i++) jj_la1[i] = -1;
-  }
-
-  public void ReInit(ContentTypeParserTokenManager tm) {
-    token_source = tm;
-    token = new Token();
-    jj_ntk = -1;
-    jj_gen = 0;
-    for (int i = 0; i < 3; i++) jj_la1[i] = -1;
-  }
-
-  final private Token jj_consume_token(int kind) throws ParseException {
-    Token oldToken;
-    if ((oldToken = token).next != null) token = token.next;
-    else token = token.next = token_source.getNextToken();
-    jj_ntk = -1;
-    if (token.kind == kind) {
-      jj_gen++;
-      return token;
-    }
-    token = oldToken;
-    jj_kind = kind;
-    throw generateParseException();
-  }
-
-  final public Token getNextToken() {
-    if (token.next != null) token = token.next;
-    else token = token.next = token_source.getNextToken();
-    jj_ntk = -1;
-    jj_gen++;
-    return token;
-  }
-
-  final public Token getToken(int index) {
-    Token t = token;
-    for (int i = 0; i < index; i++) {
-      if (t.next != null) t = t.next;
-      else t = t.next = token_source.getNextToken();
-    }
-    return t;
-  }
-
-  final private int jj_ntk() {
-    if ((jj_nt=token.next) == null)
-      return (jj_ntk = (token.next=token_source.getNextToken()).kind);
-    else
-      return (jj_ntk = jj_nt.kind);
-  }
-
-  private Vector<int[]> jj_expentries = new Vector<int[]>();
-  private int[] jj_expentry;
-  private int jj_kind = -1;
-
-  public ParseException generateParseException() {
-    jj_expentries.removeAllElements();
-    boolean[] la1tokens = new boolean[24];
-    for (int i = 0; i < 24; i++) {
-      la1tokens[i] = false;
-    }
-    if (jj_kind >= 0) {
-      la1tokens[jj_kind] = true;
-      jj_kind = -1;
-    }
-    for (int i = 0; i < 3; i++) {
-      if (jj_la1[i] == jj_gen) {
-        for (int j = 0; j < 32; j++) {
-          if ((jj_la1_0[i] & (1<<j)) != 0) {
-            la1tokens[j] = true;
-          }
-        }
-      }
-    }
-    for (int i = 0; i < 24; i++) {
-      if (la1tokens[i]) {
-        jj_expentry = new int[1];
-        jj_expentry[0] = i;
-        jj_expentries.addElement(jj_expentry);
-      }
-    }
-    int[][] exptokseq = new int[jj_expentries.size()][];
-    for (int i = 0; i < jj_expentries.size(); i++) {
-      exptokseq[i] = jj_expentries.elementAt(i);
-    }
-    return new ParseException(token, exptokseq, tokenImage);
-  }
-
-  final public void enable_tracing() {
-  }
-
-  final public void disable_tracing() {
-  }
-
-}
diff --git a/src/org/apache/james/mime4j/field/contenttype/parser/ContentTypeParserConstants.java b/src/org/apache/james/mime4j/field/contenttype/parser/ContentTypeParserConstants.java
deleted file mode 100644
index d933d80..0000000
--- a/src/org/apache/james/mime4j/field/contenttype/parser/ContentTypeParserConstants.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/* Generated By:JavaCC: Do not edit this line. ContentTypeParserConstants.java */
-/*
- *  Copyright 2004 the mime4j 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 org.apache.james.mime4j.field.contenttype.parser;
-
-public interface ContentTypeParserConstants {
-
-  int EOF = 0;
-  int WS = 6;
-  int COMMENT = 8;
-  int QUOTEDSTRING = 19;
-  int DIGITS = 20;
-  int ATOKEN = 21;
-  int QUOTEDPAIR = 22;
-  int ANY = 23;
-
-  int DEFAULT = 0;
-  int INCOMMENT = 1;
-  int NESTED_COMMENT = 2;
-  int INQUOTEDSTRING = 3;
-
-  String[] tokenImage = {
-    "<EOF>",
-    "\"\\r\"",
-    "\"\\n\"",
-    "\"/\"",
-    "\";\"",
-    "\"=\"",
-    "<WS>",
-    "\"(\"",
-    "\")\"",
-    "<token of kind 9>",
-    "\"(\"",
-    "<token of kind 11>",
-    "<token of kind 12>",
-    "\"(\"",
-    "\")\"",
-    "<token of kind 15>",
-    "\"\\\"\"",
-    "<token of kind 17>",
-    "<token of kind 18>",
-    "\"\\\"\"",
-    "<DIGITS>",
-    "<ATOKEN>",
-    "<QUOTEDPAIR>",
-    "<ANY>",
-  };
-
-}
diff --git a/src/org/apache/james/mime4j/field/contenttype/parser/ContentTypeParserTokenManager.java b/src/org/apache/james/mime4j/field/contenttype/parser/ContentTypeParserTokenManager.java
deleted file mode 100644
index 25b7aba..0000000
--- a/src/org/apache/james/mime4j/field/contenttype/parser/ContentTypeParserTokenManager.java
+++ /dev/null
@@ -1,877 +0,0 @@
-/* Generated By:JavaCC: Do not edit this line. ContentTypeParserTokenManager.java */
-/*
- *  Copyright 2004 the mime4j 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 org.apache.james.mime4j.field.contenttype.parser;
-import java.util.ArrayList;
-
-public class ContentTypeParserTokenManager implements ContentTypeParserConstants
-{
-        // Keeps track of how many levels of comment nesting
-        // we've encountered.  This is only used when the 2nd
-        // level is reached, for example ((this)), not (this).
-        // This is because the outermost level must be treated
-        // specially anyway, because the outermost ")" has a
-        // different token type than inner ")" instances.
-        static int commentNest;
-  public  java.io.PrintStream debugStream = System.out;
-  public  void setDebugStream(java.io.PrintStream ds) { debugStream = ds; }
-private final int jjStopStringLiteralDfa_0(int pos, long active0)
-{
-   switch (pos)
-   {
-      default :
-         return -1;
-   }
-}
-private final int jjStartNfa_0(int pos, long active0)
-{
-   return jjMoveNfa_0(jjStopStringLiteralDfa_0(pos, active0), pos + 1);
-}
-private final int jjStopAtPos(int pos, int kind)
-{
-   jjmatchedKind = kind;
-   jjmatchedPos = pos;
-   return pos + 1;
-}
-private final int jjStartNfaWithStates_0(int pos, int kind, int state)
-{
-   jjmatchedKind = kind;
-   jjmatchedPos = pos;
-   try { curChar = input_stream.readChar(); }
-   catch(java.io.IOException e) { return pos + 1; }
-   return jjMoveNfa_0(state, pos + 1);
-}
-private final int jjMoveStringLiteralDfa0_0()
-{
-   switch(curChar)
-   {
-      case 10:
-         return jjStartNfaWithStates_0(0, 2, 2);
-      case 13:
-         return jjStartNfaWithStates_0(0, 1, 2);
-      case 34:
-         return jjStopAtPos(0, 16);
-      case 40:
-         return jjStopAtPos(0, 7);
-      case 47:
-         return jjStopAtPos(0, 3);
-      case 59:
-         return jjStopAtPos(0, 4);
-      case 61:
-         return jjStopAtPos(0, 5);
-      default :
-         return jjMoveNfa_0(3, 0);
-   }
-}
-private final void jjCheckNAdd(int state)
-{
-   if (jjrounds[state] != jjround)
-   {
-      jjstateSet[jjnewStateCnt++] = state;
-      jjrounds[state] = jjround;
-   }
-}
-private final void jjAddStates(int start, int end)
-{
-   do {
-      jjstateSet[jjnewStateCnt++] = jjnextStates[start];
-   } while (start++ != end);
-}
-private final void jjCheckNAddTwoStates(int state1, int state2)
-{
-   jjCheckNAdd(state1);
-   jjCheckNAdd(state2);
-}
-private final void jjCheckNAddStates(int start, int end)
-{
-   do {
-      jjCheckNAdd(jjnextStates[start]);
-   } while (start++ != end);
-}
-private final void jjCheckNAddStates(int start)
-{
-   jjCheckNAdd(jjnextStates[start]);
-   jjCheckNAdd(jjnextStates[start + 1]);
-}
-static final long[] jjbitVec0 = {
-   0x0L, 0x0L, 0xffffffffffffffffL, 0xffffffffffffffffL
-};
-private final int jjMoveNfa_0(int startState, int curPos)
-{
-   int[] nextStates;
-   int startsAt = 0;
-   jjnewStateCnt = 3;
-   int i = 1;
-   jjstateSet[0] = startState;
-   int j, kind = 0x7fffffff;
-   for (;;)
-   {
-      if (++jjround == 0x7fffffff)
-         ReInitRounds();
-      if (curChar < 64)
-      {
-         long l = 1L << curChar;
-         MatchLoop: do
-         {
-            switch(jjstateSet[--i])
-            {
-               case 3:
-                  if ((0x3ff6cfafffffdffL & l) != 0L)
-                  {
-                     if (kind > 21)
-                        kind = 21;
-                     jjCheckNAdd(2);
-                  }
-                  else if ((0x100000200L & l) != 0L)
-                  {
-                     if (kind > 6)
-                        kind = 6;
-                     jjCheckNAdd(0);
-                  }
-                  if ((0x3ff000000000000L & l) != 0L)
-                  {
-                     if (kind > 20)
-                        kind = 20;
-                     jjCheckNAdd(1);
-                  }
-                  break;
-               case 0:
-                  if ((0x100000200L & l) == 0L)
-                     break;
-                  kind = 6;
-                  jjCheckNAdd(0);
-                  break;
-               case 1:
-                  if ((0x3ff000000000000L & l) == 0L)
-                     break;
-                  if (kind > 20)
-                     kind = 20;
-                  jjCheckNAdd(1);
-                  break;
-               case 2:
-                  if ((0x3ff6cfafffffdffL & l) == 0L)
-                     break;
-                  if (kind > 21)
-                     kind = 21;
-                  jjCheckNAdd(2);
-                  break;
-               default : break;
-            }
-         } while(i != startsAt);
-      }
-      else if (curChar < 128)
-      {
-         long l = 1L << (curChar & 077);
-         MatchLoop: do
-         {
-            switch(jjstateSet[--i])
-            {
-               case 3:
-               case 2:
-                  if ((0xffffffffc7fffffeL & l) == 0L)
-                     break;
-                  kind = 21;
-                  jjCheckNAdd(2);
-                  break;
-               default : break;
-            }
-         } while(i != startsAt);
-      }
-      else
-      {
-         int i2 = (curChar & 0xff) >> 6;
-         long l2 = 1L << (curChar & 077);
-         MatchLoop: do
-         {
-            switch(jjstateSet[--i])
-            {
-               case 3:
-               case 2:
-                  if ((jjbitVec0[i2] & l2) == 0L)
-                     break;
-                  if (kind > 21)
-                     kind = 21;
-                  jjCheckNAdd(2);
-                  break;
-               default : break;
-            }
-         } while(i != startsAt);
-      }
-      if (kind != 0x7fffffff)
-      {
-         jjmatchedKind = kind;
-         jjmatchedPos = curPos;
-         kind = 0x7fffffff;
-      }
-      ++curPos;
-      if ((i = jjnewStateCnt) == (startsAt = 3 - (jjnewStateCnt = startsAt)))
-         return curPos;
-      try { curChar = input_stream.readChar(); }
-      catch(java.io.IOException e) { return curPos; }
-   }
-}
-private final int jjStopStringLiteralDfa_1(int pos, long active0)
-{
-   switch (pos)
-   {
-      default :
-         return -1;
-   }
-}
-private final int jjStartNfa_1(int pos, long active0)
-{
-   return jjMoveNfa_1(jjStopStringLiteralDfa_1(pos, active0), pos + 1);
-}
-private final int jjStartNfaWithStates_1(int pos, int kind, int state)
-{
-   jjmatchedKind = kind;
-   jjmatchedPos = pos;
-   try { curChar = input_stream.readChar(); }
-   catch(java.io.IOException e) { return pos + 1; }
-   return jjMoveNfa_1(state, pos + 1);
-}
-private final int jjMoveStringLiteralDfa0_1()
-{
-   switch(curChar)
-   {
-      case 40:
-         return jjStopAtPos(0, 10);
-      case 41:
-         return jjStopAtPos(0, 8);
-      default :
-         return jjMoveNfa_1(0, 0);
-   }
-}
-private final int jjMoveNfa_1(int startState, int curPos)
-{
-   int[] nextStates;
-   int startsAt = 0;
-   jjnewStateCnt = 3;
-   int i = 1;
-   jjstateSet[0] = startState;
-   int j, kind = 0x7fffffff;
-   for (;;)
-   {
-      if (++jjround == 0x7fffffff)
-         ReInitRounds();
-      if (curChar < 64)
-      {
-         long l = 1L << curChar;
-         MatchLoop: do
-         {
-            switch(jjstateSet[--i])
-            {
-               case 0:
-                  if (kind > 11)
-                     kind = 11;
-                  break;
-               case 1:
-                  if (kind > 9)
-                     kind = 9;
-                  break;
-               default : break;
-            }
-         } while(i != startsAt);
-      }
-      else if (curChar < 128)
-      {
-         long l = 1L << (curChar & 077);
-         MatchLoop: do
-         {
-            switch(jjstateSet[--i])
-            {
-               case 0:
-                  if (kind > 11)
-                     kind = 11;
-                  if (curChar == 92)
-                     jjstateSet[jjnewStateCnt++] = 1;
-                  break;
-               case 1:
-                  if (kind > 9)
-                     kind = 9;
-                  break;
-               case 2:
-                  if (kind > 11)
-                     kind = 11;
-                  break;
-               default : break;
-            }
-         } while(i != startsAt);
-      }
-      else
-      {
-         int i2 = (curChar & 0xff) >> 6;
-         long l2 = 1L << (curChar & 077);
-         MatchLoop: do
-         {
-            switch(jjstateSet[--i])
-            {
-               case 0:
-                  if ((jjbitVec0[i2] & l2) != 0L && kind > 11)
-                     kind = 11;
-                  break;
-               case 1:
-                  if ((jjbitVec0[i2] & l2) != 0L && kind > 9)
-                     kind = 9;
-                  break;
-               default : break;
-            }
-         } while(i != startsAt);
-      }
-      if (kind != 0x7fffffff)
-      {
-         jjmatchedKind = kind;
-         jjmatchedPos = curPos;
-         kind = 0x7fffffff;
-      }
-      ++curPos;
-      if ((i = jjnewStateCnt) == (startsAt = 3 - (jjnewStateCnt = startsAt)))
-         return curPos;
-      try { curChar = input_stream.readChar(); }
-      catch(java.io.IOException e) { return curPos; }
-   }
-}
-private final int jjStopStringLiteralDfa_3(int pos, long active0)
-{
-   switch (pos)
-   {
-      default :
-         return -1;
-   }
-}
-private final int jjStartNfa_3(int pos, long active0)
-{
-   return jjMoveNfa_3(jjStopStringLiteralDfa_3(pos, active0), pos + 1);
-}
-private final int jjStartNfaWithStates_3(int pos, int kind, int state)
-{
-   jjmatchedKind = kind;
-   jjmatchedPos = pos;
-   try { curChar = input_stream.readChar(); }
-   catch(java.io.IOException e) { return pos + 1; }
-   return jjMoveNfa_3(state, pos + 1);
-}
-private final int jjMoveStringLiteralDfa0_3()
-{
-   switch(curChar)
-   {
-      case 34:
-         return jjStopAtPos(0, 19);
-      default :
-         return jjMoveNfa_3(0, 0);
-   }
-}
-private final int jjMoveNfa_3(int startState, int curPos)
-{
-   int[] nextStates;
-   int startsAt = 0;
-   jjnewStateCnt = 3;
-   int i = 1;
-   jjstateSet[0] = startState;
-   int j, kind = 0x7fffffff;
-   for (;;)
-   {
-      if (++jjround == 0x7fffffff)
-         ReInitRounds();
-      if (curChar < 64)
-      {
-         long l = 1L << curChar;
-         MatchLoop: do
-         {
-            switch(jjstateSet[--i])
-            {
-               case 0:
-               case 2:
-                  if ((0xfffffffbffffffffL & l) == 0L)
-                     break;
-                  if (kind > 18)
-                     kind = 18;
-                  jjCheckNAdd(2);
-                  break;
-               case 1:
-                  if (kind > 17)
-                     kind = 17;
-                  break;
-               default : break;
-            }
-         } while(i != startsAt);
-      }
-      else if (curChar < 128)
-      {
-         long l = 1L << (curChar & 077);
-         MatchLoop: do
-         {
-            switch(jjstateSet[--i])
-            {
-               case 0:
-                  if ((0xffffffffefffffffL & l) != 0L)
-                  {
-                     if (kind > 18)
-                        kind = 18;
-                     jjCheckNAdd(2);
-                  }
-                  else if (curChar == 92)
-                     jjstateSet[jjnewStateCnt++] = 1;
-                  break;
-               case 1:
-                  if (kind > 17)
-                     kind = 17;
-                  break;
-               case 2:
-                  if ((0xffffffffefffffffL & l) == 0L)
-                     break;
-                  if (kind > 18)
-                     kind = 18;
-                  jjCheckNAdd(2);
-                  break;
-               default : break;
-            }
-         } while(i != startsAt);
-      }
-      else
-      {
-         int i2 = (curChar & 0xff) >> 6;
-         long l2 = 1L << (curChar & 077);
-         MatchLoop: do
-         {
-            switch(jjstateSet[--i])
-            {
-               case 0:
-               case 2:
-                  if ((jjbitVec0[i2] & l2) == 0L)
-                     break;
-                  if (kind > 18)
-                     kind = 18;
-                  jjCheckNAdd(2);
-                  break;
-               case 1:
-                  if ((jjbitVec0[i2] & l2) != 0L && kind > 17)
-                     kind = 17;
-                  break;
-               default : break;
-            }
-         } while(i != startsAt);
-      }
-      if (kind != 0x7fffffff)
-      {
-         jjmatchedKind = kind;
-         jjmatchedPos = curPos;
-         kind = 0x7fffffff;
-      }
-      ++curPos;
-      if ((i = jjnewStateCnt) == (startsAt = 3 - (jjnewStateCnt = startsAt)))
-         return curPos;
-      try { curChar = input_stream.readChar(); }
-      catch(java.io.IOException e) { return curPos; }
-   }
-}
-private final int jjStopStringLiteralDfa_2(int pos, long active0)
-{
-   switch (pos)
-   {
-      default :
-         return -1;
-   }
-}
-private final int jjStartNfa_2(int pos, long active0)
-{
-   return jjMoveNfa_2(jjStopStringLiteralDfa_2(pos, active0), pos + 1);
-}
-private final int jjStartNfaWithStates_2(int pos, int kind, int state)
-{
-   jjmatchedKind = kind;
-   jjmatchedPos = pos;
-   try { curChar = input_stream.readChar(); }
-   catch(java.io.IOException e) { return pos + 1; }
-   return jjMoveNfa_2(state, pos + 1);
-}
-private final int jjMoveStringLiteralDfa0_2()
-{
-   switch(curChar)
-   {
-      case 40:
-         return jjStopAtPos(0, 13);
-      case 41:
-         return jjStopAtPos(0, 14);
-      default :
-         return jjMoveNfa_2(0, 0);
-   }
-}
-private final int jjMoveNfa_2(int startState, int curPos)
-{
-   int[] nextStates;
-   int startsAt = 0;
-   jjnewStateCnt = 3;
-   int i = 1;
-   jjstateSet[0] = startState;
-   int j, kind = 0x7fffffff;
-   for (;;)
-   {
-      if (++jjround == 0x7fffffff)
-         ReInitRounds();
-      if (curChar < 64)
-      {
-         long l = 1L << curChar;
-         MatchLoop: do
-         {
-            switch(jjstateSet[--i])
-            {
-               case 0:
-                  if (kind > 15)
-                     kind = 15;
-                  break;
-               case 1:
-                  if (kind > 12)
-                     kind = 12;
-                  break;
-               default : break;
-            }
-         } while(i != startsAt);
-      }
-      else if (curChar < 128)
-      {
-         long l = 1L << (curChar & 077);
-         MatchLoop: do
-         {
-            switch(jjstateSet[--i])
-            {
-               case 0:
-                  if (kind > 15)
-                     kind = 15;
-                  if (curChar == 92)
-                     jjstateSet[jjnewStateCnt++] = 1;
-                  break;
-               case 1:
-                  if (kind > 12)
-                     kind = 12;
-                  break;
-               case 2:
-                  if (kind > 15)
-                     kind = 15;
-                  break;
-               default : break;
-            }
-         } while(i != startsAt);
-      }
-      else
-      {
-         int i2 = (curChar & 0xff) >> 6;
-         long l2 = 1L << (curChar & 077);
-         MatchLoop: do
-         {
-            switch(jjstateSet[--i])
-            {
-               case 0:
-                  if ((jjbitVec0[i2] & l2) != 0L && kind > 15)
-                     kind = 15;
-                  break;
-               case 1:
-                  if ((jjbitVec0[i2] & l2) != 0L && kind > 12)
-                     kind = 12;
-                  break;
-               default : break;
-            }
-         } while(i != startsAt);
-      }
-      if (kind != 0x7fffffff)
-      {
-         jjmatchedKind = kind;
-         jjmatchedPos = curPos;
-         kind = 0x7fffffff;
-      }
-      ++curPos;
-      if ((i = jjnewStateCnt) == (startsAt = 3 - (jjnewStateCnt = startsAt)))
-         return curPos;
-      try { curChar = input_stream.readChar(); }
-      catch(java.io.IOException e) { return curPos; }
-   }
-}
-static final int[] jjnextStates = {
-};
-public static final String[] jjstrLiteralImages = {
-"", "\15", "\12", "\57", "\73", "\75", null, null, null, null, null, null, 
-null, null, null, null, null, null, null, null, null, null, null, null, };
-public static final String[] lexStateNames = {
-   "DEFAULT", 
-   "INCOMMENT", 
-   "NESTED_COMMENT", 
-   "INQUOTEDSTRING", 
-};
-public static final int[] jjnewLexState = {
-   -1, -1, -1, -1, -1, -1, -1, 1, 0, -1, 2, -1, -1, -1, -1, -1, 3, -1, -1, 0, -1, -1, -1, -1, 
-};
-static final long[] jjtoToken = {
-   0x38003fL, 
-};
-static final long[] jjtoSkip = {
-   0x140L, 
-};
-static final long[] jjtoSpecial = {
-   0x40L, 
-};
-static final long[] jjtoMore = {
-   0x7fe80L, 
-};
-protected SimpleCharStream input_stream;
-private final int[] jjrounds = new int[3];
-private final int[] jjstateSet = new int[6];
-StringBuffer image;
-int jjimageLen;
-int lengthOfMatch;
-protected char curChar;
-public ContentTypeParserTokenManager(SimpleCharStream stream){
-   if (SimpleCharStream.staticFlag)
-      throw new Error("ERROR: Cannot use a static CharStream class with a non-static lexical analyzer.");
-   input_stream = stream;
-}
-public ContentTypeParserTokenManager(SimpleCharStream stream, int lexState){
-   this(stream);
-   SwitchTo(lexState);
-}
-public void ReInit(SimpleCharStream stream)
-{
-   jjmatchedPos = jjnewStateCnt = 0;
-   curLexState = defaultLexState;
-   input_stream = stream;
-   ReInitRounds();
-}
-private final void ReInitRounds()
-{
-   int i;
-   jjround = 0x80000001;
-   for (i = 3; i-- > 0;)
-      jjrounds[i] = 0x80000000;
-}
-public void ReInit(SimpleCharStream stream, int lexState)
-{
-   ReInit(stream);
-   SwitchTo(lexState);
-}
-public void SwitchTo(int lexState)
-{
-   if (lexState >= 4 || lexState < 0)
-      throw new TokenMgrError("Error: Ignoring invalid lexical state : " + lexState + ". State unchanged.", TokenMgrError.INVALID_LEXICAL_STATE);
-   else
-      curLexState = lexState;
-}
-
-protected Token jjFillToken()
-{
-   Token t = Token.newToken(jjmatchedKind);
-   t.kind = jjmatchedKind;
-   String im = jjstrLiteralImages[jjmatchedKind];
-   t.image = (im == null) ? input_stream.GetImage() : im;
-   t.beginLine = input_stream.getBeginLine();
-   t.beginColumn = input_stream.getBeginColumn();
-   t.endLine = input_stream.getEndLine();
-   t.endColumn = input_stream.getEndColumn();
-   return t;
-}
-
-int curLexState = 0;
-int defaultLexState = 0;
-int jjnewStateCnt;
-int jjround;
-int jjmatchedPos;
-int jjmatchedKind;
-
-public Token getNextToken() 
-{
-  int kind;
-  Token specialToken = null;
-  Token matchedToken;
-  int curPos = 0;
-
-  EOFLoop :
-  for (;;)
-  {   
-   try   
-   {     
-      curChar = input_stream.BeginToken();
-   }     
-   catch(java.io.IOException e)
-   {        
-      jjmatchedKind = 0;
-      matchedToken = jjFillToken();
-      matchedToken.specialToken = specialToken;
-      return matchedToken;
-   }
-   image = null;
-   jjimageLen = 0;
-
-   for (;;)
-   {
-     switch(curLexState)
-     {
-       case 0:
-         jjmatchedKind = 0x7fffffff;
-         jjmatchedPos = 0;
-         curPos = jjMoveStringLiteralDfa0_0();
-         break;
-       case 1:
-         jjmatchedKind = 0x7fffffff;
-         jjmatchedPos = 0;
-         curPos = jjMoveStringLiteralDfa0_1();
-         break;
-       case 2:
-         jjmatchedKind = 0x7fffffff;
-         jjmatchedPos = 0;
-         curPos = jjMoveStringLiteralDfa0_2();
-         break;
-       case 3:
-         jjmatchedKind = 0x7fffffff;
-         jjmatchedPos = 0;
-         curPos = jjMoveStringLiteralDfa0_3();
-         break;
-     }
-     if (jjmatchedKind != 0x7fffffff)
-     {
-        if (jjmatchedPos + 1 < curPos)
-           input_stream.backup(curPos - jjmatchedPos - 1);
-        if ((jjtoToken[jjmatchedKind >> 6] & (1L << (jjmatchedKind & 077))) != 0L)
-        {
-           matchedToken = jjFillToken();
-           matchedToken.specialToken = specialToken;
-           TokenLexicalActions(matchedToken);
-       if (jjnewLexState[jjmatchedKind] != -1)
-         curLexState = jjnewLexState[jjmatchedKind];
-           return matchedToken;
-        }
-        else if ((jjtoSkip[jjmatchedKind >> 6] & (1L << (jjmatchedKind & 077))) != 0L)
-        {
-           if ((jjtoSpecial[jjmatchedKind >> 6] & (1L << (jjmatchedKind & 077))) != 0L)
-           {
-              matchedToken = jjFillToken();
-              if (specialToken == null)
-                 specialToken = matchedToken;
-              else
-              {
-                 matchedToken.specialToken = specialToken;
-                 specialToken = (specialToken.next = matchedToken);
-              }
-           }
-         if (jjnewLexState[jjmatchedKind] != -1)
-           curLexState = jjnewLexState[jjmatchedKind];
-           continue EOFLoop;
-        }
-        MoreLexicalActions();
-      if (jjnewLexState[jjmatchedKind] != -1)
-        curLexState = jjnewLexState[jjmatchedKind];
-        curPos = 0;
-        jjmatchedKind = 0x7fffffff;
-        try {
-           curChar = input_stream.readChar();
-           continue;
-        }
-        catch (java.io.IOException e1) { }
-     }
-     int error_line = input_stream.getEndLine();
-     int error_column = input_stream.getEndColumn();
-     String error_after = null;
-     boolean EOFSeen = false;
-     try { input_stream.readChar(); input_stream.backup(1); }
-     catch (java.io.IOException e1) {
-        EOFSeen = true;
-        error_after = curPos <= 1 ? "" : input_stream.GetImage();
-        if (curChar == '\n' || curChar == '\r') {
-           error_line++;
-           error_column = 0;
-        }
-        else
-           error_column++;
-     }
-     if (!EOFSeen) {
-        input_stream.backup(1);
-        error_after = curPos <= 1 ? "" : input_stream.GetImage();
-     }
-     throw new TokenMgrError(EOFSeen, curLexState, error_line, error_column, error_after, curChar, TokenMgrError.LEXICAL_ERROR);
-   }
-  }
-}
-
-void MoreLexicalActions()
-{
-   jjimageLen += (lengthOfMatch = jjmatchedPos + 1);
-   switch(jjmatchedKind)
-   {
-      case 9 :
-         if (image == null)
-            image = new StringBuffer();
-         image.append(input_stream.GetSuffix(jjimageLen));
-         jjimageLen = 0;
-                          image.deleteCharAt(image.length() - 2);
-         break;
-      case 10 :
-         if (image == null)
-            image = new StringBuffer();
-         image.append(input_stream.GetSuffix(jjimageLen));
-         jjimageLen = 0;
-              commentNest = 1;
-         break;
-      case 12 :
-         if (image == null)
-            image = new StringBuffer();
-         image.append(input_stream.GetSuffix(jjimageLen));
-         jjimageLen = 0;
-                          image.deleteCharAt(image.length() - 2);
-         break;
-      case 13 :
-         if (image == null)
-            image = new StringBuffer();
-         image.append(input_stream.GetSuffix(jjimageLen));
-         jjimageLen = 0;
-              ++commentNest;
-         break;
-      case 14 :
-         if (image == null)
-            image = new StringBuffer();
-         image.append(input_stream.GetSuffix(jjimageLen));
-         jjimageLen = 0;
-              --commentNest; if (commentNest == 0) SwitchTo(INCOMMENT);
-         break;
-      case 16 :
-         if (image == null)
-            image = new StringBuffer();
-         image.append(input_stream.GetSuffix(jjimageLen));
-         jjimageLen = 0;
-               image.deleteCharAt(image.length() - 1);
-         break;
-      case 17 :
-         if (image == null)
-            image = new StringBuffer();
-         image.append(input_stream.GetSuffix(jjimageLen));
-         jjimageLen = 0;
-                          image.deleteCharAt(image.length() - 2);
-         break;
-      default : 
-         break;
-   }
-}
-void TokenLexicalActions(Token matchedToken)
-{
-   switch(jjmatchedKind)
-   {
-      case 19 :
-        if (image == null)
-            image = new StringBuffer();
-            image.append(input_stream.GetSuffix(jjimageLen + (lengthOfMatch = jjmatchedPos + 1)));
-                                 matchedToken.image = image.substring(0, image.length() - 1);
-         break;
-      default : 
-         break;
-   }
-}
-}
diff --git a/src/org/apache/james/mime4j/field/contenttype/parser/ParseException.java b/src/org/apache/james/mime4j/field/contenttype/parser/ParseException.java
deleted file mode 100644
index d9b69b2..0000000
--- a/src/org/apache/james/mime4j/field/contenttype/parser/ParseException.java
+++ /dev/null
@@ -1,207 +0,0 @@
-/* Generated By:JavaCC: Do not edit this line. ParseException.java Version 3.0 */
-/*
- *  Copyright 2004 the mime4j 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 org.apache.james.mime4j.field.contenttype.parser;
-
-/**
- * This exception is thrown when parse errors are encountered.
- * You can explicitly create objects of this exception type by
- * calling the method generateParseException in the generated
- * parser.
- *
- * You can modify this class to customize your error reporting
- * mechanisms so long as you retain the public fields.
- */
-public class ParseException extends Exception {
-
-  /**
-   * This constructor is used by the method "generateParseException"
-   * in the generated parser.  Calling this constructor generates
-   * a new object of this type with the fields "currentToken",
-   * "expectedTokenSequences", and "tokenImage" set.  The boolean
-   * flag "specialConstructor" is also set to true to indicate that
-   * this constructor was used to create this object.
-   * This constructor calls its super class with the empty string
-   * to force the "toString" method of parent class "Throwable" to
-   * print the error message in the form:
-   *     ParseException: <result of getMessage>
-   */
-  public ParseException(Token currentTokenVal,
-                        int[][] expectedTokenSequencesVal,
-                        String[] tokenImageVal
-                       )
-  {
-    super("");
-    specialConstructor = true;
-    currentToken = currentTokenVal;
-    expectedTokenSequences = expectedTokenSequencesVal;
-    tokenImage = tokenImageVal;
-  }
-
-  /**
-   * The following constructors are for use by you for whatever
-   * purpose you can think of.  Constructing the exception in this
-   * manner makes the exception behave in the normal way - i.e., as
-   * documented in the class "Throwable".  The fields "errorToken",
-   * "expectedTokenSequences", and "tokenImage" do not contain
-   * relevant information.  The JavaCC generated code does not use
-   * these constructors.
-   */
-
-  public ParseException() {
-    super();
-    specialConstructor = false;
-  }
-
-  public ParseException(String message) {
-    super(message);
-    specialConstructor = false;
-  }
-
-  /**
-   * This variable determines which constructor was used to create
-   * this object and thereby affects the semantics of the
-   * "getMessage" method (see below).
-   */
-  protected boolean specialConstructor;
-
-  /**
-   * This is the last token that has been consumed successfully.  If
-   * this object has been created due to a parse error, the token
-   * followng this token will (therefore) be the first error token.
-   */
-  public Token currentToken;
-
-  /**
-   * Each entry in this array is an array of integers.  Each array
-   * of integers represents a sequence of tokens (by their ordinal
-   * values) that is expected at this point of the parse.
-   */
-  public int[][] expectedTokenSequences;
-
-  /**
-   * This is a reference to the "tokenImage" array of the generated
-   * parser within which the parse error occurred.  This array is
-   * defined in the generated ...Constants interface.
-   */
-  public String[] tokenImage;
-
-  /**
-   * This method has the standard behavior when this object has been
-   * created using the standard constructors.  Otherwise, it uses
-   * "currentToken" and "expectedTokenSequences" to generate a parse
-   * error message and returns it.  If this object has been created
-   * due to a parse error, and you do not catch it (it gets thrown
-   * from the parser), then this method is called during the printing
-   * of the final stack trace, and hence the correct error message
-   * gets displayed.
-   */
-  public String getMessage() {
-    if (!specialConstructor) {
-      return super.getMessage();
-    }
-    StringBuffer expected = new StringBuffer();
-    int maxSize = 0;
-    for (int i = 0; i < expectedTokenSequences.length; i++) {
-      if (maxSize < expectedTokenSequences[i].length) {
-        maxSize = expectedTokenSequences[i].length;
-      }
-      for (int j = 0; j < expectedTokenSequences[i].length; j++) {
-        expected.append(tokenImage[expectedTokenSequences[i][j]]).append(" ");
-      }
-      if (expectedTokenSequences[i][expectedTokenSequences[i].length - 1] != 0) {
-        expected.append("...");
-      }
-      expected.append(eol).append("    ");
-    }
-    String retval = "Encountered \"";
-    Token tok = currentToken.next;
-    for (int i = 0; i < maxSize; i++) {
-      if (i != 0) retval += " ";
-      if (tok.kind == 0) {
-        retval += tokenImage[0];
-        break;
-      }
-      retval += add_escapes(tok.image);
-      tok = tok.next; 
-    }
-    retval += "\" at line " + currentToken.next.beginLine + ", column " + currentToken.next.beginColumn;
-    retval += "." + eol;
-    if (expectedTokenSequences.length == 1) {
-      retval += "Was expecting:" + eol + "    ";
-    } else {
-      retval += "Was expecting one of:" + eol + "    ";
-    }
-    retval += expected.toString();
-    return retval;
-  }
-
-  /**
-   * The end of line string for this machine.
-   */
-  protected String eol = System.getProperty("line.separator", "\n");
- 
-  /**
-   * Used to convert raw characters to their escaped version
-   * when these raw version cannot be used as part of an ASCII
-   * string literal.
-   */
-  protected String add_escapes(String str) {
-      StringBuffer retval = new StringBuffer();
-      char ch;
-      for (int i = 0; i < str.length(); i++) {
-        switch (str.charAt(i))
-        {
-           case 0 :
-              continue;
-           case '\b':
-              retval.append("\\b");
-              continue;
-           case '\t':
-              retval.append("\\t");
-              continue;
-           case '\n':
-              retval.append("\\n");
-              continue;
-           case '\f':
-              retval.append("\\f");
-              continue;
-           case '\r':
-              retval.append("\\r");
-              continue;
-           case '\"':
-              retval.append("\\\"");
-              continue;
-           case '\'':
-              retval.append("\\\'");
-              continue;
-           case '\\':
-              retval.append("\\\\");
-              continue;
-           default:
-              if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) {
-                 String s = "0000" + Integer.toString(ch, 16);
-                 retval.append("\\u" + s.substring(s.length() - 4, s.length()));
-              } else {
-                 retval.append(ch);
-              }
-              continue;
-        }
-      }
-      return retval.toString();
-   }
-
-}
diff --git a/src/org/apache/james/mime4j/field/contenttype/parser/SimpleCharStream.java b/src/org/apache/james/mime4j/field/contenttype/parser/SimpleCharStream.java
deleted file mode 100644
index ae035b7..0000000
--- a/src/org/apache/james/mime4j/field/contenttype/parser/SimpleCharStream.java
+++ /dev/null
@@ -1,454 +0,0 @@
-/* Generated By:JavaCC: Do not edit this line. SimpleCharStream.java Version 4.0 */
-/*
- *  Copyright 2004 the mime4j 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 org.apache.james.mime4j.field.contenttype.parser;
-
-/**
- * An implementation of interface CharStream, where the stream is assumed to
- * contain only ASCII characters (without unicode processing).
- */
-
-public class SimpleCharStream
-{
-  public static final boolean staticFlag = false;
-  int bufsize;
-  int available;
-  int tokenBegin;
-  public int bufpos = -1;
-  protected int bufline[];
-  protected int bufcolumn[];
-
-  protected int column = 0;
-  protected int line = 1;
-
-  protected boolean prevCharIsCR = false;
-  protected boolean prevCharIsLF = false;
-
-  protected java.io.Reader inputStream;
-
-  protected char[] buffer;
-  protected int maxNextCharInd = 0;
-  protected int inBuf = 0;
-  protected int tabSize = 8;
-
-  protected void setTabSize(int i) { tabSize = i; }
-  protected int getTabSize(int i) { return tabSize; }
-
-
-  protected void ExpandBuff(boolean wrapAround)
-  {
-     char[] newbuffer = new char[bufsize + 2048];
-     int newbufline[] = new int[bufsize + 2048];
-     int newbufcolumn[] = new int[bufsize + 2048];
-
-     try
-     {
-        if (wrapAround)
-        {
-           System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin);
-           System.arraycopy(buffer, 0, newbuffer,
-                                             bufsize - tokenBegin, bufpos);
-           buffer = newbuffer;
-
-           System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin);
-           System.arraycopy(bufline, 0, newbufline, bufsize - tokenBegin, bufpos);
-           bufline = newbufline;
-
-           System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin);
-           System.arraycopy(bufcolumn, 0, newbufcolumn, bufsize - tokenBegin, bufpos);
-           bufcolumn = newbufcolumn;
-
-           maxNextCharInd = (bufpos += (bufsize - tokenBegin));
-        }
-        else
-        {
-           System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin);
-           buffer = newbuffer;
-
-           System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin);
-           bufline = newbufline;
-
-           System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin);
-           bufcolumn = newbufcolumn;
-
-           maxNextCharInd = (bufpos -= tokenBegin);
-        }
-     }
-     catch (Throwable t)
-     {
-        throw new Error(t.getMessage());
-     }
-
-
-     bufsize += 2048;
-     available = bufsize;
-     tokenBegin = 0;
-  }
-
-  protected void FillBuff() throws java.io.IOException
-  {
-     if (maxNextCharInd == available)
-     {
-        if (available == bufsize)
-        {
-           if (tokenBegin > 2048)
-           {
-              bufpos = maxNextCharInd = 0;
-              available = tokenBegin;
-           }
-           else if (tokenBegin < 0)
-              bufpos = maxNextCharInd = 0;
-           else
-              ExpandBuff(false);
-        }
-        else if (available > tokenBegin)
-           available = bufsize;
-        else if ((tokenBegin - available) < 2048)
-           ExpandBuff(true);
-        else
-           available = tokenBegin;
-     }
-
-     int i;
-     try {
-        if ((i = inputStream.read(buffer, maxNextCharInd,
-                                    available - maxNextCharInd)) == -1)
-        {
-           inputStream.close();
-           throw new java.io.IOException();
-        }
-        else
-           maxNextCharInd += i;
-        return;
-     }
-     catch(java.io.IOException e) {
-        --bufpos;
-        backup(0);
-        if (tokenBegin == -1)
-           tokenBegin = bufpos;
-        throw e;
-     }
-  }
-
-  public char BeginToken() throws java.io.IOException
-  {
-     tokenBegin = -1;
-     char c = readChar();
-     tokenBegin = bufpos;
-
-     return c;
-  }
-
-  protected void UpdateLineColumn(char c)
-  {
-     column++;
-
-     if (prevCharIsLF)
-     {
-        prevCharIsLF = false;
-        line += (column = 1);
-     }
-     else if (prevCharIsCR)
-     {
-        prevCharIsCR = false;
-        if (c == '\n')
-        {
-           prevCharIsLF = true;
-        }
-        else
-           line += (column = 1);
-     }
-
-     switch (c)
-     {
-        case '\r' :
-           prevCharIsCR = true;
-           break;
-        case '\n' :
-           prevCharIsLF = true;
-           break;
-        case '\t' :
-           column--;
-           column += (tabSize - (column % tabSize));
-           break;
-        default :
-           break;
-     }
-
-     bufline[bufpos] = line;
-     bufcolumn[bufpos] = column;
-  }
-
-  public char readChar() throws java.io.IOException
-  {
-     if (inBuf > 0)
-     {
-        --inBuf;
-
-        if (++bufpos == bufsize)
-           bufpos = 0;
-
-        return buffer[bufpos];
-     }
-
-     if (++bufpos >= maxNextCharInd)
-        FillBuff();
-
-     char c = buffer[bufpos];
-
-     UpdateLineColumn(c);
-     return (c);
-  }
-
-  /**
-   * @deprecated 
-   * @see #getEndColumn
-   */
-  @Deprecated
-  public int getColumn() {
-     return bufcolumn[bufpos];
-  }
-
-  /**
-   * @deprecated 
-   * @see #getEndLine
-   */
-  @Deprecated
-  public int getLine() {
-     return bufline[bufpos];
-  }
-
-  public int getEndColumn() {
-     return bufcolumn[bufpos];
-  }
-
-  public int getEndLine() {
-     return bufline[bufpos];
-  }
-
-  public int getBeginColumn() {
-     return bufcolumn[tokenBegin];
-  }
-
-  public int getBeginLine() {
-     return bufline[tokenBegin];
-  }
-
-  public void backup(int amount) {
-
-    inBuf += amount;
-    if ((bufpos -= amount) < 0)
-       bufpos += bufsize;
-  }
-
-  public SimpleCharStream(java.io.Reader dstream, int startline,
-  int startcolumn, int buffersize)
-  {
-    inputStream = dstream;
-    line = startline;
-    column = startcolumn - 1;
-
-    available = bufsize = buffersize;
-    buffer = new char[buffersize];
-    bufline = new int[buffersize];
-    bufcolumn = new int[buffersize];
-  }
-
-  public SimpleCharStream(java.io.Reader dstream, int startline,
-                          int startcolumn)
-  {
-     this(dstream, startline, startcolumn, 4096);
-  }
-
-  public SimpleCharStream(java.io.Reader dstream)
-  {
-     this(dstream, 1, 1, 4096);
-  }
-  public void ReInit(java.io.Reader dstream, int startline,
-  int startcolumn, int buffersize)
-  {
-    inputStream = dstream;
-    line = startline;
-    column = startcolumn - 1;
-
-    if (buffer == null || buffersize != buffer.length)
-    {
-      available = bufsize = buffersize;
-      buffer = new char[buffersize];
-      bufline = new int[buffersize];
-      bufcolumn = new int[buffersize];
-    }
-    prevCharIsLF = prevCharIsCR = false;
-    tokenBegin = inBuf = maxNextCharInd = 0;
-    bufpos = -1;
-  }
-
-  public void ReInit(java.io.Reader dstream, int startline,
-                     int startcolumn)
-  {
-     ReInit(dstream, startline, startcolumn, 4096);
-  }
-
-  public void ReInit(java.io.Reader dstream)
-  {
-     ReInit(dstream, 1, 1, 4096);
-  }
-  public SimpleCharStream(java.io.InputStream dstream, String encoding, int startline,
-  int startcolumn, int buffersize) throws java.io.UnsupportedEncodingException
-  {
-     this(encoding == null ? new java.io.InputStreamReader(dstream) : new java.io.InputStreamReader(dstream, encoding), startline, startcolumn, buffersize);
-  }
-
-  public SimpleCharStream(java.io.InputStream dstream, int startline,
-  int startcolumn, int buffersize)
-  {
-     this(new java.io.InputStreamReader(dstream), startline, startcolumn, buffersize);
-  }
-
-  public SimpleCharStream(java.io.InputStream dstream, String encoding, int startline,
-                          int startcolumn) throws java.io.UnsupportedEncodingException
-  {
-     this(dstream, encoding, startline, startcolumn, 4096);
-  }
-
-  public SimpleCharStream(java.io.InputStream dstream, int startline,
-                          int startcolumn)
-  {
-     this(dstream, startline, startcolumn, 4096);
-  }
-
-  public SimpleCharStream(java.io.InputStream dstream, String encoding) throws java.io.UnsupportedEncodingException
-  {
-     this(dstream, encoding, 1, 1, 4096);
-  }
-
-  public SimpleCharStream(java.io.InputStream dstream)
-  {
-     this(dstream, 1, 1, 4096);
-  }
-
-  public void ReInit(java.io.InputStream dstream, String encoding, int startline,
-                          int startcolumn, int buffersize) throws java.io.UnsupportedEncodingException
-  {
-     ReInit(encoding == null ? new java.io.InputStreamReader(dstream) : new java.io.InputStreamReader(dstream, encoding), startline, startcolumn, buffersize);
-  }
-
-  public void ReInit(java.io.InputStream dstream, int startline,
-                          int startcolumn, int buffersize)
-  {
-     ReInit(new java.io.InputStreamReader(dstream), startline, startcolumn, buffersize);
-  }
-
-  public void ReInit(java.io.InputStream dstream, String encoding) throws java.io.UnsupportedEncodingException
-  {
-     ReInit(dstream, encoding, 1, 1, 4096);
-  }
-
-  public void ReInit(java.io.InputStream dstream)
-  {
-     ReInit(dstream, 1, 1, 4096);
-  }
-  public void ReInit(java.io.InputStream dstream, String encoding, int startline,
-                     int startcolumn) throws java.io.UnsupportedEncodingException
-  {
-     ReInit(dstream, encoding, startline, startcolumn, 4096);
-  }
-  public void ReInit(java.io.InputStream dstream, int startline,
-                     int startcolumn)
-  {
-     ReInit(dstream, startline, startcolumn, 4096);
-  }
-  public String GetImage()
-  {
-     if (bufpos >= tokenBegin)
-        return new String(buffer, tokenBegin, bufpos - tokenBegin + 1);
-     else
-        return new String(buffer, tokenBegin, bufsize - tokenBegin) +
-                              new String(buffer, 0, bufpos + 1);
-  }
-
-  public char[] GetSuffix(int len)
-  {
-     char[] ret = new char[len];
-
-     if ((bufpos + 1) >= len)
-        System.arraycopy(buffer, bufpos - len + 1, ret, 0, len);
-     else
-     {
-        System.arraycopy(buffer, bufsize - (len - bufpos - 1), ret, 0,
-                                                          len - bufpos - 1);
-        System.arraycopy(buffer, 0, ret, len - bufpos - 1, bufpos + 1);
-     }
-
-     return ret;
-  }
-
-  public void Done()
-  {
-     buffer = null;
-     bufline = null;
-     bufcolumn = null;
-  }
-
-  /**
-   * Method to adjust line and column numbers for the start of a token.
-   */
-  public void adjustBeginLineColumn(int newLine, int newCol)
-  {
-     int start = tokenBegin;
-     int len;
-
-     if (bufpos >= tokenBegin)
-     {
-        len = bufpos - tokenBegin + inBuf + 1;
-     }
-     else
-     {
-        len = bufsize - tokenBegin + bufpos + 1 + inBuf;
-     }
-
-     int i = 0, j = 0, k = 0;
-     int nextColDiff = 0, columnDiff = 0;
-
-     while (i < len &&
-            bufline[j = start % bufsize] == bufline[k = ++start % bufsize])
-     {
-        bufline[j] = newLine;
-        nextColDiff = columnDiff + bufcolumn[k] - bufcolumn[j];
-        bufcolumn[j] = newCol + columnDiff;
-        columnDiff = nextColDiff;
-        i++;
-     } 
-
-     if (i < len)
-     {
-        bufline[j] = newLine++;
-        bufcolumn[j] = newCol + columnDiff;
-
-        while (i++ < len)
-        {
-           if (bufline[j = start % bufsize] != bufline[++start % bufsize])
-              bufline[j] = newLine++;
-           else
-              bufline[j] = newLine;
-        }
-     }
-
-     line = bufline[j];
-     column = bufcolumn[j];
-  }
-
-}
diff --git a/src/org/apache/james/mime4j/field/contenttype/parser/Token.java b/src/org/apache/james/mime4j/field/contenttype/parser/Token.java
deleted file mode 100644
index 34e65ee..0000000
--- a/src/org/apache/james/mime4j/field/contenttype/parser/Token.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/* Generated By:JavaCC: Do not edit this line. Token.java Version 3.0 */
-/*
- *  Copyright 2004 the mime4j 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 org.apache.james.mime4j.field.contenttype.parser;
-
-/**
- * Describes the input token stream.
- */
-
-public class Token {
-
-  /**
-   * An integer that describes the kind of this token.  This numbering
-   * system is determined by JavaCCParser, and a table of these numbers is
-   * stored in the file ...Constants.java.
-   */
-  public int kind;
-
-  /**
-   * beginLine and beginColumn describe the position of the first character
-   * of this token; endLine and endColumn describe the position of the
-   * last character of this token.
-   */
-  public int beginLine, beginColumn, endLine, endColumn;
-
-  /**
-   * The string image of the token.
-   */
-  public String image;
-
-  /**
-   * A reference to the next regular (non-special) token from the input
-   * stream.  If this is the last token from the input stream, or if the
-   * token manager has not read tokens beyond this one, this field is
-   * set to null.  This is true only if this token is also a regular
-   * token.  Otherwise, see below for a description of the contents of
-   * this field.
-   */
-  public Token next;
-
-  /**
-   * This field is used to access special tokens that occur prior to this
-   * token, but after the immediately preceding regular (non-special) token.
-   * If there are no such special tokens, this field is set to null.
-   * When there are more than one such special token, this field refers
-   * to the last of these special tokens, which in turn refers to the next
-   * previous special token through its specialToken field, and so on
-   * until the first special token (whose specialToken field is null).
-   * The next fields of special tokens refer to other special tokens that
-   * immediately follow it (without an intervening regular token).  If there
-   * is no such token, this field is null.
-   */
-  public Token specialToken;
-
-  /**
-   * Returns the image.
-   */
-  public String toString()
-  {
-     return image;
-  }
-
-  /**
-   * Returns a new Token object, by default. However, if you want, you
-   * can create and return subclass objects based on the value of ofKind.
-   * Simply add the cases to the switch for all those special cases.
-   * For example, if you have a subclass of Token called IDToken that
-   * you want to create if ofKind is ID, simlpy add something like :
-   *
-   *    case MyParserConstants.ID : return new IDToken();
-   *
-   * to the following switch statement. Then you can cast matchedToken
-   * variable to the appropriate type and use it in your lexical actions.
-   */
-  public static final Token newToken(int ofKind)
-  {
-     switch(ofKind)
-     {
-       default : return new Token();
-     }
-  }
-
-}
diff --git a/src/org/apache/james/mime4j/field/contenttype/parser/TokenMgrError.java b/src/org/apache/james/mime4j/field/contenttype/parser/TokenMgrError.java
deleted file mode 100644
index ea5a782..0000000
--- a/src/org/apache/james/mime4j/field/contenttype/parser/TokenMgrError.java
+++ /dev/null
@@ -1,148 +0,0 @@
-/* Generated By:JavaCC: Do not edit this line. TokenMgrError.java Version 3.0 */
-/*
- *  Copyright 2004 the mime4j 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 org.apache.james.mime4j.field.contenttype.parser;
-
-public class TokenMgrError extends Error
-{
-   /*
-    * Ordinals for various reasons why an Error of this type can be thrown.
-    */
-
-   /**
-    * Lexical error occured.
-    */
-   static final int LEXICAL_ERROR = 0;
-
-   /**
-    * An attempt wass made to create a second instance of a static token manager.
-    */
-   static final int STATIC_LEXER_ERROR = 1;
-
-   /**
-    * Tried to change to an invalid lexical state.
-    */
-   static final int INVALID_LEXICAL_STATE = 2;
-
-   /**
-    * Detected (and bailed out of) an infinite loop in the token manager.
-    */
-   static final int LOOP_DETECTED = 3;
-
-   /**
-    * Indicates the reason why the exception is thrown. It will have
-    * one of the above 4 values.
-    */
-   int errorCode;
-
-   /**
-    * Replaces unprintable characters by their espaced (or unicode escaped)
-    * equivalents in the given string
-    */
-   protected static final String addEscapes(String str) {
-      StringBuffer retval = new StringBuffer();
-      char ch;
-      for (int i = 0; i < str.length(); i++) {
-        switch (str.charAt(i))
-        {
-           case 0 :
-              continue;
-           case '\b':
-              retval.append("\\b");
-              continue;
-           case '\t':
-              retval.append("\\t");
-              continue;
-           case '\n':
-              retval.append("\\n");
-              continue;
-           case '\f':
-              retval.append("\\f");
-              continue;
-           case '\r':
-              retval.append("\\r");
-              continue;
-           case '\"':
-              retval.append("\\\"");
-              continue;
-           case '\'':
-              retval.append("\\\'");
-              continue;
-           case '\\':
-              retval.append("\\\\");
-              continue;
-           default:
-              if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) {
-                 String s = "0000" + Integer.toString(ch, 16);
-                 retval.append("\\u" + s.substring(s.length() - 4, s.length()));
-              } else {
-                 retval.append(ch);
-              }
-              continue;
-        }
-      }
-      return retval.toString();
-   }
-
-   /**
-    * Returns a detailed message for the Error when it is thrown by the
-    * token manager to indicate a lexical error.
-    * Parameters : 
-    *    EOFSeen     : indicates if EOF caused the lexicl error
-    *    curLexState : lexical state in which this error occured
-    *    errorLine   : line number when the error occured
-    *    errorColumn : column number when the error occured
-    *    errorAfter  : prefix that was seen before this error occured
-    *    curchar     : the offending character
-    * Note: You can customize the lexical error message by modifying this method.
-    */
-   protected static String LexicalError(boolean EOFSeen, int lexState, int errorLine, int errorColumn, String errorAfter, char curChar) {
-      return("Lexical error at line " +
-           errorLine + ", column " +
-           errorColumn + ".  Encountered: " +
-           (EOFSeen ? "<EOF> " : ("\"" + addEscapes(String.valueOf(curChar)) + "\"") + " (" + (int)curChar + "), ") +
-           "after : \"" + addEscapes(errorAfter) + "\"");
-   }
-
-   /**
-    * You can also modify the body of this method to customize your error messages.
-    * For example, cases like LOOP_DETECTED and INVALID_LEXICAL_STATE are not
-    * of end-users concern, so you can return something like : 
-    *
-    *     "Internal Error : Please file a bug report .... "
-    *
-    * from this method for such cases in the release version of your parser.
-    */
-   public String getMessage() {
-      return super.getMessage();
-   }
-
-   /*
-    * Constructors of various flavors follow.
-    */
-
-   public TokenMgrError() {
-   }
-
-   public TokenMgrError(String message, int reason) {
-      super(message);
-      errorCode = reason;
-   }
-
-   public TokenMgrError(boolean EOFSeen, int lexState, int errorLine, int errorColumn, String errorAfter, char curChar, int reason) {
-      this(LexicalError(EOFSeen, lexState, errorLine, errorColumn, errorAfter, curChar), reason);
-   }
-}
diff --git a/src/org/apache/james/mime4j/field/datetime/DateTime.java b/src/org/apache/james/mime4j/field/datetime/DateTime.java
deleted file mode 100644
index 506ff54..0000000
--- a/src/org/apache/james/mime4j/field/datetime/DateTime.java
+++ /dev/null
@@ -1,127 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one   *
- * or more contributor license agreements.  See the NOTICE file *
- * distributed with this work for additional information        *
- * regarding copyright ownership.  The ASF licenses this file   *
- * to you 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 org.apache.james.mime4j.field.datetime;
-
-import org.apache.james.mime4j.field.datetime.parser.DateTimeParser;
-import org.apache.james.mime4j.field.datetime.parser.ParseException;
-import org.apache.james.mime4j.field.datetime.parser.TokenMgrError;
-
-import java.util.Date;
-import java.util.Calendar;
-import java.util.TimeZone;
-import java.util.GregorianCalendar;
-import java.io.StringReader;
-
-public class DateTime {
-    private final Date date;
-    private final int year;
-    private final int month;
-    private final int day;
-    private final int hour;
-    private final int minute;
-    private final int second;
-    private final int timeZone;
-
-    public DateTime(String yearString, int month, int day, int hour, int minute, int second, int timeZone) {
-        this.year = convertToYear(yearString);
-        this.date = convertToDate(year, month, day, hour, minute, second, timeZone);
-        this.month = month;
-        this.day = day;
-        this.hour = hour;
-        this.minute = minute;
-        this.second = second;
-        this.timeZone = timeZone;
-    }
-
-    private int convertToYear(String yearString) {
-        int year = Integer.parseInt(yearString);
-        switch (yearString.length()) {
-            case 1:
-            case 2:
-                if (year >= 0 && year < 50)
-                    return 2000 + year;
-                else
-                    return 1900 + year;
-            case 3:
-                return 1900 + year;
-            default:
-                return year;
-        }
-    }
-
-    public static Date convertToDate(int year, int month, int day, int hour, int minute, int second, int timeZone) {
-        Calendar c = new GregorianCalendar(TimeZone.getTimeZone("GMT+0"));
-        c.set(year, month - 1, day, hour, minute, second);
-        c.set(Calendar.MILLISECOND, 0);
-
-        if (timeZone != Integer.MIN_VALUE) {
-            int minutes = ((timeZone / 100) * 60) + timeZone % 100;
-            c.add(Calendar.MINUTE, -1 * minutes);
-        }
-
-        return c.getTime();
-    }
-
-    public Date getDate() {
-        return date;
-    }
-
-    public int getYear() {
-        return year;
-    }
-
-    public int getMonth() {
-        return month;
-    }
-
-    public int getDay() {
-        return day;
-    }
-
-    public int getHour() {
-        return hour;
-    }
-
-    public int getMinute() {
-        return minute;
-    }
-
-    public int getSecond() {
-        return second;
-    }
-
-    public int getTimeZone() {
-        return timeZone;
-    }
-
-    public void print() {
-        System.out.println(getYear() + " " + getMonth() + " " + getDay() + "; " + getHour() + " " + getMinute() + " " + getSecond() + " " + getTimeZone());
-    }
-
-
-    public static DateTime parse(String dateString) throws ParseException {
-        try {
-            return new DateTimeParser(new StringReader(dateString)).parseAll();
-        }
-        catch (TokenMgrError err) {
-            throw new ParseException(err.getMessage());
-        }
-    }
-}
diff --git a/src/org/apache/james/mime4j/field/datetime/parser/DateTimeParser.java b/src/org/apache/james/mime4j/field/datetime/parser/DateTimeParser.java
deleted file mode 100644
index 43edebb..0000000
--- a/src/org/apache/james/mime4j/field/datetime/parser/DateTimeParser.java
+++ /dev/null
@@ -1,570 +0,0 @@
-/* Generated By:JavaCC: Do not edit this line. DateTimeParser.java */
-/*
- *  Copyright 2004 the mime4j 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 org.apache.james.mime4j.field.datetime.parser;
-
-import org.apache.james.mime4j.field.datetime.DateTime;
-
-import java.util.Vector;
-
-public class DateTimeParser implements DateTimeParserConstants {
-    private static final boolean ignoreMilitaryZoneOffset = true;
-
-    public static void main(String args[]) throws ParseException {
-                while (true) {
-                    try {
-                                DateTimeParser parser = new DateTimeParser(System.in);
-                        parser.parseLine();
-                    } catch (Exception x) {
-                                x.printStackTrace();
-                                return;
-                    }
-                }
-    }
-
-    private static int parseDigits(Token token) {
-        return Integer.parseInt(token.image, 10);
-    }
-
-    private static int getMilitaryZoneOffset(char c) {
-        if (ignoreMilitaryZoneOffset)
-            return 0;
-
-        c = Character.toUpperCase(c);
-
-        switch (c) {
-            case 'A': return 1;
-            case 'B': return 2;
-            case 'C': return 3;
-            case 'D': return 4;
-            case 'E': return 5;
-            case 'F': return 6;
-            case 'G': return 7;
-            case 'H': return 8;
-            case 'I': return 9;
-            case 'K': return 10;
-            case 'L': return 11;
-            case 'M': return 12;
-
-            case 'N': return -1;
-            case 'O': return -2;
-            case 'P': return -3;
-            case 'Q': return -4;
-            case 'R': return -5;
-            case 'S': return -6;
-            case 'T': return -7;
-            case 'U': return -8;
-            case 'V': return -9;
-            case 'W': return -10;
-            case 'X': return -11;
-            case 'Y': return -12;
-
-            case 'Z': return 0;
-            default: return 0;
-        }
-    }
-
-    private static class Time {
-        private int hour;
-        private int minute;
-        private int second;
-        private int zone;
-
-        public Time(int hour, int minute, int second, int zone) {
-            this.hour = hour;
-            this.minute = minute;
-            this.second = second;
-            this.zone = zone;
-        }
-
-        public int getHour() { return hour; }
-        public int getMinute() { return minute; }
-        public int getSecond() { return second; }
-        public int getZone() { return zone; }
-    }
-
-    private static class Date {
-        private String year;
-        private int month;
-        private int day;
-
-        public Date(String year, int month, int day) {
-            this.year = year;
-            this.month = month;
-            this.day = day;
-        }
-
-        public String getYear() { return year; }
-        public int getMonth() { return month; }
-        public int getDay() { return day; }
-    }
-
-  final public DateTime parseLine() throws ParseException {
- DateTime dt;
-    dt = date_time();
-    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-    case 1:
-      jj_consume_token(1);
-      break;
-    default:
-      jj_la1[0] = jj_gen;
-      ;
-    }
-    jj_consume_token(2);
-          {if (true) return dt;}
-    throw new Error("Missing return statement in function");
-  }
-
-  final public DateTime parseAll() throws ParseException {
- DateTime dt;
-    dt = date_time();
-    jj_consume_token(0);
-          {if (true) return dt;}
-    throw new Error("Missing return statement in function");
-  }
-
-  final public DateTime date_time() throws ParseException {
- Date d; Time t;
-    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-    case 4:
-    case 5:
-    case 6:
-    case 7:
-    case 8:
-    case 9:
-    case 10:
-      day_of_week();
-      jj_consume_token(3);
-      break;
-    default:
-      jj_la1[1] = jj_gen;
-      ;
-    }
-    d = date();
-    t = time();
-            {if (true) return new DateTime(
-                    d.getYear(),
-                    d.getMonth(),
-                    d.getDay(),
-                    t.getHour(),
-                    t.getMinute(),
-                    t.getSecond(),
-                    t.getZone());}    // time zone offset
-
-    throw new Error("Missing return statement in function");
-  }
-
-  final public String day_of_week() throws ParseException {
-    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-    case 4:
-      jj_consume_token(4);
-      break;
-    case 5:
-      jj_consume_token(5);
-      break;
-    case 6:
-      jj_consume_token(6);
-      break;
-    case 7:
-      jj_consume_token(7);
-      break;
-    case 8:
-      jj_consume_token(8);
-      break;
-    case 9:
-      jj_consume_token(9);
-      break;
-    case 10:
-      jj_consume_token(10);
-      break;
-    default:
-      jj_la1[2] = jj_gen;
-      jj_consume_token(-1);
-      throw new ParseException();
-    }
-      {if (true) return token.image;}
-    throw new Error("Missing return statement in function");
-  }
-
-  final public Date date() throws ParseException {
- int d, m; String y;
-    d = day();
-    m = month();
-    y = year();
-      {if (true) return new Date(y, m, d);}
-    throw new Error("Missing return statement in function");
-  }
-
-  final public int day() throws ParseException {
- Token t;
-    t = jj_consume_token(DIGITS);
-                 {if (true) return parseDigits(t);}
-    throw new Error("Missing return statement in function");
-  }
-
-  final public int month() throws ParseException {
-    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-    case 11:
-      jj_consume_token(11);
-            {if (true) return 1;}
-      break;
-    case 12:
-      jj_consume_token(12);
-            {if (true) return 2;}
-      break;
-    case 13:
-      jj_consume_token(13);
-            {if (true) return 3;}
-      break;
-    case 14:
-      jj_consume_token(14);
-            {if (true) return 4;}
-      break;
-    case 15:
-      jj_consume_token(15);
-            {if (true) return 5;}
-      break;
-    case 16:
-      jj_consume_token(16);
-            {if (true) return 6;}
-      break;
-    case 17:
-      jj_consume_token(17);
-            {if (true) return 7;}
-      break;
-    case 18:
-      jj_consume_token(18);
-            {if (true) return 8;}
-      break;
-    case 19:
-      jj_consume_token(19);
-            {if (true) return 9;}
-      break;
-    case 20:
-      jj_consume_token(20);
-            {if (true) return 10;}
-      break;
-    case 21:
-      jj_consume_token(21);
-            {if (true) return 11;}
-      break;
-    case 22:
-      jj_consume_token(22);
-            {if (true) return 12;}
-      break;
-    default:
-      jj_la1[3] = jj_gen;
-      jj_consume_token(-1);
-      throw new ParseException();
-    }
-    throw new Error("Missing return statement in function");
-  }
-
-  final public String year() throws ParseException {
- Token t;
-    t = jj_consume_token(DIGITS);
-                 {if (true) return t.image;}
-    throw new Error("Missing return statement in function");
-  }
-
-  final public Time time() throws ParseException {
- int h, m, s=0, z;
-    h = hour();
-    jj_consume_token(23);
-    m = minute();
-    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-    case 23:
-      jj_consume_token(23);
-      s = second();
-      break;
-    default:
-      jj_la1[4] = jj_gen;
-      ;
-    }
-    z = zone();
-      {if (true) return new Time(h, m, s, z);}
-    throw new Error("Missing return statement in function");
-  }
-
-  final public int hour() throws ParseException {
- Token t;
-    t = jj_consume_token(DIGITS);
-                 {if (true) return parseDigits(t);}
-    throw new Error("Missing return statement in function");
-  }
-
-  final public int minute() throws ParseException {
- Token t;
-    t = jj_consume_token(DIGITS);
-                 {if (true) return parseDigits(t);}
-    throw new Error("Missing return statement in function");
-  }
-
-  final public int second() throws ParseException {
- Token t;
-    t = jj_consume_token(DIGITS);
-                 {if (true) return parseDigits(t);}
-    throw new Error("Missing return statement in function");
-  }
-
-  final public int zone() throws ParseException {
-  Token t, u; int z;
-    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-    case OFFSETDIR:
-      t = jj_consume_token(OFFSETDIR);
-      u = jj_consume_token(DIGITS);
-                                              z=parseDigits(u)*(t.image.equals("-") ? -1 : 1);
-      break;
-    case 25:
-    case 26:
-    case 27:
-    case 28:
-    case 29:
-    case 30:
-    case 31:
-    case 32:
-    case 33:
-    case 34:
-    case MILITARY_ZONE:
-      z = obs_zone();
-      break;
-    default:
-      jj_la1[5] = jj_gen;
-      jj_consume_token(-1);
-      throw new ParseException();
-    }
-      {if (true) return z;}
-    throw new Error("Missing return statement in function");
-  }
-
-  final public int obs_zone() throws ParseException {
- Token t; int z;
-    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-    case 25:
-      jj_consume_token(25);
-            z=0;
-      break;
-    case 26:
-      jj_consume_token(26);
-            z=0;
-      break;
-    case 27:
-      jj_consume_token(27);
-            z=-5;
-      break;
-    case 28:
-      jj_consume_token(28);
-            z=-4;
-      break;
-    case 29:
-      jj_consume_token(29);
-            z=-6;
-      break;
-    case 30:
-      jj_consume_token(30);
-            z=-5;
-      break;
-    case 31:
-      jj_consume_token(31);
-            z=-7;
-      break;
-    case 32:
-      jj_consume_token(32);
-            z=-6;
-      break;
-    case 33:
-      jj_consume_token(33);
-            z=-8;
-      break;
-    case 34:
-      jj_consume_token(34);
-            z=-7;
-      break;
-    case MILITARY_ZONE:
-      t = jj_consume_token(MILITARY_ZONE);
-                                                             z=getMilitaryZoneOffset(t.image.charAt(0));
-      break;
-    default:
-      jj_la1[6] = jj_gen;
-      jj_consume_token(-1);
-      throw new ParseException();
-    }
-      {if (true) return z * 100;}
-    throw new Error("Missing return statement in function");
-  }
-
-  public DateTimeParserTokenManager token_source;
-  SimpleCharStream jj_input_stream;
-  public Token token, jj_nt;
-  private int jj_ntk;
-  private int jj_gen;
-  final private int[] jj_la1 = new int[7];
-  static private int[] jj_la1_0;
-  static private int[] jj_la1_1;
-  static {
-      jj_la1_0();
-      jj_la1_1();
-   }
-   private static void jj_la1_0() {
-      jj_la1_0 = new int[] {0x2,0x7f0,0x7f0,0x7ff800,0x800000,0xff000000,0xfe000000,};
-   }
-   private static void jj_la1_1() {
-      jj_la1_1 = new int[] {0x0,0x0,0x0,0x0,0x0,0xf,0xf,};
-   }
-
-  public DateTimeParser(java.io.InputStream stream) {
-     this(stream, null);
-  }
-  public DateTimeParser(java.io.InputStream stream, String encoding) {
-    try { jj_input_stream = new SimpleCharStream(stream, encoding, 1, 1); } catch(java.io.UnsupportedEncodingException e) { throw new RuntimeException(e); }
-    token_source = new DateTimeParserTokenManager(jj_input_stream);
-    token = new Token();
-    jj_ntk = -1;
-    jj_gen = 0;
-    for (int i = 0; i < 7; i++) jj_la1[i] = -1;
-  }
-
-  public void ReInit(java.io.InputStream stream) {
-     ReInit(stream, null);
-  }
-  public void ReInit(java.io.InputStream stream, String encoding) {
-    try { jj_input_stream.ReInit(stream, encoding, 1, 1); } catch(java.io.UnsupportedEncodingException e) { throw new RuntimeException(e); }
-    token_source.ReInit(jj_input_stream);
-    token = new Token();
-    jj_ntk = -1;
-    jj_gen = 0;
-    for (int i = 0; i < 7; i++) jj_la1[i] = -1;
-  }
-
-  public DateTimeParser(java.io.Reader stream) {
-    jj_input_stream = new SimpleCharStream(stream, 1, 1);
-    token_source = new DateTimeParserTokenManager(jj_input_stream);
-    token = new Token();
-    jj_ntk = -1;
-    jj_gen = 0;
-    for (int i = 0; i < 7; i++) jj_la1[i] = -1;
-  }
-
-  public void ReInit(java.io.Reader stream) {
-    jj_input_stream.ReInit(stream, 1, 1);
-    token_source.ReInit(jj_input_stream);
-    token = new Token();
-    jj_ntk = -1;
-    jj_gen = 0;
-    for (int i = 0; i < 7; i++) jj_la1[i] = -1;
-  }
-
-  public DateTimeParser(DateTimeParserTokenManager tm) {
-    token_source = tm;
-    token = new Token();
-    jj_ntk = -1;
-    jj_gen = 0;
-    for (int i = 0; i < 7; i++) jj_la1[i] = -1;
-  }
-
-  public void ReInit(DateTimeParserTokenManager tm) {
-    token_source = tm;
-    token = new Token();
-    jj_ntk = -1;
-    jj_gen = 0;
-    for (int i = 0; i < 7; i++) jj_la1[i] = -1;
-  }
-
-  final private Token jj_consume_token(int kind) throws ParseException {
-    Token oldToken;
-    if ((oldToken = token).next != null) token = token.next;
-    else token = token.next = token_source.getNextToken();
-    jj_ntk = -1;
-    if (token.kind == kind) {
-      jj_gen++;
-      return token;
-    }
-    token = oldToken;
-    jj_kind = kind;
-    throw generateParseException();
-  }
-
-  final public Token getNextToken() {
-    if (token.next != null) token = token.next;
-    else token = token.next = token_source.getNextToken();
-    jj_ntk = -1;
-    jj_gen++;
-    return token;
-  }
-
-  final public Token getToken(int index) {
-    Token t = token;
-    for (int i = 0; i < index; i++) {
-      if (t.next != null) t = t.next;
-      else t = t.next = token_source.getNextToken();
-    }
-    return t;
-  }
-
-  final private int jj_ntk() {
-    if ((jj_nt=token.next) == null)
-      return (jj_ntk = (token.next=token_source.getNextToken()).kind);
-    else
-      return (jj_ntk = jj_nt.kind);
-  }
-
-  private Vector<int[]> jj_expentries = new Vector<int[]>();
-  private int[] jj_expentry;
-  private int jj_kind = -1;
-
-  public ParseException generateParseException() {
-    jj_expentries.removeAllElements();
-    boolean[] la1tokens = new boolean[49];
-    for (int i = 0; i < 49; i++) {
-      la1tokens[i] = false;
-    }
-    if (jj_kind >= 0) {
-      la1tokens[jj_kind] = true;
-      jj_kind = -1;
-    }
-    for (int i = 0; i < 7; i++) {
-      if (jj_la1[i] == jj_gen) {
-        for (int j = 0; j < 32; j++) {
-          if ((jj_la1_0[i] & (1<<j)) != 0) {
-            la1tokens[j] = true;
-          }
-          if ((jj_la1_1[i] & (1<<j)) != 0) {
-            la1tokens[32+j] = true;
-          }
-        }
-      }
-    }
-    for (int i = 0; i < 49; i++) {
-      if (la1tokens[i]) {
-        jj_expentry = new int[1];
-        jj_expentry[0] = i;
-        jj_expentries.addElement(jj_expentry);
-      }
-    }
-    int[][] exptokseq = new int[jj_expentries.size()][];
-    for (int i = 0; i < jj_expentries.size(); i++) {
-      exptokseq[i] = jj_expentries.elementAt(i);
-    }
-    return new ParseException(token, exptokseq, tokenImage);
-  }
-
-  final public void enable_tracing() {
-  }
-
-  final public void disable_tracing() {
-  }
-
-}
diff --git a/src/org/apache/james/mime4j/field/datetime/parser/DateTimeParserConstants.java b/src/org/apache/james/mime4j/field/datetime/parser/DateTimeParserConstants.java
deleted file mode 100644
index 2c203db..0000000
--- a/src/org/apache/james/mime4j/field/datetime/parser/DateTimeParserConstants.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/* Generated By:JavaCC: Do not edit this line. DateTimeParserConstants.java */
-/*
- *  Copyright 2004 the mime4j 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 org.apache.james.mime4j.field.datetime.parser;
-
-public interface DateTimeParserConstants {
-
-  int EOF = 0;
-  int OFFSETDIR = 24;
-  int MILITARY_ZONE = 35;
-  int WS = 36;
-  int COMMENT = 38;
-  int DIGITS = 46;
-  int QUOTEDPAIR = 47;
-  int ANY = 48;
-
-  int DEFAULT = 0;
-  int INCOMMENT = 1;
-  int NESTED_COMMENT = 2;
-
-  String[] tokenImage = {
-    "<EOF>",
-    "\"\\r\"",
-    "\"\\n\"",
-    "\",\"",
-    "\"Mon\"",
-    "\"Tue\"",
-    "\"Wed\"",
-    "\"Thu\"",
-    "\"Fri\"",
-    "\"Sat\"",
-    "\"Sun\"",
-    "\"Jan\"",
-    "\"Feb\"",
-    "\"Mar\"",
-    "\"Apr\"",
-    "\"May\"",
-    "\"Jun\"",
-    "\"Jul\"",
-    "\"Aug\"",
-    "\"Sep\"",
-    "\"Oct\"",
-    "\"Nov\"",
-    "\"Dec\"",
-    "\":\"",
-    "<OFFSETDIR>",
-    "\"UT\"",
-    "\"GMT\"",
-    "\"EST\"",
-    "\"EDT\"",
-    "\"CST\"",
-    "\"CDT\"",
-    "\"MST\"",
-    "\"MDT\"",
-    "\"PST\"",
-    "\"PDT\"",
-    "<MILITARY_ZONE>",
-    "<WS>",
-    "\"(\"",
-    "\")\"",
-    "<token of kind 39>",
-    "\"(\"",
-    "<token of kind 41>",
-    "<token of kind 42>",
-    "\"(\"",
-    "\")\"",
-    "<token of kind 45>",
-    "<DIGITS>",
-    "<QUOTEDPAIR>",
-    "<ANY>",
-  };
-
-}
diff --git a/src/org/apache/james/mime4j/field/datetime/parser/DateTimeParserTokenManager.java b/src/org/apache/james/mime4j/field/datetime/parser/DateTimeParserTokenManager.java
deleted file mode 100644
index 4b2d2fd..0000000
--- a/src/org/apache/james/mime4j/field/datetime/parser/DateTimeParserTokenManager.java
+++ /dev/null
@@ -1,882 +0,0 @@
-/* Generated By:JavaCC: Do not edit this line. DateTimeParserTokenManager.java */
-/*
- *  Copyright 2004 the mime4j 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 org.apache.james.mime4j.field.datetime.parser;
-import org.apache.james.mime4j.field.datetime.DateTime;
-import java.util.Calendar;
-
-public class DateTimeParserTokenManager implements DateTimeParserConstants
-{
-        // Keeps track of how many levels of comment nesting
-        // we've encountered.  This is only used when the 2nd
-        // level is reached, for example ((this)), not (this).
-        // This is because the outermost level must be treated
-        // specially anyway, because the outermost ")" has a
-        // different token type than inner ")" instances.
-        static int commentNest;
-  public  java.io.PrintStream debugStream = System.out;
-  public  void setDebugStream(java.io.PrintStream ds) { debugStream = ds; }
-private final int jjStopStringLiteralDfa_0(int pos, long active0)
-{
-   switch (pos)
-   {
-      case 0:
-         if ((active0 & 0x7fe7cf7f0L) != 0L)
-         {
-            jjmatchedKind = 35;
-            return -1;
-         }
-         return -1;
-      case 1:
-         if ((active0 & 0x7fe7cf7f0L) != 0L)
-         {
-            if (jjmatchedPos == 0)
-            {
-               jjmatchedKind = 35;
-               jjmatchedPos = 0;
-            }
-            return -1;
-         }
-         return -1;
-      default :
-         return -1;
-   }
-}
-private final int jjStartNfa_0(int pos, long active0)
-{
-   return jjMoveNfa_0(jjStopStringLiteralDfa_0(pos, active0), pos + 1);
-}
-private final int jjStopAtPos(int pos, int kind)
-{
-   jjmatchedKind = kind;
-   jjmatchedPos = pos;
-   return pos + 1;
-}
-private final int jjStartNfaWithStates_0(int pos, int kind, int state)
-{
-   jjmatchedKind = kind;
-   jjmatchedPos = pos;
-   try { curChar = input_stream.readChar(); }
-   catch(java.io.IOException e) { return pos + 1; }
-   return jjMoveNfa_0(state, pos + 1);
-}
-private final int jjMoveStringLiteralDfa0_0()
-{
-   switch(curChar)
-   {
-      case 10:
-         return jjStopAtPos(0, 2);
-      case 13:
-         return jjStopAtPos(0, 1);
-      case 40:
-         return jjStopAtPos(0, 37);
-      case 44:
-         return jjStopAtPos(0, 3);
-      case 58:
-         return jjStopAtPos(0, 23);
-      case 65:
-         return jjMoveStringLiteralDfa1_0(0x44000L);
-      case 67:
-         return jjMoveStringLiteralDfa1_0(0x60000000L);
-      case 68:
-         return jjMoveStringLiteralDfa1_0(0x400000L);
-      case 69:
-         return jjMoveStringLiteralDfa1_0(0x18000000L);
-      case 70:
-         return jjMoveStringLiteralDfa1_0(0x1100L);
-      case 71:
-         return jjMoveStringLiteralDfa1_0(0x4000000L);
-      case 74:
-         return jjMoveStringLiteralDfa1_0(0x30800L);
-      case 77:
-         return jjMoveStringLiteralDfa1_0(0x18000a010L);
-      case 78:
-         return jjMoveStringLiteralDfa1_0(0x200000L);
-      case 79:
-         return jjMoveStringLiteralDfa1_0(0x100000L);
-      case 80:
-         return jjMoveStringLiteralDfa1_0(0x600000000L);
-      case 83:
-         return jjMoveStringLiteralDfa1_0(0x80600L);
-      case 84:
-         return jjMoveStringLiteralDfa1_0(0xa0L);
-      case 85:
-         return jjMoveStringLiteralDfa1_0(0x2000000L);
-      case 87:
-         return jjMoveStringLiteralDfa1_0(0x40L);
-      default :
-         return jjMoveNfa_0(0, 0);
-   }
-}
-private final int jjMoveStringLiteralDfa1_0(long active0)
-{
-   try { curChar = input_stream.readChar(); }
-   catch(java.io.IOException e) {
-      jjStopStringLiteralDfa_0(0, active0);
-      return 1;
-   }
-   switch(curChar)
-   {
-      case 68:
-         return jjMoveStringLiteralDfa2_0(active0, 0x550000000L);
-      case 77:
-         return jjMoveStringLiteralDfa2_0(active0, 0x4000000L);
-      case 83:
-         return jjMoveStringLiteralDfa2_0(active0, 0x2a8000000L);
-      case 84:
-         if ((active0 & 0x2000000L) != 0L)
-            return jjStopAtPos(1, 25);
-         break;
-      case 97:
-         return jjMoveStringLiteralDfa2_0(active0, 0xaa00L);
-      case 99:
-         return jjMoveStringLiteralDfa2_0(active0, 0x100000L);
-      case 101:
-         return jjMoveStringLiteralDfa2_0(active0, 0x481040L);
-      case 104:
-         return jjMoveStringLiteralDfa2_0(active0, 0x80L);
-      case 111:
-         return jjMoveStringLiteralDfa2_0(active0, 0x200010L);
-      case 112:
-         return jjMoveStringLiteralDfa2_0(active0, 0x4000L);
-      case 114:
-         return jjMoveStringLiteralDfa2_0(active0, 0x100L);
-      case 117:
-         return jjMoveStringLiteralDfa2_0(active0, 0x70420L);
-      default :
-         break;
-   }
-   return jjStartNfa_0(0, active0);
-}
-private final int jjMoveStringLiteralDfa2_0(long old0, long active0)
-{
-   if (((active0 &= old0)) == 0L)
-      return jjStartNfa_0(0, old0); 
-   try { curChar = input_stream.readChar(); }
-   catch(java.io.IOException e) {
-      jjStopStringLiteralDfa_0(1, active0);
-      return 2;
-   }
-   switch(curChar)
-   {
-      case 84:
-         if ((active0 & 0x4000000L) != 0L)
-            return jjStopAtPos(2, 26);
-         else if ((active0 & 0x8000000L) != 0L)
-            return jjStopAtPos(2, 27);
-         else if ((active0 & 0x10000000L) != 0L)
-            return jjStopAtPos(2, 28);
-         else if ((active0 & 0x20000000L) != 0L)
-            return jjStopAtPos(2, 29);
-         else if ((active0 & 0x40000000L) != 0L)
-            return jjStopAtPos(2, 30);
-         else if ((active0 & 0x80000000L) != 0L)
-            return jjStopAtPos(2, 31);
-         else if ((active0 & 0x100000000L) != 0L)
-            return jjStopAtPos(2, 32);
-         else if ((active0 & 0x200000000L) != 0L)
-            return jjStopAtPos(2, 33);
-         else if ((active0 & 0x400000000L) != 0L)
-            return jjStopAtPos(2, 34);
-         break;
-      case 98:
-         if ((active0 & 0x1000L) != 0L)
-            return jjStopAtPos(2, 12);
-         break;
-      case 99:
-         if ((active0 & 0x400000L) != 0L)
-            return jjStopAtPos(2, 22);
-         break;
-      case 100:
-         if ((active0 & 0x40L) != 0L)
-            return jjStopAtPos(2, 6);
-         break;
-      case 101:
-         if ((active0 & 0x20L) != 0L)
-            return jjStopAtPos(2, 5);
-         break;
-      case 103:
-         if ((active0 & 0x40000L) != 0L)
-            return jjStopAtPos(2, 18);
-         break;
-      case 105:
-         if ((active0 & 0x100L) != 0L)
-            return jjStopAtPos(2, 8);
-         break;
-      case 108:
-         if ((active0 & 0x20000L) != 0L)
-            return jjStopAtPos(2, 17);
-         break;
-      case 110:
-         if ((active0 & 0x10L) != 0L)
-            return jjStopAtPos(2, 4);
-         else if ((active0 & 0x400L) != 0L)
-            return jjStopAtPos(2, 10);
-         else if ((active0 & 0x800L) != 0L)
-            return jjStopAtPos(2, 11);
-         else if ((active0 & 0x10000L) != 0L)
-            return jjStopAtPos(2, 16);
-         break;
-      case 112:
-         if ((active0 & 0x80000L) != 0L)
-            return jjStopAtPos(2, 19);
-         break;
-      case 114:
-         if ((active0 & 0x2000L) != 0L)
-            return jjStopAtPos(2, 13);
-         else if ((active0 & 0x4000L) != 0L)
-            return jjStopAtPos(2, 14);
-         break;
-      case 116:
-         if ((active0 & 0x200L) != 0L)
-            return jjStopAtPos(2, 9);
-         else if ((active0 & 0x100000L) != 0L)
-            return jjStopAtPos(2, 20);
-         break;
-      case 117:
-         if ((active0 & 0x80L) != 0L)
-            return jjStopAtPos(2, 7);
-         break;
-      case 118:
-         if ((active0 & 0x200000L) != 0L)
-            return jjStopAtPos(2, 21);
-         break;
-      case 121:
-         if ((active0 & 0x8000L) != 0L)
-            return jjStopAtPos(2, 15);
-         break;
-      default :
-         break;
-   }
-   return jjStartNfa_0(1, active0);
-}
-private final void jjCheckNAdd(int state)
-{
-   if (jjrounds[state] != jjround)
-   {
-      jjstateSet[jjnewStateCnt++] = state;
-      jjrounds[state] = jjround;
-   }
-}
-private final void jjAddStates(int start, int end)
-{
-   do {
-      jjstateSet[jjnewStateCnt++] = jjnextStates[start];
-   } while (start++ != end);
-}
-private final void jjCheckNAddTwoStates(int state1, int state2)
-{
-   jjCheckNAdd(state1);
-   jjCheckNAdd(state2);
-}
-private final void jjCheckNAddStates(int start, int end)
-{
-   do {
-      jjCheckNAdd(jjnextStates[start]);
-   } while (start++ != end);
-}
-private final void jjCheckNAddStates(int start)
-{
-   jjCheckNAdd(jjnextStates[start]);
-   jjCheckNAdd(jjnextStates[start + 1]);
-}
-private final int jjMoveNfa_0(int startState, int curPos)
-{
-   int[] nextStates;
-   int startsAt = 0;
-   jjnewStateCnt = 4;
-   int i = 1;
-   jjstateSet[0] = startState;
-   int j, kind = 0x7fffffff;
-   for (;;)
-   {
-      if (++jjround == 0x7fffffff)
-         ReInitRounds();
-      if (curChar < 64)
-      {
-         long l = 1L << curChar;
-         MatchLoop: do
-         {
-            switch(jjstateSet[--i])
-            {
-               case 0:
-                  if ((0x3ff000000000000L & l) != 0L)
-                  {
-                     if (kind > 46)
-                        kind = 46;
-                     jjCheckNAdd(3);
-                  }
-                  else if ((0x100000200L & l) != 0L)
-                  {
-                     if (kind > 36)
-                        kind = 36;
-                     jjCheckNAdd(2);
-                  }
-                  else if ((0x280000000000L & l) != 0L)
-                  {
-                     if (kind > 24)
-                        kind = 24;
-                  }
-                  break;
-               case 2:
-                  if ((0x100000200L & l) == 0L)
-                     break;
-                  kind = 36;
-                  jjCheckNAdd(2);
-                  break;
-               case 3:
-                  if ((0x3ff000000000000L & l) == 0L)
-                     break;
-                  kind = 46;
-                  jjCheckNAdd(3);
-                  break;
-               default : break;
-            }
-         } while(i != startsAt);
-      }
-      else if (curChar < 128)
-      {
-         long l = 1L << (curChar & 077);
-         MatchLoop: do
-         {
-            switch(jjstateSet[--i])
-            {
-               case 0:
-                  if ((0x7fffbfe07fffbfeL & l) != 0L)
-                     kind = 35;
-                  break;
-               default : break;
-            }
-         } while(i != startsAt);
-      }
-      else
-      {
-         int i2 = (curChar & 0xff) >> 6;
-         long l2 = 1L << (curChar & 077);
-         MatchLoop: do
-         {
-            switch(jjstateSet[--i])
-            {
-               default : break;
-            }
-         } while(i != startsAt);
-      }
-      if (kind != 0x7fffffff)
-      {
-         jjmatchedKind = kind;
-         jjmatchedPos = curPos;
-         kind = 0x7fffffff;
-      }
-      ++curPos;
-      if ((i = jjnewStateCnt) == (startsAt = 4 - (jjnewStateCnt = startsAt)))
-         return curPos;
-      try { curChar = input_stream.readChar(); }
-      catch(java.io.IOException e) { return curPos; }
-   }
-}
-private final int jjStopStringLiteralDfa_1(int pos, long active0)
-{
-   switch (pos)
-   {
-      default :
-         return -1;
-   }
-}
-private final int jjStartNfa_1(int pos, long active0)
-{
-   return jjMoveNfa_1(jjStopStringLiteralDfa_1(pos, active0), pos + 1);
-}
-private final int jjStartNfaWithStates_1(int pos, int kind, int state)
-{
-   jjmatchedKind = kind;
-   jjmatchedPos = pos;
-   try { curChar = input_stream.readChar(); }
-   catch(java.io.IOException e) { return pos + 1; }
-   return jjMoveNfa_1(state, pos + 1);
-}
-private final int jjMoveStringLiteralDfa0_1()
-{
-   switch(curChar)
-   {
-      case 40:
-         return jjStopAtPos(0, 40);
-      case 41:
-         return jjStopAtPos(0, 38);
-      default :
-         return jjMoveNfa_1(0, 0);
-   }
-}
-static final long[] jjbitVec0 = {
-   0x0L, 0x0L, 0xffffffffffffffffL, 0xffffffffffffffffL
-};
-private final int jjMoveNfa_1(int startState, int curPos)
-{
-   int[] nextStates;
-   int startsAt = 0;
-   jjnewStateCnt = 3;
-   int i = 1;
-   jjstateSet[0] = startState;
-   int j, kind = 0x7fffffff;
-   for (;;)
-   {
-      if (++jjround == 0x7fffffff)
-         ReInitRounds();
-      if (curChar < 64)
-      {
-         long l = 1L << curChar;
-         MatchLoop: do
-         {
-            switch(jjstateSet[--i])
-            {
-               case 0:
-                  if (kind > 41)
-                     kind = 41;
-                  break;
-               case 1:
-                  if (kind > 39)
-                     kind = 39;
-                  break;
-               default : break;
-            }
-         } while(i != startsAt);
-      }
-      else if (curChar < 128)
-      {
-         long l = 1L << (curChar & 077);
-         MatchLoop: do
-         {
-            switch(jjstateSet[--i])
-            {
-               case 0:
-                  if (kind > 41)
-                     kind = 41;
-                  if (curChar == 92)
-                     jjstateSet[jjnewStateCnt++] = 1;
-                  break;
-               case 1:
-                  if (kind > 39)
-                     kind = 39;
-                  break;
-               case 2:
-                  if (kind > 41)
-                     kind = 41;
-                  break;
-               default : break;
-            }
-         } while(i != startsAt);
-      }
-      else
-      {
-         int i2 = (curChar & 0xff) >> 6;
-         long l2 = 1L << (curChar & 077);
-         MatchLoop: do
-         {
-            switch(jjstateSet[--i])
-            {
-               case 0:
-                  if ((jjbitVec0[i2] & l2) != 0L && kind > 41)
-                     kind = 41;
-                  break;
-               case 1:
-                  if ((jjbitVec0[i2] & l2) != 0L && kind > 39)
-                     kind = 39;
-                  break;
-               default : break;
-            }
-         } while(i != startsAt);
-      }
-      if (kind != 0x7fffffff)
-      {
-         jjmatchedKind = kind;
-         jjmatchedPos = curPos;
-         kind = 0x7fffffff;
-      }
-      ++curPos;
-      if ((i = jjnewStateCnt) == (startsAt = 3 - (jjnewStateCnt = startsAt)))
-         return curPos;
-      try { curChar = input_stream.readChar(); }
-      catch(java.io.IOException e) { return curPos; }
-   }
-}
-private final int jjStopStringLiteralDfa_2(int pos, long active0)
-{
-   switch (pos)
-   {
-      default :
-         return -1;
-   }
-}
-private final int jjStartNfa_2(int pos, long active0)
-{
-   return jjMoveNfa_2(jjStopStringLiteralDfa_2(pos, active0), pos + 1);
-}
-private final int jjStartNfaWithStates_2(int pos, int kind, int state)
-{
-   jjmatchedKind = kind;
-   jjmatchedPos = pos;
-   try { curChar = input_stream.readChar(); }
-   catch(java.io.IOException e) { return pos + 1; }
-   return jjMoveNfa_2(state, pos + 1);
-}
-private final int jjMoveStringLiteralDfa0_2()
-{
-   switch(curChar)
-   {
-      case 40:
-         return jjStopAtPos(0, 43);
-      case 41:
-         return jjStopAtPos(0, 44);
-      default :
-         return jjMoveNfa_2(0, 0);
-   }
-}
-private final int jjMoveNfa_2(int startState, int curPos)
-{
-   int[] nextStates;
-   int startsAt = 0;
-   jjnewStateCnt = 3;
-   int i = 1;
-   jjstateSet[0] = startState;
-   int j, kind = 0x7fffffff;
-   for (;;)
-   {
-      if (++jjround == 0x7fffffff)
-         ReInitRounds();
-      if (curChar < 64)
-      {
-         long l = 1L << curChar;
-         MatchLoop: do
-         {
-            switch(jjstateSet[--i])
-            {
-               case 0:
-                  if (kind > 45)
-                     kind = 45;
-                  break;
-               case 1:
-                  if (kind > 42)
-                     kind = 42;
-                  break;
-               default : break;
-            }
-         } while(i != startsAt);
-      }
-      else if (curChar < 128)
-      {
-         long l = 1L << (curChar & 077);
-         MatchLoop: do
-         {
-            switch(jjstateSet[--i])
-            {
-               case 0:
-                  if (kind > 45)
-                     kind = 45;
-                  if (curChar == 92)
-                     jjstateSet[jjnewStateCnt++] = 1;
-                  break;
-               case 1:
-                  if (kind > 42)
-                     kind = 42;
-                  break;
-               case 2:
-                  if (kind > 45)
-                     kind = 45;
-                  break;
-               default : break;
-            }
-         } while(i != startsAt);
-      }
-      else
-      {
-         int i2 = (curChar & 0xff) >> 6;
-         long l2 = 1L << (curChar & 077);
-         MatchLoop: do
-         {
-            switch(jjstateSet[--i])
-            {
-               case 0:
-                  if ((jjbitVec0[i2] & l2) != 0L && kind > 45)
-                     kind = 45;
-                  break;
-               case 1:
-                  if ((jjbitVec0[i2] & l2) != 0L && kind > 42)
-                     kind = 42;
-                  break;
-               default : break;
-            }
-         } while(i != startsAt);
-      }
-      if (kind != 0x7fffffff)
-      {
-         jjmatchedKind = kind;
-         jjmatchedPos = curPos;
-         kind = 0x7fffffff;
-      }
-      ++curPos;
-      if ((i = jjnewStateCnt) == (startsAt = 3 - (jjnewStateCnt = startsAt)))
-         return curPos;
-      try { curChar = input_stream.readChar(); }
-      catch(java.io.IOException e) { return curPos; }
-   }
-}
-static final int[] jjnextStates = {
-};
-public static final String[] jjstrLiteralImages = {
-"", "\15", "\12", "\54", "\115\157\156", "\124\165\145", "\127\145\144", 
-"\124\150\165", "\106\162\151", "\123\141\164", "\123\165\156", "\112\141\156", 
-"\106\145\142", "\115\141\162", "\101\160\162", "\115\141\171", "\112\165\156", 
-"\112\165\154", "\101\165\147", "\123\145\160", "\117\143\164", "\116\157\166", 
-"\104\145\143", "\72", null, "\125\124", "\107\115\124", "\105\123\124", "\105\104\124", 
-"\103\123\124", "\103\104\124", "\115\123\124", "\115\104\124", "\120\123\124", 
-"\120\104\124", null, null, null, null, null, null, null, null, null, null, null, null, null, 
-null, };
-public static final String[] lexStateNames = {
-   "DEFAULT", 
-   "INCOMMENT", 
-   "NESTED_COMMENT", 
-};
-public static final int[] jjnewLexState = {
-   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
-   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 0, -1, 2, -1, -1, -1, -1, -1, -1, -1, -1, 
-};
-static final long[] jjtoToken = {
-   0x400fffffffffL, 
-};
-static final long[] jjtoSkip = {
-   0x5000000000L, 
-};
-static final long[] jjtoSpecial = {
-   0x1000000000L, 
-};
-static final long[] jjtoMore = {
-   0x3fa000000000L, 
-};
-protected SimpleCharStream input_stream;
-private final int[] jjrounds = new int[4];
-private final int[] jjstateSet = new int[8];
-StringBuffer image;
-int jjimageLen;
-int lengthOfMatch;
-protected char curChar;
-public DateTimeParserTokenManager(SimpleCharStream stream){
-   if (SimpleCharStream.staticFlag)
-      throw new Error("ERROR: Cannot use a static CharStream class with a non-static lexical analyzer.");
-   input_stream = stream;
-}
-public DateTimeParserTokenManager(SimpleCharStream stream, int lexState){
-   this(stream);
-   SwitchTo(lexState);
-}
-public void ReInit(SimpleCharStream stream)
-{
-   jjmatchedPos = jjnewStateCnt = 0;
-   curLexState = defaultLexState;
-   input_stream = stream;
-   ReInitRounds();
-}
-private final void ReInitRounds()
-{
-   int i;
-   jjround = 0x80000001;
-   for (i = 4; i-- > 0;)
-      jjrounds[i] = 0x80000000;
-}
-public void ReInit(SimpleCharStream stream, int lexState)
-{
-   ReInit(stream);
-   SwitchTo(lexState);
-}
-public void SwitchTo(int lexState)
-{
-   if (lexState >= 3 || lexState < 0)
-      throw new TokenMgrError("Error: Ignoring invalid lexical state : " + lexState + ". State unchanged.", TokenMgrError.INVALID_LEXICAL_STATE);
-   else
-      curLexState = lexState;
-}
-
-protected Token jjFillToken()
-{
-   Token t = Token.newToken(jjmatchedKind);
-   t.kind = jjmatchedKind;
-   String im = jjstrLiteralImages[jjmatchedKind];
-   t.image = (im == null) ? input_stream.GetImage() : im;
-   t.beginLine = input_stream.getBeginLine();
-   t.beginColumn = input_stream.getBeginColumn();
-   t.endLine = input_stream.getEndLine();
-   t.endColumn = input_stream.getEndColumn();
-   return t;
-}
-
-int curLexState = 0;
-int defaultLexState = 0;
-int jjnewStateCnt;
-int jjround;
-int jjmatchedPos;
-int jjmatchedKind;
-
-public Token getNextToken() 
-{
-  int kind;
-  Token specialToken = null;
-  Token matchedToken;
-  int curPos = 0;
-
-  EOFLoop :
-  for (;;)
-  {   
-   try   
-   {     
-      curChar = input_stream.BeginToken();
-   }     
-   catch(java.io.IOException e)
-   {        
-      jjmatchedKind = 0;
-      matchedToken = jjFillToken();
-      matchedToken.specialToken = specialToken;
-      return matchedToken;
-   }
-   image = null;
-   jjimageLen = 0;
-
-   for (;;)
-   {
-     switch(curLexState)
-     {
-       case 0:
-         jjmatchedKind = 0x7fffffff;
-         jjmatchedPos = 0;
-         curPos = jjMoveStringLiteralDfa0_0();
-         break;
-       case 1:
-         jjmatchedKind = 0x7fffffff;
-         jjmatchedPos = 0;
-         curPos = jjMoveStringLiteralDfa0_1();
-         break;
-       case 2:
-         jjmatchedKind = 0x7fffffff;
-         jjmatchedPos = 0;
-         curPos = jjMoveStringLiteralDfa0_2();
-         break;
-     }
-     if (jjmatchedKind != 0x7fffffff)
-     {
-        if (jjmatchedPos + 1 < curPos)
-           input_stream.backup(curPos - jjmatchedPos - 1);
-        if ((jjtoToken[jjmatchedKind >> 6] & (1L << (jjmatchedKind & 077))) != 0L)
-        {
-           matchedToken = jjFillToken();
-           matchedToken.specialToken = specialToken;
-       if (jjnewLexState[jjmatchedKind] != -1)
-         curLexState = jjnewLexState[jjmatchedKind];
-           return matchedToken;
-        }
-        else if ((jjtoSkip[jjmatchedKind >> 6] & (1L << (jjmatchedKind & 077))) != 0L)
-        {
-           if ((jjtoSpecial[jjmatchedKind >> 6] & (1L << (jjmatchedKind & 077))) != 0L)
-           {
-              matchedToken = jjFillToken();
-              if (specialToken == null)
-                 specialToken = matchedToken;
-              else
-              {
-                 matchedToken.specialToken = specialToken;
-                 specialToken = (specialToken.next = matchedToken);
-              }
-           }
-         if (jjnewLexState[jjmatchedKind] != -1)
-           curLexState = jjnewLexState[jjmatchedKind];
-           continue EOFLoop;
-        }
-        MoreLexicalActions();
-      if (jjnewLexState[jjmatchedKind] != -1)
-        curLexState = jjnewLexState[jjmatchedKind];
-        curPos = 0;
-        jjmatchedKind = 0x7fffffff;
-        try {
-           curChar = input_stream.readChar();
-           continue;
-        }
-        catch (java.io.IOException e1) { }
-     }
-     int error_line = input_stream.getEndLine();
-     int error_column = input_stream.getEndColumn();
-     String error_after = null;
-     boolean EOFSeen = false;
-     try { input_stream.readChar(); input_stream.backup(1); }
-     catch (java.io.IOException e1) {
-        EOFSeen = true;
-        error_after = curPos <= 1 ? "" : input_stream.GetImage();
-        if (curChar == '\n' || curChar == '\r') {
-           error_line++;
-           error_column = 0;
-        }
-        else
-           error_column++;
-     }
-     if (!EOFSeen) {
-        input_stream.backup(1);
-        error_after = curPos <= 1 ? "" : input_stream.GetImage();
-     }
-     throw new TokenMgrError(EOFSeen, curLexState, error_line, error_column, error_after, curChar, TokenMgrError.LEXICAL_ERROR);
-   }
-  }
-}
-
-void MoreLexicalActions()
-{
-   jjimageLen += (lengthOfMatch = jjmatchedPos + 1);
-   switch(jjmatchedKind)
-   {
-      case 39 :
-         if (image == null)
-            image = new StringBuffer();
-         image.append(input_stream.GetSuffix(jjimageLen));
-         jjimageLen = 0;
-                          image.deleteCharAt(image.length() - 2);
-         break;
-      case 40 :
-         if (image == null)
-            image = new StringBuffer();
-         image.append(input_stream.GetSuffix(jjimageLen));
-         jjimageLen = 0;
-              commentNest = 1;
-         break;
-      case 42 :
-         if (image == null)
-            image = new StringBuffer();
-         image.append(input_stream.GetSuffix(jjimageLen));
-         jjimageLen = 0;
-                          image.deleteCharAt(image.length() - 2);
-         break;
-      case 43 :
-         if (image == null)
-            image = new StringBuffer();
-         image.append(input_stream.GetSuffix(jjimageLen));
-         jjimageLen = 0;
-              ++commentNest;
-         break;
-      case 44 :
-         if (image == null)
-            image = new StringBuffer();
-         image.append(input_stream.GetSuffix(jjimageLen));
-         jjimageLen = 0;
-              --commentNest; if (commentNest == 0) SwitchTo(INCOMMENT);
-         break;
-      default : 
-         break;
-   }
-}
-}
diff --git a/src/org/apache/james/mime4j/field/datetime/parser/ParseException.java b/src/org/apache/james/mime4j/field/datetime/parser/ParseException.java
deleted file mode 100644
index 13b3ff0..0000000
--- a/src/org/apache/james/mime4j/field/datetime/parser/ParseException.java
+++ /dev/null
@@ -1,207 +0,0 @@
-/* Generated By:JavaCC: Do not edit this line. ParseException.java Version 3.0 */
-/*
- *  Copyright 2004 the mime4j 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 org.apache.james.mime4j.field.datetime.parser;
-
-/**
- * This exception is thrown when parse errors are encountered.
- * You can explicitly create objects of this exception type by
- * calling the method generateParseException in the generated
- * parser.
- *
- * You can modify this class to customize your error reporting
- * mechanisms so long as you retain the public fields.
- */
-public class ParseException extends Exception {
-
-  /**
-   * This constructor is used by the method "generateParseException"
-   * in the generated parser.  Calling this constructor generates
-   * a new object of this type with the fields "currentToken",
-   * "expectedTokenSequences", and "tokenImage" set.  The boolean
-   * flag "specialConstructor" is also set to true to indicate that
-   * this constructor was used to create this object.
-   * This constructor calls its super class with the empty string
-   * to force the "toString" method of parent class "Throwable" to
-   * print the error message in the form:
-   *     ParseException: <result of getMessage>
-   */
-  public ParseException(Token currentTokenVal,
-                        int[][] expectedTokenSequencesVal,
-                        String[] tokenImageVal
-                       )
-  {
-    super("");
-    specialConstructor = true;
-    currentToken = currentTokenVal;
-    expectedTokenSequences = expectedTokenSequencesVal;
-    tokenImage = tokenImageVal;
-  }
-
-  /**
-   * The following constructors are for use by you for whatever
-   * purpose you can think of.  Constructing the exception in this
-   * manner makes the exception behave in the normal way - i.e., as
-   * documented in the class "Throwable".  The fields "errorToken",
-   * "expectedTokenSequences", and "tokenImage" do not contain
-   * relevant information.  The JavaCC generated code does not use
-   * these constructors.
-   */
-
-  public ParseException() {
-    super();
-    specialConstructor = false;
-  }
-
-  public ParseException(String message) {
-    super(message);
-    specialConstructor = false;
-  }
-
-  /**
-   * This variable determines which constructor was used to create
-   * this object and thereby affects the semantics of the
-   * "getMessage" method (see below).
-   */
-  protected boolean specialConstructor;
-
-  /**
-   * This is the last token that has been consumed successfully.  If
-   * this object has been created due to a parse error, the token
-   * followng this token will (therefore) be the first error token.
-   */
-  public Token currentToken;
-
-  /**
-   * Each entry in this array is an array of integers.  Each array
-   * of integers represents a sequence of tokens (by their ordinal
-   * values) that is expected at this point of the parse.
-   */
-  public int[][] expectedTokenSequences;
-
-  /**
-   * This is a reference to the "tokenImage" array of the generated
-   * parser within which the parse error occurred.  This array is
-   * defined in the generated ...Constants interface.
-   */
-  public String[] tokenImage;
-
-  /**
-   * This method has the standard behavior when this object has been
-   * created using the standard constructors.  Otherwise, it uses
-   * "currentToken" and "expectedTokenSequences" to generate a parse
-   * error message and returns it.  If this object has been created
-   * due to a parse error, and you do not catch it (it gets thrown
-   * from the parser), then this method is called during the printing
-   * of the final stack trace, and hence the correct error message
-   * gets displayed.
-   */
-  public String getMessage() {
-    if (!specialConstructor) {
-      return super.getMessage();
-    }
-    StringBuffer expected = new StringBuffer();
-    int maxSize = 0;
-    for (int i = 0; i < expectedTokenSequences.length; i++) {
-      if (maxSize < expectedTokenSequences[i].length) {
-        maxSize = expectedTokenSequences[i].length;
-      }
-      for (int j = 0; j < expectedTokenSequences[i].length; j++) {
-        expected.append(tokenImage[expectedTokenSequences[i][j]]).append(" ");
-      }
-      if (expectedTokenSequences[i][expectedTokenSequences[i].length - 1] != 0) {
-        expected.append("...");
-      }
-      expected.append(eol).append("    ");
-    }
-    String retval = "Encountered \"";
-    Token tok = currentToken.next;
-    for (int i = 0; i < maxSize; i++) {
-      if (i != 0) retval += " ";
-      if (tok.kind == 0) {
-        retval += tokenImage[0];
-        break;
-      }
-      retval += add_escapes(tok.image);
-      tok = tok.next; 
-    }
-    retval += "\" at line " + currentToken.next.beginLine + ", column " + currentToken.next.beginColumn;
-    retval += "." + eol;
-    if (expectedTokenSequences.length == 1) {
-      retval += "Was expecting:" + eol + "    ";
-    } else {
-      retval += "Was expecting one of:" + eol + "    ";
-    }
-    retval += expected.toString();
-    return retval;
-  }
-
-  /**
-   * The end of line string for this machine.
-   */
-  protected String eol = System.getProperty("line.separator", "\n");
- 
-  /**
-   * Used to convert raw characters to their escaped version
-   * when these raw version cannot be used as part of an ASCII
-   * string literal.
-   */
-  protected String add_escapes(String str) {
-      StringBuffer retval = new StringBuffer();
-      char ch;
-      for (int i = 0; i < str.length(); i++) {
-        switch (str.charAt(i))
-        {
-           case 0 :
-              continue;
-           case '\b':
-              retval.append("\\b");
-              continue;
-           case '\t':
-              retval.append("\\t");
-              continue;
-           case '\n':
-              retval.append("\\n");
-              continue;
-           case '\f':
-              retval.append("\\f");
-              continue;
-           case '\r':
-              retval.append("\\r");
-              continue;
-           case '\"':
-              retval.append("\\\"");
-              continue;
-           case '\'':
-              retval.append("\\\'");
-              continue;
-           case '\\':
-              retval.append("\\\\");
-              continue;
-           default:
-              if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) {
-                 String s = "0000" + Integer.toString(ch, 16);
-                 retval.append("\\u" + s.substring(s.length() - 4, s.length()));
-              } else {
-                 retval.append(ch);
-              }
-              continue;
-        }
-      }
-      return retval.toString();
-   }
-
-}
diff --git a/src/org/apache/james/mime4j/field/datetime/parser/SimpleCharStream.java b/src/org/apache/james/mime4j/field/datetime/parser/SimpleCharStream.java
deleted file mode 100644
index 2724529..0000000
--- a/src/org/apache/james/mime4j/field/datetime/parser/SimpleCharStream.java
+++ /dev/null
@@ -1,454 +0,0 @@
-/* Generated By:JavaCC: Do not edit this line. SimpleCharStream.java Version 4.0 */
-/*
- *  Copyright 2004 the mime4j 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 org.apache.james.mime4j.field.datetime.parser;
-
-/**
- * An implementation of interface CharStream, where the stream is assumed to
- * contain only ASCII characters (without unicode processing).
- */
-
-public class SimpleCharStream
-{
-  public static final boolean staticFlag = false;
-  int bufsize;
-  int available;
-  int tokenBegin;
-  public int bufpos = -1;
-  protected int bufline[];
-  protected int bufcolumn[];
-
-  protected int column = 0;
-  protected int line = 1;
-
-  protected boolean prevCharIsCR = false;
-  protected boolean prevCharIsLF = false;
-
-  protected java.io.Reader inputStream;
-
-  protected char[] buffer;
-  protected int maxNextCharInd = 0;
-  protected int inBuf = 0;
-  protected int tabSize = 8;
-
-  protected void setTabSize(int i) { tabSize = i; }
-  protected int getTabSize(int i) { return tabSize; }
-
-
-  protected void ExpandBuff(boolean wrapAround)
-  {
-     char[] newbuffer = new char[bufsize + 2048];
-     int newbufline[] = new int[bufsize + 2048];
-     int newbufcolumn[] = new int[bufsize + 2048];
-
-     try
-     {
-        if (wrapAround)
-        {
-           System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin);
-           System.arraycopy(buffer, 0, newbuffer,
-                                             bufsize - tokenBegin, bufpos);
-           buffer = newbuffer;
-
-           System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin);
-           System.arraycopy(bufline, 0, newbufline, bufsize - tokenBegin, bufpos);
-           bufline = newbufline;
-
-           System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin);
-           System.arraycopy(bufcolumn, 0, newbufcolumn, bufsize - tokenBegin, bufpos);
-           bufcolumn = newbufcolumn;
-
-           maxNextCharInd = (bufpos += (bufsize - tokenBegin));
-        }
-        else
-        {
-           System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin);
-           buffer = newbuffer;
-
-           System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin);
-           bufline = newbufline;
-
-           System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin);
-           bufcolumn = newbufcolumn;
-
-           maxNextCharInd = (bufpos -= tokenBegin);
-        }
-     }
-     catch (Throwable t)
-     {
-        throw new Error(t.getMessage());
-     }
-
-
-     bufsize += 2048;
-     available = bufsize;
-     tokenBegin = 0;
-  }
-
-  protected void FillBuff() throws java.io.IOException
-  {
-     if (maxNextCharInd == available)
-     {
-        if (available == bufsize)
-        {
-           if (tokenBegin > 2048)
-           {
-              bufpos = maxNextCharInd = 0;
-              available = tokenBegin;
-           }
-           else if (tokenBegin < 0)
-              bufpos = maxNextCharInd = 0;
-           else
-              ExpandBuff(false);
-        }
-        else if (available > tokenBegin)
-           available = bufsize;
-        else if ((tokenBegin - available) < 2048)
-           ExpandBuff(true);
-        else
-           available = tokenBegin;
-     }
-
-     int i;
-     try {
-        if ((i = inputStream.read(buffer, maxNextCharInd,
-                                    available - maxNextCharInd)) == -1)
-        {
-           inputStream.close();
-           throw new java.io.IOException();
-        }
-        else
-           maxNextCharInd += i;
-        return;
-     }
-     catch(java.io.IOException e) {
-        --bufpos;
-        backup(0);
-        if (tokenBegin == -1)
-           tokenBegin = bufpos;
-        throw e;
-     }
-  }
-
-  public char BeginToken() throws java.io.IOException
-  {
-     tokenBegin = -1;
-     char c = readChar();
-     tokenBegin = bufpos;
-
-     return c;
-  }
-
-  protected void UpdateLineColumn(char c)
-  {
-     column++;
-
-     if (prevCharIsLF)
-     {
-        prevCharIsLF = false;
-        line += (column = 1);
-     }
-     else if (prevCharIsCR)
-     {
-        prevCharIsCR = false;
-        if (c == '\n')
-        {
-           prevCharIsLF = true;
-        }
-        else
-           line += (column = 1);
-     }
-
-     switch (c)
-     {
-        case '\r' :
-           prevCharIsCR = true;
-           break;
-        case '\n' :
-           prevCharIsLF = true;
-           break;
-        case '\t' :
-           column--;
-           column += (tabSize - (column % tabSize));
-           break;
-        default :
-           break;
-     }
-
-     bufline[bufpos] = line;
-     bufcolumn[bufpos] = column;
-  }
-
-  public char readChar() throws java.io.IOException
-  {
-     if (inBuf > 0)
-     {
-        --inBuf;
-
-        if (++bufpos == bufsize)
-           bufpos = 0;
-
-        return buffer[bufpos];
-     }
-
-     if (++bufpos >= maxNextCharInd)
-        FillBuff();
-
-     char c = buffer[bufpos];
-
-     UpdateLineColumn(c);
-     return (c);
-  }
-
-  /**
-   * @deprecated 
-   * @see #getEndColumn
-   */
-  @Deprecated
-  public int getColumn() {
-     return bufcolumn[bufpos];
-  }
-
-  /**
-   * @deprecated 
-   * @see #getEndLine
-   */
-  @Deprecated
-  public int getLine() {
-     return bufline[bufpos];
-  }
-
-  public int getEndColumn() {
-     return bufcolumn[bufpos];
-  }
-
-  public int getEndLine() {
-     return bufline[bufpos];
-  }
-
-  public int getBeginColumn() {
-     return bufcolumn[tokenBegin];
-  }
-
-  public int getBeginLine() {
-     return bufline[tokenBegin];
-  }
-
-  public void backup(int amount) {
-
-    inBuf += amount;
-    if ((bufpos -= amount) < 0)
-       bufpos += bufsize;
-  }
-
-  public SimpleCharStream(java.io.Reader dstream, int startline,
-  int startcolumn, int buffersize)
-  {
-    inputStream = dstream;
-    line = startline;
-    column = startcolumn - 1;
-
-    available = bufsize = buffersize;
-    buffer = new char[buffersize];
-    bufline = new int[buffersize];
-    bufcolumn = new int[buffersize];
-  }
-
-  public SimpleCharStream(java.io.Reader dstream, int startline,
-                          int startcolumn)
-  {
-     this(dstream, startline, startcolumn, 4096);
-  }
-
-  public SimpleCharStream(java.io.Reader dstream)
-  {
-     this(dstream, 1, 1, 4096);
-  }
-  public void ReInit(java.io.Reader dstream, int startline,
-  int startcolumn, int buffersize)
-  {
-    inputStream = dstream;
-    line = startline;
-    column = startcolumn - 1;
-
-    if (buffer == null || buffersize != buffer.length)
-    {
-      available = bufsize = buffersize;
-      buffer = new char[buffersize];
-      bufline = new int[buffersize];
-      bufcolumn = new int[buffersize];
-    }
-    prevCharIsLF = prevCharIsCR = false;
-    tokenBegin = inBuf = maxNextCharInd = 0;
-    bufpos = -1;
-  }
-
-  public void ReInit(java.io.Reader dstream, int startline,
-                     int startcolumn)
-  {
-     ReInit(dstream, startline, startcolumn, 4096);
-  }
-
-  public void ReInit(java.io.Reader dstream)
-  {
-     ReInit(dstream, 1, 1, 4096);
-  }
-  public SimpleCharStream(java.io.InputStream dstream, String encoding, int startline,
-  int startcolumn, int buffersize) throws java.io.UnsupportedEncodingException
-  {
-     this(encoding == null ? new java.io.InputStreamReader(dstream) : new java.io.InputStreamReader(dstream, encoding), startline, startcolumn, buffersize);
-  }
-
-  public SimpleCharStream(java.io.InputStream dstream, int startline,
-  int startcolumn, int buffersize)
-  {
-     this(new java.io.InputStreamReader(dstream), startline, startcolumn, buffersize);
-  }
-
-  public SimpleCharStream(java.io.InputStream dstream, String encoding, int startline,
-                          int startcolumn) throws java.io.UnsupportedEncodingException
-  {
-     this(dstream, encoding, startline, startcolumn, 4096);
-  }
-
-  public SimpleCharStream(java.io.InputStream dstream, int startline,
-                          int startcolumn)
-  {
-     this(dstream, startline, startcolumn, 4096);
-  }
-
-  public SimpleCharStream(java.io.InputStream dstream, String encoding) throws java.io.UnsupportedEncodingException
-  {
-     this(dstream, encoding, 1, 1, 4096);
-  }
-
-  public SimpleCharStream(java.io.InputStream dstream)
-  {
-     this(dstream, 1, 1, 4096);
-  }
-
-  public void ReInit(java.io.InputStream dstream, String encoding, int startline,
-                          int startcolumn, int buffersize) throws java.io.UnsupportedEncodingException
-  {
-     ReInit(encoding == null ? new java.io.InputStreamReader(dstream) : new java.io.InputStreamReader(dstream, encoding), startline, startcolumn, buffersize);
-  }
-
-  public void ReInit(java.io.InputStream dstream, int startline,
-                          int startcolumn, int buffersize)
-  {
-     ReInit(new java.io.InputStreamReader(dstream), startline, startcolumn, buffersize);
-  }
-
-  public void ReInit(java.io.InputStream dstream, String encoding) throws java.io.UnsupportedEncodingException
-  {
-     ReInit(dstream, encoding, 1, 1, 4096);
-  }
-
-  public void ReInit(java.io.InputStream dstream)
-  {
-     ReInit(dstream, 1, 1, 4096);
-  }
-  public void ReInit(java.io.InputStream dstream, String encoding, int startline,
-                     int startcolumn) throws java.io.UnsupportedEncodingException
-  {
-     ReInit(dstream, encoding, startline, startcolumn, 4096);
-  }
-  public void ReInit(java.io.InputStream dstream, int startline,
-                     int startcolumn)
-  {
-     ReInit(dstream, startline, startcolumn, 4096);
-  }
-  public String GetImage()
-  {
-     if (bufpos >= tokenBegin)
-        return new String(buffer, tokenBegin, bufpos - tokenBegin + 1);
-     else
-        return new String(buffer, tokenBegin, bufsize - tokenBegin) +
-                              new String(buffer, 0, bufpos + 1);
-  }
-
-  public char[] GetSuffix(int len)
-  {
-     char[] ret = new char[len];
-
-     if ((bufpos + 1) >= len)
-        System.arraycopy(buffer, bufpos - len + 1, ret, 0, len);
-     else
-     {
-        System.arraycopy(buffer, bufsize - (len - bufpos - 1), ret, 0,
-                                                          len - bufpos - 1);
-        System.arraycopy(buffer, 0, ret, len - bufpos - 1, bufpos + 1);
-     }
-
-     return ret;
-  }
-
-  public void Done()
-  {
-     buffer = null;
-     bufline = null;
-     bufcolumn = null;
-  }
-
-  /**
-   * Method to adjust line and column numbers for the start of a token.
-   */
-  public void adjustBeginLineColumn(int newLine, int newCol)
-  {
-     int start = tokenBegin;
-     int len;
-
-     if (bufpos >= tokenBegin)
-     {
-        len = bufpos - tokenBegin + inBuf + 1;
-     }
-     else
-     {
-        len = bufsize - tokenBegin + bufpos + 1 + inBuf;
-     }
-
-     int i = 0, j = 0, k = 0;
-     int nextColDiff = 0, columnDiff = 0;
-
-     while (i < len &&
-            bufline[j = start % bufsize] == bufline[k = ++start % bufsize])
-     {
-        bufline[j] = newLine;
-        nextColDiff = columnDiff + bufcolumn[k] - bufcolumn[j];
-        bufcolumn[j] = newCol + columnDiff;
-        columnDiff = nextColDiff;
-        i++;
-     } 
-
-     if (i < len)
-     {
-        bufline[j] = newLine++;
-        bufcolumn[j] = newCol + columnDiff;
-
-        while (i++ < len)
-        {
-           if (bufline[j = start % bufsize] != bufline[++start % bufsize])
-              bufline[j] = newLine++;
-           else
-              bufline[j] = newLine;
-        }
-     }
-
-     line = bufline[j];
-     column = bufcolumn[j];
-  }
-
-}
diff --git a/src/org/apache/james/mime4j/field/datetime/parser/Token.java b/src/org/apache/james/mime4j/field/datetime/parser/Token.java
deleted file mode 100644
index 0927a09..0000000
--- a/src/org/apache/james/mime4j/field/datetime/parser/Token.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/* Generated By:JavaCC: Do not edit this line. Token.java Version 3.0 */
-/*
- *  Copyright 2004 the mime4j 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 org.apache.james.mime4j.field.datetime.parser;
-
-/**
- * Describes the input token stream.
- */
-
-public class Token {
-
-  /**
-   * An integer that describes the kind of this token.  This numbering
-   * system is determined by JavaCCParser, and a table of these numbers is
-   * stored in the file ...Constants.java.
-   */
-  public int kind;
-
-  /**
-   * beginLine and beginColumn describe the position of the first character
-   * of this token; endLine and endColumn describe the position of the
-   * last character of this token.
-   */
-  public int beginLine, beginColumn, endLine, endColumn;
-
-  /**
-   * The string image of the token.
-   */
-  public String image;
-
-  /**
-   * A reference to the next regular (non-special) token from the input
-   * stream.  If this is the last token from the input stream, or if the
-   * token manager has not read tokens beyond this one, this field is
-   * set to null.  This is true only if this token is also a regular
-   * token.  Otherwise, see below for a description of the contents of
-   * this field.
-   */
-  public Token next;
-
-  /**
-   * This field is used to access special tokens that occur prior to this
-   * token, but after the immediately preceding regular (non-special) token.
-   * If there are no such special tokens, this field is set to null.
-   * When there are more than one such special token, this field refers
-   * to the last of these special tokens, which in turn refers to the next
-   * previous special token through its specialToken field, and so on
-   * until the first special token (whose specialToken field is null).
-   * The next fields of special tokens refer to other special tokens that
-   * immediately follow it (without an intervening regular token).  If there
-   * is no such token, this field is null.
-   */
-  public Token specialToken;
-
-  /**
-   * Returns the image.
-   */
-  public String toString()
-  {
-     return image;
-  }
-
-  /**
-   * Returns a new Token object, by default. However, if you want, you
-   * can create and return subclass objects based on the value of ofKind.
-   * Simply add the cases to the switch for all those special cases.
-   * For example, if you have a subclass of Token called IDToken that
-   * you want to create if ofKind is ID, simlpy add something like :
-   *
-   *    case MyParserConstants.ID : return new IDToken();
-   *
-   * to the following switch statement. Then you can cast matchedToken
-   * variable to the appropriate type and use it in your lexical actions.
-   */
-  public static final Token newToken(int ofKind)
-  {
-     switch(ofKind)
-     {
-       default : return new Token();
-     }
-  }
-
-}
diff --git a/src/org/apache/james/mime4j/field/datetime/parser/TokenMgrError.java b/src/org/apache/james/mime4j/field/datetime/parser/TokenMgrError.java
deleted file mode 100644
index e7043c1..0000000
--- a/src/org/apache/james/mime4j/field/datetime/parser/TokenMgrError.java
+++ /dev/null
@@ -1,148 +0,0 @@
-/* Generated By:JavaCC: Do not edit this line. TokenMgrError.java Version 3.0 */
-/*
- *  Copyright 2004 the mime4j 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 org.apache.james.mime4j.field.datetime.parser;
-
-public class TokenMgrError extends Error
-{
-   /*
-    * Ordinals for various reasons why an Error of this type can be thrown.
-    */
-
-   /**
-    * Lexical error occured.
-    */
-   static final int LEXICAL_ERROR = 0;
-
-   /**
-    * An attempt wass made to create a second instance of a static token manager.
-    */
-   static final int STATIC_LEXER_ERROR = 1;
-
-   /**
-    * Tried to change to an invalid lexical state.
-    */
-   static final int INVALID_LEXICAL_STATE = 2;
-
-   /**
-    * Detected (and bailed out of) an infinite loop in the token manager.
-    */
-   static final int LOOP_DETECTED = 3;
-
-   /**
-    * Indicates the reason why the exception is thrown. It will have
-    * one of the above 4 values.
-    */
-   int errorCode;
-
-   /**
-    * Replaces unprintable characters by their espaced (or unicode escaped)
-    * equivalents in the given string
-    */
-   protected static final String addEscapes(String str) {
-      StringBuffer retval = new StringBuffer();
-      char ch;
-      for (int i = 0; i < str.length(); i++) {
-        switch (str.charAt(i))
-        {
-           case 0 :
-              continue;
-           case '\b':
-              retval.append("\\b");
-              continue;
-           case '\t':
-              retval.append("\\t");
-              continue;
-           case '\n':
-              retval.append("\\n");
-              continue;
-           case '\f':
-              retval.append("\\f");
-              continue;
-           case '\r':
-              retval.append("\\r");
-              continue;
-           case '\"':
-              retval.append("\\\"");
-              continue;
-           case '\'':
-              retval.append("\\\'");
-              continue;
-           case '\\':
-              retval.append("\\\\");
-              continue;
-           default:
-              if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) {
-                 String s = "0000" + Integer.toString(ch, 16);
-                 retval.append("\\u" + s.substring(s.length() - 4, s.length()));
-              } else {
-                 retval.append(ch);
-              }
-              continue;
-        }
-      }
-      return retval.toString();
-   }
-
-   /**
-    * Returns a detailed message for the Error when it is thrown by the
-    * token manager to indicate a lexical error.
-    * Parameters : 
-    *    EOFSeen     : indicates if EOF caused the lexicl error
-    *    curLexState : lexical state in which this error occured
-    *    errorLine   : line number when the error occured
-    *    errorColumn : column number when the error occured
-    *    errorAfter  : prefix that was seen before this error occured
-    *    curchar     : the offending character
-    * Note: You can customize the lexical error message by modifying this method.
-    */
-   protected static String LexicalError(boolean EOFSeen, int lexState, int errorLine, int errorColumn, String errorAfter, char curChar) {
-      return("Lexical error at line " +
-           errorLine + ", column " +
-           errorColumn + ".  Encountered: " +
-           (EOFSeen ? "<EOF> " : ("\"" + addEscapes(String.valueOf(curChar)) + "\"") + " (" + (int)curChar + "), ") +
-           "after : \"" + addEscapes(errorAfter) + "\"");
-   }
-
-   /**
-    * You can also modify the body of this method to customize your error messages.
-    * For example, cases like LOOP_DETECTED and INVALID_LEXICAL_STATE are not
-    * of end-users concern, so you can return something like : 
-    *
-    *     "Internal Error : Please file a bug report .... "
-    *
-    * from this method for such cases in the release version of your parser.
-    */
-   public String getMessage() {
-      return super.getMessage();
-   }
-
-   /*
-    * Constructors of various flavors follow.
-    */
-
-   public TokenMgrError() {
-   }
-
-   public TokenMgrError(String message, int reason) {
-      super(message);
-      errorCode = reason;
-   }
-
-   public TokenMgrError(boolean EOFSeen, int lexState, int errorLine, int errorColumn, String errorAfter, char curChar, int reason) {
-      this(LexicalError(EOFSeen, lexState, errorLine, errorColumn, errorAfter, curChar), reason);
-   }
-}
diff --git a/src/org/apache/james/mime4j/util/CharsetUtil.java b/src/org/apache/james/mime4j/util/CharsetUtil.java
deleted file mode 100644
index 4e712fc..0000000
--- a/src/org/apache/james/mime4j/util/CharsetUtil.java
+++ /dev/null
@@ -1,1249 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one   *
- * or more contributor license agreements.  See the NOTICE file *
- * distributed with this work for additional information        *
- * regarding copyright ownership.  The ASF licenses this file   *
- * to you 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 org.apache.james.mime4j.util;
-
-import java.io.UnsupportedEncodingException;
-import java.nio.charset.IllegalCharsetNameException;
-import java.nio.charset.UnsupportedCharsetException;
-import java.util.HashMap;
-import java.util.Locale;
-import java.util.TreeSet;
-
-//BEGIN android-changed: Stubbing out logging
-import org.apache.james.mime4j.Log;
-import org.apache.james.mime4j.LogFactory;
-//END android-changed
-
-/**
- * Utility class for working with character sets. It is somewhat similar to
- * the Java 1.4 <code>java.nio.charset.Charset</code> class but knows many
- * more aliases and is compatible with Java 1.3. It will use a simple detection
- * mechanism to detect what character sets the current VM supports. This will
- * be a sub-set of the character sets listed in the
- * <a href="http://java.sun.com/j2se/1.5.0/docs/guide/intl/encoding.doc.html">
- * Java 1.5 (J2SE5.0) Supported Encodings</a> document.
- * <p>
- * The <a href="http://www.iana.org/assignments/character-sets">
- * IANA Character Sets</a> document has been used to determine the preferred
- * MIME character set names and to get a list of known aliases.
- * <p>
- * This is a complete list of the character sets known to this class:
- * <table>
- *     <tr>
- *         <td>Canonical (Java) name</td>
- *         <td>MIME preferred</td>
- *         <td>Aliases</td>
- *     </tr>
- *     <tr>
- *         <td>ASCII</td>
- *         <td>US-ASCII</td>
- *         <td>ANSI_X3.4-1968 iso-ir-6 ANSI_X3.4-1986 ISO_646.irv:1991 ISO646-US us IBM367 cp367 csASCII ascii7 646 iso_646.irv:1983 </td>
- *     </tr>
- *     <tr>
- *         <td>Big5</td>
- *         <td>Big5</td>
- *         <td>csBig5 CN-Big5 BIG-FIVE BIGFIVE </td>
- *     </tr>
- *     <tr>
- *         <td>Big5_HKSCS</td>
- *         <td>Big5-HKSCS</td>
- *         <td>big5hkscs </td>
- *     </tr>
- *     <tr>
- *         <td>Big5_Solaris</td>
- *         <td>?</td>
- *         <td></td>
- *     </tr>
- *     <tr>
- *         <td>Cp037</td>
- *         <td>IBM037</td>
- *         <td>ebcdic-cp-us ebcdic-cp-ca ebcdic-cp-wt ebcdic-cp-nl csIBM037 </td>
- *     </tr>
- *     <tr>
- *         <td>Cp1006</td>
- *         <td>?</td>
- *         <td></td>
- *     </tr>
- *     <tr>
- *         <td>Cp1025</td>
- *         <td>?</td>
- *         <td></td>
- *     </tr>
- *     <tr>
- *         <td>Cp1026</td>
- *         <td>IBM1026</td>
- *         <td>csIBM1026 </td>
- *     </tr>
- *     <tr>
- *         <td>Cp1046</td>
- *         <td>?</td>
- *         <td></td>
- *     </tr>
- *     <tr>
- *         <td>Cp1047</td>
- *         <td>IBM1047</td>
- *         <td>IBM-1047 </td>
- *     </tr>
- *     <tr>
- *         <td>Cp1097</td>
- *         <td>?</td>
- *         <td></td>
- *     </tr>
- *     <tr>
- *         <td>Cp1098</td>
- *         <td>?</td>
- *         <td></td>
- *     </tr>
- *     <tr>
- *         <td>Cp1112</td>
- *         <td>?</td>
- *         <td></td>
- *     </tr>
- *     <tr>
- *         <td>Cp1122</td>
- *         <td>?</td>
- *         <td></td>
- *     </tr>
- *     <tr>
- *         <td>Cp1123</td>
- *         <td>?</td>
- *         <td></td>
- *     </tr>
- *     <tr>
- *         <td>Cp1124</td>
- *         <td>?</td>
- *         <td></td>
- *     </tr>
- *     <tr>
- *         <td>Cp1140</td>
- *         <td>IBM01140</td>
- *         <td>CCSID01140 CP01140 ebcdic-us-37+euro </td>
- *     </tr>
- *     <tr>
- *         <td>Cp1141</td>
- *         <td>IBM01141</td>
- *         <td>CCSID01141 CP01141 ebcdic-de-273+euro </td>
- *     </tr>
- *     <tr>
- *         <td>Cp1142</td>
- *         <td>IBM01142</td>
- *         <td>CCSID01142 CP01142 ebcdic-dk-277+euro ebcdic-no-277+euro </td>
- *     </tr>
- *     <tr>
- *         <td>Cp1143</td>
- *         <td>IBM01143</td>
- *         <td>CCSID01143 CP01143 ebcdic-fi-278+euro ebcdic-se-278+euro </td>
- *     </tr>
- *     <tr>
- *         <td>Cp1144</td>
- *         <td>IBM01144</td>
- *         <td>CCSID01144 CP01144 ebcdic-it-280+euro </td>
- *     </tr>
- *     <tr>
- *         <td>Cp1145</td>
- *         <td>IBM01145</td>
- *         <td>CCSID01145 CP01145 ebcdic-es-284+euro </td>
- *     </tr>
- *     <tr>
- *         <td>Cp1146</td>
- *         <td>IBM01146</td>
- *         <td>CCSID01146 CP01146 ebcdic-gb-285+euro </td>
- *     </tr>
- *     <tr>
- *         <td>Cp1147</td>
- *         <td>IBM01147</td>
- *         <td>CCSID01147 CP01147 ebcdic-fr-297+euro </td>
- *     </tr>
- *     <tr>
- *         <td>Cp1148</td>
- *         <td>IBM01148</td>
- *         <td>CCSID01148 CP01148 ebcdic-international-500+euro </td>
- *     </tr>
- *     <tr>
- *         <td>Cp1149</td>
- *         <td>IBM01149</td>
- *         <td>CCSID01149 CP01149 ebcdic-is-871+euro </td>
- *     </tr>
- *     <tr>
- *         <td>Cp1250</td>
- *         <td>windows-1250</td>
- *         <td></td>
- *     </tr>
- *     <tr>
- *         <td>Cp1251</td>
- *         <td>windows-1251</td>
- *         <td></td>
- *     </tr>
- *     <tr>
- *         <td>Cp1252</td>
- *         <td>windows-1252</td>
- *         <td></td>
- *     </tr>
- *     <tr>
- *         <td>Cp1253</td>
- *         <td>windows-1253</td>
- *         <td></td>
- *     </tr>
- *     <tr>
- *         <td>Cp1254</td>
- *         <td>windows-1254</td>
- *         <td></td>
- *     </tr>
- *     <tr>
- *         <td>Cp1255</td>
- *         <td>windows-1255</td>
- *         <td></td>
- *     </tr>
- *     <tr>
- *         <td>Cp1256</td>
- *         <td>windows-1256</td>
- *         <td></td>
- *     </tr>
- *     <tr>
- *         <td>Cp1257</td>
- *         <td>windows-1257</td>
- *         <td></td>
- *     </tr>
- *     <tr>
- *         <td>Cp1258</td>
- *         <td>windows-1258</td>
- *         <td></td>
- *     </tr>
- *     <tr>
- *         <td>Cp1381</td>
- *         <td>?</td>
- *         <td></td>
- *     </tr>
- *     <tr>
- *         <td>Cp1383</td>
- *         <td>?</td>
- *         <td></td>
- *     </tr>
- *     <tr>
- *         <td>Cp273</td>
- *         <td>IBM273</td>
- *         <td>csIBM273 </td>
- *     </tr>
- *     <tr>
- *         <td>Cp277</td>
- *         <td>IBM277</td>
- *         <td>EBCDIC-CP-DK EBCDIC-CP-NO csIBM277 </td>
- *     </tr>
- *     <tr>
- *         <td>Cp278</td>
- *         <td>IBM278</td>
- *         <td>CP278 ebcdic-cp-fi ebcdic-cp-se csIBM278 </td>
- *     </tr>
- *     <tr>
- *         <td>Cp280</td>
- *         <td>IBM280</td>
- *         <td>ebcdic-cp-it csIBM280 </td>
- *     </tr>
- *     <tr>
- *         <td>Cp284</td>
- *         <td>IBM284</td>
- *         <td>ebcdic-cp-es csIBM284 </td>
- *     </tr>
- *     <tr>
- *         <td>Cp285</td>
- *         <td>IBM285</td>
- *         <td>ebcdic-cp-gb csIBM285 </td>
- *     </tr>
- *     <tr>
- *         <td>Cp297</td>
- *         <td>IBM297</td>
- *         <td>ebcdic-cp-fr csIBM297 </td>
- *     </tr>
- *     <tr>
- *         <td>Cp33722</td>
- *         <td>?</td>
- *         <td></td>
- *     </tr>
- *     <tr>
- *         <td>Cp420</td>
- *         <td>IBM420</td>
- *         <td>ebcdic-cp-ar1 csIBM420 </td>
- *     </tr>
- *     <tr>
- *         <td>Cp424</td>
- *         <td>IBM424</td>
- *         <td>ebcdic-cp-he csIBM424 </td>
- *     </tr>
- *     <tr>
- *         <td>Cp437</td>
- *         <td>IBM437</td>
- *         <td>437 csPC8CodePage437 </td>
- *     </tr>
- *     <tr>
- *         <td>Cp500</td>
- *         <td>IBM500</td>
- *         <td>ebcdic-cp-be ebcdic-cp-ch csIBM500 </td>
- *     </tr>
- *     <tr>
- *         <td>Cp737</td>
- *         <td>?</td>
- *         <td></td>
- *     </tr>
- *     <tr>
- *         <td>Cp775</td>
- *         <td>IBM775</td>
- *         <td>csPC775Baltic </td>
- *     </tr>
- *     <tr>
- *         <td>Cp838</td>
- *         <td>IBM-Thai</td>
- *         <td></td>
- *     </tr>
- *     <tr>
- *         <td>Cp850</td>
- *         <td>IBM850</td>
- *         <td>850 csPC850Multilingual </td>
- *     </tr>
- *     <tr>
- *         <td>Cp852</td>
- *         <td>IBM852</td>
- *         <td>852 csPCp852 </td>
- *     </tr>
- *     <tr>
- *         <td>Cp855</td>
- *         <td>IBM855</td>
- *         <td>855 csIBM855 </td>
- *     </tr>
- *     <tr>
- *         <td>Cp856</td>
- *         <td>?</td>
- *         <td></td>
- *     </tr>
- *     <tr>
- *         <td>Cp857</td>
- *         <td>IBM857</td>
- *         <td>857 csIBM857 </td>
- *     </tr>
- *     <tr>
- *         <td>Cp858</td>
- *         <td>IBM00858</td>
- *         <td>CCSID00858 CP00858 PC-Multilingual-850+euro </td>
- *     </tr>
- *     <tr>
- *         <td>Cp860</td>
- *         <td>IBM860</td>
- *         <td>860 csIBM860 </td>
- *     </tr>
- *     <tr>
- *         <td>Cp861</td>
- *         <td>IBM861</td>
- *         <td>861 cp-is csIBM861 </td>
- *     </tr>
- *     <tr>
- *         <td>Cp862</td>
- *         <td>IBM862</td>
- *         <td>862 csPC862LatinHebrew </td>
- *     </tr>
- *     <tr>
- *         <td>Cp863</td>
- *         <td>IBM863</td>
- *         <td>863 csIBM863 </td>
- *     </tr>
- *     <tr>
- *         <td>Cp864</td>
- *         <td>IBM864</td>
- *         <td>cp864 csIBM864 </td>
- *     </tr>
- *     <tr>
- *         <td>Cp865</td>
- *         <td>IBM865</td>
- *         <td>865 csIBM865 </td>
- *     </tr>
- *     <tr>
- *         <td>Cp866</td>
- *         <td>IBM866</td>
- *         <td>866 csIBM866 </td>
- *     </tr>
- *     <tr>
- *         <td>Cp868</td>
- *         <td>IBM868</td>
- *         <td>cp-ar csIBM868 </td>
- *     </tr>
- *     <tr>
- *         <td>Cp869</td>
- *         <td>IBM869</td>
- *         <td>cp-gr csIBM869 </td>
- *     </tr>
- *     <tr>
- *         <td>Cp870</td>
- *         <td>IBM870</td>
- *         <td>ebcdic-cp-roece ebcdic-cp-yu csIBM870 </td>
- *     </tr>
- *     <tr>
- *         <td>Cp871</td>
- *         <td>IBM871</td>
- *         <td>ebcdic-cp-is csIBM871 </td>
- *     </tr>
- *     <tr>
- *         <td>Cp875</td>
- *         <td>?</td>
- *         <td></td>
- *     </tr>
- *     <tr>
- *         <td>Cp918</td>
- *         <td>IBM918</td>
- *         <td>ebcdic-cp-ar2 csIBM918 </td>
- *     </tr>
- *     <tr>
- *         <td>Cp921</td>
- *         <td>?</td>
- *         <td></td>
- *     </tr>
- *     <tr>
- *         <td>Cp922</td>
- *         <td>?</td>
- *         <td></td>
- *     </tr>
- *     <tr>
- *         <td>Cp930</td>
- *         <td>?</td>
- *         <td></td>
- *     </tr>
- *     <tr>
- *         <td>Cp933</td>
- *         <td>?</td>
- *         <td></td>
- *     </tr>
- *     <tr>
- *         <td>Cp935</td>
- *         <td>?</td>
- *         <td></td>
- *     </tr>
- *     <tr>
- *         <td>Cp937</td>
- *         <td>?</td>
- *         <td></td>
- *     </tr>
- *     <tr>
- *         <td>Cp939</td>
- *         <td>?</td>
- *         <td></td>
- *     </tr>
- *     <tr>
- *         <td>Cp942</td>
- *         <td>?</td>
- *         <td></td>
- *     </tr>
- *     <tr>
- *         <td>Cp942C</td>
- *         <td>?</td>
- *         <td></td>
- *     </tr>
- *     <tr>
- *         <td>Cp943</td>
- *         <td>?</td>
- *         <td></td>
- *     </tr>
- *     <tr>
- *         <td>Cp943C</td>
- *         <td>?</td>
- *         <td></td>
- *     </tr>
- *     <tr>
- *         <td>Cp948</td>
- *         <td>?</td>
- *         <td></td>
- *     </tr>
- *     <tr>
- *         <td>Cp949</td>
- *         <td>?</td>
- *         <td></td>
- *     </tr>
- *     <tr>
- *         <td>Cp949C</td>
- *         <td>?</td>
- *         <td></td>
- *     </tr>
- *     <tr>
- *         <td>Cp950</td>
- *         <td>?</td>
- *         <td></td>
- *     </tr>
- *     <tr>
- *         <td>Cp964</td>
- *         <td>?</td>
- *         <td></td>
- *     </tr>
- *     <tr>
- *         <td>Cp970</td>
- *         <td>?</td>
- *         <td></td>
- *     </tr>
- *     <tr>
- *         <td>EUC_CN</td>
- *         <td>GB2312</td>
- *         <td>x-EUC-CN csGB2312 euccn euc-cn gb2312-80 gb2312-1980 CN-GB CN-GB-ISOIR165 </td>
- *     </tr>
- *     <tr>
- *         <td>EUC_JP</td>
- *         <td>EUC-JP</td>
- *         <td>csEUCPkdFmtJapanese Extended_UNIX_Code_Packed_Format_for_Japanese eucjis x-eucjp eucjp x-euc-jp </td>
- *     </tr>
- *     <tr>
- *         <td>EUC_JP_LINUX</td>
- *         <td>?</td>
- *         <td></td>
- *     </tr>
- *     <tr>
- *         <td>EUC_JP_Solaris</td>
- *         <td>?</td>
- *         <td></td>
- *     </tr>
- *     <tr>
- *         <td>EUC_KR</td>
- *         <td>EUC-KR</td>
- *         <td>csEUCKR ksc5601 5601 ksc5601_1987 ksc_5601 ksc5601-1987 ks_c_5601-1987 euckr </td>
- *     </tr>
- *     <tr>
- *         <td>EUC_TW</td>
- *         <td>EUC-TW</td>
- *         <td>x-EUC-TW cns11643 euctw </td>
- *     </tr>
- *     <tr>
- *         <td>GB18030</td>
- *         <td>GB18030</td>
- *         <td>gb18030-2000 </td>
- *     </tr>
- *     <tr>
- *         <td>GBK</td>
- *         <td>windows-936</td>
- *         <td>CP936 MS936 ms_936 x-mswin-936 </td>
- *     </tr>
- *     <tr>
- *         <td>ISCII91</td>
- *         <td>?</td>
- *         <td>x-ISCII91 iscii </td>
- *     </tr>
- *     <tr>
- *         <td>ISO2022CN</td>
- *         <td>ISO-2022-CN</td>
- *         <td></td>
- *     </tr>
- *     <tr>
- *         <td>ISO2022JP</td>
- *         <td>ISO-2022-JP</td>
- *         <td>csISO2022JP JIS jis_encoding csjisencoding </td>
- *     </tr>
- *     <tr>
- *         <td>ISO2022KR</td>
- *         <td>ISO-2022-KR</td>
- *         <td>csISO2022KR </td>
- *     </tr>
- *     <tr>
- *         <td>ISO2022_CN_CNS</td>
- *         <td>?</td>
- *         <td></td>
- *     </tr>
- *     <tr>
- *         <td>ISO2022_CN_GB</td>
- *         <td>?</td>
- *         <td></td>
- *     </tr>
- *     <tr>
- *         <td>ISO8859_1</td>
- *         <td>ISO-8859-1</td>
- *         <td>ISO_8859-1:1987 iso-ir-100 ISO_8859-1 latin1 l1 IBM819 CP819 csISOLatin1 8859_1 819 IBM-819 ISO8859-1 ISO_8859_1 </td>
- *     </tr>
- *     <tr>
- *         <td>ISO8859_13</td>
- *         <td>ISO-8859-13</td>
- *         <td></td>
- *     </tr>
- *     <tr>
- *         <td>ISO8859_15</td>
- *         <td>ISO-8859-15</td>
- *         <td>ISO_8859-15 Latin-9 8859_15 csISOlatin9 IBM923 cp923 923 L9 IBM-923 ISO8859-15 LATIN9 LATIN0 csISOlatin0 ISO8859_15_FDIS </td>
- *     </tr>
- *     <tr>
- *         <td>ISO8859_2</td>
- *         <td>ISO-8859-2</td>
- *         <td>ISO_8859-2:1987 iso-ir-101 ISO_8859-2 latin2 l2 csISOLatin2 8859_2 iso8859_2 </td>
- *     </tr>
- *     <tr>
- *         <td>ISO8859_3</td>
- *         <td>ISO-8859-3</td>
- *         <td>ISO_8859-3:1988 iso-ir-109 ISO_8859-3 latin3 l3 csISOLatin3 8859_3 </td>
- *     </tr>
- *     <tr>
- *         <td>ISO8859_4</td>
- *         <td>ISO-8859-4</td>
- *         <td>ISO_8859-4:1988 iso-ir-110 ISO_8859-4 latin4 l4 csISOLatin4 8859_4 </td>
- *     </tr>
- *     <tr>
- *         <td>ISO8859_5</td>
- *         <td>ISO-8859-5</td>
- *         <td>ISO_8859-5:1988 iso-ir-144 ISO_8859-5 cyrillic csISOLatinCyrillic 8859_5 </td>
- *     </tr>
- *     <tr>
- *         <td>ISO8859_6</td>
- *         <td>ISO-8859-6</td>
- *         <td>ISO_8859-6:1987 iso-ir-127 ISO_8859-6 ECMA-114 ASMO-708 arabic csISOLatinArabic 8859_6 </td>
- *     </tr>
- *     <tr>
- *         <td>ISO8859_7</td>
- *         <td>ISO-8859-7</td>
- *         <td>ISO_8859-7:1987 iso-ir-126 ISO_8859-7 ELOT_928 ECMA-118 greek greek8 csISOLatinGreek 8859_7 sun_eu_greek </td>
- *     </tr>
- *     <tr>
- *         <td>ISO8859_8</td>
- *         <td>ISO-8859-8</td>
- *         <td>ISO_8859-8:1988 iso-ir-138 ISO_8859-8 hebrew csISOLatinHebrew 8859_8 </td>
- *     </tr>
- *     <tr>
- *         <td>ISO8859_9</td>
- *         <td>ISO-8859-9</td>
- *         <td>ISO_8859-9:1989 iso-ir-148 ISO_8859-9 latin5 l5 csISOLatin5 8859_9 </td>
- *     </tr>
- *     <tr>
- *         <td>JISAutoDetect</td>
- *         <td>?</td>
- *         <td></td>
- *     </tr>
- *     <tr>
- *         <td>JIS_C6626-1983</td>
- *         <td>JIS_C6626-1983</td>
- *         <td>x-JIS0208 JIS0208 csISO87JISX0208 x0208 JIS_X0208-1983 iso-ir-87 </td>
- *     </tr>
- *     <tr>
- *         <td>JIS_X0201</td>
- *         <td>JIS_X0201</td>
- *         <td>X0201 JIS0201 csHalfWidthKatakana </td>
- *     </tr>
- *     <tr>
- *         <td>JIS_X0212-1990</td>
- *         <td>JIS_X0212-1990</td>
- *         <td>iso-ir-159 x0212 JIS0212 csISO159JISX02121990 </td>
- *     </tr>
- *     <tr>
- *         <td>KOI8_R</td>
- *         <td>KOI8-R</td>
- *         <td>csKOI8R koi8 </td>
- *     </tr>
- *     <tr>
- *         <td>MS874</td>
- *         <td>windows-874</td>
- *         <td>cp874 </td>
- *     </tr>
- *     <tr>
- *         <td>MS932</td>
- *         <td>Windows-31J</td>
- *         <td>windows-932 csWindows31J x-ms-cp932 </td>
- *     </tr>
- *     <tr>
- *         <td>MS949</td>
- *         <td>windows-949</td>
- *         <td>windows949 ms_949 x-windows-949 </td>
- *     </tr>
- *     <tr>
- *         <td>MS950</td>
- *         <td>windows-950</td>
- *         <td>x-windows-950 </td>
- *     </tr>
- *     <tr>
- *         <td>MS950_HKSCS</td>
- *         <td></td>
- *         <td></td>
- *     </tr>
- *     <tr>
- *         <td>MacArabic</td>
- *         <td>?</td>
- *         <td></td>
- *     </tr>
- *     <tr>
- *         <td>MacCentralEurope</td>
- *         <td>?</td>
- *         <td></td>
- *     </tr>
- *     <tr>
- *         <td>MacCroatian</td>
- *         <td>?</td>
- *         <td></td>
- *     </tr>
- *     <tr>
- *         <td>MacCyrillic</td>
- *         <td>?</td>
- *         <td></td>
- *     </tr>
- *     <tr>
- *         <td>MacDingbat</td>
- *         <td>?</td>
- *         <td></td>
- *     </tr>
- *     <tr>
- *         <td>MacGreek</td>
- *         <td>MacGreek</td>
- *         <td></td>
- *     </tr>
- *     <tr>
- *         <td>MacHebrew</td>
- *         <td>?</td>
- *         <td></td>
- *     </tr>
- *     <tr>
- *         <td>MacIceland</td>
- *         <td>?</td>
- *         <td></td>
- *     </tr>
- *     <tr>
- *         <td>MacRoman</td>
- *         <td>MacRoman</td>
- *         <td>Macintosh MAC csMacintosh </td>
- *     </tr>
- *     <tr>
- *         <td>MacRomania</td>
- *         <td>?</td>
- *         <td></td>
- *     </tr>
- *     <tr>
- *         <td>MacSymbol</td>
- *         <td>?</td>
- *         <td></td>
- *     </tr>
- *     <tr>
- *         <td>MacThai</td>
- *         <td>?</td>
- *         <td></td>
- *     </tr>
- *     <tr>
- *         <td>MacTurkish</td>
- *         <td>?</td>
- *         <td></td>
- *     </tr>
- *     <tr>
- *         <td>MacUkraine</td>
- *         <td>?</td>
- *         <td></td>
- *     </tr>
- *     <tr>
- *         <td>SJIS</td>
- *         <td>Shift_JIS</td>
- *         <td>MS_Kanji csShiftJIS shift-jis x-sjis pck </td>
- *     </tr>
- *     <tr>
- *         <td>TIS620</td>
- *         <td>TIS-620</td>
- *         <td></td>
- *     </tr>
- *     <tr>
- *         <td>UTF-16</td>
- *         <td>UTF-16</td>
- *         <td>UTF_16 </td>
- *     </tr>
- *     <tr>
- *         <td>UTF8</td>
- *         <td>UTF-8</td>
- *         <td></td>
- *     </tr>
- *     <tr>
- *         <td>UnicodeBig</td>
- *         <td>?</td>
- *         <td></td>
- *     </tr>
- *     <tr>
- *         <td>UnicodeBigUnmarked</td>
- *         <td>UTF-16BE</td>
- *         <td>X-UTF-16BE UTF_16BE ISO-10646-UCS-2 </td>
- *     </tr>
- *     <tr>
- *         <td>UnicodeLittle</td>
- *         <td>?</td>
- *         <td></td>
- *     </tr>
- *     <tr>
- *         <td>UnicodeLittleUnmarked</td>
- *         <td>UTF-16LE</td>
- *         <td>UTF_16LE X-UTF-16LE </td>
- *     </tr>
- *     <tr>
- *         <td>x-Johab</td>
- *         <td>johab</td>
- *         <td>johab cp1361 ms1361 ksc5601-1992 ksc5601_1992 </td>
- *     </tr>
- *     <tr>
- *         <td>x-iso-8859-11</td>
- *         <td>?</td>
- *         <td></td>
- *     </tr>
- * </table>
- *
- *
- * @version $Id: CharsetUtil.java,v 1.1 2004/10/25 07:26:46 ntherning Exp $
- */
-public class CharsetUtil {
-    private static Log log = LogFactory.getLog(CharsetUtil.class);
-
-    private static class Charset implements Comparable<Charset> {
-        private String canonical = null;
-        private String mime = null;
-        private String[] aliases = null;
-
-        private Charset(String canonical, String mime, String[] aliases) {
-            this.canonical = canonical;
-            this.mime = mime;
-            this.aliases = aliases;
-        }
-
-        public int compareTo(Charset c) {
-            return this.canonical.compareTo(c.canonical);
-        }
-    }
-
-    private static Charset[] JAVA_CHARSETS = {
-        new Charset("ISO8859_1", "ISO-8859-1",
-                    new String[] {"ISO_8859-1:1987", "iso-ir-100", "ISO_8859-1",
-                                  "latin1", "l1", "IBM819", "CP819",
-                                  "csISOLatin1", "8859_1", "819", "IBM-819",
-                                  "ISO8859-1", "ISO_8859_1"}),
-        new Charset("ISO8859_2", "ISO-8859-2",
-                    new String[] {"ISO_8859-2:1987", "iso-ir-101", "ISO_8859-2",
-                                  "latin2", "l2", "csISOLatin2", "8859_2",
-                                  "iso8859_2"}),
-        new Charset("ISO8859_3", "ISO-8859-3", new String[] {"ISO_8859-3:1988", "iso-ir-109", "ISO_8859-3", "latin3", "l3", "csISOLatin3", "8859_3"}),
-        new Charset("ISO8859_4", "ISO-8859-4",
-                    new String[] {"ISO_8859-4:1988", "iso-ir-110", "ISO_8859-4",
-                                  "latin4", "l4", "csISOLatin4", "8859_4"}),
-        new Charset("ISO8859_5", "ISO-8859-5",
-                    new String[] {"ISO_8859-5:1988", "iso-ir-144", "ISO_8859-5",
-                                  "cyrillic", "csISOLatinCyrillic", "8859_5"}),
-        new Charset("ISO8859_6", "ISO-8859-6", new String[] {"ISO_8859-6:1987", "iso-ir-127", "ISO_8859-6", "ECMA-114", "ASMO-708", "arabic", "csISOLatinArabic", "8859_6"}),
-        new Charset("ISO8859_7", "ISO-8859-7",
-                    new String[] {"ISO_8859-7:1987", "iso-ir-126", "ISO_8859-7",
-                                  "ELOT_928", "ECMA-118", "greek", "greek8",
-                                  "csISOLatinGreek", "8859_7", "sun_eu_greek"}),
-        new Charset("ISO8859_8", "ISO-8859-8", new String[] {"ISO_8859-8:1988", "iso-ir-138", "ISO_8859-8", "hebrew", "csISOLatinHebrew", "8859_8"}),
-        new Charset("ISO8859_9", "ISO-8859-9",
-                    new String[] {"ISO_8859-9:1989", "iso-ir-148", "ISO_8859-9",
-                                  "latin5", "l5", "csISOLatin5", "8859_9"}),
-
-        new Charset("ISO8859_13", "ISO-8859-13", new String[] {}),
-        new Charset("ISO8859_15", "ISO-8859-15",
-                    new String[] {"ISO_8859-15", "Latin-9", "8859_15",
-                                  "csISOlatin9", "IBM923", "cp923", "923", "L9",
-                                  "IBM-923", "ISO8859-15", "LATIN9", "LATIN0",
-                                  "csISOlatin0", "ISO8859_15_FDIS"}),
-        new Charset("KOI8_R", "KOI8-R", new String[] {"csKOI8R", "koi8"}),
-        new Charset("ASCII", "US-ASCII",
-                    new String[] {"ANSI_X3.4-1968", "iso-ir-6",
-                                  "ANSI_X3.4-1986", "ISO_646.irv:1991",
-                                  "ISO646-US", "us", "IBM367", "cp367",
-                                  "csASCII", "ascii7", "646", "iso_646.irv:1983"}),
-        new Charset("UTF8", "UTF-8", new String[] {}),
-        new Charset("UTF-16", "UTF-16", new String[] {"UTF_16"}),
-        new Charset("UnicodeBigUnmarked", "UTF-16BE", new String[] {"X-UTF-16BE", "UTF_16BE", "ISO-10646-UCS-2"}),
-        new Charset("UnicodeLittleUnmarked", "UTF-16LE", new String[] {"UTF_16LE", "X-UTF-16LE"}),
-        new Charset("Big5", "Big5", new String[] {"csBig5", "CN-Big5", "BIG-FIVE", "BIGFIVE"}),
-        new Charset("Big5_HKSCS", "Big5-HKSCS", new String[] {"big5hkscs"}),
-        new Charset("EUC_JP", "EUC-JP",
-                    new String[] {"csEUCPkdFmtJapanese",
-                              "Extended_UNIX_Code_Packed_Format_for_Japanese",
-                              "eucjis", "x-eucjp", "eucjp", "x-euc-jp"}),
-        new Charset("EUC_KR", "EUC-KR",
-                    new String[] {"csEUCKR", "ksc5601", "5601", "ksc5601_1987",
-                                  "ksc_5601", "ksc5601-1987", "ks_c_5601-1987",
-                                  "euckr"}),
-        new Charset("GB18030", "GB18030", new String[] {"gb18030-2000"}),
-        new Charset("EUC_CN", "GB2312", new String[] {"x-EUC-CN", "csGB2312", "euccn", "euc-cn", "gb2312-80", "gb2312-1980", "CN-GB", "CN-GB-ISOIR165"}),
-        new Charset("GBK", "windows-936", new String[] {"CP936", "MS936", "ms_936", "x-mswin-936"}),
-
-        new Charset("Cp037", "IBM037", new String[] {"ebcdic-cp-us", "ebcdic-cp-ca", "ebcdic-cp-wt", "ebcdic-cp-nl", "csIBM037"}),
-        new Charset("Cp273", "IBM273", new String[] {"csIBM273"}),
-        new Charset("Cp277", "IBM277", new String[] {"EBCDIC-CP-DK", "EBCDIC-CP-NO", "csIBM277"}),
-        new Charset("Cp278", "IBM278", new String[] {"CP278", "ebcdic-cp-fi", "ebcdic-cp-se", "csIBM278"}),
-        new Charset("Cp280", "IBM280", new String[] {"ebcdic-cp-it", "csIBM280"}),
-        new Charset("Cp284", "IBM284", new String[] {"ebcdic-cp-es", "csIBM284"}),
-        new Charset("Cp285", "IBM285", new String[] {"ebcdic-cp-gb", "csIBM285"}),
-        new Charset("Cp297", "IBM297", new String[] {"ebcdic-cp-fr", "csIBM297"}),
-        new Charset("Cp420", "IBM420", new String[] {"ebcdic-cp-ar1", "csIBM420"}),
-        new Charset("Cp424", "IBM424", new String[] {"ebcdic-cp-he", "csIBM424"}),
-        new Charset("Cp437", "IBM437", new String[] {"437", "csPC8CodePage437"}),
-        new Charset("Cp500", "IBM500", new String[] {"ebcdic-cp-be", "ebcdic-cp-ch", "csIBM500"}),
-        new Charset("Cp775", "IBM775", new String[] {"csPC775Baltic"}),
-        new Charset("Cp838", "IBM-Thai", new String[] {}),
-        new Charset("Cp850", "IBM850", new String[] {"850", "csPC850Multilingual"}),
-        new Charset("Cp852", "IBM852", new String[] {"852", "csPCp852"}),
-        new Charset("Cp855", "IBM855", new String[] {"855", "csIBM855"}),
-        new Charset("Cp857", "IBM857", new String[] {"857", "csIBM857"}),
-        new Charset("Cp858", "IBM00858",
-                new String[] {"CCSID00858", "CP00858",
-                              "PC-Multilingual-850+euro"}),
-        new Charset("Cp860", "IBM860", new String[] {"860", "csIBM860"}),
-        new Charset("Cp861", "IBM861", new String[] {"861", "cp-is", "csIBM861"}),
-        new Charset("Cp862", "IBM862", new String[] {"862", "csPC862LatinHebrew"}),
-        new Charset("Cp863", "IBM863", new String[] {"863", "csIBM863"}),
-        new Charset("Cp864", "IBM864", new String[] {"cp864", "csIBM864"}),
-        new Charset("Cp865", "IBM865", new String[] {"865", "csIBM865"}),
-        new Charset("Cp866", "IBM866", new String[] {"866", "csIBM866"}),
-        new Charset("Cp868", "IBM868", new String[] {"cp-ar", "csIBM868"}),
-        new Charset("Cp869", "IBM869", new String[] {"cp-gr", "csIBM869"}),
-        new Charset("Cp870", "IBM870", new String[] {"ebcdic-cp-roece", "ebcdic-cp-yu", "csIBM870"}),
-        new Charset("Cp871", "IBM871", new String[] {"ebcdic-cp-is", "csIBM871"}),
-        new Charset("Cp918", "IBM918", new String[] {"ebcdic-cp-ar2", "csIBM918"}),
-        new Charset("Cp1026", "IBM1026", new String[] {"csIBM1026"}),
-        new Charset("Cp1047", "IBM1047", new String[] {"IBM-1047"}),
-        new Charset("Cp1140", "IBM01140",
-                    new String[] {"CCSID01140", "CP01140",
-                                  "ebcdic-us-37+euro"}),
-        new Charset("Cp1141", "IBM01141",
-                    new String[] {"CCSID01141", "CP01141",
-                                  "ebcdic-de-273+euro"}),
-        new Charset("Cp1142", "IBM01142", new String[] {"CCSID01142", "CP01142", "ebcdic-dk-277+euro", "ebcdic-no-277+euro"}),
-        new Charset("Cp1143", "IBM01143", new String[] {"CCSID01143", "CP01143", "ebcdic-fi-278+euro", "ebcdic-se-278+euro"}),
-        new Charset("Cp1144", "IBM01144", new String[] {"CCSID01144", "CP01144", "ebcdic-it-280+euro"}),
-        new Charset("Cp1145", "IBM01145", new String[] {"CCSID01145", "CP01145", "ebcdic-es-284+euro"}),
-        new Charset("Cp1146", "IBM01146", new String[] {"CCSID01146", "CP01146", "ebcdic-gb-285+euro"}),
-        new Charset("Cp1147", "IBM01147", new String[] {"CCSID01147", "CP01147", "ebcdic-fr-297+euro"}),
-        new Charset("Cp1148", "IBM01148", new String[] {"CCSID01148", "CP01148", "ebcdic-international-500+euro"}),
-        new Charset("Cp1149", "IBM01149", new String[] {"CCSID01149", "CP01149", "ebcdic-is-871+euro"}),
-        new Charset("Cp1250", "windows-1250", new String[] {}),
-        new Charset("Cp1251", "windows-1251", new String[] {}),
-        new Charset("Cp1252", "windows-1252", new String[] {}),
-        new Charset("Cp1253", "windows-1253", new String[] {}),
-        new Charset("Cp1254", "windows-1254", new String[] {}),
-        new Charset("Cp1255", "windows-1255", new String[] {}),
-        new Charset("Cp1256", "windows-1256", new String[] {}),
-        new Charset("Cp1257", "windows-1257", new String[] {}),
-        new Charset("Cp1258", "windows-1258", new String[] {}),
-        new Charset("ISO2022CN", "ISO-2022-CN", new String[] {}),
-        new Charset("ISO2022JP", "ISO-2022-JP", new String[] {"csISO2022JP", "JIS", "jis_encoding", "csjisencoding"}),
-        new Charset("ISO2022KR", "ISO-2022-KR", new String[] {"csISO2022KR"}),
-        new Charset("JIS_X0201", "JIS_X0201", new String[] {"X0201", "JIS0201", "csHalfWidthKatakana"}),
-        new Charset("JIS_X0212-1990", "JIS_X0212-1990", new String[] {"iso-ir-159", "x0212", "JIS0212", "csISO159JISX02121990"}),
-        new Charset("JIS_C6626-1983", "JIS_C6626-1983", new String[] {"x-JIS0208", "JIS0208", "csISO87JISX0208", "x0208", "JIS_X0208-1983", "iso-ir-87"}),
-        new Charset("SJIS", "Shift_JIS", new String[] {"MS_Kanji", "csShiftJIS", "shift-jis", "x-sjis", "pck"}),
-        new Charset("TIS620", "TIS-620", new String[] {}),
-        new Charset("MS932", "Windows-31J", new String[] {"windows-932", "csWindows31J", "x-ms-cp932"}),
-        new Charset("EUC_TW", "EUC-TW", new String[] {"x-EUC-TW", "cns11643", "euctw"}),
-        new Charset("x-Johab", "johab", new String[] {"johab", "cp1361", "ms1361", "ksc5601-1992", "ksc5601_1992"}),
-        new Charset("MS950_HKSCS", "", new String[] {}),
-        new Charset("MS874", "windows-874", new String[] {"cp874"}),
-        new Charset("MS949", "windows-949", new String[] {"windows949", "ms_949", "x-windows-949"}),
-        new Charset("MS950", "windows-950", new String[] {"x-windows-950"}),
-
-        new Charset("Cp737", null, new String[] {}),
-        new Charset("Cp856", null, new String[] {}),
-        new Charset("Cp875", null, new String[] {}),
-        new Charset("Cp921", null, new String[] {}),
-        new Charset("Cp922", null, new String[] {}),
-        new Charset("Cp930", null, new String[] {}),
-        new Charset("Cp933", null, new String[] {}),
-        new Charset("Cp935", null, new String[] {}),
-        new Charset("Cp937", null, new String[] {}),
-        new Charset("Cp939", null, new String[] {}),
-        new Charset("Cp942", null, new String[] {}),
-        new Charset("Cp942C", null, new String[] {}),
-        new Charset("Cp943", null, new String[] {}),
-        new Charset("Cp943C", null, new String[] {}),
-        new Charset("Cp948", null, new String[] {}),
-        new Charset("Cp949", null, new String[] {}),
-        new Charset("Cp949C", null, new String[] {}),
-        new Charset("Cp950", null, new String[] {}),
-        new Charset("Cp964", null, new String[] {}),
-        new Charset("Cp970", null, new String[] {}),
-        new Charset("Cp1006", null, new String[] {}),
-        new Charset("Cp1025", null, new String[] {}),
-        new Charset("Cp1046", null, new String[] {}),
-        new Charset("Cp1097", null, new String[] {}),
-        new Charset("Cp1098", null, new String[] {}),
-        new Charset("Cp1112", null, new String[] {}),
-        new Charset("Cp1122", null, new String[] {}),
-        new Charset("Cp1123", null, new String[] {}),
-        new Charset("Cp1124", null, new String[] {}),
-        new Charset("Cp1381", null, new String[] {}),
-        new Charset("Cp1383", null, new String[] {}),
-        new Charset("Cp33722", null, new String[] {}),
-        new Charset("Big5_Solaris", null, new String[] {}),
-        new Charset("EUC_JP_LINUX", null, new String[] {}),
-        new Charset("EUC_JP_Solaris", null, new String[] {}),
-        new Charset("ISCII91", null, new String[] {"x-ISCII91", "iscii"}),
-        new Charset("ISO2022_CN_CNS", null, new String[] {}),
-        new Charset("ISO2022_CN_GB", null, new String[] {}),
-        new Charset("x-iso-8859-11", null, new String[] {}),
-        new Charset("JISAutoDetect", null, new String[] {}),
-        new Charset("MacArabic", null, new String[] {}),
-        new Charset("MacCentralEurope", null, new String[] {}),
-        new Charset("MacCroatian", null, new String[] {}),
-        new Charset("MacCyrillic", null, new String[] {}),
-        new Charset("MacDingbat", null, new String[] {}),
-        new Charset("MacGreek", "MacGreek", new String[] {}),
-        new Charset("MacHebrew", null, new String[] {}),
-        new Charset("MacIceland", null, new String[] {}),
-        new Charset("MacRoman", "MacRoman", new String[] {"Macintosh", "MAC", "csMacintosh"}),
-        new Charset("MacRomania", null, new String[] {}),
-        new Charset("MacSymbol", null, new String[] {}),
-        new Charset("MacThai", null, new String[] {}),
-        new Charset("MacTurkish", null, new String[] {}),
-        new Charset("MacUkraine", null, new String[] {}),
-        new Charset("UnicodeBig", null, new String[] {}),
-        new Charset("UnicodeLittle", null, new String[] {})
-    };
-
-    /**
-     * Contains the canonical names of character sets which can be used to
-     * decode bytes into Java chars.
-     */
-    private static TreeSet<String> decodingSupported = null;
-
-    /**
-     * Contains the canonical names of character sets which can be used to
-     * encode Java chars into bytes.
-     */
-    private static TreeSet<String> encodingSupported = null;
-
-    /**
-     * Maps character set names to Charset objects. All possible names of
-     * a charset will be mapped to the Charset.
-     */
-    private static HashMap<String, Charset> charsetMap = null;
-
-    static {
-        decodingSupported = new TreeSet<String>();
-        encodingSupported = new TreeSet<String>();
-        byte[] dummy = new byte[] {'d', 'u', 'm', 'm', 'y'};
-        for (int i = 0; i < JAVA_CHARSETS.length; i++) {
-            try {
-                String s = new String(dummy, JAVA_CHARSETS[i].canonical);
-                decodingSupported.add(JAVA_CHARSETS[i].canonical.toLowerCase(Locale.US));
-            } catch (UnsupportedOperationException e) {
-            } catch (UnsupportedEncodingException e) {
-            }
-            try {
-                "dummy".getBytes(JAVA_CHARSETS[i].canonical);
-                encodingSupported.add(JAVA_CHARSETS[i].canonical.toLowerCase(Locale.US));
-            } catch (UnsupportedOperationException e) {
-            } catch (UnsupportedEncodingException e) {
-            }
-        }
-
-        charsetMap = new HashMap<String, Charset>();
-        for (int i = 0; i < JAVA_CHARSETS.length; i++) {
-            Charset c = JAVA_CHARSETS[i];
-            charsetMap.put(c.canonical.toLowerCase(Locale.US), c);
-            if (c.mime != null) {
-                charsetMap.put(c.mime.toLowerCase(Locale.US), c);
-            }
-            if (c.aliases != null) {
-                for (int j = 0; j < c.aliases.length; j++) {
-                    charsetMap.put(c.aliases[j].toLowerCase(Locale.US), c);
-                }
-            }
-        }
-
-        if (log.isDebugEnabled()) {
-            log.debug("Character sets which support decoding: "
-                        + decodingSupported);
-            log.debug("Character sets which support encoding: "
-                        + encodingSupported);
-        }
-    }
-
-    /**
-     * ANDROID:  THE FOLLOWING SET OF STATIC STRINGS ARE COPIED FROM A NEWER VERSION OF MIME4J
-     */
-
-    /** carriage return - line feed sequence */
-    public static final String CRLF = "\r\n";
-
-    /** US-ASCII CR, carriage return (13) */
-    public static final int CR = '\r';
-
-    /** US-ASCII LF, line feed (10) */
-    public static final int LF = '\n';
-
-    /** US-ASCII SP, space (32) */
-    public static final int SP = ' ';
-
-    /** US-ASCII HT, horizontal-tab (9)*/
-    public static final int HT = '\t';
-
-    public static final java.nio.charset.Charset US_ASCII = java.nio.charset.Charset
-            .forName("US-ASCII");
-
-    public static final java.nio.charset.Charset ISO_8859_1 = java.nio.charset.Charset
-            .forName("ISO-8859-1");
-
-    public static final java.nio.charset.Charset UTF_8 = java.nio.charset.Charset
-            .forName("UTF-8");
-
-    /**
-     * Returns <code>true</code> if the specified character is a whitespace
-     * character (CR, LF, SP or HT).
-     *
-     * ANDROID:  COPIED FROM A NEWER VERSION OF MIME4J
-     *
-     * @param ch
-     *            character to test.
-     * @return <code>true</code> if the specified character is a whitespace
-     *         character, <code>false</code> otherwise.
-     */
-    public static boolean isWhitespace(char ch) {
-        return ch == SP || ch == HT || ch == CR || ch == LF;
-    }
-
-    /**
-     * Returns <code>true</code> if the specified string consists entirely of
-     * whitespace characters.
-     *
-     * ANDROID:  COPIED FROM A NEWER VERSION OF MIME4J
-     *
-     * @param s
-     *            string to test.
-     * @return <code>true</code> if the specified string consists entirely of
-     *         whitespace characters, <code>false</code> otherwise.
-     */
-    public static boolean isWhitespace(final String s) {
-        if (s == null) {
-            throw new IllegalArgumentException("String may not be null");
-        }
-        final int len = s.length();
-        for (int i = 0; i < len; i++) {
-            if (!isWhitespace(s.charAt(i))) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    /**
-     * Determines if the VM supports encoding (chars to bytes) the
-     * specified character set. NOTE: the given character set name may
-     * not be known to the VM even if this method returns <code>true</code>.
-     * Use {@link #toJavaCharset(String)} to get the canonical Java character
-     * set name.
-     *
-     * @param charsetName the characters set name.
-     * @return <code>true</code> if encoding is supported, <code>false</code>
-     *         otherwise.
-     */
-    public static boolean isEncodingSupported(String charsetName) {
-        return encodingSupported.contains(charsetName.toLowerCase(Locale.US));
-    }
-
-    /**
-     * Determines if the VM supports decoding (bytes to chars) the
-     * specified character set. NOTE: the given character set name may
-     * not be known to the VM even if this method returns <code>true</code>.
-     * Use {@link #toJavaCharset(String)} to get the canonical Java character
-     * set name.
-     *
-     * @param charsetName the characters set name.
-     * @return <code>true</code> if decoding is supported, <code>false</code>
-     *         otherwise.
-     */
-    public static boolean isDecodingSupported(String charsetName) {
-        return decodingSupported.contains(charsetName.toLowerCase(Locale.US));
-    }
-
-    /**
-     * Gets the preferred MIME character set name for the specified
-     * character set or <code>null</code> if not known.
-     *
-     * @param charsetName the character set name to look for.
-     * @return the MIME preferred name or <code>null</code> if not known.
-     */
-    public static String toMimeCharset(String charsetName) {
-        Charset c = charsetMap.get(charsetName.toLowerCase(Locale.US));
-        if (c != null) {
-            return c.mime;
-        }
-        return null;
-    }
-
-    /**
-     * Gets the canonical Java character set name for the specified
-     * character set or <code>null</code> if not known. This should be
-     * called before doing any conversions using the Java API. NOTE:
-     * you must use {@link #isEncodingSupported(String)} or
-     * {@link #isDecodingSupported(String)} to make sure the returned
-     * Java character set is supported by the current VM.
-     *
-     * @param charsetName the character set name to look for.
-     * @return the canonical Java name or <code>null</code> if not known.
-     */
-    public static String toJavaCharset(String charsetName) {
-        Charset c = charsetMap.get(charsetName.toLowerCase(Locale.US));
-        if (c != null) {
-            return c.canonical;
-        }
-        return null;
-    }
-
-    public static java.nio.charset.Charset getCharset(String charsetName) {
-        String defaultCharset = "ISO-8859-1";
-
-        // Use the default chareset if given charset is null
-        if(charsetName == null) charsetName = defaultCharset;
-
-        try {
-            return java.nio.charset.Charset.forName(charsetName);
-        } catch (IllegalCharsetNameException e) {
-            log.info("Illegal charset " + charsetName + ", fallback to " +
-                    defaultCharset + ": " + e);
-            // Use default charset on exception
-            return java.nio.charset.Charset.forName(defaultCharset);
-        } catch (UnsupportedCharsetException ex) {
-            log.info("Unsupported charset " + charsetName + ", fallback to " +
-                    defaultCharset + ": " + ex);
-            // Use default charset on exception
-            return java.nio.charset.Charset.forName(defaultCharset);
-        }
-
-    }
-    /*
-     * Uncomment the code below and run the main method to regenerate the
-     * Javadoc table above when the known charsets change.
-     */
-
-    /*
-    private static String dumpHtmlTable() {
-        LinkedList l = new LinkedList(Arrays.asList(JAVA_CHARSETS));
-        Collections.sort(l);
-        StringBuffer sb = new StringBuffer();
-        sb.append(" * <table>\n");
-        sb.append(" *     <tr>\n");
-        sb.append(" *         <td>Canonical (Java) name</td>\n");
-        sb.append(" *         <td>MIME preferred</td>\n");
-        sb.append(" *         <td>Aliases</td>\n");
-        sb.append(" *     </tr>\n");
-
-        for (Iterator it = l.iterator(); it.hasNext();) {
-            Charset c = (Charset) it.next();
-            sb.append(" *     <tr>\n");
-            sb.append(" *         <td>" + c.canonical + "</td>\n");
-            sb.append(" *         <td>" + (c.mime == null ? "?" : c.mime)+ "</td>\n");
-            sb.append(" *         <td>");
-            for (int i = 0; c.aliases != null && i < c.aliases.length; i++) {
-                sb.append(c.aliases[i] + " ");
-            }
-            sb.append("</td>\n");
-            sb.append(" *     </tr>\n");
-        }
-        sb.append(" * </table>\n");
-        return sb.toString();
-    }
-
-    public static void main(String[] args) {
-        System.out.println(dumpHtmlTable());
-    }*/
-}
\ No newline at end of file
