diff --git a/src/com/android/phone/GsmUmtsOptions.java b/src/com/android/phone/GsmUmtsOptions.java
index 70ba4af..697fca8 100644
--- a/src/com/android/phone/GsmUmtsOptions.java
+++ b/src/com/android/phone/GsmUmtsOptions.java
@@ -22,9 +22,9 @@
 import android.preference.Preference;
 import android.preference.PreferenceFragment;
 import android.preference.PreferenceScreen;
+import android.preference.TwoStatePreference;
 import android.provider.Settings;
 import android.telephony.CarrierConfigManager;
-import android.content.ComponentName;
 
 import com.android.internal.telephony.PhoneConstants;
 import com.android.internal.telephony.PhoneFactory;
@@ -36,34 +36,43 @@
     private static final String LOG_TAG = "GsmUmtsOptions";
 
     private PreferenceScreen mButtonAPNExpand;
-    private PreferenceScreen mButtonOperatorSelectionExpand;
+    private TwoStatePreference mButtonAutoSelect;
+    private NetworkSelectListPreference mButtonOperatorSelection;
+
+    private NetworkOperators mNetworkOperator;
 
     private static final String BUTTON_APN_EXPAND_KEY = "button_apn_key";
-    private static final String BUTTON_OPERATOR_SELECTION_EXPAND_KEY = "button_carrier_sel_key";
     private static final String BUTTON_CARRIER_SETTINGS_KEY = "carrier_settings_key";
+
     public static final String EXTRA_SUB_ID = "sub_id";
     private PreferenceFragment mPrefFragment;
     private PreferenceScreen mPrefScreen;
+    INetworkQueryService mNetworkQueryService;
     private int mSubId;
 
     public GsmUmtsOptions(PreferenceFragment prefFragment, PreferenceScreen prefScreen,
-            final int subId) {
+            final int subId, INetworkQueryService queryService) {
         mPrefFragment = prefFragment;
         mPrefScreen = prefScreen;
         mSubId = subId;
+        mNetworkQueryService = queryService;
         create();
     }
 
     protected void create() {
         mPrefFragment.addPreferencesFromResource(R.xml.gsm_umts_options);
         mButtonAPNExpand = (PreferenceScreen) mPrefScreen.findPreference(BUTTON_APN_EXPAND_KEY);
+
+        mNetworkOperator = (NetworkOperators) mPrefScreen
+                .findPreference(NetworkOperators.CATEGORY_NETWORK_OPERATORS_KEY);
+        mNetworkOperator.initialize(mPrefScreen, mSubId, mNetworkQueryService);
+
         boolean removedAPNExpand = false;
-        mButtonOperatorSelectionExpand =
-                (PreferenceScreen) mPrefScreen.findPreference(BUTTON_OPERATOR_SELECTION_EXPAND_KEY);
+        boolean removedNetworkOperatorsCategory = false;
         if (PhoneFactory.getDefaultPhone().getPhoneType() != PhoneConstants.PHONE_TYPE_GSM) {
             log("Not a GSM phone");
             mButtonAPNExpand.setEnabled(false);
-            mButtonOperatorSelectionExpand.setEnabled(false);
+            mNetworkOperator.setEnabled(false);
         } else {
             log("Not a CDMA phone");
             Resources res = mPrefFragment.getResources();
@@ -83,17 +92,19 @@
             if (!carrierConfig.getBoolean(
                     CarrierConfigManager.KEY_OPERATOR_SELECTION_EXPAND_BOOL)) {
                 mPrefScreen.removePreference(mPrefScreen
-                        .findPreference(BUTTON_OPERATOR_SELECTION_EXPAND_KEY));
+                        .findPreference(NetworkOperators.CATEGORY_NETWORK_OPERATORS_KEY));
+                removedNetworkOperatorsCategory = true;
             }
 
             if (carrierConfig.getBoolean(CarrierConfigManager.KEY_CSP_ENABLED_BOOL)) {
                 if (PhoneFactory.getDefaultPhone().isCspPlmnEnabled()) {
                     log("[CSP] Enabling Operator Selection menu.");
-                    mButtonOperatorSelectionExpand.setEnabled(true);
+                    mNetworkOperator.setEnabled(true);
                 } else {
                     log("[CSP] Disabling Operator Selection menu.");
                     mPrefScreen.removePreference(mPrefScreen
-                          .findPreference(BUTTON_OPERATOR_SELECTION_EXPAND_KEY));
+                            .findPreference(NetworkOperators.CATEGORY_NETWORK_OPERATORS_KEY));
+                    removedNetworkOperatorsCategory = true;
                 }
             }
 
@@ -124,25 +135,22 @@
                         }
             });
         }
-        if (mPrefScreen.findPreference(BUTTON_OPERATOR_SELECTION_EXPAND_KEY) != null) {
-            mButtonOperatorSelectionExpand.setOnPreferenceClickListener(
-                    new Preference.OnPreferenceClickListener() {
-                        @Override
-                        public boolean onPreferenceClick(Preference preference) {
-                            final Intent intent = new Intent(Intent.ACTION_MAIN);
-                            intent.setComponent(new ComponentName("com.android.phone",
-                                    "com.android.phone.NetworkSetting"));
-                            intent.putExtra(EXTRA_SUB_ID, mSubId);
-                            mPrefFragment.startActivity(intent);
-                            return true;
-                        }
-            });
+
+        if (!removedNetworkOperatorsCategory) {
+            mButtonAutoSelect = (TwoStatePreference) mPrefScreen
+                    .findPreference(NetworkOperators.BUTTON_AUTO_SELECT_KEY);
+            mButtonOperatorSelection = (NetworkSelectListPreference) mPrefScreen
+                    .findPreference(NetworkOperators.BUTTON_NETWORK_SELECT_KEY);
         }
     }
 
     public boolean preferenceTreeClick(Preference preference) {
-        log("preferenceTreeClick: return false");
-        return false;
+        if (preference == mButtonAutoSelect || preference == mButtonOperatorSelection) {
+            return true;
+        } else {
+            log("preferenceTreeClick: return false");
+            return false;
+        }
     }
 
     protected void log(String s) {
diff --git a/src/com/android/phone/MobileNetworkSettings.java b/src/com/android/phone/MobileNetworkSettings.java
index 03865fe..27ebaf0 100644
--- a/src/com/android/phone/MobileNetworkSettings.java
+++ b/src/com/android/phone/MobileNetworkSettings.java
@@ -22,16 +22,19 @@
 import android.app.Fragment;
 import android.app.FragmentManager;
 import android.content.BroadcastReceiver;
+import android.content.ComponentName;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.content.ServiceConnection;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.net.Uri;
 import android.os.AsyncResult;
 import android.os.Bundle;
 import android.os.Handler;
+import android.os.IBinder;
 import android.os.Message;
 import android.os.PersistableBundle;
 import android.os.UserHandle;
@@ -177,7 +180,6 @@
         private static final String BUTTON_4G_LTE_KEY = "enhanced_4g_lte";
         private static final String BUTTON_CELL_BROADCAST_SETTINGS = "cell_broadcast_settings";
         private static final String BUTTON_APN_EXPAND_KEY = "button_apn_key";
-        private static final String BUTTON_OPERATOR_SELECTION_EXPAND_KEY = "button_carrier_sel_key";
         private static final String BUTTON_CARRIER_SETTINGS_KEY = "carrier_settings_key";
         private static final String BUTTON_CDMA_SYSTEM_SELECT_KEY = "cdma_system_select_key";
         private static final String BUTTON_CARRIER_SETTINGS_EUICC_KEY =
@@ -208,6 +210,7 @@
         private PreferenceCategory mCallingCategory;
         private Preference mWiFiCallingPref;
         private SwitchPreference mVideoCallingPref;
+        private NetworkSelectListPreference mButtonNetworkSelect;
 
         private static final String iface = "rmnet0"; //TODO: this will go away
         private List<SubscriptionInfo> mActiveSubInfos;
@@ -248,6 +251,53 @@
             }
         };
 
+        /**
+         * Service connection code for the NetworkQueryService.
+         * Handles the work of binding to a local object so that we can make
+         * the appropriate service calls.
+         */
+
+        /** Local service interface */
+        private INetworkQueryService mNetworkQueryService = null;
+
+        private void setNetworkQueryService() {
+            mButtonNetworkSelect = (NetworkSelectListPreference) getPreferenceScreen()
+                    .findPreference(NetworkOperators.BUTTON_NETWORK_SELECT_KEY);
+            if (mButtonNetworkSelect != null) {
+                mButtonNetworkSelect.setNetworkQueryService(mNetworkQueryService);
+            }
+
+        }
+        /** Service connection */
+        private final ServiceConnection mNetworkQueryServiceConnection = new ServiceConnection() {
+
+            /** Handle the task of binding the local object to the service */
+            public void onServiceConnected(ComponentName className, IBinder service) {
+                if (DBG) log("connection created, binding local service.");
+                mNetworkQueryService = ((NetworkQueryService.LocalBinder) service).getService();
+                setNetworkQueryService();
+            }
+
+            /** Handle the task of cleaning up the local binding */
+            public void onServiceDisconnected(ComponentName className) {
+                if (DBG) log("connection disconnected, cleaning local binding.");
+                mNetworkQueryService = null;
+                setNetworkQueryService();
+            }
+        };
+
+        private void bindNetworkQueryService() {
+            getContext().startService(new Intent(getContext(), NetworkQueryService.class));
+            getContext().bindService(new Intent(getContext(), NetworkQueryService.class).setAction(
+                        NetworkQueryService.ACTION_LOCAL_BINDER),
+                        mNetworkQueryServiceConnection, Context.BIND_AUTO_CREATE);
+        }
+
+        private void unbindNetworkQueryService() {
+            // unbind the service.
+            getContext().unbindService(mNetworkQueryServiceConnection);
+        }
+
         @Override
         public void onPositiveButtonClick(DialogFragment dialog) {
             mPhone.setDataRoamingEnabled(true);
@@ -517,6 +567,8 @@
             mTelephonyManager = (TelephonyManager) activity.getSystemService(
                             Context.TELEPHONY_SERVICE);
 
+            bindNetworkQueryService();
+
             if (mUm.hasUserRestriction(UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS)) {
                 mUnavailable = true;
                 activity.setContentView(R.layout.telephony_disallowed_preference_screen);
@@ -595,6 +647,7 @@
 
         @Override
         public void onDestroy() {
+            unbindNetworkQueryService();
             super.onDestroy();
             if (getActivity() != null && !getActivity().isDestroyed()) {
                 getActivity().unregisterReceiver(mPhoneChangeReceiver);
@@ -715,7 +768,8 @@
                         mGsmUmtsOptions = null;
                     }
                 } else if (phoneType == PhoneConstants.PHONE_TYPE_GSM) {
-                    mGsmUmtsOptions = new GsmUmtsOptions(this, prefSet, phoneSubId);
+                    mGsmUmtsOptions = new GsmUmtsOptions(this, prefSet, phoneSubId,
+                            mNetworkQueryService);
                 } else {
                     throw new IllegalStateException("Unexpected phone type: " + phoneType);
                 }
@@ -731,7 +785,8 @@
                 mButtonPreferredNetworkMode.setOnPreferenceChangeListener(this);
 
                 mCdmaOptions = new CdmaOptions(this, prefSet, mPhone);
-                mGsmUmtsOptions = new GsmUmtsOptions(this, prefSet, phoneSubId);
+                mGsmUmtsOptions = new GsmUmtsOptions(this, prefSet, phoneSubId,
+                        mNetworkQueryService);
             } else {
                 prefSet.removePreference(mButtonPreferredNetworkMode);
                 final int phoneType = mPhone.getPhoneType();
@@ -817,7 +872,8 @@
                         mButtonEnabledNetworks.setEntryValues(
                                 R.array.enabled_networks_values);
                     }
-                    mGsmUmtsOptions = new GsmUmtsOptions(this, prefSet, phoneSubId);
+                    mGsmUmtsOptions = new GsmUmtsOptions(this, prefSet, phoneSubId,
+                            mNetworkQueryService);
                 } else {
                     throw new IllegalStateException("Unexpected phone type: " + phoneType);
                 }
@@ -924,7 +980,7 @@
             if (ps != null) {
                 ps.setEnabled(hasActiveSubscriptions);
             }
-            ps = findPreference(BUTTON_OPERATOR_SELECTION_EXPAND_KEY);
+            ps = findPreference(NetworkOperators.CATEGORY_NETWORK_OPERATORS_KEY);
             if (ps != null) {
                 ps.setEnabled(hasActiveSubscriptions);
             }
@@ -1608,22 +1664,24 @@
             }
 
             if (mGsmUmtsOptions == null) {
-                mGsmUmtsOptions = new GsmUmtsOptions(this, prefSet, mPhone.getSubId());
+                mGsmUmtsOptions = new GsmUmtsOptions(this, prefSet, mPhone.getSubId(),
+                        mNetworkQueryService);
             }
             PreferenceScreen apnExpand =
                     (PreferenceScreen) prefSet.findPreference(BUTTON_APN_EXPAND_KEY);
-            PreferenceScreen operatorSelectionExpand =
-                    (PreferenceScreen) prefSet.findPreference(BUTTON_OPERATOR_SELECTION_EXPAND_KEY);
+            PreferenceCategory networkOperatorCategory =
+                    (PreferenceCategory) prefSet.findPreference(
+                            NetworkOperators.CATEGORY_NETWORK_OPERATORS_KEY);
             PreferenceScreen carrierSettings =
                     (PreferenceScreen) prefSet.findPreference(BUTTON_CARRIER_SETTINGS_KEY);
             if (apnExpand != null) {
                 apnExpand.setEnabled(isWorldMode() || enable);
             }
-            if (operatorSelectionExpand != null) {
+            if (networkOperatorCategory != null) {
                 if (enable) {
-                    operatorSelectionExpand.setEnabled(true);
+                    networkOperatorCategory.setEnabled(true);
                 } else {
-                    prefSet.removePreference(operatorSelectionExpand);
+                    prefSet.removePreference(networkOperatorCategory);
                 }
             }
             if (carrierSettings != null) {
diff --git a/src/com/android/phone/NetworkOperators.java b/src/com/android/phone/NetworkOperators.java
new file mode 100644
index 0000000..b46bec9
--- /dev/null
+++ b/src/com/android/phone/NetworkOperators.java
@@ -0,0 +1,240 @@
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.phone;
+
+import android.content.Context;
+import android.os.AsyncResult;
+import android.os.Handler;
+import android.os.Message;
+import android.preference.Preference;
+import android.preference.PreferenceCategory;
+import android.preference.PreferenceScreen;
+import android.preference.TwoStatePreference;
+import android.telephony.ServiceState;
+import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
+import android.util.AttributeSet;
+import android.util.Log;
+
+import com.android.internal.telephony.CommandException;
+import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.PhoneFactory;
+
+/**
+ * "Networks" settings UI for the Phone app.
+ */
+public class NetworkOperators extends PreferenceCategory
+        implements Preference.OnPreferenceChangeListener {
+
+    private static final String LOG_TAG = "NetworkOperators";
+    private static final boolean DBG = true;
+
+    private static final int EVENT_AUTO_SELECT_DONE = 100;
+    private static final int EVENT_GET_NETWORK_SELECTION_MODE_DONE = 200;
+
+    //String keys for preference lookup
+    public static final String BUTTON_NETWORK_SELECT_KEY = "button_network_select_key";
+    public static final String BUTTON_AUTO_SELECT_KEY = "button_auto_select_key";
+    public static final String CATEGORY_NETWORK_OPERATORS_KEY = "network_operators_category_key";
+
+    int mPhoneId = SubscriptionManager.INVALID_PHONE_INDEX;
+
+    //preference objects
+    private NetworkSelectListPreference mNetworkSelect;
+    private TwoStatePreference mAutoSelect;
+
+    private int mSubId;
+
+    public NetworkOperators(
+            Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+    }
+
+    public NetworkOperators(Context context, AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+    }
+
+    public NetworkOperators(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    public NetworkOperators(Context context) {
+        super(context);
+    }
+
+    /**
+     * Initialize NetworkOperators instance with information like subId, queryService.
+     * It is required to have preferences work properly.
+     *
+     * @param prefScreen prefScreen this category is in.
+     * @param subId Corresponding subscription ID of this network.
+     * @param queryService The service to do network queries.
+     */
+    public void initialize(PreferenceScreen prefScreen,
+            final int subId, INetworkQueryService queryService) {
+        mSubId = subId;
+
+        mNetworkSelect =
+                (NetworkSelectListPreference) prefScreen.findPreference(BUTTON_NETWORK_SELECT_KEY);
+        mAutoSelect =
+                (TwoStatePreference) prefScreen.findPreference(BUTTON_AUTO_SELECT_KEY);
+
+        mPhoneId = SubscriptionManager.getPhoneId(mSubId);
+
+        if (mAutoSelect != null) {
+            mAutoSelect.setOnPreferenceChangeListener(this);
+        }
+
+        if (mAutoSelect != null) {
+            mNetworkSelect.initialize(mSubId, queryService, this);
+        }
+
+        getNetworkSelectionMode();
+    }
+
+    /**
+     * Implemented to support onPreferenceChangeListener to look for preference
+     * changes specifically on auto select button.
+     *
+     * @param preference is the preference to be changed, should be auto select button.
+     * @param newValue should be the value of whether autoSelect is checked.
+     */
+    @Override
+    public boolean onPreferenceChange(Preference preference, Object newValue) {
+        if (preference == mAutoSelect) {
+            boolean autoSelect = (Boolean) newValue;
+            selectNetworkAutomatic(autoSelect);
+            return true;
+        }
+        return false;
+    }
+
+    private final Handler mHandler = new Handler() {
+        @Override
+        public void handleMessage(Message msg) {
+            AsyncResult ar;
+            switch (msg.what) {
+                case EVENT_AUTO_SELECT_DONE:
+                    mAutoSelect.setEnabled(true);
+
+                    ar = (AsyncResult) msg.obj;
+                    if (ar.exception != null) {
+                        if (DBG) logd("automatic network selection: failed!");
+                        displayNetworkSelectionFailed(ar.exception);
+                    } else {
+                        if (DBG) logd("automatic network selection: succeeded!");
+                        displayNetworkSelectionSucceeded();
+                    }
+
+                    break;
+                case EVENT_GET_NETWORK_SELECTION_MODE_DONE:
+                    ar = (AsyncResult) msg.obj;
+                    if (ar.exception != null) {
+                        if (DBG) logd("get network selection mode: failed!");
+                    } else if (ar.result != null) {
+                        try {
+                            int[] modes = (int[]) ar.result;
+                            boolean autoSelect = (modes[0] == 0);
+                            if (DBG) {
+                                logd("get network selection mode: "
+                                        + (autoSelect ? "auto" : "manual") + " selection");
+                            }
+                            if (mAutoSelect != null) {
+                                mAutoSelect.setChecked(autoSelect);
+                            }
+                            if (mNetworkSelect != null) {
+                                mNetworkSelect.setEnabled(!autoSelect);
+                            }
+                        } catch (Exception e) {
+                            if (DBG) loge("get network selection mode: unable to parse result.");
+                        }
+                    }
+            }
+
+            return;
+        }
+    };
+
+    // Used by both mAutoSelect and mNetworkSelect buttons.
+    protected void displayNetworkSelectionFailed(Throwable ex) {
+        String status;
+
+        if ((ex != null && ex instanceof CommandException)
+                && ((CommandException) ex).getCommandError()
+                        == CommandException.Error.ILLEGAL_SIM_OR_ME) {
+            status = getContext().getResources().getString(R.string.not_allowed);
+        } else {
+            status = getContext().getResources().getString(R.string.connect_later);
+        }
+
+        final PhoneGlobals app = PhoneGlobals.getInstance();
+        app.notificationMgr.postTransientNotification(
+                NotificationMgr.NETWORK_SELECTION_NOTIFICATION, status);
+
+        TelephonyManager tm = (TelephonyManager) app.getSystemService(Context.TELEPHONY_SERVICE);
+        Phone phone = PhoneFactory.getPhone(mPhoneId);
+        if (phone != null) {
+            ServiceState ss = tm.getServiceStateForSubscriber(phone.getSubId());
+            if (ss != null) {
+                app.notificationMgr.updateNetworkSelection(ss.getState(), phone.getSubId());
+            }
+        }
+    }
+
+    // Used by both mAutoSelect and mNetworkSelect buttons.
+    protected void displayNetworkSelectionSucceeded() {
+        String status = getContext().getResources().getString(R.string.registration_done);
+
+        final PhoneGlobals app = PhoneGlobals.getInstance();
+        app.notificationMgr.postTransientNotification(
+                NotificationMgr.NETWORK_SELECTION_NOTIFICATION, status);
+    }
+
+    private void selectNetworkAutomatic(boolean autoSelect) {
+        if (mNetworkSelect != null) {
+            mNetworkSelect.setEnabled(!autoSelect);
+        }
+        if (autoSelect) {
+            if (DBG) logd("select network automatically...");
+            mAutoSelect.setEnabled(false);
+            Message msg = mHandler.obtainMessage(EVENT_AUTO_SELECT_DONE);
+            Phone phone = PhoneFactory.getPhone(mPhoneId);
+            if (phone != null) {
+                phone.setNetworkSelectionModeAutomatic(msg);
+            }
+        } else if (mNetworkSelect != null) {
+            mNetworkSelect.onClick();
+        }
+    }
+
+    protected void getNetworkSelectionMode() {
+        if (DBG) logd("getting network selection mode...");
+        Message msg = mHandler.obtainMessage(EVENT_GET_NETWORK_SELECTION_MODE_DONE);
+        Phone phone = PhoneFactory.getPhone(mPhoneId);
+        if (phone != null) {
+            phone.getNetworkSelectionMode(msg);
+        }
+    }
+
+    private void logd(String msg) {
+        Log.d(LOG_TAG, "[NetworksList] " + msg);
+    }
+
+    private void loge(String msg) {
+        Log.e(LOG_TAG, "[NetworksList] " + msg);
+    }
+}
diff --git a/src/com/android/phone/NetworkSelectListPreference.java b/src/com/android/phone/NetworkSelectListPreference.java
new file mode 100644
index 0000000..28050c9
--- /dev/null
+++ b/src/com/android/phone/NetworkSelectListPreference.java
@@ -0,0 +1,415 @@
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.phone;
+
+import android.app.ProgressDialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.os.AsyncResult;
+import android.os.Handler;
+import android.os.Message;
+import android.os.RemoteException;
+import android.preference.ListPreference;
+import android.preference.Preference;
+import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
+import android.text.BidiFormatter;
+import android.text.TextDirectionHeuristics;
+import android.text.TextUtils;
+import android.util.AttributeSet;
+import android.util.Log;
+
+import com.android.internal.telephony.OperatorInfo;
+import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.PhoneFactory;
+
+import java.util.List;
+
+
+/**
+ * "Networks" preference in "Mobile network" settings UI for the Phone app.
+ * It's used to manually search and choose mobile network. Enabled only when
+ * autoSelect preference is turned off.
+ */
+public class NetworkSelectListPreference extends ListPreference
+        implements DialogInterface.OnCancelListener,
+        Preference.OnPreferenceChangeListener{
+
+    private static final String LOG_TAG = "networkSelect";
+    private static final boolean DBG = true;
+
+    private static final int EVENT_NETWORK_SCAN_COMPLETED = 100;
+    private static final int EVENT_NETWORK_SELECTION_DONE = 200;
+
+    //dialog ids
+    private static final int DIALOG_NETWORK_SELECTION = 100;
+    private static final int DIALOG_NETWORK_LIST_LOAD = 200;
+
+    private int mPhoneId = SubscriptionManager.INVALID_PHONE_INDEX;
+    private List<OperatorInfo> mOperatorInfoList;
+    private  OperatorInfo mOperatorInfo;
+
+    private int mSubId;
+    private NetworkOperators mNetworkOperators;
+
+    private ProgressDialog mProgressDialog;
+    public NetworkSelectListPreference(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    public NetworkSelectListPreference(Context context, AttributeSet attrs, int defStyleAttr,
+            int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+    }
+
+    @Override
+    protected void onClick() {
+        loadNetworksList();
+    }
+
+    private final Handler mHandler = new Handler() {
+        @Override
+        public void handleMessage(Message msg) {
+            AsyncResult ar;
+            switch (msg.what) {
+                case EVENT_NETWORK_SCAN_COMPLETED:
+                    networksListLoaded((List<OperatorInfo>) msg.obj, msg.arg1);
+                    break;
+
+                case EVENT_NETWORK_SELECTION_DONE:
+                    if (DBG) logd("hideProgressPanel");
+                    try {
+                        dismissProgressBar();
+                    } catch (IllegalArgumentException e) {
+                    }
+                    setEnabled(true);
+
+                    ar = (AsyncResult) msg.obj;
+                    if (ar.exception != null) {
+                        if (DBG) logd("manual network selection: failed!");
+                        mNetworkOperators.displayNetworkSelectionFailed(ar.exception);
+                    } else {
+                        if (DBG) {
+                            logd("manual network selection: succeeded!"
+                                    + getNetworkTitle(mOperatorInfo));
+                        }
+                        mNetworkOperators.displayNetworkSelectionSucceeded();
+                    }
+                    mNetworkOperators.getNetworkSelectionMode();
+                    break;
+            }
+
+            return;
+        }
+    };
+
+    INetworkQueryService mNetworkQueryService = null;
+    /**
+     * This implementation of INetworkQueryServiceCallback is used to receive
+     * callback notifications from the network query service.
+     */
+    private final INetworkQueryServiceCallback mCallback = new INetworkQueryServiceCallback.Stub() {
+
+        /** place the message on the looper queue upon query completion. */
+        public void onQueryComplete(List<OperatorInfo> networkInfoArray, int status) {
+            if (DBG) logd("notifying message loop of query completion.");
+            Message msg = mHandler.obtainMessage(EVENT_NETWORK_SCAN_COMPLETED,
+                    status, 0, networkInfoArray);
+            msg.sendToTarget();
+        }
+    };
+
+    @Override
+    //implemented for DialogInterface.OnCancelListener
+    public void onCancel(DialogInterface dialog) {
+        // request that the service stop the query with this callback object.
+        try {
+            if (mNetworkQueryService != null) {
+                mNetworkQueryService.stopNetworkQuery(mCallback);
+            }
+            // If cancelled, we query NetworkSelectMode and update states of AutoSelect button.
+            mNetworkOperators.getNetworkSelectionMode();
+        } catch (RemoteException e) {
+            loge("onCancel: exception from stopNetworkQuery " + e);
+        }
+    }
+
+    @Override
+    protected void onDialogClosed(boolean positiveResult) {
+        super.onDialogClosed(positiveResult);
+
+        // If dismissed, we query NetworkSelectMode and update states of AutoSelect button.
+        if (!positiveResult) {
+            mNetworkOperators.getNetworkSelectionMode();
+        }
+    }
+
+    /**
+     * Return normalized carrier name given network info.
+     *
+     * @param ni is network information in OperatorInfo type.
+     */
+    public String getNormalizedCarrierName(OperatorInfo ni) {
+        if (ni != null) {
+            return ni.getOperatorAlphaLong() + " (" + ni.getOperatorNumeric() + ")";
+        }
+        return null;
+    }
+
+    // This method is provided besides initialize() because bind to network query service
+    // may be binded after initialize(). In that case this method needs to be called explicitly
+    // to set mNetworkQueryService. Otherwise mNetworkQueryService will remain null.
+    public void setNetworkQueryService(INetworkQueryService queryService) {
+        mNetworkQueryService = queryService;
+    }
+
+    // This initialize method needs to be called for this preference to work properly.
+    protected void initialize(int subId, INetworkQueryService queryService,
+            NetworkOperators networkOperators) {
+        mSubId = subId;
+        mNetworkQueryService = queryService;
+        mNetworkOperators = networkOperators;
+
+        if (SubscriptionManager.isValidSubscriptionId(mSubId)) {
+            mPhoneId = SubscriptionManager.getPhoneId(mSubId);
+        }
+
+        TelephonyManager telephonyManager = (TelephonyManager)
+                getContext().getSystemService(Context.TELEPHONY_SERVICE);
+
+        setSummary(telephonyManager.getNetworkOperatorName());
+
+        setOnPreferenceChangeListener(this);
+    }
+
+    @Override
+    protected void onPrepareForRemoval() {
+        destroy();
+        super.onPrepareForRemoval();
+    }
+
+    private void destroy() {
+        try {
+            dismissProgressBar();
+        } catch (IllegalArgumentException e) {
+            loge("onDestroy: exception from dismissProgressBar " + e);
+        }
+
+        try {
+            if (mNetworkQueryService != null) {
+                // used to un-register callback
+                mNetworkQueryService.unregisterCallback(mCallback);
+            }
+        } catch (RemoteException e) {
+            loge("onDestroy: exception from unregisterCallback " + e);
+        }
+    }
+
+    private void displayEmptyNetworkList() {
+        String status = getContext().getResources().getString(R.string.empty_networks_list);
+
+        final PhoneGlobals app = PhoneGlobals.getInstance();
+        app.notificationMgr.postTransientNotification(
+                NotificationMgr.NETWORK_SELECTION_NOTIFICATION, status);
+    }
+
+    private void displayNetworkSeletionInProgress() {
+        showProgressBar(DIALOG_NETWORK_SELECTION);
+    }
+
+    private void displayNetworkQueryFailed(int error) {
+        String status = getContext().getResources().getString(R.string.network_query_error);
+
+        try {
+            dismissProgressBar();
+        } catch (IllegalArgumentException e1) {
+            // do nothing
+        }
+
+        final PhoneGlobals app = PhoneGlobals.getInstance();
+        app.notificationMgr.postTransientNotification(
+                NotificationMgr.NETWORK_SELECTION_NOTIFICATION, status);
+    }
+
+    private void loadNetworksList() {
+        if (DBG) logd("load networks list...");
+
+        showProgressBar(DIALOG_NETWORK_LIST_LOAD);
+
+        // delegate query request to the service.
+        try {
+            if (mNetworkQueryService != null) {
+                mNetworkQueryService.startNetworkQuery(mCallback, mPhoneId);
+            } else {
+                displayNetworkQueryFailed(NetworkQueryService.QUERY_EXCEPTION);
+            }
+        } catch (RemoteException e) {
+            loge("loadNetworksList: exception from startNetworkQuery " + e);
+            displayNetworkQueryFailed(NetworkQueryService.QUERY_EXCEPTION);
+        }
+    }
+
+    /**
+     * networksListLoaded has been rewritten to take an array of
+     * OperatorInfo objects and a status field, instead of an
+     * AsyncResult.  Otherwise, the functionality which takes the
+     * OperatorInfo array and creates a list of preferences from it,
+     * remains unchanged.
+     */
+    private void networksListLoaded(List<OperatorInfo> result, int status) {
+        if (DBG) logd("networks list loaded");
+
+        // used to un-register callback
+        try {
+            if (mNetworkQueryService != null) {
+                mNetworkQueryService.unregisterCallback(mCallback);
+            }
+        } catch (RemoteException e) {
+            loge("networksListLoaded: exception from unregisterCallback " + e);
+        }
+
+        // update the state of the preferences.
+        if (DBG) logd("hideProgressPanel");
+
+        // Always try to dismiss the dialog because activity may
+        // be moved to background after dialog is shown.
+        try {
+            dismissProgressBar();
+        } catch (IllegalArgumentException e) {
+            // It's not a error in following scenario, we just ignore it.
+            // "Load list" dialog will not show, if NetworkQueryService is
+            // connected after this activity is moved to background.
+            loge("Fail to dismiss network load list dialog " + e);
+        }
+
+        setEnabled(true);
+        clearList();
+
+        if (status != NetworkQueryService.QUERY_OK) {
+            if (DBG) logd("error while querying available networks");
+            displayNetworkQueryFailed(status);
+        } else {
+            if (result != null) {
+                // create a preference for each item in the list.
+                // just use the operator name instead of the mildly
+                // confusing mcc/mnc.
+                mOperatorInfoList = result;
+                CharSequence[] networkEntries = new CharSequence[result.size()];
+                CharSequence[] networkEntryValues = new CharSequence[result.size()];
+                for (int i = 0; i < mOperatorInfoList.size(); i++) {
+                    networkEntries[i] = getNetworkTitle(mOperatorInfoList.get(i));
+                    networkEntryValues[i] = Integer.toString(i + 2);
+                }
+
+                setEntries(networkEntries);
+                setEntryValues(networkEntryValues);
+
+                super.onClick();
+            } else {
+                displayEmptyNetworkList();
+            }
+        }
+    }
+
+    /**
+     * Returns the title of the network obtained in the manual search.
+     *
+     * @param ni contains the information of the network.
+     *
+     * @return Long Name if not null/empty, otherwise Short Name if not null/empty,
+     * else MCCMNC string.
+     */
+    private String getNetworkTitle(OperatorInfo ni) {
+        if (!TextUtils.isEmpty(ni.getOperatorAlphaLong())) {
+            return ni.getOperatorAlphaLong();
+        } else if (!TextUtils.isEmpty(ni.getOperatorAlphaShort())) {
+            return ni.getOperatorAlphaShort();
+        } else {
+            BidiFormatter bidiFormatter = BidiFormatter.getInstance();
+            return bidiFormatter.unicodeWrap(ni.getOperatorNumeric(), TextDirectionHeuristics.LTR);
+        }
+    }
+
+    private void clearList() {
+        if (mOperatorInfoList != null) {
+            mOperatorInfoList.clear();
+        }
+    }
+
+    private void dismissProgressBar() {
+        if (mProgressDialog != null && mProgressDialog.isShowing()) {
+            mProgressDialog.dismiss();
+        }
+    }
+
+    private void showProgressBar(int id) {
+        if ((id == DIALOG_NETWORK_SELECTION) || (id == DIALOG_NETWORK_LIST_LOAD)) {
+            mProgressDialog = new ProgressDialog(getContext());
+            switch (id) {
+                case DIALOG_NETWORK_SELECTION:
+                    final String networkSelectMsg = getContext().getResources()
+                            .getString(R.string.register_on_network,
+                                    getNetworkTitle(mOperatorInfo));
+                    mProgressDialog.setMessage(networkSelectMsg);
+                    mProgressDialog.setCancelable(false);
+                    mProgressDialog.setIndeterminate(true);
+                    break;
+                case DIALOG_NETWORK_LIST_LOAD:
+                    mProgressDialog.setMessage(
+                            getContext().getResources().getString(R.string.load_networks_progress));
+                    mProgressDialog.setCanceledOnTouchOutside(false);
+                    mProgressDialog.setOnCancelListener(this);
+                    break;
+                default:
+            }
+            mProgressDialog.show();
+        }
+    }
+
+    /**
+     * Implemented to support onPreferenceChangeListener to look for preference
+     * changes specifically on this button.
+     *
+     * @param preference is the preference to be changed, should be network select button.
+     * @param newValue should be the value of the selection as index of operators.
+     */
+    public boolean onPreferenceChange(Preference preference, Object newValue) {
+        int operatorIndex = findIndexOfValue((String) newValue);
+        mOperatorInfo = mOperatorInfoList.get(operatorIndex);
+
+        if (DBG) logd("selected network: " + getNetworkTitle(mOperatorInfo));
+
+        Message msg = mHandler.obtainMessage(EVENT_NETWORK_SELECTION_DONE);
+        Phone phone = PhoneFactory.getPhone(mPhoneId);
+        if (phone != null) {
+            phone.selectNetworkManually(mOperatorInfo, true, msg);
+            displayNetworkSeletionInProgress();
+        } else {
+            loge("Error selecting network. phone is null.");
+        }
+
+        return true;
+    }
+
+    private void logd(String msg) {
+        Log.d(LOG_TAG, "[NetworksList] " + msg);
+    }
+
+    private void loge(String msg) {
+        Log.e(LOG_TAG, "[NetworksList] " + msg);
+    }
+}
diff --git a/src/com/android/phone/NetworkSetting.java b/src/com/android/phone/NetworkSetting.java
deleted file mode 100644
index 72ad513..0000000
--- a/src/com/android/phone/NetworkSetting.java
+++ /dev/null
@@ -1,543 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.phone;
-
-import android.app.Dialog;
-import android.app.ProgressDialog;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.content.ServiceConnection;
-import android.os.AsyncResult;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.Message;
-import android.os.RemoteException;
-import android.os.UserManager;
-import android.preference.Preference;
-import android.preference.PreferenceActivity;
-import android.preference.PreferenceGroup;
-import android.preference.PreferenceScreen;
-import android.telephony.ServiceState;
-import android.telephony.TelephonyManager;
-import android.text.TextUtils;
-import android.util.Log;
-import android.telephony.SubscriptionManager;
-
-import com.android.internal.telephony.CommandException;
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.PhoneFactory;
-import com.android.internal.telephony.OperatorInfo;
-
-import java.util.HashMap;
-import java.util.List;
-import android.text.BidiFormatter;
-import android.text.TextDirectionHeuristics;
-
-/**
- * "Networks" settings UI for the Phone app.
- */
-public class NetworkSetting extends PreferenceActivity
-        implements DialogInterface.OnCancelListener {
-
-    private static final String LOG_TAG = "phone";
-    private static final boolean DBG = true;
-
-    private static final int EVENT_NETWORK_SCAN_COMPLETED = 100;
-    private static final int EVENT_NETWORK_SELECTION_DONE = 200;
-    private static final int EVENT_AUTO_SELECT_DONE = 300;
-
-    //dialog ids
-    private static final int DIALOG_NETWORK_SELECTION = 100;
-    private static final int DIALOG_NETWORK_LIST_LOAD = 200;
-    private static final int DIALOG_NETWORK_AUTO_SELECT = 300;
-
-    //String keys for preference lookup
-    private static final String LIST_NETWORKS_KEY = "list_networks_key";
-    private static final String BUTTON_SRCH_NETWRKS_KEY = "button_srch_netwrks_key";
-    private static final String BUTTON_AUTO_SELECT_KEY = "button_auto_select_key";
-
-    //map of network controls to the network data.
-    private HashMap<Preference, OperatorInfo> mNetworkMap;
-
-    int mPhoneId = SubscriptionManager.INVALID_PHONE_INDEX;
-    protected boolean mIsForeground = false;
-
-    private UserManager mUm;
-    private boolean mUnavailable;
-
-    /** message for network selection */
-    String mNetworkSelectMsg;
-
-    //preference objects
-    private PreferenceGroup mNetworkList;
-    private Preference mSearchButton;
-    private Preference mAutoSelect;
-
-    private final Handler mHandler = new Handler() {
-        @Override
-        public void handleMessage(Message msg) {
-            AsyncResult ar;
-            switch (msg.what) {
-                case EVENT_NETWORK_SCAN_COMPLETED:
-                    networksListLoaded ((List<OperatorInfo>) msg.obj, msg.arg1);
-                    break;
-
-                case EVENT_NETWORK_SELECTION_DONE:
-                    if (DBG) log("hideProgressPanel");
-                    removeDialog(DIALOG_NETWORK_SELECTION);
-                    getPreferenceScreen().setEnabled(true);
-
-                    ar = (AsyncResult) msg.obj;
-                    if (ar.exception != null) {
-                        if (DBG) log("manual network selection: failed!");
-                        displayNetworkSelectionFailed(ar.exception);
-                    } else {
-                        if (DBG) log("manual network selection: succeeded!");
-                        displayNetworkSelectionSucceeded();
-                    }
-
-                    break;
-                case EVENT_AUTO_SELECT_DONE:
-                    if (DBG) log("hideProgressPanel");
-
-                    // Always try to dismiss the dialog because activity may
-                    // be moved to background after dialog is shown.
-                    try {
-                        dismissDialog(DIALOG_NETWORK_AUTO_SELECT);
-                    } catch (IllegalArgumentException e) {
-                        // "auto select" is always trigged in foreground, so "auto select" dialog
-                        //  should be shown when "auto select" is trigged. Should NOT get
-                        // this exception, and Log it.
-                        Log.w(LOG_TAG, "[NetworksList] Fail to dismiss auto select dialog ", e);
-                    }
-                    getPreferenceScreen().setEnabled(true);
-
-                    ar = (AsyncResult) msg.obj;
-                    if (ar.exception != null) {
-                        if (DBG) log("automatic network selection: failed!");
-                        displayNetworkSelectionFailed(ar.exception);
-                    } else {
-                        if (DBG) log("automatic network selection: succeeded!");
-                        displayNetworkSelectionSucceeded();
-                    }
-
-                    break;
-            }
-
-            return;
-        }
-    };
-
-    /**
-     * Service connection code for the NetworkQueryService.
-     * Handles the work of binding to a local object so that we can make
-     * the appropriate service calls.
-     */
-
-    /** Local service interface */
-    private INetworkQueryService mNetworkQueryService = null;
-
-    /** Service connection */
-    private final ServiceConnection mNetworkQueryServiceConnection = new ServiceConnection() {
-
-        /** Handle the task of binding the local object to the service */
-        public void onServiceConnected(ComponentName className, IBinder service) {
-            if (DBG) log("connection created, binding local service.");
-            mNetworkQueryService = ((NetworkQueryService.LocalBinder) service).getService();
-        }
-
-        /** Handle the task of cleaning up the local binding */
-        public void onServiceDisconnected(ComponentName className) {
-            if (DBG) log("connection disconnected, cleaning local binding.");
-            mNetworkQueryService = null;
-        }
-    };
-
-    /**
-     * This implementation of INetworkQueryServiceCallback is used to receive
-     * callback notifications from the network query service.
-     */
-    private final INetworkQueryServiceCallback mCallback = new INetworkQueryServiceCallback.Stub() {
-
-        /** place the message on the looper queue upon query completion. */
-        public void onQueryComplete(List<OperatorInfo> networkInfoArray, int status) {
-            if (DBG) log("notifying message loop of query completion.");
-            Message msg = mHandler.obtainMessage(EVENT_NETWORK_SCAN_COMPLETED,
-                    status, 0, networkInfoArray);
-            msg.sendToTarget();
-        }
-    };
-
-    @Override
-    public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
-        boolean handled = false;
-
-        if (preference == mSearchButton) {
-            loadNetworksList();
-            handled = true;
-        } else if (preference == mAutoSelect) {
-            selectNetworkAutomatic();
-            handled = true;
-        } else {
-            Preference selectedCarrier = preference;
-
-            String networkStr = selectedCarrier.getTitle().toString();
-            if (DBG) log("selected network: " + networkStr);
-
-            Message msg = mHandler.obtainMessage(EVENT_NETWORK_SELECTION_DONE);
-            Phone phone = PhoneFactory.getPhone(mPhoneId);
-            if (phone != null) {
-                phone.selectNetworkManually(mNetworkMap.get(selectedCarrier), true, msg);
-                displayNetworkSeletionInProgress(networkStr);
-                handled = true;
-            } else {
-                log("Error selecting network. phone is null.");
-            }
-
-
-        }
-
-        return handled;
-    }
-
-    //implemented for DialogInterface.OnCancelListener
-    public void onCancel(DialogInterface dialog) {
-        // request that the service stop the query with this callback object.
-        try {
-            mNetworkQueryService.stopNetworkQuery(mCallback);
-        } catch (RemoteException e) {
-            log("onCancel: exception from stopNetworkQuery " + e);
-        }
-        finish();
-    }
-
-    public String getNormalizedCarrierName(OperatorInfo ni) {
-        if (ni != null) {
-            return ni.getOperatorAlphaLong() + " (" + ni.getOperatorNumeric() + ")";
-        }
-        return null;
-    }
-
-    @Override
-    protected void onCreate(Bundle icicle) {
-        super.onCreate(icicle);
-
-        mUm = (UserManager) getSystemService(Context.USER_SERVICE);
-
-        if (mUm.hasUserRestriction(UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS)) {
-            setContentView(R.layout.telephony_disallowed_preference_screen);
-            mUnavailable = true;
-            return;
-        }
-
-        addPreferencesFromResource(R.xml.carrier_select);
-
-        int subId;
-        Intent intent = getIntent();
-        if (intent != null && intent.getExtras() != null) {
-            subId = intent.getExtras().getInt(GsmUmtsOptions.EXTRA_SUB_ID);
-            if (SubscriptionManager.isValidSubscriptionId(subId)) {
-                mPhoneId = SubscriptionManager.getPhoneId(subId);
-            }
-        }
-
-        mNetworkList = (PreferenceGroup) getPreferenceScreen().findPreference(LIST_NETWORKS_KEY);
-        mNetworkMap = new HashMap<Preference, OperatorInfo>();
-
-        mSearchButton = getPreferenceScreen().findPreference(BUTTON_SRCH_NETWRKS_KEY);
-        mAutoSelect = getPreferenceScreen().findPreference(BUTTON_AUTO_SELECT_KEY);
-
-        // Start the Network Query service, and bind it.
-        // The OS knows to start he service only once and keep the instance around (so
-        // long as startService is called) until a stopservice request is made.  Since
-        // we want this service to just stay in the background until it is killed, we
-        // don't bother stopping it from our end.
-        startService (new Intent(this, NetworkQueryService.class));
-        bindService (new Intent(this, NetworkQueryService.class).setAction(
-                NetworkQueryService.ACTION_LOCAL_BINDER),
-                mNetworkQueryServiceConnection, Context.BIND_AUTO_CREATE);
-    }
-
-    @Override
-    public void onResume() {
-        super.onResume();
-        mIsForeground = true;
-    }
-
-    @Override
-    public void onPause() {
-        super.onPause();
-        mIsForeground = false;
-    }
-
-    /**
-     * Override onDestroy() to unbind the query service, avoiding service
-     * leak exceptions.
-     */
-    @Override
-    protected void onDestroy() {
-        try {
-            // used to un-register callback
-            mNetworkQueryService.unregisterCallback(mCallback);
-        } catch (RemoteException e) {
-            log("onDestroy: exception from unregisterCallback " + e);
-        }
-
-        if (!mUnavailable) {
-            // unbind the service.
-            unbindService(mNetworkQueryServiceConnection);
-        }
-        super.onDestroy();
-    }
-
-    @Override
-    protected Dialog onCreateDialog(int id) {
-
-        if ((id == DIALOG_NETWORK_SELECTION) || (id == DIALOG_NETWORK_LIST_LOAD) ||
-                (id == DIALOG_NETWORK_AUTO_SELECT)) {
-            ProgressDialog dialog = new ProgressDialog(this);
-            switch (id) {
-                case DIALOG_NETWORK_SELECTION:
-                    // It would be more efficient to reuse this dialog by moving
-                    // this setMessage() into onPreparedDialog() and NOT use
-                    // removeDialog().  However, this is not possible since the
-                    // message is rendered only 2 times in the ProgressDialog -
-                    // after show() and before onCreate.
-                    dialog.setMessage(mNetworkSelectMsg);
-                    dialog.setCancelable(false);
-                    dialog.setIndeterminate(true);
-                    break;
-                case DIALOG_NETWORK_AUTO_SELECT:
-                    dialog.setMessage(getResources().getString(R.string.register_automatically));
-                    dialog.setCancelable(false);
-                    dialog.setIndeterminate(true);
-                    break;
-                case DIALOG_NETWORK_LIST_LOAD:
-                default:
-                    // reinstate the cancelablity of the dialog.
-                    dialog.setMessage(getResources().getString(R.string.load_networks_progress));
-                    dialog.setCanceledOnTouchOutside(false);
-                    dialog.setOnCancelListener(this);
-                    break;
-            }
-            return dialog;
-        }
-        return null;
-    }
-
-    @Override
-    protected void onPrepareDialog(int id, Dialog dialog) {
-        if ((id == DIALOG_NETWORK_SELECTION) || (id == DIALOG_NETWORK_LIST_LOAD) ||
-                (id == DIALOG_NETWORK_AUTO_SELECT)) {
-            // when the dialogs come up, we'll need to indicate that
-            // we're in a busy state to dissallow further input.
-            getPreferenceScreen().setEnabled(false);
-        }
-    }
-
-    private void displayEmptyNetworkList(boolean flag) {
-        mNetworkList.setTitle(flag ? R.string.empty_networks_list : R.string.label_available);
-    }
-
-    private void displayNetworkSeletionInProgress(String networkStr) {
-        // TODO: use notification manager?
-        mNetworkSelectMsg = getResources().getString(R.string.register_on_network, networkStr);
-
-        if (mIsForeground) {
-            showDialog(DIALOG_NETWORK_SELECTION);
-        }
-    }
-
-    private void displayNetworkQueryFailed(int error) {
-        String status = getResources().getString(R.string.network_query_error);
-
-        final PhoneGlobals app = PhoneGlobals.getInstance();
-        app.notificationMgr.postTransientNotification(
-                NotificationMgr.NETWORK_SELECTION_NOTIFICATION, status);
-    }
-
-    private void displayNetworkSelectionFailed(Throwable ex) {
-        String status;
-
-        if ((ex != null && ex instanceof CommandException) &&
-                ((CommandException)ex).getCommandError()
-                  == CommandException.Error.ILLEGAL_SIM_OR_ME)
-        {
-            status = getResources().getString(R.string.not_allowed);
-        } else {
-            status = getResources().getString(R.string.connect_later);
-        }
-
-        final PhoneGlobals app = PhoneGlobals.getInstance();
-        app.notificationMgr.postTransientNotification(
-                NotificationMgr.NETWORK_SELECTION_NOTIFICATION, status);
-
-        TelephonyManager tm = (TelephonyManager) app.getSystemService(Context.TELEPHONY_SERVICE);
-        Phone phone = PhoneFactory.getPhone(mPhoneId);
-        if (phone != null) {
-            ServiceState ss = tm.getServiceStateForSubscriber(phone.getSubId());
-            if (ss != null) {
-                app.notificationMgr.updateNetworkSelection(ss.getState(), phone.getSubId());
-            }
-        }
-    }
-
-    private void displayNetworkSelectionSucceeded() {
-        String status = getResources().getString(R.string.registration_done);
-
-        final PhoneGlobals app = PhoneGlobals.getInstance();
-        app.notificationMgr.postTransientNotification(
-                NotificationMgr.NETWORK_SELECTION_NOTIFICATION, status);
-
-        mHandler.postDelayed(new Runnable() {
-            public void run() {
-                finish();
-            }
-        }, 3000);
-    }
-
-    private void loadNetworksList() {
-        if (DBG) log("load networks list...");
-
-        if (mIsForeground) {
-            showDialog(DIALOG_NETWORK_LIST_LOAD);
-        }
-
-        // delegate query request to the service.
-        try {
-            mNetworkQueryService.startNetworkQuery(mCallback, mPhoneId);
-        } catch (RemoteException e) {
-            log("loadNetworksList: exception from startNetworkQuery " + e);
-            if (mIsForeground) {
-                try {
-                    dismissDialog(DIALOG_NETWORK_LIST_LOAD);
-                } catch (IllegalArgumentException e1) {
-                    // do nothing
-                }
-            }
-        }
-
-        displayEmptyNetworkList(false);
-    }
-
-    /**
-     * networksListLoaded has been rewritten to take an array of
-     * OperatorInfo objects and a status field, instead of an
-     * AsyncResult.  Otherwise, the functionality which takes the
-     * OperatorInfo array and creates a list of preferences from it,
-     * remains unchanged.
-     */
-    private void networksListLoaded(List<OperatorInfo> result, int status) {
-        if (DBG) log("networks list loaded");
-
-        // used to un-register callback
-        try {
-            mNetworkQueryService.unregisterCallback(mCallback);
-        } catch (RemoteException e) {
-            log("networksListLoaded: exception from unregisterCallback " + e);
-        }
-
-        // update the state of the preferences.
-        if (DBG) log("hideProgressPanel");
-
-        // Always try to dismiss the dialog because activity may
-        // be moved to background after dialog is shown.
-        try {
-            dismissDialog(DIALOG_NETWORK_LIST_LOAD);
-        } catch (IllegalArgumentException e) {
-            // It's not a error in following scenario, we just ignore it.
-            // "Load list" dialog will not show, if NetworkQueryService is
-            // connected after this activity is moved to background.
-            if (DBG) log("Fail to dismiss network load list dialog " + e);
-        }
-
-        getPreferenceScreen().setEnabled(true);
-        clearList();
-
-        if (status != NetworkQueryService.QUERY_OK) {
-            if (DBG) log("error while querying available networks");
-            displayNetworkQueryFailed(status);
-            displayEmptyNetworkList(true);
-        } else {
-            if (result != null){
-                displayEmptyNetworkList(false);
-
-                // create a preference for each item in the list.
-                // just use the operator name instead of the mildly
-                // confusing mcc/mnc.
-                for (OperatorInfo ni : result) {
-                    Preference carrier = new Preference(this, null);
-                    carrier.setTitle(getNetworkTitle(ni));
-                    carrier.setPersistent(false);
-                    mNetworkList.addPreference(carrier);
-                    mNetworkMap.put(carrier, ni);
-
-                    if (DBG) log("  " + ni);
-                }
-            } else {
-                displayEmptyNetworkList(true);
-            }
-        }
-    }
-
-    /**
-     * Returns the title of the network obtained in the manual search.
-     *
-     * @param OperatorInfo contains the information of the network.
-     *
-     * @return Long Name if not null/empty, otherwise Short Name if not null/empty,
-     * else MCCMNC string.
-     */
-
-    private String getNetworkTitle(OperatorInfo ni) {
-        if (!TextUtils.isEmpty(ni.getOperatorAlphaLong())) {
-            return ni.getOperatorAlphaLong();
-        } else if (!TextUtils.isEmpty(ni.getOperatorAlphaShort())) {
-            return ni.getOperatorAlphaShort();
-        } else {
-            BidiFormatter bidiFormatter = BidiFormatter.getInstance();
-            return bidiFormatter.unicodeWrap(ni.getOperatorNumeric(), TextDirectionHeuristics.LTR);
-        }
-    }
-
-    private void clearList() {
-        for (Preference p : mNetworkMap.keySet()) {
-            mNetworkList.removePreference(p);
-        }
-        mNetworkMap.clear();
-    }
-
-    private void selectNetworkAutomatic() {
-        if (DBG) log("select network automatically...");
-        if (mIsForeground) {
-            showDialog(DIALOG_NETWORK_AUTO_SELECT);
-        }
-
-        Message msg = mHandler.obtainMessage(EVENT_AUTO_SELECT_DONE);
-        Phone phone = PhoneFactory.getPhone(mPhoneId);
-        if (phone != null) {
-            phone.setNetworkSelectionModeAutomatic(msg);
-        }
-    }
-
-    private void log(String msg) {
-        Log.d(LOG_TAG, "[NetworksList] " + msg);
-    }
-}
diff --git a/src/com/android/phone/NotificationMgr.java b/src/com/android/phone/NotificationMgr.java
index eefa2c5..38eb946 100644
--- a/src/com/android/phone/NotificationMgr.java
+++ b/src/com/android/phone/NotificationMgr.java
@@ -16,6 +16,8 @@
 
 package com.android.phone;
 
+import static android.Manifest.permission.READ_PHONE_STATE;
+
 import android.app.Notification;
 import android.app.NotificationManager;
 import android.app.PendingIntent;
@@ -60,8 +62,6 @@
 import java.util.List;
 import java.util.Set;
 
-import static android.Manifest.permission.READ_PHONE_STATE;
-
 /**
  * NotificationManager-related utility code for the Phone app.
  *
@@ -603,10 +603,10 @@
         Intent intent = new Intent(Intent.ACTION_MAIN);
         intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
                 Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
-        // Use NetworkSetting to handle the selection intent
+        // Use MobileNetworkSettings to handle the selection intent
         intent.setComponent(new ComponentName(
-                mContext.getString(R.string.network_operator_settings_package),
-                mContext.getString(R.string.network_operator_settings_class)));
+                mContext.getString(R.string.mobile_network_settings_package),
+                mContext.getString(R.string.mobile_network_settings_class)));
         intent.putExtra(GsmUmtsOptions.EXTRA_SUB_ID, subId);
         PendingIntent contentIntent = PendingIntent.getActivity(mContext, 0, intent, 0);
 
diff --git a/src/com/android/phone/PhoneSearchIndexablesProvider.java b/src/com/android/phone/PhoneSearchIndexablesProvider.java
index 1cee227..ed3c7df 100644
--- a/src/com/android/phone/PhoneSearchIndexablesProvider.java
+++ b/src/com/android/phone/PhoneSearchIndexablesProvider.java
@@ -102,7 +102,7 @@
         if (!mUserManager.isAdminUser()) {
             final String[] values = new String[]{"preferred_network_mode_key", "button_roaming_key",
                     "cdma_lte_data_service_key", "enabled_networks_key", "enhanced_4g_lte",
-                    "button_apn_key", "button_carrier_sel_key", "carrier_settings_key",
+                    "button_apn_key", "button_network_select_key", "carrier_settings_key",
                     "cdma_system_select_key", "esim_list_profile"};
             for (String nik : values) {
                 cursor.addRow(createNonIndexableRow(nik));
