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
