diff --git a/src/com/android/phone/CallFeaturesSetting.java b/src/com/android/phone/CallFeaturesSetting.java
index 3bb3080..b88d8f1 100644
--- a/src/com/android/phone/CallFeaturesSetting.java
+++ b/src/com/android/phone/CallFeaturesSetting.java
@@ -25,18 +25,13 @@
 import android.content.Context;
 import android.content.DialogInterface;
 import android.content.Intent;
-import android.database.Cursor;
-import android.os.AsyncResult;
 import android.os.Bundle;
-import android.os.Handler;
-import android.os.Message;
 import android.os.UserHandle;
 import android.preference.CheckBoxPreference;
 import android.preference.ListPreference;
 import android.preference.Preference;
 import android.preference.PreferenceActivity;
 import android.preference.PreferenceScreen;
-import android.provider.ContactsContract.CommonDataKinds;
 import android.provider.Settings;
 import android.telecom.PhoneAccountHandle;
 import android.telecom.TelecomManager;
@@ -44,7 +39,6 @@
 import android.text.TextUtils;
 import android.util.Log;
 import android.view.MenuItem;
-import android.widget.ListAdapter;
 import android.widget.Toast;
 
 import com.android.ims.ImsConfig;
@@ -54,26 +48,13 @@
 import com.android.internal.telephony.PhoneConstants;
 import com.android.phone.common.util.SettingsUtil;
 import com.android.phone.settings.AccountSelectionPreference;
-import com.android.phone.settings.CallForwardInfoUtil;
-import com.android.phone.settings.SettingsConstants;
-import com.android.phone.settings.VoicemailDialogUtil;
-import com.android.phone.settings.VoicemailNotificationSettingsUtil;
-import com.android.phone.settings.VoicemailProviderListPreference;
-import com.android.phone.settings.VoicemailProviderListPreference.VoicemailProvider;
-import com.android.phone.settings.VoicemailProviderSettings;
-import com.android.phone.settings.VoicemailProviderSettingsUtil;
-import com.android.phone.settings.VoicemailRingtonePreference;
+import com.android.phone.settings.VoicemailSettingsActivity;
 import com.android.phone.settings.fdn.FdnSetting;
 import com.android.services.telephony.sip.SipUtil;
 
 import java.lang.String;
 import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
 import java.util.List;
-import java.util.Map;
 
 /**
  * Top level "Call settings" UI; see res/xml/call_feature_setting.xml
@@ -90,57 +71,15 @@
  * For the "Mobile network settings" screen under the main Settings app,
  * See {@link MobileNetworkSettings}.
  *
- * TODO: Settings should be split into PreferenceFragments where possible (ie. voicemail).
- *
  * @see com.android.phone.MobileNetworkSettings
  */
 public class CallFeaturesSetting extends PreferenceActivity
-        implements DialogInterface.OnClickListener,
-                Preference.OnPreferenceChangeListener,
-                EditPhoneNumberPreference.OnDialogClosedListener,
-                EditPhoneNumberPreference.GetDefaultNumberListener {
+        implements Preference.OnPreferenceChangeListener {
     private static final String LOG_TAG = "CallFeaturesSetting";
     private static final boolean DBG = (PhoneGlobals.DBG_LEVEL >= 2);
     // STOPSHIP if true. Flag to override behavior default behavior to hide VT setting.
     private static final boolean ENABLE_VT_FLAG = false;
 
-    /**
-     * Intent action to bring up Voicemail Provider settings.
-     *
-     * @see #IGNORE_PROVIDER_EXTRA
-     */
-    public static final String ACTION_ADD_VOICEMAIL =
-            "com.android.phone.CallFeaturesSetting.ADD_VOICEMAIL";
-    // intent action sent by this activity to a voice mail provider
-    // to trigger its configuration UI
-    public static final String ACTION_CONFIGURE_VOICEMAIL =
-            "com.android.phone.CallFeaturesSetting.CONFIGURE_VOICEMAIL";
-    // Extra put in the return from VM provider config containing voicemail number to set
-    public static final String VM_NUMBER_EXTRA = "com.android.phone.VoicemailNumber";
-    // Extra put in the return from VM provider config containing call forwarding number to set
-    public static final String FWD_NUMBER_EXTRA = "com.android.phone.ForwardingNumber";
-    // Extra put in the return from VM provider config containing call forwarding number to set
-    public static final String FWD_NUMBER_TIME_EXTRA = "com.android.phone.ForwardingNumberTime";
-    // If the VM provider returns non null value in this extra we will force the user to
-    // choose another VM provider
-    public static final String SIGNOUT_EXTRA = "com.android.phone.Signout";
-
-    /**
-     * String Extra put into ACTION_ADD_VOICEMAIL call to indicate which provider should be hidden
-     * in the list of providers presented to the user. This allows a provider which is being
-     * disabled (e.g. GV user logging out) to force the user to pick some other provider.
-     */
-    public static final String IGNORE_PROVIDER_EXTRA = "com.android.phone.ProviderToIgnore";
-
-    /**
-     * String Extra put into ACTION_ADD_VOICEMAIL to indicate that the voicemail setup screen should
-     * be opened.
-     */
-    public static final String SETUP_VOICEMAIL_EXTRA = "com.android.phone.SetupVoicemail";
-
-    // string constants
-    private static final String NUM_PROJECTION[] = {CommonDataKinds.Phone.NUMBER};
-
     // String keys for preference lookup
     // TODO: Naming these "BUTTON_*" is confusing since they're not actually buttons(!)
     // TODO: Consider moving these strings to strings.xml, so that they are not duplicated here and
@@ -148,13 +87,8 @@
     // persistent, they are used as the key to store shared preferences and the name should not be
     // changed unless the settings are also migrated.
     private static final String VOICEMAIL_SETTING_SCREEN_PREF_KEY = "button_voicemail_category_key";
-    private static final String BUTTON_VOICEMAIL_KEY = "button_voicemail_key";
-    private static final String BUTTON_VOICEMAIL_PROVIDER_KEY = "button_voicemail_provider_key";
-    private static final String BUTTON_VOICEMAIL_SETTING_KEY = "button_voicemail_setting_key";
     private static final String BUTTON_FDN_KEY   = "button_fdn_key";
-
     private static final String BUTTON_RETRY_KEY       = "button_auto_retry_key";
-
     private static final String BUTTON_GSM_UMTS_OPTIONS = "button_gsm_more_expand_key";
     private static final String BUTTON_CDMA_OPTIONS = "button_cdma_more_expand_key";
     private static final String CALL_FORWARDING_KEY = "call_forwarding_key";
@@ -165,119 +99,13 @@
 
     private static final String ENABLE_VIDEO_CALLING_KEY = "button_enable_video_calling";
 
-    /** Event for Async voicemail change call */
-    private static final int EVENT_VOICEMAIL_CHANGED        = 500;
-    private static final int EVENT_FORWARDING_CHANGED       = 501;
-    private static final int EVENT_FORWARDING_GET_COMPLETED = 502;
-
-    /** Handle to voicemail pref */
-    private static final int VOICEMAIL_PREF_ID = 1;
-    private static final int VOICEMAIL_PROVIDER_CFG_ID = 2;
-
     private Phone mPhone;
-
     private SubscriptionInfoHelper mSubscriptionInfoHelper;
 
-    private EditPhoneNumberPreference mSubMenuVoicemailSettings;
-
     private CheckBoxPreference mButtonAutoRetry;
-    private VoicemailProviderListPreference mVoicemailProviders;
     private PreferenceScreen mVoicemailSettingsScreen;
-    private PreferenceScreen mVoicemailSettings;
-    private VoicemailRingtonePreference mVoicemailNotificationRingtone;
-    private CheckBoxPreference mVoicemailNotificationVibrate;
     private CheckBoxPreference mEnableVideoCalling;
 
-    /**
-     * Results of reading forwarding settings
-     */
-    private CallForwardInfo[] mForwardingReadResults = null;
-
-    /**
-     * Result of forwarding number change.
-     * Keys are reasons (eg. unconditional forwarding).
-     */
-    private Map<Integer, AsyncResult> mForwardingChangeResults = null;
-
-    /**
-     * Expected CF read result types.
-     * This set keeps track of the CF types for which we've issued change
-     * commands so we can tell when we've received all of the responses.
-     */
-    private Collection<Integer> mExpectedChangeResultReasons = null;
-
-    /**
-     * Result of vm number change
-     */
-    private AsyncResult mVoicemailChangeResult = null;
-
-    /**
-     * Previous VM provider setting so we can return to it in case of failure.
-     */
-    private String mPreviousVMProviderKey = null;
-
-    /**
-     * Id of the dialog being currently shown.
-     */
-    private int mCurrentDialogId = 0;
-
-    /**
-     * Flag indicating that we are invoking settings for the voicemail provider programmatically
-     * due to vm provider change.
-     */
-    private boolean mVMProviderSettingsForced = false;
-
-    /**
-     * Flag indicating that we are making changes to vm or fwd numbers
-     * due to vm provider change.
-     */
-    private boolean mChangingVMorFwdDueToProviderChange = false;
-
-    /**
-     * True if we are in the process of vm & fwd number change and vm has already been changed.
-     * This is used to decide what to do in case of rollback.
-     */
-    private boolean mVMChangeCompletedSuccessfully = false;
-
-    /**
-     * True if we had full or partial failure setting forwarding numbers and so need to roll them
-     * back.
-     */
-    private boolean mFwdChangesRequireRollback = false;
-
-    /**
-     * Id of error msg to display to user once we are done reverting the VM provider to the previous
-     * one.
-     */
-    private int mVMOrFwdSetError = 0;
-
-    /** string to hold old voicemail number as it is being updated. */
-    private String mOldVmNumber;
-
-    // New call forwarding settings and vm number we will be setting
-    // Need to save these since before we get to saving we need to asynchronously
-    // query the existing forwarding settings.
-    private CallForwardInfo[] mNewFwdSettings;
-    private String mNewVMNumber;
-
-    private boolean mForeground;
-
-    @Override
-    public void onPause() {
-        super.onPause();
-        mForeground = false;
-    }
-
-    /**
-     * Used to indicate that the voicemail preference should be shown.
-     */
-    private boolean mShowVoicemailPreference = false;
-
-    /**
-     * Used to indicate that the voicemail setup screen should be shown.
-     */
-    private boolean mSetupVoicemail = false;
-
     /*
      * Click Listeners, handle click based on objects attached to UI.
      */
@@ -285,44 +113,11 @@
     // Click listener for all toggle events
     @Override
     public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
-        if (preference == mSubMenuVoicemailSettings) {
-            return true;
-        } else if (preference == mButtonAutoRetry) {
+        if (preference == mButtonAutoRetry) {
             android.provider.Settings.Global.putInt(mPhone.getContext().getContentResolver(),
                     android.provider.Settings.Global.CALL_AUTO_RETRY,
                     mButtonAutoRetry.isChecked() ? 1 : 0);
             return true;
-        } else if (preference.getKey().equals(mVoicemailSettings.getKey())) {
-            // Check key instead of comparing reference because closing the voicemail notification
-            // ringtone dialog invokes onResume(), but leaves the old preference screen up,
-            // TODO: Revert to checking reference after migrating voicemail to its own activity.
-            if (DBG) log("onPreferenceTreeClick: Voicemail Settings Preference is clicked.");
-
-            final Dialog dialog = ((PreferenceScreen) preference).getDialog();
-            if (dialog != null) {
-                dialog.getActionBar().setDisplayHomeAsUpEnabled(false);
-            }
-
-            if (preference.getIntent() != null) {
-                if (DBG) log("Invoking cfg intent " + preference.getIntent().getPackage());
-
-                // onActivityResult() will be responsible for resetting some of variables.
-                this.startActivityForResult(preference.getIntent(), VOICEMAIL_PROVIDER_CFG_ID);
-                return true;
-            } else {
-                if (DBG) log("onPreferenceTreeClick(). No intent; use default behavior in xml.");
-
-                // onActivityResult() will not be called, so reset variables here.
-                mPreviousVMProviderKey = VoicemailProviderListPreference.DEFAULT_KEY;
-                mVMProviderSettingsForced = false;
-                return false;
-            }
-        } else if (preference == mVoicemailSettingsScreen) {
-            final Dialog dialog = mVoicemailSettingsScreen.getDialog();
-            if (dialog != null) {
-                dialog.getActionBar().setDisplayHomeAsUpEnabled(false);
-            }
-            return false;
         }
         return false;
     }
@@ -339,40 +134,7 @@
     public boolean onPreferenceChange(Preference preference, Object objValue) {
         if (DBG) log("onPreferenceChange: \"" + preference + "\" changed to \"" + objValue + "\"");
 
-        if (preference == mVoicemailProviders) {
-            final String newProviderKey = (String) objValue;
-
-            // If previous provider key and the new one is same, we don't need to handle it.
-            if (mPreviousVMProviderKey.equals(newProviderKey)) {
-                if (DBG) log("No change is made to the VM provider setting.");
-                return true;
-            }
-            updateVMPreferenceWidgets(newProviderKey);
-
-            final VoicemailProviderSettings newProviderSettings =
-                    VoicemailProviderSettingsUtil.load(this, newProviderKey);
-
-            // If the user switches to a voice mail provider and we have numbers stored for it we
-            // will automatically change the phone's voice mail and forwarding number to the stored
-            // ones. Otherwise we will bring up provider's configuration UI.
-            if (newProviderSettings == null) {
-                // Force the user into a configuration of the chosen provider
-                Log.w(LOG_TAG, "Saved preferences not found - invoking config");
-                mVMProviderSettingsForced = true;
-                simulatePreferenceClick(mVoicemailSettings);
-            } else {
-                if (DBG) log("Saved preferences found - switching to them");
-                // Set this flag so if we get a failure we revert to previous provider
-                mChangingVMorFwdDueToProviderChange = true;
-                saveVoiceMailAndForwardingNumber(newProviderKey, newProviderSettings);
-            }
-        } else if (preference.getKey().equals(mVoicemailNotificationVibrate.getKey())) {
-            // Check key instead of comparing reference because closing the voicemail notification
-            // ringtone dialog invokes onResume(), but leaves the old preference screen up,
-            // TODO: Revert to checking reference after migrating voicemail to its own activity.
-            VoicemailNotificationSettingsUtil.setVibrationEnabled(
-                    mPhone, Boolean.TRUE.equals(objValue));
-        } else if (preference == mEnableVideoCalling) {
+        if (preference == mEnableVideoCalling) {
             if (ImsManager.isEnhanced4gLteModeSettingEnabledByUser(mPhone.getContext())) {
                 PhoneGlobals.getInstance().phoneMgr.enableVideoCalling((boolean) objValue);
             } else {
@@ -401,667 +163,6 @@
     }
 
     @Override
-    public void onDialogClosed(EditPhoneNumberPreference preference, int buttonClicked) {
-        if (DBG) log("onDialogClosed: Button clicked is " + buttonClicked);
-
-        if (buttonClicked == DialogInterface.BUTTON_NEGATIVE) {
-            return;
-        }
-
-        if (preference == mSubMenuVoicemailSettings) {
-            VoicemailProviderSettings newSettings = new VoicemailProviderSettings(
-                    mSubMenuVoicemailSettings.getPhoneNumber(),
-                    VoicemailProviderSettings.NO_FORWARDING);
-            saveVoiceMailAndForwardingNumber(mVoicemailProviders.getKey(), newSettings);
-        }
-    }
-
-    /**
-     * Implemented for EditPhoneNumberPreference.GetDefaultNumberListener.
-     * This method set the default values for the various
-     * EditPhoneNumberPreference dialogs.
-     */
-    @Override
-    public String onGetDefaultNumber(EditPhoneNumberPreference preference) {
-        if (preference == mSubMenuVoicemailSettings) {
-            // update the voicemail number field, which takes care of the
-            // mSubMenuVoicemailSettings itself, so we should return null.
-            if (DBG) log("updating default for voicemail dialog");
-            updateVoiceNumberField();
-            return null;
-        }
-
-        String vmDisplay = mPhone.getVoiceMailNumber();
-        if (TextUtils.isEmpty(vmDisplay)) {
-            // if there is no voicemail number, we just return null to
-            // indicate no contribution.
-            return null;
-        }
-
-        // Return the voicemail number prepended with "VM: "
-        if (DBG) log("updating default for call forwarding dialogs");
-        return getString(R.string.voicemail_abbreviated) + " " + vmDisplay;
-    }
-
-    private void switchToPreviousVoicemailProvider() {
-        if (DBG) log("switchToPreviousVoicemailProvider " + mPreviousVMProviderKey);
-
-        if (mPreviousVMProviderKey == null) {
-            return;
-        }
-
-        if (mVMChangeCompletedSuccessfully || mFwdChangesRequireRollback) {
-            showDialogIfForeground(VoicemailDialogUtil.VM_REVERTING_DIALOG);
-            final VoicemailProviderSettings prevSettings =
-                    VoicemailProviderSettingsUtil.load(this, mPreviousVMProviderKey);
-            if (prevSettings == null) {
-                Log.e(LOG_TAG, "VoicemailProviderSettings for the key \""
-                        + mPreviousVMProviderKey + "\" is null but should be loaded.");
-            }
-
-            if (mVMChangeCompletedSuccessfully) {
-                mNewVMNumber = prevSettings.getVoicemailNumber();
-                Log.i(LOG_TAG, "VM change is already completed successfully."
-                        + "Have to revert VM back to " + mNewVMNumber + " again.");
-                mPhone.setVoiceMailNumber(
-                        mPhone.getVoiceMailAlphaTag().toString(),
-                        mNewVMNumber,
-                        Message.obtain(mRevertOptionComplete, EVENT_VOICEMAIL_CHANGED));
-            }
-
-            if (mFwdChangesRequireRollback) {
-                Log.i(LOG_TAG, "Requested to rollback forwarding changes.");
-
-                final CallForwardInfo[] prevFwdSettings = prevSettings.getForwardingSettings();
-                if (prevFwdSettings != null) {
-                    Map<Integer, AsyncResult> results = mForwardingChangeResults;
-                    resetForwardingChangeState();
-                    for (int i = 0; i < prevFwdSettings.length; i++) {
-                        CallForwardInfo fi = prevFwdSettings[i];
-                        if (DBG) log("Reverting fwd #: " + i + ": " + fi.toString());
-                        // Only revert the settings for which the update succeeded.
-                        AsyncResult result = results.get(fi.reason);
-                        if (result != null && result.exception == null) {
-                            mExpectedChangeResultReasons.add(fi.reason);
-                            CallForwardInfoUtil.setCallForwardingOption(mPhone, fi,
-                                    mRevertOptionComplete.obtainMessage(
-                                            EVENT_FORWARDING_CHANGED, i, 0));
-                        }
-                    }
-                }
-            }
-        } else {
-            if (DBG) log("No need to revert");
-            onRevertDone();
-        }
-    }
-
-    private void onRevertDone() {
-        if (DBG) log("onRevertDone: Changing provider key back to " + mPreviousVMProviderKey);
-
-        updateVMPreferenceWidgets(mPreviousVMProviderKey);
-        updateVoiceNumberField();
-        if (mVMOrFwdSetError != 0) {
-            showDialogIfForeground(mVMOrFwdSetError);
-            mVMOrFwdSetError = 0;
-        }
-    }
-
-    @Override
-    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
-        if (DBG) {
-            log("onActivityResult: requestCode: " + requestCode
-                    + ", resultCode: " + resultCode
-                    + ", data: " + data);
-        }
-
-        // there are cases where the contact picker may end up sending us more than one
-        // request.  We want to ignore the request if we're not in the correct state.
-        if (requestCode == VOICEMAIL_PROVIDER_CFG_ID) {
-            boolean failure = false;
-
-            // No matter how the processing of result goes lets clear the flag
-            if (DBG) log("mVMProviderSettingsForced: " + mVMProviderSettingsForced);
-            final boolean isVMProviderSettingsForced = mVMProviderSettingsForced;
-            mVMProviderSettingsForced = false;
-
-            String vmNum = null;
-            if (resultCode != RESULT_OK) {
-                if (DBG) log("onActivityResult: vm provider cfg result not OK.");
-                failure = true;
-            } else {
-                if (data == null) {
-                    if (DBG) log("onActivityResult: vm provider cfg result has no data");
-                    failure = true;
-                } else {
-                    if (data.getBooleanExtra(SIGNOUT_EXTRA, false)) {
-                        if (DBG) log("Provider requested signout");
-                        if (isVMProviderSettingsForced) {
-                            if (DBG) log("Going back to previous provider on signout");
-                            switchToPreviousVoicemailProvider();
-                        } else {
-                            final String victim = mVoicemailProviders.getKey();
-                            if (DBG) log("Relaunching activity and ignoring " + victim);
-                            Intent i = new Intent(ACTION_ADD_VOICEMAIL);
-                            i.putExtra(IGNORE_PROVIDER_EXTRA, victim);
-                            i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
-                            this.startActivity(i);
-                        }
-                        return;
-                    }
-                    vmNum = data.getStringExtra(VM_NUMBER_EXTRA);
-                    if (vmNum == null || vmNum.length() == 0) {
-                        if (DBG) log("onActivityResult: vm provider cfg result has no vmnum");
-                        failure = true;
-                    }
-                }
-            }
-            if (failure) {
-                if (DBG) log("Failure in return from voicemail provider.");
-                if (isVMProviderSettingsForced) {
-                    switchToPreviousVoicemailProvider();
-                }
-
-                return;
-            }
-            mChangingVMorFwdDueToProviderChange = isVMProviderSettingsForced;
-            final String fwdNum = data.getStringExtra(FWD_NUMBER_EXTRA);
-
-            // TODO: It would be nice to load the current network setting for this and
-            // send it to the provider when it's config is invoked so it can use this as default
-            final int fwdNumTime = data.getIntExtra(FWD_NUMBER_TIME_EXTRA, 20);
-
-            if (DBG) log("onActivityResult: cfg result has forwarding number " + fwdNum);
-            saveVoiceMailAndForwardingNumber(mVoicemailProviders.getKey(),
-                    new VoicemailProviderSettings(vmNum, fwdNum, fwdNumTime));
-            return;
-        }
-
-        if (requestCode == VOICEMAIL_PREF_ID) {
-            if (resultCode != RESULT_OK) {
-                if (DBG) log("onActivityResult: contact picker result not OK.");
-                return;
-            }
-
-            Cursor cursor = null;
-            try {
-                cursor = getContentResolver().query(data.getData(),
-                    NUM_PROJECTION, null, null, null);
-                if ((cursor == null) || (!cursor.moveToFirst())) {
-                    if (DBG) log("onActivityResult: bad contact data, no results found.");
-                    return;
-                }
-                mSubMenuVoicemailSettings.onPickActivityResult(cursor.getString(0));
-                return;
-            } finally {
-                if (cursor != null) {
-                    cursor.close();
-                }
-            }
-        }
-
-        super.onActivityResult(requestCode, resultCode, data);
-    }
-
-    /**
-     * Wrapper around showDialog() that will silently do nothing if we're
-     * not in the foreground.
-     *
-     * This is useful here because most of the dialogs we display from
-     * this class are triggered by asynchronous events (like
-     * success/failure messages from the telephony layer) and it's
-     * possible for those events to come in even after the user has gone
-     * to a different screen.
-     */
-    // TODO: this is too brittle: it's still easy to accidentally add new
-    // code here that calls showDialog() directly (which will result in a
-    // WindowManager$BadTokenException if called after the activity has
-    // been stopped.)
-    //
-    // It would be cleaner to do the "if (mForeground)" check in one
-    // central place, maybe by using a single Handler for all asynchronous
-    // events (and have *that* discard events if we're not in the
-    // foreground.)
-    //
-    // Unfortunately it's not that simple, since we sometimes need to do
-    // actual work to handle these events whether or not we're in the
-    // foreground (see the Handler code in mSetOptionComplete for
-    // example.)
-    //
-    // TODO: It's a bit worrisome that we don't do anything in error cases when we're not in the
-    // foreground. Consider displaying a toast instead.
-    private void showDialogIfForeground(int id) {
-        if (mForeground) {
-            showDialog(id);
-        }
-    }
-
-    private void dismissDialogSafely(int id) {
-        try {
-            dismissDialog(id);
-        } catch (IllegalArgumentException e) {
-            // This is expected in the case where we were in the background
-            // at the time we would normally have shown the dialog, so we didn't
-            // show it.
-        }
-    }
-
-    /**
-     * TODO: Refactor to make it easier to understand what's done in the different stages.
-     */
-    private void saveVoiceMailAndForwardingNumber(
-            String key, VoicemailProviderSettings newSettings) {
-        if (DBG) log("saveVoiceMailAndForwardingNumber: " + newSettings.toString());
-        mNewVMNumber = newSettings.getVoicemailNumber();
-        mNewVMNumber = (mNewVMNumber == null) ? "" : mNewVMNumber;
-        mNewFwdSettings = newSettings.getForwardingSettings();
-
-        // Call forwarding is not suppported on CDMA.
-        if (mPhone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
-            if (DBG) log("Ignoring forwarding setting since this is CDMA phone");
-            mNewFwdSettings = VoicemailProviderSettings.NO_FORWARDING;
-        }
-
-        // Throw a warning if the voicemail is the same and we did not change forwarding.
-        if (mNewVMNumber.equals(mOldVmNumber)
-                && mNewFwdSettings == VoicemailProviderSettings.NO_FORWARDING) {
-            showDialogIfForeground(VoicemailDialogUtil.VM_NOCHANGE_ERROR_DIALOG);
-            return;
-        }
-
-        VoicemailProviderSettingsUtil.save(this, key, newSettings);
-        mVMChangeCompletedSuccessfully = false;
-        mFwdChangesRequireRollback = false;
-        mVMOrFwdSetError = 0;
-
-        if (mNewFwdSettings == VoicemailProviderSettings.NO_FORWARDING
-                || key.equals(mPreviousVMProviderKey)) {
-            if (DBG) log("Set voicemail number. No changes to forwarding number.");
-            setVoicemailNumberWithCarrier();
-        } else {
-            if (DBG) log("Reading current forwarding settings.");
-            int numSettingsReasons = VoicemailProviderSettings.FORWARDING_SETTINGS_REASONS.length;
-            mForwardingReadResults = new CallForwardInfo[numSettingsReasons];
-            for (int i = 0; i < mForwardingReadResults.length; i++) {
-                mPhone.getCallForwardingOption(
-                        VoicemailProviderSettings.FORWARDING_SETTINGS_REASONS[i],
-                        mGetOptionComplete.obtainMessage(EVENT_FORWARDING_GET_COMPLETED, i, 0));
-            }
-            showDialogIfForeground(VoicemailDialogUtil.VM_FWD_READING_DIALOG);
-        }
-
-        PhoneGlobals.getInstance().refreshMwiIndicator(mSubscriptionInfoHelper.getSubId());
-    }
-
-    private final Handler mGetOptionComplete = new Handler() {
-        @Override
-        public void handleMessage(Message msg) {
-            AsyncResult result = (AsyncResult) msg.obj;
-            switch (msg.what) {
-                case EVENT_FORWARDING_GET_COMPLETED:
-                    handleForwardingSettingsReadResult(result, msg.arg1);
-                    break;
-            }
-        }
-    };
-
-    private void handleForwardingSettingsReadResult(AsyncResult ar, int idx) {
-        if (DBG) Log.d(LOG_TAG, "handleForwardingSettingsReadResult: " + idx);
-
-        Throwable error = null;
-        if (ar.exception != null) {
-            error = ar.exception;
-            if (DBG) Log.d(LOG_TAG, "FwdRead: ar.exception=" + error.getMessage());
-        }
-        if (ar.userObj instanceof Throwable) {
-            error = (Throwable) ar.userObj;
-            if (DBG) Log.d(LOG_TAG, "FwdRead: userObj=" + error.getMessage());
-        }
-
-        // We may have already gotten an error and decided to ignore the other results.
-        if (mForwardingReadResults == null) {
-            if (DBG) Log.d(LOG_TAG, "Ignoring fwd reading result: " + idx);
-            return;
-        }
-
-        // In case of error ignore other results, show an error dialog
-        if (error != null) {
-            if (DBG) Log.d(LOG_TAG, "Error discovered for fwd read : " + idx);
-            mForwardingReadResults = null;
-            dismissDialogSafely(VoicemailDialogUtil.VM_FWD_READING_DIALOG);
-            showDialogIfForeground(VoicemailDialogUtil.FWD_GET_RESPONSE_ERROR_DIALOG);
-            return;
-        }
-
-        // Get the forwarding info.
-        mForwardingReadResults[idx] = CallForwardInfoUtil.getCallForwardInfo(
-                (CallForwardInfo[]) ar.result,
-                VoicemailProviderSettings.FORWARDING_SETTINGS_REASONS[idx]);
-
-        // Check if we got all the results already
-        boolean done = true;
-        for (int i = 0; i < mForwardingReadResults.length; i++) {
-            if (mForwardingReadResults[i] == null) {
-                done = false;
-                break;
-            }
-        }
-
-        if (done) {
-            if (DBG) Log.d(LOG_TAG, "Done receiving fwd info");
-            dismissDialogSafely(VoicemailDialogUtil.VM_FWD_READING_DIALOG);
-
-            if (mPreviousVMProviderKey.equals(VoicemailProviderListPreference.DEFAULT_KEY)) {
-                VoicemailProviderSettingsUtil.save(mPhone.getContext(),
-                        VoicemailProviderListPreference.DEFAULT_KEY,
-                        new VoicemailProviderSettings(mOldVmNumber, mForwardingReadResults));
-            }
-            saveVoiceMailAndForwardingNumberStage2();
-        }
-    }
-
-    private void resetForwardingChangeState() {
-        mForwardingChangeResults = new HashMap<Integer, AsyncResult>();
-        mExpectedChangeResultReasons = new HashSet<Integer>();
-    }
-
-    // Called after we are done saving the previous forwarding settings if we needed.
-    private void saveVoiceMailAndForwardingNumberStage2() {
-        mForwardingChangeResults = null;
-        mVoicemailChangeResult = null;
-
-        resetForwardingChangeState();
-        for (int i = 0; i < mNewFwdSettings.length; i++) {
-            CallForwardInfo fi = mNewFwdSettings[i];
-            CallForwardInfo fiForReason =
-                    CallForwardInfoUtil.infoForReason(mForwardingReadResults, fi.reason);
-            final boolean doUpdate = CallForwardInfoUtil.isUpdateRequired(fiForReason, fi);
-
-            if (doUpdate) {
-                if (DBG) log("Setting fwd #: " + i + ": " + fi.toString());
-                mExpectedChangeResultReasons.add(i);
-
-                CallForwardInfoUtil.setCallForwardingOption(mPhone, fi,
-                        mSetOptionComplete.obtainMessage(
-                                EVENT_FORWARDING_CHANGED, fi.reason, 0));
-            }
-        }
-        showDialogIfForeground(VoicemailDialogUtil.VM_FWD_SAVING_DIALOG);
-    }
-
-    private void setVoicemailNumberWithCarrier() {
-        if (DBG) log("save voicemail #: " + mNewVMNumber);
-
-        mVoicemailChangeResult = null;
-        mPhone.setVoiceMailNumber(
-                mPhone.getVoiceMailAlphaTag().toString(),
-                mNewVMNumber,
-                Message.obtain(mSetOptionComplete, EVENT_VOICEMAIL_CHANGED));
-    }
-
-    /**
-     * Callback to handle option update completions
-     */
-    private final Handler mSetOptionComplete = new Handler() {
-        @Override
-        public void handleMessage(Message msg) {
-            AsyncResult result = (AsyncResult) msg.obj;
-            boolean done = false;
-            switch (msg.what) {
-                case EVENT_VOICEMAIL_CHANGED:
-                    mVoicemailChangeResult = result;
-                    mVMChangeCompletedSuccessfully = isVmChangeSuccess();
-                    done = true;
-                    break;
-                case EVENT_FORWARDING_CHANGED:
-                    mForwardingChangeResults.put(msg.arg1, result);
-                    if (result.exception != null) {
-                        Log.w(LOG_TAG, "Error in setting fwd# " + msg.arg1 + ": " +
-                                result.exception.getMessage());
-                    }
-                    if (isForwardingCompleted()) {
-                        if (isFwdChangeSuccess()) {
-                            if (DBG) log("Overall fwd changes completed ok, starting vm change");
-                            setVoicemailNumberWithCarrier();
-                        } else {
-                            Log.w(LOG_TAG, "Overall fwd changes completed in failure. " +
-                                    "Check if we need to try rollback for some settings.");
-                            mFwdChangesRequireRollback = false;
-                            Iterator<Map.Entry<Integer,AsyncResult>> it =
-                                mForwardingChangeResults.entrySet().iterator();
-                            while (it.hasNext()) {
-                                Map.Entry<Integer,AsyncResult> entry = it.next();
-                                if (entry.getValue().exception == null) {
-                                    // If at least one succeeded we have to revert
-                                    Log.i(LOG_TAG, "Rollback will be required");
-                                    mFwdChangesRequireRollback = true;
-                                    break;
-                                }
-                            }
-                            if (!mFwdChangesRequireRollback) {
-                                Log.i(LOG_TAG, "No rollback needed.");
-                            }
-                            done = true;
-                        }
-                    }
-                    break;
-                default:
-                    // TODO: should never reach this, may want to throw exception
-            }
-
-            if (done) {
-                if (DBG) log("All VM provider related changes done");
-                if (mForwardingChangeResults != null) {
-                    dismissDialogSafely(VoicemailDialogUtil.VM_FWD_SAVING_DIALOG);
-                }
-                handleSetVmOrFwdMessage();
-            }
-        }
-    };
-
-    /**
-     * Callback to handle option revert completions
-     */
-    private final Handler mRevertOptionComplete = new Handler() {
-        @Override
-        public void handleMessage(Message msg) {
-            AsyncResult result = (AsyncResult) msg.obj;
-            switch (msg.what) {
-                case EVENT_VOICEMAIL_CHANGED:
-                    if (DBG) log("VM revert complete msg");
-                    mVoicemailChangeResult = result;
-                    break;
-
-                case EVENT_FORWARDING_CHANGED:
-                    if (DBG) log("FWD revert complete msg ");
-                    mForwardingChangeResults.put(msg.arg1, result);
-                    if (result.exception != null) {
-                        if (DBG) log("Error in reverting fwd# " + msg.arg1 + ": " +
-                                result.exception.getMessage());
-                    }
-                    break;
-
-                default:
-                    // TODO: should never reach this, may want to throw exception
-            }
-
-            final boolean done = (!mVMChangeCompletedSuccessfully || mVoicemailChangeResult != null)
-                    && (!mFwdChangesRequireRollback || isForwardingCompleted());
-            if (done) {
-                if (DBG) log("All VM reverts done");
-                dismissDialogSafely(VoicemailDialogUtil.VM_REVERTING_DIALOG);
-                onRevertDone();
-            }
-        }
-    };
-
-    /**
-     * Return true if there is a change result for every reason for which we expect a result.
-     */
-    private boolean isForwardingCompleted() {
-        if (mForwardingChangeResults == null) {
-            return true;
-        }
-
-        for (Integer reason : mExpectedChangeResultReasons) {
-            if (mForwardingChangeResults.get(reason) == null) {
-                return false;
-            }
-        }
-
-        return true;
-    }
-
-    private boolean isFwdChangeSuccess() {
-        if (mForwardingChangeResults == null) {
-            return true;
-        }
-
-        for (AsyncResult result : mForwardingChangeResults.values()) {
-            Throwable exception = result.exception;
-            if (exception != null) {
-                String msg = exception.getMessage();
-                msg = (msg != null) ? msg : "";
-                Log.w(LOG_TAG, "Failed to change forwarding setting. Reason: " + msg);
-                return false;
-            }
-        }
-        return true;
-    }
-
-    private boolean isVmChangeSuccess() {
-        if (mVoicemailChangeResult.exception != null) {
-            String msg = mVoicemailChangeResult.exception.getMessage();
-            msg = (msg != null) ? msg : "";
-            Log.w(LOG_TAG, "Failed to change voicemail. Reason: " + msg);
-            return false;
-        }
-        return true;
-    }
-
-    private void handleSetVmOrFwdMessage() {
-        if (DBG) log("handleSetVMMessage: set VM request complete");
-
-        if (!isFwdChangeSuccess()) {
-            handleVmOrFwdSetError(VoicemailDialogUtil.FWD_SET_RESPONSE_ERROR_DIALOG);
-        } else if (!isVmChangeSuccess()) {
-            handleVmOrFwdSetError(VoicemailDialogUtil.VM_RESPONSE_ERROR_DIALOG);
-        } else {
-            handleVmAndFwdSetSuccess(VoicemailDialogUtil.VM_CONFIRM_DIALOG);
-        }
-    }
-
-    /**
-     * Called when Voicemail Provider or its forwarding settings failed. Rolls back partly made
-     * changes to those settings and show "failure" dialog.
-     *
-     * @param dialogId ID of the dialog to show for the specific error case. Either
-     *     {@link #FWD_SET_RESPONSE_ERROR_DIALOG} or {@link #VM_RESPONSE_ERROR_DIALOG}
-     */
-    private void handleVmOrFwdSetError(int dialogId) {
-        if (mChangingVMorFwdDueToProviderChange) {
-            mVMOrFwdSetError = dialogId;
-            mChangingVMorFwdDueToProviderChange = false;
-            switchToPreviousVoicemailProvider();
-            return;
-        }
-        mChangingVMorFwdDueToProviderChange = false;
-        showDialogIfForeground(dialogId);
-        updateVoiceNumberField();
-    }
-
-    /**
-     * Called when Voicemail Provider and its forwarding settings were successfully finished.
-     * This updates a bunch of variables and show "success" dialog.
-     */
-    private void handleVmAndFwdSetSuccess(int dialogId) {
-        if (DBG) log("handleVmAndFwdSetSuccess: key is " + mVoicemailProviders.getKey());
-
-        mPreviousVMProviderKey = mVoicemailProviders.getKey();
-        mChangingVMorFwdDueToProviderChange = false;
-        showDialogIfForeground(dialogId);
-        updateVoiceNumberField();
-    }
-
-    /**
-     * Update the voicemail number from what we've recorded on the sim.
-     */
-    private void updateVoiceNumberField() {
-        if (DBG) log("updateVoiceNumberField()");
-
-        mOldVmNumber = mPhone.getVoiceMailNumber();
-        if (TextUtils.isEmpty(mOldVmNumber)) {
-            mSubMenuVoicemailSettings.setPhoneNumber("");
-            mSubMenuVoicemailSettings.setSummary(getString(R.string.voicemail_number_not_set));
-        } else {
-            mSubMenuVoicemailSettings.setPhoneNumber(mOldVmNumber);
-            mSubMenuVoicemailSettings.setSummary(mOldVmNumber);
-        }
-    }
-
-    /*
-     * Helper Methods for Activity class.
-     * The initial query commands are split into two pieces now
-     * for individual expansion.  This combined with the ability
-     * to cancel queries allows for a much better user experience,
-     * and also ensures that the user only waits to update the
-     * data that is relevant.
-     */
-
-    @Override
-    protected void onPrepareDialog(int id, Dialog dialog) {
-        super.onPrepareDialog(id, dialog);
-        mCurrentDialogId = id;
-    }
-
-    // dialog creation method, called by showDialog()
-    @Override
-    protected Dialog onCreateDialog(int dialogId) {
-        return VoicemailDialogUtil.getDialog(this, dialogId);
-    }
-
-    // This is a method implemented for DialogInterface.OnClickListener.
-    // Used with the error dialog to close the app, voicemail dialog to just dismiss.
-    // Close button is mapped to BUTTON_POSITIVE for the errors that close the activity,
-    // while those that are mapped to BUTTON_NEUTRAL only move the preference focus.
-    public void onClick(DialogInterface dialog, int which) {
-        if (DBG) log("onClick: button clicked is " + which);
-
-        dialog.dismiss();
-        switch (which){
-            case DialogInterface.BUTTON_NEGATIVE:
-                if (mCurrentDialogId == VoicemailDialogUtil.FWD_GET_RESPONSE_ERROR_DIALOG) {
-                    // We failed to get current forwarding settings and the user
-                    // does not wish to continue.
-                    switchToPreviousVoicemailProvider();
-                }
-                break;
-            case DialogInterface.BUTTON_POSITIVE:
-                if (mCurrentDialogId == VoicemailDialogUtil.FWD_GET_RESPONSE_ERROR_DIALOG) {
-                    // We failed to get current forwarding settings but the user
-                    // wishes to continue changing settings to the new vm provider
-                    setVoicemailNumberWithCarrier();
-                } else {
-                    finish();
-                }
-                return;
-            default:
-                // just let the dialog close and go back to the input
-        }
-
-        // In all dialogs, all buttons except BUTTON_POSITIVE lead to the end of user interaction
-        // with settings UI. If we were called to explicitly configure voice mail then
-        // we finish the settings activity here to come back to whatever the user was doing.
-        if (getIntent().getAction().equals(ACTION_ADD_VOICEMAIL)) {
-            finish();
-        }
-    }
-
-    /*
-     * Activity class methods
-     */
-
-    @Override
     protected void onCreate(Bundle icicle) {
         super.onCreate(icicle);
         if (DBG) log("onCreate: Intent is " + getIntent());
@@ -1074,13 +175,6 @@
             return;
         }
 
-        // Show the voicemail preference in onResume if the calling intent specifies the
-        // ACTION_ADD_VOICEMAIL action.
-        mShowVoicemailPreference = (icicle == null) &&
-                TextUtils.equals(getIntent().getAction(), ACTION_ADD_VOICEMAIL);
-        mSetupVoicemail = mShowVoicemailPreference &&
-                getIntent().getBooleanExtra(SETUP_VOICEMAIL_EXTRA, false);
-
         mSubscriptionInfoHelper = new SubscriptionInfoHelper(this, getIntent());
         mSubscriptionInfoHelper.setActionBarTitle(
                 getActionBar(), getResources(), R.string.call_settings_with_label);
@@ -1090,7 +184,6 @@
     @Override
     protected void onResume() {
         super.onResume();
-        mForeground = true;
 
         PreferenceScreen preferenceScreen = getPreferenceScreen();
         if (preferenceScreen != null) {
@@ -1110,32 +203,12 @@
         }
 
         PreferenceScreen prefSet = getPreferenceScreen();
-        mSubMenuVoicemailSettings = (EditPhoneNumberPreference) findPreference(BUTTON_VOICEMAIL_KEY);
-        mSubMenuVoicemailSettings.setParentActivity(this, VOICEMAIL_PREF_ID, this);
-        mSubMenuVoicemailSettings.setDialogOnClosedListener(this);
-        mSubMenuVoicemailSettings.setDialogTitle(R.string.voicemail_settings_number_label);
-
-        mButtonAutoRetry = (CheckBoxPreference) findPreference(BUTTON_RETRY_KEY);
-
-        mVoicemailProviders = (VoicemailProviderListPreference) findPreference(
-                BUTTON_VOICEMAIL_PROVIDER_KEY);
-        mVoicemailProviders.init(mPhone, getIntent());
-        mVoicemailProviders.setOnPreferenceChangeListener(this);
-        mPreviousVMProviderKey = mVoicemailProviders.getValue();
-
         mVoicemailSettingsScreen =
                 (PreferenceScreen) findPreference(VOICEMAIL_SETTING_SCREEN_PREF_KEY);
-        mVoicemailSettings = (PreferenceScreen) findPreference(BUTTON_VOICEMAIL_SETTING_KEY);
+        mVoicemailSettingsScreen.setIntent(mSubscriptionInfoHelper.getIntent(
+                VoicemailSettingsActivity.class));
 
-        mVoicemailNotificationRingtone = (VoicemailRingtonePreference) findPreference(
-                getResources().getString(R.string.voicemail_notification_ringtone_key));
-        mVoicemailNotificationRingtone.init(mPhone);
-
-        mVoicemailNotificationVibrate = (CheckBoxPreference) findPreference(
-                getResources().getString(R.string.voicemail_notification_vibrate_key));
-        mVoicemailNotificationVibrate.setOnPreferenceChangeListener(this);
-
-        updateVMPreferenceWidgets(mVoicemailProviders.getValue());
+        mButtonAutoRetry = (CheckBoxPreference) findPreference(BUTTON_RETRY_KEY);
 
         mEnableVideoCalling = (CheckBoxPreference) findPreference(ENABLE_VIDEO_CALLING_KEY);
 
@@ -1191,32 +264,6 @@
             }
         }
 
-        // check the intent that started this activity and pop up the voicemail
-        // dialog if we've been asked to.
-        // If we have at least one non default VM provider registered then bring up
-        // the selection for the VM provider, otherwise bring up a VM number dialog.
-        // We only bring up the dialog the first time we are called (not after orientation change)
-        if (mShowVoicemailPreference) {
-            if (DBG) log("ACTION_ADD_VOICEMAIL Intent is thrown");
-            if (mSetupVoicemail) {
-                simulatePreferenceClick(mVoicemailSettingsScreen);
-                mSetupVoicemail = false;
-            } else if (mVoicemailProviders.hasMoreThanOneVoicemailProvider()) {
-                if (DBG) log("Voicemail data has more than one provider.");
-                simulatePreferenceClick(mVoicemailProviders);
-            } else {
-                onPreferenceChange(mVoicemailProviders, VoicemailProviderListPreference.DEFAULT_KEY);
-                mVoicemailProviders.setValue(VoicemailProviderListPreference.DEFAULT_KEY);
-            }
-            mShowVoicemailPreference = false;
-        }
-
-        updateVoiceNumberField();
-        mVMProviderSettingsForced = false;
-
-        mVoicemailNotificationVibrate.setChecked(
-                VoicemailNotificationSettingsUtil.isVibrationEnabled(mPhone));
-
         if (ImsManager.isVtEnabledByPlatform(mPhone.getContext()) && ENABLE_VT_FLAG) {
             boolean currentValue =
                     ImsManager.isEnhanced4gLteModeSettingEnabledByUser(mPhone.getContext())
@@ -1274,58 +321,6 @@
         Log.d(LOG_TAG, msg);
     }
 
-    /**
-     * Updates the look of the VM preference widgets based on current VM provider settings.
-     * Note that the provider name is loaded fxrorm the found activity via loadLabel in
-     * {@link VoicemailProviderListPreference#initVoiceMailProviders()} in order for it to be
-     * localizable.
-     */
-    private void updateVMPreferenceWidgets(String currentProviderSetting) {
-        final String key = currentProviderSetting;
-        final VoicemailProvider provider = mVoicemailProviders.getVoicemailProvider(key);
-
-        /* This is the case when we are coming up on a freshly wiped phone and there is no
-         persisted value for the list preference mVoicemailProviders.
-         In this case we want to show the UI asking the user to select a voicemail provider as
-         opposed to silently falling back to default one. */
-        if (provider == null) {
-            if (DBG) log("updateVMPreferenceWidget: key: " + key + " -> null.");
-
-            mVoicemailProviders.setSummary(getString(R.string.sum_voicemail_choose_provider));
-            mVoicemailSettings.setEnabled(false);
-            mVoicemailSettings.setIntent(null);
-            mVoicemailNotificationVibrate.setEnabled(false);
-        } else {
-            if (DBG) log("updateVMPreferenceWidget: key: " + key + " -> " + provider.toString());
-
-            final String providerName = provider.name;
-            mVoicemailProviders.setSummary(providerName);
-            mVoicemailSettings.setEnabled(true);
-            mVoicemailSettings.setIntent(provider.intent);
-            mVoicemailNotificationVibrate.setEnabled(true);
-        }
-    }
-
-
-    /**
-     * Simulates user clicking on a passed preference.
-     * Usually needed when the preference is a dialog preference and we want to invoke
-     * a dialog for this preference programmatically.
-     * TODO: figure out if there is a cleaner way to cause preference dlg to come up
-     */
-    private void simulatePreferenceClick(Preference preference) {
-        // Go through settings until we find our setting
-        // and then simulate a click on it to bring up the dialog
-        final ListAdapter adapter = getPreferenceScreen().getRootAdapter();
-        for (int idx = 0; idx < adapter.getCount(); idx++) {
-            if (adapter.getItem(idx) == preference) {
-                getPreferenceScreen().onItemClick(this.getListView(),
-                        null, idx, adapter.getItemId(idx));
-                break;
-            }
-        }
-    }
-
     @Override
     public boolean onOptionsItemSelected(MenuItem item) {
         final int itemId = item.getItemId();
diff --git a/src/com/android/phone/EditPhoneNumberPreference.java b/src/com/android/phone/EditPhoneNumberPreference.java
index 86671a8..8a672f1 100644
--- a/src/com/android/phone/EditPhoneNumberPreference.java
+++ b/src/com/android/phone/EditPhoneNumberPreference.java
@@ -94,7 +94,7 @@
      * DialogPreference.onDialogClosed(), except we also pass in a buttonClicked
      * value indicating which of the three possible buttons were pressed.
      */
-    interface OnDialogClosedListener {
+    public interface OnDialogClosedListener {
         void onDialogClosed(EditPhoneNumberPreference preference, int buttonClicked);
     }
 
@@ -102,7 +102,7 @@
      * Interface for the default number setting listener.  Handles requests for
      * the default display number for the dialog.
      */
-    interface GetDefaultNumberListener {
+    public interface GetDefaultNumberListener {
         /**
          * Notify that we are looking for a default display value.
          * @return null if there is no contribution from this interface,
diff --git a/src/com/android/phone/ErrorDialogActivity.java b/src/com/android/phone/ErrorDialogActivity.java
index 4635f86..bf09376 100644
--- a/src/com/android/phone/ErrorDialogActivity.java
+++ b/src/com/android/phone/ErrorDialogActivity.java
@@ -23,6 +23,8 @@
 import android.os.Bundle;
 import android.util.Log;
 
+import com.android.phone.settings.VoicemailSettingsActivity;
+
 /**
  * Used to display an error dialog from within the Telephony service when an outgoing call fails
  */
@@ -105,8 +107,8 @@
         }
 
         // navigate to the Voicemail setting in the Call Settings activity.
-        Intent intent = new Intent(CallFeaturesSetting.ACTION_ADD_VOICEMAIL);
-        intent.setClass(this, CallFeaturesSetting.class);
+        Intent intent = new Intent(VoicemailSettingsActivity.ACTION_ADD_VOICEMAIL);
+        intent.setClass(this, VoicemailSettingsActivity.class);
         startActivity(intent);
         finish();
     }
diff --git a/src/com/android/phone/NotificationMgr.java b/src/com/android/phone/NotificationMgr.java
index d308a28..1460d63 100644
--- a/src/com/android/phone/NotificationMgr.java
+++ b/src/com/android/phone/NotificationMgr.java
@@ -49,6 +49,7 @@
 import com.android.internal.telephony.Phone;
 import com.android.internal.telephony.PhoneBase;
 import com.android.internal.telephony.TelephonyCapabilities;
+import com.android.phone.settings.VoicemailSettingsActivity;
 import com.android.phone.settings.VoicemailNotificationSettingsUtil;
 import com.android.phone.settings.VoicemailProviderSettingsUtil;
 
@@ -358,10 +359,9 @@
                 // to the voicemail settings.
                 notificationText = mContext.getString(
                         R.string.notification_voicemail_no_vm_number);
-                intent = new Intent(CallFeaturesSetting.ACTION_ADD_VOICEMAIL);
-                intent.putExtra(CallFeaturesSetting.SETUP_VOICEMAIL_EXTRA, true);
+                intent = new Intent(VoicemailSettingsActivity.ACTION_ADD_VOICEMAIL);
                 intent.putExtra(SubscriptionInfoHelper.SUB_ID_EXTRA, subId);
-                intent.setClass(mContext, CallFeaturesSetting.class);
+                intent.setClass(mContext, VoicemailSettingsActivity.class);
             } else {
                 if (mTelephonyManager.getPhoneCount() > 1) {
                     notificationText = subInfo.getDisplayName().toString();
diff --git a/src/com/android/phone/settings/VoicemailDialogUtil.java b/src/com/android/phone/settings/VoicemailDialogUtil.java
index 0a9e4bc..26bc227 100644
--- a/src/com/android/phone/settings/VoicemailDialogUtil.java
+++ b/src/com/android/phone/settings/VoicemailDialogUtil.java
@@ -21,7 +21,6 @@
 import android.app.ProgressDialog;
 import android.view.WindowManager;
 
-import com.android.phone.CallFeaturesSetting;
 import com.android.phone.R;
 
 public class VoicemailDialogUtil {
@@ -36,7 +35,7 @@
     public static final int VM_FWD_READING_DIALOG = 602;
     public static final int VM_REVERTING_DIALOG = 603;
 
-    public static Dialog getDialog(CallFeaturesSetting parent, int id) {
+    public static Dialog getDialog(VoicemailSettingsActivity parent, int id) {
         if ((id == VM_RESPONSE_ERROR_DIALOG) || (id == VM_NOCHANGE_ERROR_DIALOG) ||
             (id == FWD_SET_RESPONSE_ERROR_DIALOG) || (id == FWD_GET_RESPONSE_ERROR_DIALOG) ||
                 (id == VM_CONFIRM_DIALOG)) {
diff --git a/src/com/android/phone/settings/VoicemailProviderListPreference.java b/src/com/android/phone/settings/VoicemailProviderListPreference.java
index 44a1c7c..d9f1a55 100644
--- a/src/com/android/phone/settings/VoicemailProviderListPreference.java
+++ b/src/com/android/phone/settings/VoicemailProviderListPreference.java
@@ -30,7 +30,6 @@
 import android.util.Log;
 
 import com.android.internal.telephony.Phone;
-import com.android.phone.CallFeaturesSetting;
 import com.android.phone.PhoneGlobals;
 import com.android.phone.R;
 
@@ -95,12 +94,14 @@
         if (DBG) log("initVoicemailProviders()");
 
         String providerToIgnore = null;
-        if (activityIntent.getAction().equals(CallFeaturesSetting.ACTION_ADD_VOICEMAIL)
-                && activityIntent.hasExtra(CallFeaturesSetting.IGNORE_PROVIDER_EXTRA)) {
+        String action = activityIntent.getAction();
+        if (!TextUtils.isEmpty(action)
+                && action.equals(VoicemailSettingsActivity.ACTION_ADD_VOICEMAIL)
+                && activityIntent.hasExtra(VoicemailSettingsActivity.IGNORE_PROVIDER_EXTRA)) {
             // Remove this provider from the list.
             if (DBG) log("Found ACTION_ADD_VOICEMAIL.");
             providerToIgnore =
-                    activityIntent.getStringExtra(CallFeaturesSetting.IGNORE_PROVIDER_EXTRA);
+                    activityIntent.getStringExtra(VoicemailSettingsActivity.IGNORE_PROVIDER_EXTRA);
             VoicemailProviderSettingsUtil.delete(mPhone.getContext(), providerToIgnore);
         }
 
@@ -119,7 +120,7 @@
 
         // Add other voicemail providers.
         PackageManager pm = mPhone.getContext().getPackageManager();
-        Intent intent = new Intent(CallFeaturesSetting.ACTION_CONFIGURE_VOICEMAIL);
+        Intent intent = new Intent(VoicemailSettingsActivity.ACTION_CONFIGURE_VOICEMAIL);
         List<ResolveInfo> resolveInfos = pm.queryIntentActivities(intent, 0);
         for (int i = 0; i < resolveInfos.size(); i++) {
             final ResolveInfo ri= resolveInfos.get(i);
@@ -137,7 +138,7 @@
             }
             String nameForDisplay = (label != null) ? label.toString() : "";
             Intent providerIntent = new Intent();
-            providerIntent.setAction(CallFeaturesSetting.ACTION_CONFIGURE_VOICEMAIL);
+            providerIntent.setAction(VoicemailSettingsActivity.ACTION_CONFIGURE_VOICEMAIL);
             providerIntent.setClassName(currentActivityInfo.packageName, currentActivityInfo.name);
             VoicemailProvider vmProvider = new VoicemailProvider(nameForDisplay, providerIntent);
 
diff --git a/src/com/android/phone/settings/VoicemailSettingsActivity.java b/src/com/android/phone/settings/VoicemailSettingsActivity.java
index a94c27a..27349fe 100644
--- a/src/com/android/phone/settings/VoicemailSettingsActivity.java
+++ b/src/com/android/phone/settings/VoicemailSettingsActivity.java
@@ -16,21 +16,268 @@
 
 package com.android.phone.settings;
 
+import android.app.Dialog;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.database.Cursor;
+import android.os.AsyncResult;
 import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.preference.CheckBoxPreference;
+import android.preference.Preference;
 import android.preference.PreferenceActivity;
+import android.preference.PreferenceScreen;
+import android.provider.ContactsContract.CommonDataKinds;
+import android.text.TextUtils;
+import android.util.Log;
 import android.view.MenuItem;
+import android.widget.ListAdapter;
 
+import com.android.internal.telephony.CallForwardInfo;
+import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.PhoneConstants;
 import com.android.phone.R;
+import com.android.phone.EditPhoneNumberPreference;
+import com.android.phone.PhoneGlobals;
+import com.android.phone.SubscriptionInfoHelper;
 
-public class VoicemailSettingsActivity extends PreferenceActivity {
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+
+public class VoicemailSettingsActivity extends PreferenceActivity
+        implements DialogInterface.OnClickListener,
+                Preference.OnPreferenceChangeListener,
+                EditPhoneNumberPreference.OnDialogClosedListener,
+                EditPhoneNumberPreference.GetDefaultNumberListener {
+    private static final String LOG_TAG = VoicemailSettingsActivity.class.getSimpleName();
+    private static final boolean DBG = (PhoneGlobals.DBG_LEVEL >= 2);
+
+    /**
+     * Intent action to bring up Voicemail Provider settings
+     * DO NOT RENAME. There are existing apps which use this intent value.
+     */
+    public static final String ACTION_ADD_VOICEMAIL =
+            "com.android.phone.CallFeaturesSetting.ADD_VOICEMAIL";
+
+    /**
+     * Intent action to bring up the {@code VoicemailSettingsActivity}.
+     * DO NOT RENAME. There are existing apps which use this intent value.
+     */
+    public static final String ACTION_CONFIGURE_VOICEMAIL =
+            "com.android.phone.CallFeaturesSetting.CONFIGURE_VOICEMAIL";
+
+    // Extra put in the return from VM provider config containing voicemail number to set
+    public static final String VM_NUMBER_EXTRA = "com.android.phone.VoicemailNumber";
+    // Extra put in the return from VM provider config containing call forwarding number to set
+    public static final String FWD_NUMBER_EXTRA = "com.android.phone.ForwardingNumber";
+    // Extra put in the return from VM provider config containing call forwarding number to set
+    public static final String FWD_NUMBER_TIME_EXTRA = "com.android.phone.ForwardingNumberTime";
+    // If the VM provider returns non null value in this extra we will force the user to
+    // choose another VM provider
+    public static final String SIGNOUT_EXTRA = "com.android.phone.Signout";
+
+    /**
+     * String Extra put into ACTION_ADD_VOICEMAIL call to indicate which provider should be hidden
+     * in the list of providers presented to the user. This allows a provider which is being
+     * disabled (e.g. GV user logging out) to force the user to pick some other provider.
+     */
+    public static final String IGNORE_PROVIDER_EXTRA = "com.android.phone.ProviderToIgnore";
+
+    /**
+     * String Extra put into ACTION_ADD_VOICEMAIL to indicate that the voicemail setup screen should
+     * be opened.
+     */
+    public static final String SETUP_VOICEMAIL_EXTRA = "com.android.phone.SetupVoicemail";
+
+    // TODO: Define these preference keys in XML.
+    private static final String BUTTON_VOICEMAIL_KEY = "button_voicemail_key";
+    private static final String BUTTON_VOICEMAIL_PROVIDER_KEY = "button_voicemail_provider_key";
+    private static final String BUTTON_VOICEMAIL_SETTING_KEY = "button_voicemail_setting_key";
+
+    /** Event for Async voicemail change call */
+    private static final int EVENT_VOICEMAIL_CHANGED        = 500;
+    private static final int EVENT_FORWARDING_CHANGED       = 501;
+    private static final int EVENT_FORWARDING_GET_COMPLETED = 502;
+
+    /** Handle to voicemail pref */
+    private static final int VOICEMAIL_PREF_ID = 1;
+    private static final int VOICEMAIL_PROVIDER_CFG_ID = 2;
+
+    /**
+     * Results of reading forwarding settings
+     */
+    private CallForwardInfo[] mForwardingReadResults = null;
+
+    /**
+     * Result of forwarding number change.
+     * Keys are reasons (eg. unconditional forwarding).
+     */
+    private Map<Integer, AsyncResult> mForwardingChangeResults = null;
+
+    /**
+     * Expected CF read result types.
+     * This set keeps track of the CF types for which we've issued change
+     * commands so we can tell when we've received all of the responses.
+     */
+    private Collection<Integer> mExpectedChangeResultReasons = null;
+
+    /**
+     * Result of vm number change
+     */
+    private AsyncResult mVoicemailChangeResult = null;
+
+    /**
+     * Previous VM provider setting so we can return to it in case of failure.
+     */
+    private String mPreviousVMProviderKey = null;
+
+    /**
+     * Id of the dialog being currently shown.
+     */
+    private int mCurrentDialogId = 0;
+
+    /**
+     * Flag indicating that we are invoking settings for the voicemail provider programmatically
+     * due to vm provider change.
+     */
+    private boolean mVMProviderSettingsForced = false;
+
+    /**
+     * Flag indicating that we are making changes to vm or fwd numbers
+     * due to vm provider change.
+     */
+    private boolean mChangingVMorFwdDueToProviderChange = false;
+
+    /**
+     * True if we are in the process of vm & fwd number change and vm has already been changed.
+     * This is used to decide what to do in case of rollback.
+     */
+    private boolean mVMChangeCompletedSuccessfully = false;
+
+    /**
+     * True if we had full or partial failure setting forwarding numbers and so need to roll them
+     * back.
+     */
+    private boolean mFwdChangesRequireRollback = false;
+
+    /**
+     * Id of error msg to display to user once we are done reverting the VM provider to the previous
+     * one.
+     */
+    private int mVMOrFwdSetError = 0;
+
+    /** string to hold old voicemail number as it is being updated. */
+    private String mOldVmNumber;
+
+    // New call forwarding settings and vm number we will be setting
+    // Need to save these since before we get to saving we need to asynchronously
+    // query the existing forwarding settings.
+    private CallForwardInfo[] mNewFwdSettings;
+    private String mNewVMNumber;
+
+    /**
+     * Used to indicate that the voicemail preference should be shown.
+     */
+    private boolean mShowVoicemailPreference = false;
+
+    private boolean mForeground;
+    private Phone mPhone;
+    private SubscriptionInfoHelper mSubscriptionInfoHelper;
+
+    private EditPhoneNumberPreference mSubMenuVoicemailSettings;
+    private VoicemailProviderListPreference mVoicemailProviders;
+    private PreferenceScreen mVoicemailSettings;
+    private VoicemailRingtonePreference mVoicemailNotificationRingtone;
+    private CheckBoxPreference mVoicemailNotificationVibrate;
+
+
+    //*********************************************************************************************
+    // Preference Activity Methods
+    //*********************************************************************************************
 
     @Override
     protected void onCreate(Bundle icicle) {
         super.onCreate(icicle);
 
-        getActionBar().setTitle(R.string.voicemail);
-        getFragmentManager().beginTransaction().replace(
-                android.R.id.content, new VoicemailSettingsFragment()).commit();
+        // Show the voicemail preference in onResume if the calling intent specifies the
+        // ACTION_ADD_VOICEMAIL action.
+        mShowVoicemailPreference = (icicle == null) &&
+                TextUtils.equals(getIntent().getAction(), ACTION_ADD_VOICEMAIL);
+
+        mSubscriptionInfoHelper = new SubscriptionInfoHelper(this, getIntent());
+        mSubscriptionInfoHelper.setActionBarTitle(
+                getActionBar(), getResources(), R.string.voicemail_settings_with_label);
+        mPhone = mSubscriptionInfoHelper.getPhone();
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+        mForeground = true;
+
+        PreferenceScreen preferenceScreen = getPreferenceScreen();
+        if (preferenceScreen != null) {
+            preferenceScreen.removeAll();
+        }
+
+        addPreferencesFromResource(R.xml.voicemail_settings);
+
+        PreferenceScreen prefSet = getPreferenceScreen();
+        mSubMenuVoicemailSettings = (EditPhoneNumberPreference) findPreference(BUTTON_VOICEMAIL_KEY);
+        mSubMenuVoicemailSettings.setParentActivity(this, VOICEMAIL_PREF_ID, this);
+        mSubMenuVoicemailSettings.setDialogOnClosedListener(this);
+        mSubMenuVoicemailSettings.setDialogTitle(R.string.voicemail_settings_number_label);
+
+        mVoicemailProviders = (VoicemailProviderListPreference) findPreference(
+                BUTTON_VOICEMAIL_PROVIDER_KEY);
+        mVoicemailProviders.init(mPhone, getIntent());
+        mVoicemailProviders.setOnPreferenceChangeListener(this);
+        mPreviousVMProviderKey = mVoicemailProviders.getValue();
+
+        mVoicemailSettings = (PreferenceScreen) findPreference(BUTTON_VOICEMAIL_SETTING_KEY);
+
+        mVoicemailNotificationRingtone = (VoicemailRingtonePreference) findPreference(
+                getResources().getString(R.string.voicemail_notification_ringtone_key));
+        mVoicemailNotificationRingtone.init(mPhone);
+
+        mVoicemailNotificationVibrate = (CheckBoxPreference) findPreference(
+                getResources().getString(R.string.voicemail_notification_vibrate_key));
+        mVoicemailNotificationVibrate.setOnPreferenceChangeListener(this);
+
+        updateVMPreferenceWidgets(mVoicemailProviders.getValue());
+
+        // check the intent that started this activity and pop up the voicemail
+        // dialog if we've been asked to.
+        // If we have at least one non default VM provider registered then bring up
+        // the selection for the VM provider, otherwise bring up a VM number dialog.
+        // We only bring up the dialog the first time we are called (not after orientation change)
+        if (mShowVoicemailPreference) {
+            if (DBG) log("ACTION_ADD_VOICEMAIL Intent is thrown");
+            if (mVoicemailProviders.hasMoreThanOneVoicemailProvider()) {
+                if (DBG) log("Voicemail data has more than one provider.");
+                simulatePreferenceClick(mVoicemailProviders);
+            } else {
+                onPreferenceChange(mVoicemailProviders, VoicemailProviderListPreference.DEFAULT_KEY);
+                mVoicemailProviders.setValue(VoicemailProviderListPreference.DEFAULT_KEY);
+            }
+            mShowVoicemailPreference = false;
+        }
+
+        updateVoiceNumberField();
+        mVMProviderSettingsForced = false;
+
+        mVoicemailNotificationVibrate.setChecked(
+                VoicemailNotificationSettingsUtil.isVibrationEnabled(mPhone));
+    }
+
+    @Override
+    public void onPause() {
+        super.onPause();
+        mForeground = false;
     }
 
     @Override
@@ -41,4 +288,812 @@
         }
         return super.onOptionsItemSelected(item);
     }
+
+    @Override
+    public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
+        if (preference == mSubMenuVoicemailSettings) {
+            return true;
+        } else if (preference.getKey().equals(mVoicemailSettings.getKey())) {
+            // Check key instead of comparing reference because closing the voicemail notification
+            // ringtone dialog invokes onResume(), but leaves the old preference screen up,
+            // TODO: Revert to checking reference after migrating voicemail to its own activity.
+            if (DBG) log("onPreferenceTreeClick: Voicemail Settings Preference is clicked.");
+
+            final Dialog dialog = ((PreferenceScreen) preference).getDialog();
+            if (dialog != null) {
+                dialog.getActionBar().setDisplayHomeAsUpEnabled(false);
+            }
+
+            if (preference.getIntent() != null) {
+                if (DBG) log("Invoking cfg intent " + preference.getIntent().getPackage());
+
+                // onActivityResult() will be responsible for resetting some of variables.
+                this.startActivityForResult(preference.getIntent(), VOICEMAIL_PROVIDER_CFG_ID);
+                return true;
+            } else {
+                if (DBG) log("onPreferenceTreeClick(). No intent; use default behavior in xml.");
+
+                // onActivityResult() will not be called, so reset variables here.
+                mPreviousVMProviderKey = VoicemailProviderListPreference.DEFAULT_KEY;
+                mVMProviderSettingsForced = false;
+                return false;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Implemented to support onPreferenceChangeListener to look for preference changes.
+     *
+     * @param preference is the preference to be changed
+     * @param objValue should be the value of the selection, NOT its localized
+     * display value.
+     */
+    @Override
+    public boolean onPreferenceChange(Preference preference, Object objValue) {
+        if (DBG) log("onPreferenceChange: \"" + preference + "\" changed to \"" + objValue + "\"");
+
+        if (preference == mVoicemailProviders) {
+            final String newProviderKey = (String) objValue;
+
+            // If previous provider key and the new one is same, we don't need to handle it.
+            if (mPreviousVMProviderKey.equals(newProviderKey)) {
+                if (DBG) log("No change is made to the VM provider setting.");
+                return true;
+            }
+            updateVMPreferenceWidgets(newProviderKey);
+
+            final VoicemailProviderSettings newProviderSettings =
+                    VoicemailProviderSettingsUtil.load(this, newProviderKey);
+
+            // If the user switches to a voice mail provider and we have numbers stored for it we
+            // will automatically change the phone's voice mail and forwarding number to the stored
+            // ones. Otherwise we will bring up provider's configuration UI.
+            if (newProviderSettings == null) {
+                // Force the user into a configuration of the chosen provider
+                Log.w(LOG_TAG, "Saved preferences not found - invoking config");
+                mVMProviderSettingsForced = true;
+                simulatePreferenceClick(mVoicemailSettings);
+            } else {
+                if (DBG) log("Saved preferences found - switching to them");
+                // Set this flag so if we get a failure we revert to previous provider
+                mChangingVMorFwdDueToProviderChange = true;
+                saveVoiceMailAndForwardingNumber(newProviderKey, newProviderSettings);
+            }
+        } else if (preference.getKey().equals(mVoicemailNotificationVibrate.getKey())) {
+            // Check key instead of comparing reference because closing the voicemail notification
+            // ringtone dialog invokes onResume(), but leaves the old preference screen up,
+            // TODO: Revert to checking reference after migrating voicemail to its own activity.
+            VoicemailNotificationSettingsUtil.setVibrationEnabled(
+                    mPhone, Boolean.TRUE.equals(objValue));
+        }
+
+        // Always let the preference setting proceed.
+        return true;
+    }
+
+    /**
+     * Implemented for EditPhoneNumberPreference.GetDefaultNumberListener.
+     * This method set the default values for the various
+     * EditPhoneNumberPreference dialogs.
+     */
+    @Override
+    public String onGetDefaultNumber(EditPhoneNumberPreference preference) {
+        if (preference == mSubMenuVoicemailSettings) {
+            // update the voicemail number field, which takes care of the
+            // mSubMenuVoicemailSettings itself, so we should return null.
+            if (DBG) log("updating default for voicemail dialog");
+            updateVoiceNumberField();
+            return null;
+        }
+
+        String vmDisplay = mPhone.getVoiceMailNumber();
+        if (TextUtils.isEmpty(vmDisplay)) {
+            // if there is no voicemail number, we just return null to
+            // indicate no contribution.
+            return null;
+        }
+
+        // Return the voicemail number prepended with "VM: "
+        if (DBG) log("updating default for call forwarding dialogs");
+        return getString(R.string.voicemail_abbreviated) + " " + vmDisplay;
+    }
+
+    @Override
+    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+        if (DBG) {
+            log("onActivityResult: requestCode: " + requestCode
+                    + ", resultCode: " + resultCode
+                    + ", data: " + data);
+        }
+
+        // there are cases where the contact picker may end up sending us more than one
+        // request.  We want to ignore the request if we're not in the correct state.
+        if (requestCode == VOICEMAIL_PROVIDER_CFG_ID) {
+            boolean failure = false;
+
+            // No matter how the processing of result goes lets clear the flag
+            if (DBG) log("mVMProviderSettingsForced: " + mVMProviderSettingsForced);
+            final boolean isVMProviderSettingsForced = mVMProviderSettingsForced;
+            mVMProviderSettingsForced = false;
+
+            String vmNum = null;
+            if (resultCode != RESULT_OK) {
+                if (DBG) log("onActivityResult: vm provider cfg result not OK.");
+                failure = true;
+            } else {
+                if (data == null) {
+                    if (DBG) log("onActivityResult: vm provider cfg result has no data");
+                    failure = true;
+                } else {
+                    if (data.getBooleanExtra(SIGNOUT_EXTRA, false)) {
+                        if (DBG) log("Provider requested signout");
+                        if (isVMProviderSettingsForced) {
+                            if (DBG) log("Going back to previous provider on signout");
+                            switchToPreviousVoicemailProvider();
+                        } else {
+                            final String victim = mVoicemailProviders.getKey();
+                            if (DBG) log("Relaunching activity and ignoring " + victim);
+                            Intent i = new Intent(ACTION_ADD_VOICEMAIL);
+                            i.putExtra(IGNORE_PROVIDER_EXTRA, victim);
+                            i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
+                            this.startActivity(i);
+                        }
+                        return;
+                    }
+                    vmNum = data.getStringExtra(VM_NUMBER_EXTRA);
+                    if (vmNum == null || vmNum.length() == 0) {
+                        if (DBG) log("onActivityResult: vm provider cfg result has no vmnum");
+                        failure = true;
+                    }
+                }
+            }
+            if (failure) {
+                if (DBG) log("Failure in return from voicemail provider.");
+                if (isVMProviderSettingsForced) {
+                    switchToPreviousVoicemailProvider();
+                }
+
+                return;
+            }
+            mChangingVMorFwdDueToProviderChange = isVMProviderSettingsForced;
+            final String fwdNum = data.getStringExtra(FWD_NUMBER_EXTRA);
+
+            // TODO: It would be nice to load the current network setting for this and
+            // send it to the provider when it's config is invoked so it can use this as default
+            final int fwdNumTime = data.getIntExtra(FWD_NUMBER_TIME_EXTRA, 20);
+
+            if (DBG) log("onActivityResult: cfg result has forwarding number " + fwdNum);
+            saveVoiceMailAndForwardingNumber(mVoicemailProviders.getKey(),
+                    new VoicemailProviderSettings(vmNum, fwdNum, fwdNumTime));
+            return;
+        }
+
+        if (requestCode == VOICEMAIL_PREF_ID) {
+            if (resultCode != RESULT_OK) {
+                if (DBG) log("onActivityResult: contact picker result not OK.");
+                return;
+            }
+
+            Cursor cursor = null;
+            try {
+                cursor = getContentResolver().query(data.getData(),
+                    new String[] { CommonDataKinds.Phone.NUMBER }, null, null, null);
+                if ((cursor == null) || (!cursor.moveToFirst())) {
+                    if (DBG) log("onActivityResult: bad contact data, no results found.");
+                    return;
+                }
+                mSubMenuVoicemailSettings.onPickActivityResult(cursor.getString(0));
+                return;
+            } finally {
+                if (cursor != null) {
+                    cursor.close();
+                }
+            }
+        }
+
+        super.onActivityResult(requestCode, resultCode, data);
+    }
+
+    /**
+     * Simulates user clicking on a passed preference.
+     * Usually needed when the preference is a dialog preference and we want to invoke
+     * a dialog for this preference programmatically.
+     * TODO: figure out if there is a cleaner way to cause preference dlg to come up
+     */
+    private void simulatePreferenceClick(Preference preference) {
+        // Go through settings until we find our setting
+        // and then simulate a click on it to bring up the dialog
+        final ListAdapter adapter = getPreferenceScreen().getRootAdapter();
+        for (int idx = 0; idx < adapter.getCount(); idx++) {
+            if (adapter.getItem(idx) == preference) {
+                getPreferenceScreen().onItemClick(this.getListView(),
+                        null, idx, adapter.getItemId(idx));
+                break;
+            }
+        }
+    }
+
+
+    //*********************************************************************************************
+    // Activity Dialog Methods
+    //*********************************************************************************************
+
+    @Override
+    protected void onPrepareDialog(int id, Dialog dialog) {
+        super.onPrepareDialog(id, dialog);
+        mCurrentDialogId = id;
+    }
+
+    // dialog creation method, called by showDialog()
+    @Override
+    protected Dialog onCreateDialog(int dialogId) {
+        return VoicemailDialogUtil.getDialog(this, dialogId);
+    }
+
+    @Override
+    public void onDialogClosed(EditPhoneNumberPreference preference, int buttonClicked) {
+        if (DBG) log("onDialogClosed: Button clicked is " + buttonClicked);
+
+        if (buttonClicked == DialogInterface.BUTTON_NEGATIVE) {
+            return;
+        }
+
+        if (preference == mSubMenuVoicemailSettings) {
+            VoicemailProviderSettings newSettings = new VoicemailProviderSettings(
+                    mSubMenuVoicemailSettings.getPhoneNumber(),
+                    VoicemailProviderSettings.NO_FORWARDING);
+            saveVoiceMailAndForwardingNumber(mVoicemailProviders.getKey(), newSettings);
+        }
+    }
+
+    /**
+     * Wrapper around showDialog() that will silently do nothing if we're
+     * not in the foreground.
+     *
+     * This is useful here because most of the dialogs we display from
+     * this class are triggered by asynchronous events (like
+     * success/failure messages from the telephony layer) and it's
+     * possible for those events to come in even after the user has gone
+     * to a different screen.
+     */
+    // TODO: this is too brittle: it's still easy to accidentally add new
+    // code here that calls showDialog() directly (which will result in a
+    // WindowManager$BadTokenException if called after the activity has
+    // been stopped.)
+    //
+    // It would be cleaner to do the "if (mForeground)" check in one
+    // central place, maybe by using a single Handler for all asynchronous
+    // events (and have *that* discard events if we're not in the
+    // foreground.)
+    //
+    // Unfortunately it's not that simple, since we sometimes need to do
+    // actual work to handle these events whether or not we're in the
+    // foreground (see the Handler code in mSetOptionComplete for
+    // example.)
+    //
+    // TODO: It's a bit worrisome that we don't do anything in error cases when we're not in the
+    // foreground. Consider displaying a toast instead.
+    private void showDialogIfForeground(int id) {
+        if (mForeground) {
+            showDialog(id);
+        }
+    }
+
+    private void dismissDialogSafely(int id) {
+        try {
+            dismissDialog(id);
+        } catch (IllegalArgumentException e) {
+            // This is expected in the case where we were in the background
+            // at the time we would normally have shown the dialog, so we didn't
+            // show it.
+        }
+    }
+
+    // This is a method implemented for DialogInterface.OnClickListener.
+    // Used with the error dialog to close the app, voicemail dialog to just dismiss.
+    // Close button is mapped to BUTTON_POSITIVE for the errors that close the activity,
+    // while those that are mapped to BUTTON_NEUTRAL only move the preference focus.
+    public void onClick(DialogInterface dialog, int which) {
+        if (DBG) log("onClick: button clicked is " + which);
+
+        dialog.dismiss();
+        switch (which){
+            case DialogInterface.BUTTON_NEGATIVE:
+                if (mCurrentDialogId == VoicemailDialogUtil.FWD_GET_RESPONSE_ERROR_DIALOG) {
+                    // We failed to get current forwarding settings and the user
+                    // does not wish to continue.
+                    switchToPreviousVoicemailProvider();
+                }
+                break;
+            case DialogInterface.BUTTON_POSITIVE:
+                if (mCurrentDialogId == VoicemailDialogUtil.FWD_GET_RESPONSE_ERROR_DIALOG) {
+                    // We failed to get current forwarding settings but the user
+                    // wishes to continue changing settings to the new vm provider
+                    setVoicemailNumberWithCarrier();
+                } else {
+                    finish();
+                }
+                return;
+            default:
+                // just let the dialog close and go back to the input
+        }
+
+        // In all dialogs, all buttons except BUTTON_POSITIVE lead to the end of user interaction
+        // with settings UI. If we were called to explicitly configure voice mail then
+        // we finish the settings activity here to come back to whatever the user was doing.
+        if (getIntent().getAction().equals(ACTION_ADD_VOICEMAIL)) {
+            finish();
+        }
+    }
+
+
+    //*********************************************************************************************
+    // Voicemail Methods
+    //*********************************************************************************************
+
+    /**
+     * TODO: Refactor to make it easier to understand what's done in the different stages.
+     */
+    private void saveVoiceMailAndForwardingNumber(
+            String key, VoicemailProviderSettings newSettings) {
+        if (DBG) log("saveVoiceMailAndForwardingNumber: " + newSettings.toString());
+        mNewVMNumber = newSettings.getVoicemailNumber();
+        mNewVMNumber = (mNewVMNumber == null) ? "" : mNewVMNumber;
+        mNewFwdSettings = newSettings.getForwardingSettings();
+
+        // Call forwarding is not suppported on CDMA.
+        if (mPhone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
+            if (DBG) log("Ignoring forwarding setting since this is CDMA phone");
+            mNewFwdSettings = VoicemailProviderSettings.NO_FORWARDING;
+        }
+
+        // Throw a warning if the voicemail is the same and we did not change forwarding.
+        if (mNewVMNumber.equals(mOldVmNumber)
+                && mNewFwdSettings == VoicemailProviderSettings.NO_FORWARDING) {
+            showDialogIfForeground(VoicemailDialogUtil.VM_NOCHANGE_ERROR_DIALOG);
+            return;
+        }
+
+        VoicemailProviderSettingsUtil.save(this, key, newSettings);
+        mVMChangeCompletedSuccessfully = false;
+        mFwdChangesRequireRollback = false;
+        mVMOrFwdSetError = 0;
+
+        if (mNewFwdSettings == VoicemailProviderSettings.NO_FORWARDING
+                || key.equals(mPreviousVMProviderKey)) {
+            if (DBG) log("Set voicemail number. No changes to forwarding number.");
+            setVoicemailNumberWithCarrier();
+        } else {
+            if (DBG) log("Reading current forwarding settings.");
+            int numSettingsReasons = VoicemailProviderSettings.FORWARDING_SETTINGS_REASONS.length;
+            mForwardingReadResults = new CallForwardInfo[numSettingsReasons];
+            for (int i = 0; i < mForwardingReadResults.length; i++) {
+                mPhone.getCallForwardingOption(
+                        VoicemailProviderSettings.FORWARDING_SETTINGS_REASONS[i],
+                        mGetOptionComplete.obtainMessage(EVENT_FORWARDING_GET_COMPLETED, i, 0));
+            }
+            showDialogIfForeground(VoicemailDialogUtil.VM_FWD_READING_DIALOG);
+        }
+
+        PhoneGlobals.getInstance().refreshMwiIndicator(mSubscriptionInfoHelper.getSubId());
+    }
+
+    private final Handler mGetOptionComplete = new Handler() {
+        @Override
+        public void handleMessage(Message msg) {
+            AsyncResult result = (AsyncResult) msg.obj;
+            switch (msg.what) {
+                case EVENT_FORWARDING_GET_COMPLETED:
+                    handleForwardingSettingsReadResult(result, msg.arg1);
+                    break;
+            }
+        }
+    };
+
+    private void handleForwardingSettingsReadResult(AsyncResult ar, int idx) {
+        if (DBG) Log.d(LOG_TAG, "handleForwardingSettingsReadResult: " + idx);
+
+        Throwable error = null;
+        if (ar.exception != null) {
+            error = ar.exception;
+            if (DBG) Log.d(LOG_TAG, "FwdRead: ar.exception=" + error.getMessage());
+        }
+        if (ar.userObj instanceof Throwable) {
+            error = (Throwable) ar.userObj;
+            if (DBG) Log.d(LOG_TAG, "FwdRead: userObj=" + error.getMessage());
+        }
+
+        // We may have already gotten an error and decided to ignore the other results.
+        if (mForwardingReadResults == null) {
+            if (DBG) Log.d(LOG_TAG, "Ignoring fwd reading result: " + idx);
+            return;
+        }
+
+        // In case of error ignore other results, show an error dialog
+        if (error != null) {
+            if (DBG) Log.d(LOG_TAG, "Error discovered for fwd read : " + idx);
+            mForwardingReadResults = null;
+            dismissDialogSafely(VoicemailDialogUtil.VM_FWD_READING_DIALOG);
+            showDialogIfForeground(VoicemailDialogUtil.FWD_GET_RESPONSE_ERROR_DIALOG);
+            return;
+        }
+
+        // Get the forwarding info.
+        mForwardingReadResults[idx] = CallForwardInfoUtil.getCallForwardInfo(
+                (CallForwardInfo[]) ar.result,
+                VoicemailProviderSettings.FORWARDING_SETTINGS_REASONS[idx]);
+
+        // Check if we got all the results already
+        boolean done = true;
+        for (int i = 0; i < mForwardingReadResults.length; i++) {
+            if (mForwardingReadResults[i] == null) {
+                done = false;
+                break;
+            }
+        }
+
+        if (done) {
+            if (DBG) Log.d(LOG_TAG, "Done receiving fwd info");
+            dismissDialogSafely(VoicemailDialogUtil.VM_FWD_READING_DIALOG);
+
+            if (mPreviousVMProviderKey.equals(VoicemailProviderListPreference.DEFAULT_KEY)) {
+                VoicemailProviderSettingsUtil.save(mPhone.getContext(),
+                        VoicemailProviderListPreference.DEFAULT_KEY,
+                        new VoicemailProviderSettings(mOldVmNumber, mForwardingReadResults));
+            }
+            saveVoiceMailAndForwardingNumberStage2();
+        }
+    }
+
+    private void resetForwardingChangeState() {
+        mForwardingChangeResults = new HashMap<Integer, AsyncResult>();
+        mExpectedChangeResultReasons = new HashSet<Integer>();
+    }
+
+    // Called after we are done saving the previous forwarding settings if we needed.
+    private void saveVoiceMailAndForwardingNumberStage2() {
+        mForwardingChangeResults = null;
+        mVoicemailChangeResult = null;
+
+        resetForwardingChangeState();
+        for (int i = 0; i < mNewFwdSettings.length; i++) {
+            CallForwardInfo fi = mNewFwdSettings[i];
+            CallForwardInfo fiForReason =
+                    CallForwardInfoUtil.infoForReason(mForwardingReadResults, fi.reason);
+            final boolean doUpdate = CallForwardInfoUtil.isUpdateRequired(fiForReason, fi);
+
+            if (doUpdate) {
+                if (DBG) log("Setting fwd #: " + i + ": " + fi.toString());
+                mExpectedChangeResultReasons.add(i);
+
+                CallForwardInfoUtil.setCallForwardingOption(mPhone, fi,
+                        mSetOptionComplete.obtainMessage(
+                                EVENT_FORWARDING_CHANGED, fi.reason, 0));
+            }
+        }
+        showDialogIfForeground(VoicemailDialogUtil.VM_FWD_SAVING_DIALOG);
+    }
+
+
+    /**
+     * Callback to handle option update completions
+     */
+    private final Handler mSetOptionComplete = new Handler() {
+        @Override
+        public void handleMessage(Message msg) {
+            AsyncResult result = (AsyncResult) msg.obj;
+            boolean done = false;
+            switch (msg.what) {
+                case EVENT_VOICEMAIL_CHANGED:
+                    mVoicemailChangeResult = result;
+                    mVMChangeCompletedSuccessfully = isVmChangeSuccess();
+                    done = true;
+                    break;
+                case EVENT_FORWARDING_CHANGED:
+                    mForwardingChangeResults.put(msg.arg1, result);
+                    if (result.exception != null) {
+                        Log.w(LOG_TAG, "Error in setting fwd# " + msg.arg1 + ": " +
+                                result.exception.getMessage());
+                    }
+                    if (isForwardingCompleted()) {
+                        if (isFwdChangeSuccess()) {
+                            if (DBG) log("Overall fwd changes completed ok, starting vm change");
+                            setVoicemailNumberWithCarrier();
+                        } else {
+                            Log.w(LOG_TAG, "Overall fwd changes completed in failure. " +
+                                    "Check if we need to try rollback for some settings.");
+                            mFwdChangesRequireRollback = false;
+                            Iterator<Map.Entry<Integer,AsyncResult>> it =
+                                mForwardingChangeResults.entrySet().iterator();
+                            while (it.hasNext()) {
+                                Map.Entry<Integer,AsyncResult> entry = it.next();
+                                if (entry.getValue().exception == null) {
+                                    // If at least one succeeded we have to revert
+                                    Log.i(LOG_TAG, "Rollback will be required");
+                                    mFwdChangesRequireRollback = true;
+                                    break;
+                                }
+                            }
+                            if (!mFwdChangesRequireRollback) {
+                                Log.i(LOG_TAG, "No rollback needed.");
+                            }
+                            done = true;
+                        }
+                    }
+                    break;
+                default:
+                    // TODO: should never reach this, may want to throw exception
+            }
+
+            if (done) {
+                if (DBG) log("All VM provider related changes done");
+                if (mForwardingChangeResults != null) {
+                    dismissDialogSafely(VoicemailDialogUtil.VM_FWD_SAVING_DIALOG);
+                }
+                handleSetVmOrFwdMessage();
+            }
+        }
+    };
+
+    /**
+     * Callback to handle option revert completions
+     */
+    private final Handler mRevertOptionComplete = new Handler() {
+        @Override
+        public void handleMessage(Message msg) {
+            AsyncResult result = (AsyncResult) msg.obj;
+            switch (msg.what) {
+                case EVENT_VOICEMAIL_CHANGED:
+                    if (DBG) log("VM revert complete msg");
+                    mVoicemailChangeResult = result;
+                    break;
+
+                case EVENT_FORWARDING_CHANGED:
+                    if (DBG) log("FWD revert complete msg ");
+                    mForwardingChangeResults.put(msg.arg1, result);
+                    if (result.exception != null) {
+                        if (DBG) log("Error in reverting fwd# " + msg.arg1 + ": " +
+                                result.exception.getMessage());
+                    }
+                    break;
+
+                default:
+                    // TODO: should never reach this, may want to throw exception
+            }
+
+            final boolean done = (!mVMChangeCompletedSuccessfully || mVoicemailChangeResult != null)
+                    && (!mFwdChangesRequireRollback || isForwardingCompleted());
+            if (done) {
+                if (DBG) log("All VM reverts done");
+                dismissDialogSafely(VoicemailDialogUtil.VM_REVERTING_DIALOG);
+                onRevertDone();
+            }
+        }
+    };
+
+    private void setVoicemailNumberWithCarrier() {
+        if (DBG) log("save voicemail #: " + mNewVMNumber);
+
+        mVoicemailChangeResult = null;
+        mPhone.setVoiceMailNumber(
+                mPhone.getVoiceMailAlphaTag().toString(),
+                mNewVMNumber,
+                Message.obtain(mSetOptionComplete, EVENT_VOICEMAIL_CHANGED));
+    }
+
+    private void switchToPreviousVoicemailProvider() {
+        if (DBG) log("switchToPreviousVoicemailProvider " + mPreviousVMProviderKey);
+
+        if (mPreviousVMProviderKey == null) {
+            return;
+        }
+
+        if (mVMChangeCompletedSuccessfully || mFwdChangesRequireRollback) {
+            showDialogIfForeground(VoicemailDialogUtil.VM_REVERTING_DIALOG);
+            final VoicemailProviderSettings prevSettings =
+                    VoicemailProviderSettingsUtil.load(this, mPreviousVMProviderKey);
+            if (prevSettings == null) {
+                Log.e(LOG_TAG, "VoicemailProviderSettings for the key \""
+                        + mPreviousVMProviderKey + "\" is null but should be loaded.");
+            }
+
+            if (mVMChangeCompletedSuccessfully) {
+                mNewVMNumber = prevSettings.getVoicemailNumber();
+                Log.i(LOG_TAG, "VM change is already completed successfully."
+                        + "Have to revert VM back to " + mNewVMNumber + " again.");
+                mPhone.setVoiceMailNumber(
+                        mPhone.getVoiceMailAlphaTag().toString(),
+                        mNewVMNumber,
+                        Message.obtain(mRevertOptionComplete, EVENT_VOICEMAIL_CHANGED));
+            }
+
+            if (mFwdChangesRequireRollback) {
+                Log.i(LOG_TAG, "Requested to rollback forwarding changes.");
+
+                final CallForwardInfo[] prevFwdSettings = prevSettings.getForwardingSettings();
+                if (prevFwdSettings != null) {
+                    Map<Integer, AsyncResult> results = mForwardingChangeResults;
+                    resetForwardingChangeState();
+                    for (int i = 0; i < prevFwdSettings.length; i++) {
+                        CallForwardInfo fi = prevFwdSettings[i];
+                        if (DBG) log("Reverting fwd #: " + i + ": " + fi.toString());
+                        // Only revert the settings for which the update succeeded.
+                        AsyncResult result = results.get(fi.reason);
+                        if (result != null && result.exception == null) {
+                            mExpectedChangeResultReasons.add(fi.reason);
+                            CallForwardInfoUtil.setCallForwardingOption(mPhone, fi,
+                                    mRevertOptionComplete.obtainMessage(
+                                            EVENT_FORWARDING_CHANGED, i, 0));
+                        }
+                    }
+                }
+            }
+        } else {
+            if (DBG) log("No need to revert");
+            onRevertDone();
+        }
+    }
+
+
+    //*********************************************************************************************
+    // Voicemail Handler Helpers
+    //*********************************************************************************************
+
+    /**
+     * Updates the look of the VM preference widgets based on current VM provider settings.
+     * Note that the provider name is loaded fxrorm the found activity via loadLabel in
+     * {@link VoicemailProviderListPreference#initVoiceMailProviders()} in order for it to be
+     * localizable.
+     */
+    private void updateVMPreferenceWidgets(String currentProviderSetting) {
+        final String key = currentProviderSetting;
+        final VoicemailProviderListPreference.VoicemailProvider provider =
+                mVoicemailProviders.getVoicemailProvider(key);
+
+        /* This is the case when we are coming up on a freshly wiped phone and there is no
+         persisted value for the list preference mVoicemailProviders.
+         In this case we want to show the UI asking the user to select a voicemail provider as
+         opposed to silently falling back to default one. */
+        if (provider == null) {
+            if (DBG) log("updateVMPreferenceWidget: key: " + key + " -> null.");
+
+            mVoicemailProviders.setSummary(getString(R.string.sum_voicemail_choose_provider));
+            mVoicemailSettings.setEnabled(false);
+            mVoicemailSettings.setIntent(null);
+            mVoicemailNotificationVibrate.setEnabled(false);
+        } else {
+            if (DBG) log("updateVMPreferenceWidget: key: " + key + " -> " + provider.toString());
+
+            final String providerName = provider.name;
+            mVoicemailProviders.setSummary(providerName);
+            mVoicemailSettings.setEnabled(true);
+            mVoicemailSettings.setIntent(provider.intent);
+            mVoicemailNotificationVibrate.setEnabled(true);
+        }
+    }
+
+    /**
+     * Update the voicemail number from what we've recorded on the sim.
+     */
+    private void updateVoiceNumberField() {
+        if (DBG) log("updateVoiceNumberField()");
+
+        mOldVmNumber = mPhone.getVoiceMailNumber();
+        if (TextUtils.isEmpty(mOldVmNumber)) {
+            mSubMenuVoicemailSettings.setPhoneNumber("");
+            mSubMenuVoicemailSettings.setSummary(getString(R.string.voicemail_number_not_set));
+        } else {
+            mSubMenuVoicemailSettings.setPhoneNumber(mOldVmNumber);
+            mSubMenuVoicemailSettings.setSummary(mOldVmNumber);
+        }
+    }
+
+    private void handleSetVmOrFwdMessage() {
+        if (DBG) log("handleSetVMMessage: set VM request complete");
+
+        if (!isFwdChangeSuccess()) {
+            handleVmOrFwdSetError(VoicemailDialogUtil.FWD_SET_RESPONSE_ERROR_DIALOG);
+        } else if (!isVmChangeSuccess()) {
+            handleVmOrFwdSetError(VoicemailDialogUtil.VM_RESPONSE_ERROR_DIALOG);
+        } else {
+            handleVmAndFwdSetSuccess(VoicemailDialogUtil.VM_CONFIRM_DIALOG);
+        }
+    }
+
+    /**
+     * Called when Voicemail Provider or its forwarding settings failed. Rolls back partly made
+     * changes to those settings and show "failure" dialog.
+     *
+     * @param dialogId ID of the dialog to show for the specific error case. Either
+     *     {@link #FWD_SET_RESPONSE_ERROR_DIALOG} or {@link #VM_RESPONSE_ERROR_DIALOG}
+     */
+    private void handleVmOrFwdSetError(int dialogId) {
+        if (mChangingVMorFwdDueToProviderChange) {
+            mVMOrFwdSetError = dialogId;
+            mChangingVMorFwdDueToProviderChange = false;
+            switchToPreviousVoicemailProvider();
+            return;
+        }
+        mChangingVMorFwdDueToProviderChange = false;
+        showDialogIfForeground(dialogId);
+        updateVoiceNumberField();
+    }
+
+    /**
+     * Called when Voicemail Provider and its forwarding settings were successfully finished.
+     * This updates a bunch of variables and show "success" dialog.
+     */
+    private void handleVmAndFwdSetSuccess(int dialogId) {
+        if (DBG) log("handleVmAndFwdSetSuccess: key is " + mVoicemailProviders.getKey());
+
+        mPreviousVMProviderKey = mVoicemailProviders.getKey();
+        mChangingVMorFwdDueToProviderChange = false;
+        showDialogIfForeground(dialogId);
+        updateVoiceNumberField();
+    }
+
+    private void onRevertDone() {
+        if (DBG) log("onRevertDone: Changing provider key back to " + mPreviousVMProviderKey);
+
+        updateVMPreferenceWidgets(mPreviousVMProviderKey);
+        updateVoiceNumberField();
+        if (mVMOrFwdSetError != 0) {
+            showDialogIfForeground(mVMOrFwdSetError);
+            mVMOrFwdSetError = 0;
+        }
+    }
+
+
+    //*********************************************************************************************
+    // Voicemail State Helpers
+    //*********************************************************************************************
+
+    /**
+     * Return true if there is a change result for every reason for which we expect a result.
+     */
+    private boolean isForwardingCompleted() {
+        if (mForwardingChangeResults == null) {
+            return true;
+        }
+
+        for (Integer reason : mExpectedChangeResultReasons) {
+            if (mForwardingChangeResults.get(reason) == null) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    private boolean isFwdChangeSuccess() {
+        if (mForwardingChangeResults == null) {
+            return true;
+        }
+
+        for (AsyncResult result : mForwardingChangeResults.values()) {
+            Throwable exception = result.exception;
+            if (exception != null) {
+                String msg = exception.getMessage();
+                msg = (msg != null) ? msg : "";
+                Log.w(LOG_TAG, "Failed to change forwarding setting. Reason: " + msg);
+                return false;
+            }
+        }
+        return true;
+    }
+
+    private boolean isVmChangeSuccess() {
+        if (mVoicemailChangeResult.exception != null) {
+            String msg = mVoicemailChangeResult.exception.getMessage();
+            msg = (msg != null) ? msg : "";
+            Log.w(LOG_TAG, "Failed to change voicemail. Reason: " + msg);
+            return false;
+        }
+        return true;
+    }
+
+    private static void log(String msg) {
+        Log.d(LOG_TAG, msg);
+    }
 }
diff --git a/src/com/android/phone/settings/VoicemailSettingsFragment.java b/src/com/android/phone/settings/VoicemailSettingsFragment.java
deleted file mode 100644
index fef3e8c..0000000
--- a/src/com/android/phone/settings/VoicemailSettingsFragment.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/**
- * Copyright (C) 2014 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.os.Bundle;
-import android.preference.PreferenceFragment;
-
-import com.android.phone.R;
-
-public class VoicemailSettingsFragment extends PreferenceFragment {
-
-    @Override
-    public void onCreate(Bundle icicle) {
-        super.onCreate(icicle);
-
-        addPreferencesFromResource(R.xml.voicemail_settings);
-    }
-}
